APUE Learning Example Source Code
guowenxue
2019-06-26 157be0b0d4c7d4809cfcafc76235cc18388378c8
add proj1_mqttd
713 files added
588186 ■■■■■ changed files
proj1_mqttd/etc/conf.c 139 ●●●●● patch | view | raw | blame | history
proj1_mqttd/etc/conf.h 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/etc/makefile 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/etc/mqttd.conf 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/cJSON.c 750 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/cJSON.h 149 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/comport.c 574 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/comport.h 106 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/ini_dictionary.c 398 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/ini_dictionary.h 165 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/iniparser.c 807 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/iniparser.h 308 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/klist.h 723 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/logger.c 364 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/logger.h 104 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/makefile 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/proc.c 341 ●●●●● patch | view | raw | blame | history
proj1_mqttd/lylib/proc.h 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/main.c 304 ●●●●● patch | view | raw | blame | history
proj1_mqttd/makefile 73 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/build.sh 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3.tar.gz patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/CMakeLists.txt 118 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/CONTRIBUTING.md 92 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/ChangeLog.txt 2175 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/LICENSE.txt 2 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/Makefile 130 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/about.html 44 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/aclfile.example 9 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/CMakeLists.txt 29 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/Makefile 82 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_props.c 193 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_props.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.c 1449 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.h 131 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_client.c 537 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_client.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.c 126 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.h 43 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_test_properties 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/rr_client.c 370 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_client.c 367 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_client_output.c 336 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_test_properties 31 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/compiling.txt 20 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/config.h 69 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/config.mk 314 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.in.out patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.out 487908 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.po.out patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/edl-v10 31 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/epl-v10 221 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/mysql_log/Makefile 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/mysql_log/mysql_log.c 123 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/Makefile 29 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/callback.c 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/multiple.c 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/single.c 33 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/Makefile 18 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/main.cpp 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/readme.txt 6 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/temperature_conversion.cpp 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/temperature_conversion.h 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/installer/mosquitto.nsi 128 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/installer/mosquitto64.nsi 129 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/CMakeLists.txt 113 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/Makefile 220 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/actions.c 260 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/actions.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/alias_mosq.c 85 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/alias_mosq.h 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/callbacks.c 120 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/callbacks.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/connect.c 330 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/connect.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/CMakeLists.txt 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/Makefile 48 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/libmosquittopp.so.1 patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.cpp 381 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.h 146 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/dummypthread.h 13 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_auth.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_auth.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_connack.c 110 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_connack.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_disconnect.c 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_disconnect.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_ping.c 70 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_ping.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubackcomp.c 118 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubackcomp.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_publish.c 167 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_publish.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrec.c 110 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrec.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrel.c 126 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrel.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_suback.c 98 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_suback.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_unsuback.c 87 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_unsuback.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/helpers.c 227 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/helpers.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/libmosquitto.so.1 patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/linker.version 134 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.c 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.h 23 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/loop.c 390 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/loop.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.c 160 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.h 41 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.c 348 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.h 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.c 612 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.h 2993 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto_internal.h 358 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mqtt_protocol.h 158 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.c 1090 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.h 82 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq_ocsp.c 159 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq_ocsp.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/options.c 486 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/options.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_datatypes.c 271 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_datatypes.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.c 456 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.h 56 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.c 1181 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.h 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.c 70 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.h 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_connect.c 204 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_connect.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_disconnect.c 85 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_disconnect.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.c 188 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.h 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_publish.c 215 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_publish.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_subscribe.c 96 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_subscribe.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_unsubscribe.c 99 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_unsubscribe.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.c 460 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.h 23 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/srv_mosq.c 112 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/srv_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/thread_mosq.c 133 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/thread_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.c 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.h 22 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.c 183 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.h 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/utf8_mosq.c 109 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/utf8_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.c 354 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.h 47 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_topic.c 252 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_topic.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.c 126 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.h 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.o patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/libmosquitto.pc.in 10 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/libmosquittopp.pc.in 10 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto-14x14.png patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto-16x16.png patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto.svg 182 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-logo-min.svg 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-logo-only.svg 60 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-text-below.svg 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-text-side.svg 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto.ico patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/CMakeLists.txt 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/Makefile 99 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/html.xsl 12 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3 253 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3.xml 506 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/manpage.xsl 14 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7 185 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7.xml 110 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8 465 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8.xml 551 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5 1560 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5.xml 1890 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1 125 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1.xml 158 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1 855 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1.xml 744 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1 1115 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1.xml 851 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1 1261 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1.meta 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1.xml 992 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7 293 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7.meta 6 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7.xml 187 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_log_mysql.pl 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_parse.pl 45 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_read.pl 23 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_read.py 22 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/CurrentCostMQTT.py 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/CurrentCostMQTT.server 28 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/currentcost.png patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/mosquitto.conf 988 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/notice.html 108 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/pskfile.example 2 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/pwfile.example 3 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/readme-windows.txt 63 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/readme.md 84 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/security/mosquitto.apparmor 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/monit/mosquitto.monit 4 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/svscan/run 3 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/README 9 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/mosquitto.service.notify 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/mosquitto.service.simple 13 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/service/upstart/mosquitto.conf 8 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/CMakeLists.txt 194 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/Makefile 293 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/bridge.c 489 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/conf.c 2388 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/conf_includedir.c 199 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/context.c 317 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/database.c 1157 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/db_dump/Makefile 16 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/db_dump/db_dump.c 618 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/deps/uthash.h 948 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/deps/utlist.h 1073 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_auth.c 148 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_connack.c 137 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_connect.c 883 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_disconnect.c 75 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_publish.c 367 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_subscribe.c 217 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_unsubscribe.c 125 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/lib_load.h 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/linker-macosx.syms 10 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/linker.syms 12 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/logging.c 404 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/loop.c 844 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto.c 471 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_broker.h 172 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_broker_internal.h 747 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_passwd.c 622 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_plugin.h 318 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/net.c 711 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist.h 157 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read.c 505 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read_v234.c 236 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read_v5.c 254 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_write.c 397 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_write_v5.c 232 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/plugin.c 118 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/plugin_defer.c 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/property_broker.c 133 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/read_handle.c 75 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/security.c 879 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/security_default.c 1131 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_auth.c 83 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_connack.c 95 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_suback.c 63 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_unsuback.c 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/service.c 170 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/session_expiry.c 110 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/signals.c 147 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/subs.c 1125 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/sys_tree.c 381 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/sys_tree.h 64 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/uhpa.h 171 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/websockets.c 777 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/src/will_delay.c 102 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/tags 8028 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/Makefile 24 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-anon-denied.pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-anon-denied.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-bad-packet.py 35 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-disconnect-v5.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-duplicate-v5.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-duplicate.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-0-311.py 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-0.py 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-missing.py 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-utf8.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-protonum.py 28 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-reserved.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-success-v5.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-success.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-invalid-utf8.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-flag.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-password-denied.pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-password-denied.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied-no-will.py 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied.pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success-no-tls.pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success-no-tls.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success.pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-pwd-no-flag.py 32 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-shared-qos0-v5.py 132 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subhier-crash.py 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-retain-as-publish.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-send-retain.py 76 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-subscription-id.py 103 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-topic-alias-unknown.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-topic-alias.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-v5.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-bad-pubcomp.py 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-bad-pubrec.py 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry-retain.py 86 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry-will.py 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry.py 73 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-nolocal.py 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-v5.py 47 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-puback-1.py 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-puback-2.py 64 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-pubcomp.py 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-pubrec-error-helper.py 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-pubrec-error.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-1.py 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-2.py 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-helper.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-v5.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-dollar-v5.py 41 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-invalid-utf8.py 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-persistence-flipflop.py 83 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos0.py 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos1.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos2.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-invalid-no-topic.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos0.py 35 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos1.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-multiple-v5.py 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-multiple.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-v5.py 35 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-pattern-matching-helper.py 20 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-pattern-matching.py 79 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos1-helper.py 25 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos1.py 63 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos2-helper.py 30 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos2.py 67 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos1-len-helper.py 24 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos1-len.py 69 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos2-len-helper.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos2-len.py 76 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos1-helper.py 24 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos1.py 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos2-helper.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos2.py 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-disconnect-qos2.py 56 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-qos2-len.py 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-timeout-qos2.py 42 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-dollar-v5.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-dollar.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-invalid-utf8.py 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-no-subscribers-v5.py 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-queued-bytes.conf 4 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-queued-bytes.py 161 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-retain-disabled.py 48 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1.py 34 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos2.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source-persist-diff-port.py 108 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source-persist.py 97 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source.py 78 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-clear.py 60 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-fresh.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-repeated.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos1-qos0.py 42 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-upgrade-outgoing-qos.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-clean-session-qos1-helper.py 25 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-clean-session-qos1.py 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-session-expiry-v5.py 87 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-disconnect-qos1.py 97 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-disconnect-qos2.py 114 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-late-connection-retain.py 95 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-late-connection.py 73 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-remapping.py 129 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos1-helper.py 24 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos1.py 94 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos2-helper.py 30 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos2.py 116 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-remapping.py 116 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-fail-persist-resend-qos1.py 86 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-fail-persist-resend-qos2.py 99 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-no-local.py 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-per-listener-settings.py 131 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-reconnect-local-out-helper.py 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-reconnect-local-out.py 96 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay-reconnect.py 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay-recover.py 60 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-disconnect-with-will.py 48 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-invalid-utf8.py 31 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-no-flag.py 33 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null-helper.py 18 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null-topic.py 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null.py 41 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-properties.py 93 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-qos0.py 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-reconnect-1273.py 75 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-bridge-helper.py 21 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-bridge.py 76 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-crl.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-expired.py 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-revoked.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-without.py 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-identity.py 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-auth-wrong-ca.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-auth.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-identity.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-bridge.psk 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-bridge.py 94 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-pub.psk 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-pub.py 69 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-access-variants.py 98 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-change.py 124 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-empty-file.py 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-auth-bad-method.py 29 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-change-username.py 84 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-multistep-reauth.py 91 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-multistep.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-single.py 84 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-single2.py 88 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-unsupported.py 33 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-pub.py 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-sub-denied.py 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-sub.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-context-params.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-defer-unpwd-fail.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-defer-unpwd-success.py 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-msg-params.py 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-unpwd-fail.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-unpwd-success.py 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-v2-unpwd-fail.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-v2-unpwd-success.py 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-pwfile-parse-invalid.py 165 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/10-listener-mount-point-helper.py 20 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/10-listener-mount-point.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-message-expiry.py 105 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription-no-local.py 96 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription-v5.py 74 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription.py 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-pub-props.py 77 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-subscription-id.py 84 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-assigned-client-identifier.py 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-broker.py 41 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-connect.py 30 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish-qos1.py 51 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish-qos2.py 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish.py 42 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-response-topic-correlation-data.py 60 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-response-topic.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-server-keepalive.py 42 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-session-expiry-invalid.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-subpub-content-type.py 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-subpub-payload-format.py 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-topic-alias-invalid.py 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/Makefile 214 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/08-tls-psk-bridge.c 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/08-tls-psk-pub.c 70 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/Makefile 40 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin.c 71 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_acl.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_acl_sub_denied.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_context_params.c 91 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_multiple.c 80 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_single.c 78 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_single2.c 78 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_msg_params.c 76 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_pwd.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_v2.c 67 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/mosquitto_plugin_v2.h 228 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/mosq_test_helper.py 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/prop_subpub_helper.py 43 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/readme.txt 19 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/test.py 182 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-con-discon-success.py 56 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-keepalive-pingreq.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-no-clean-session.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-server-keepalive-pingreq.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-unpwd-set.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-will-set.py 48 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-will-unpwd-set.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos0.py 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos1.py 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos2.py 65 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe-multiple-v5.py 63 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe-v5.py 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe.py 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos1.py 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos2-len.py 79 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos2.py 83 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-disconnect.py 67 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-len.py 77 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-receive-maximum.py 102 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-timeout.py 73 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-disconnect.py 82 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-len.py 86 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-maximum-qos-0.py 68 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-maximum-qos-1.py 74 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-pubrec-error.py 85 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-receive-maximum-1.py 118 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-receive-maximum-2.py 119 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-timeout.py 83 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2.py 79 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-qos0-no-payload.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-qos0.py 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-request-response-correlation.py 91 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-request-response.py 84 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/04-retain-qos0.py 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-bad-cacert.py 25 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-cert-auth-enc.py 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-cert-auth.py 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-no-auth.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-fake-cacert.py 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/09-util-topic-tokenise.py 18 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-oversize-packet.py 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-send-content-type.py 53 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-send-payload-format.py 63 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/Makefile 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-con-discon-success.c 45 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-keepalive-pingreq.c 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-no-clean-session.c 27 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-server-keepalive-pingreq.c 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-unpwd-set.c 28 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-will-set.c 28 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-will-unpwd-set.c 29 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos0.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos1.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos2.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe-multiple-v5.c 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe-v5.c 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos1.c 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos2-len.c 74 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos2.c 68 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-disconnect.c 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-len.c 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-receive-maximum.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-disconnect.c 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-len.c 52 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c 59 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-pubrec-error.c 49 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2.c 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-qos0-no-payload.c 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-qos0.c 50 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-1.c 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-2.c 66 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-correlation-1.c 62 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/04-retain-qos0.c 38 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-bad-cacert.c 20 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-cert-auth-enc.c 54 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-cert-auth.c 45 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-no-auth.c 45 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-fake-cacert.c 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/09-util-topic-tokenise.c 130 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-oversize-packet.c 72 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-send-content-type.c 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-send-payload-format.c 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/Makefile 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-con-discon-success.cpp 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-keepalive-pingreq.cpp 43 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-no-clean-session.cpp 35 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-unpwd-set.cpp 36 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-will-set.cpp 39 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-will-unpwd-set.cpp 37 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos0.cpp 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos1.cpp 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos2.cpp 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-unsubscribe.cpp 57 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-b2c-qos1.cpp 78 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-b2c-qos2.cpp 80 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp 70 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp 70 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos2.cpp 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-qos0-no-payload.cpp 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-qos0.cpp 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/04-retain-qos0.cpp 47 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-bad-cacert.cpp 31 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp 64 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-cert-auth.cpp 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-no-auth.cpp 55 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-fake-cacert.cpp 44 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/09-util-topic-tokenise.cpp 129 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/Makefile 96 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/mosq_test_helper.py 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/test.py 86 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mosq_test.py 620 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_opts.py 5 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_props.py 73 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_rc.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/Makefile 25 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_common.h 9 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_pub.c 81 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_sub.c 82 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ptest.py 78 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/Makefile 26 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/auth_plugin.c 56 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/pwfile 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/random.conf 92 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/random_client.py 150 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/test.py 46 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/all-ca.crt 75 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-encrypted.crt 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-encrypted.key 18 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-expired.crt 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-revoked.crt 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-revoked.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client.crt 61 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/crl.pem 10 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/crlnumber 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/index.txt 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/index.txt.attr 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/serial 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/gen.sh 75 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/openssl.cnf 406 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/readme.txt 2 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/crlnumber 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/index.txt.attr 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/serial 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server-expired.crt patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server.crt 60 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/crlnumber 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/index.txt.attr 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/serial 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-alt-ca.crt 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-alt-ca.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-bad-root-ca.crt 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-bad-root-ca.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-ca.srl 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-fake-root-ca.crt 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-fake-root-ca.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-root-ca.crt 17 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-root-ca.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-signing-ca.crt 58 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-signing-ca.key 15 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/Makefile 127 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/datatype_read.c 829 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/datatype_write.c 153 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/corrupt-header-long.test-db 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/corrupt-header-short.test-db 1 ●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/empty.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/unsupported-version.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-bad-chunk.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg-bad-dbid.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg-truncated.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-client-message.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-client.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-message-store.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-retain.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-sub.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v4-cfg.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v4-message-store.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-bad-chunk.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-cfg-truncated.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-cfg.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client-message-props.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client-message.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-message-store-props.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-message-store.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-retain.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-sub.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/empty.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/v4-full.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/v5-message-store-no-ref.test-db patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_read_stubs.c 150 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_read_test.c 820 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_write_stubs.c 71 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_write_test.c 386 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_add.c 614 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_read.c 1910 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_user_read.c 613 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_write.c 576 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/publish_test.c 43 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/stubs.c 6 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/test.c 47 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/utf8.c 482 ●●●●● patch | view | raw | blame | history
proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/util_topic_test.c 284 ●●●●● patch | view | raw | blame | history
proj1_mqttd/etc/conf.c
New file
@@ -0,0 +1,139 @@
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  conf.c
 *    Description:  This file is mqttd configure file parser function
 *
 *        Version:  1.0.0(2019年06月25日)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "2019年06月25日 22时23分55秒"
 *
 ********************************************************************************/
#include "conf.h"
#include "lylib/logger.h"
#include "lylib/iniparser.h"
int mqttd_parser_conf(const char *conf_file, mqtt_ctx_t *ctx, int debug)
{
    dictionary          *ini;
    char                *str;
    int                  val;
    memset(ctx, 0, sizeof(*ctx));
    if( !conf_file )
    {
        /* logger settings */
        strncpy(ctx->logfile, DBG_LOG_FILE, sizeof(ctx->logfile));
        ctx->loglevel = LOG_LEVEL_DEBUG;
        ctx->logsize = 1024;
        if( logger_init(ctx->logfile, ctx->loglevel, ctx->logsize) < 0 )
        {
            fprintf(stderr, "Logger system initialise failure\n");
            return -2;
        }
        log_nrml("Logger system initialise ok\n");
        log_warn("WARNNING: Use default MQTT configure\n");
        /* Broker settings */
        strncpy(ctx->host, DEF_BORKER_HOSTNAME, sizeof(ctx->host));
        ctx->port = DEF_BROKER_PORT;
        log_nrml("Use default broker server [%s:%d]\n", ctx->host, ctx->port);
        strncpy(ctx->uid, DEF_BROKER_USERNAME, sizeof(ctx->uid));
        strncpy(ctx->pwd, DEF_BROKER_PASSWD, sizeof(ctx->pwd));
        log_nrml("Use default broker author by [%s:%s]\n", ctx->uid, ctx->pwd);
        ctx->keepalive = DEF_BROKER_KEEPALIVE;
        log_nrml("Use default broker keepalive timeout [%d] seconds\n", ctx->keepalive);
        /* Subscriber settings */
        strncpy(ctx->subTopic, DEF_SUBTOPIC, sizeof(ctx->subTopic));
        ctx->subQos = DEF_SUBQOS;
        log_nrml("Use default subscriber topic \"%s\" with Qos[%d]\n", ctx->subTopic, ctx->subQos);
        return 0;
    }
    ini = iniparser_load(conf_file);
    if( !ini )
    {
        fprintf(stderr, "ERROR: cannot parse file: '%s'\n", conf_file);
        return -1;
    }
    /*+------------------------------------------------------+
     *|    parser logger settings and start logger system    |
     *+------------------------------------------------------+*/
    if( !debug )
    {
        str = iniparser_getstring(ini, "logger:file", "/tmp/mqttd.log");
        strncpy(ctx->logfile, str, sizeof(ctx->logfile));
        ctx->logsize = iniparser_getint(ini, "logger:size", 1024);
        ctx->loglevel = iniparser_getint(ini, "logger:level", LOG_LEVEL_DEBUG);
    }
    else
    {
        strncpy(ctx->logfile, DBG_LOG_FILE, sizeof(ctx->logfile));
        ctx->loglevel = LOG_LEVEL_DEBUG;
        ctx->logsize = 1024;
    }
    if( logger_init(ctx->logfile, ctx->loglevel, ctx->logsize) < 0 )
    {
        fprintf(stderr, "Logger system initialise failure\n");
        return -2;
    }
    log_nrml("Logger system initialise ok\n");
    /*+------------------------------------------------------+
     *|              parser broker settings                  |
     *+------------------------------------------------------+*/
    if( !(str=iniparser_getstring(ini, "broker:hostname", NULL)) )
    {
        log_err("ERROR: Parser broker server hostname failure\n");
        return -2;
    }
    strncpy(ctx->host, str, sizeof(ctx->host) );
    if( (val=iniparser_getint(ini, "broker:port", -1)) < 0 )
    {
        log_err("ERROR: Parser broker server port failure\n");
        return -2;
    }
    ctx->port = val;
    log_nrml("Parser broker server [%s:%d]\n", ctx->host, ctx->port);
    str=iniparser_getstring(ini, "broker:username", DEF_BROKER_USERNAME);
    strncpy(ctx->uid, str, sizeof(ctx->uid) );
    str=iniparser_getstring(ini, "broker:password", DEF_BROKER_PASSWD);
    strncpy(ctx->pwd, str, sizeof(ctx->pwd) );
    log_nrml("Parser broker author by [%s:%s]\n", ctx->uid, ctx->pwd);
    ctx->keepalive = iniparser_getint(ini, "broker:keepalive", DEF_BROKER_KEEPALIVE);
    log_nrml("Parser broker keepalive timeout [%d] seconds\n", ctx->keepalive);
    /*+------------------------------------------------------+
     *|             parser subscriber settings               |
     *+------------------------------------------------------+*/
    str=iniparser_getstring(ini, "subsciber:subTopic", DEF_SUBTOPIC);
    strncpy(ctx->subTopic, str, sizeof(ctx->subTopic) );
    ctx->subQos = iniparser_getint(ini, "subsciber:subQos", DEF_SUBQOS);
    log_nrml("Parser subscriber topic \"%s\" with Qos[%d]\n", ctx->subTopic, ctx->subQos);
    return 0;
}
proj1_mqttd/etc/conf.h
New file
@@ -0,0 +1,58 @@
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  conf.h
 *    Description:  This file is mqttd configure file parser function
 *
 *        Version:  1.0.0(2019年06月25日)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "2019年06月25日 22时23分55秒"
 *
 ********************************************************************************/
#ifndef  __CONF_H_
#define  __CONF_H_
#define DEF_BORKER_HOSTNAME        "master.iot-yun.com"
#define DEF_BROKER_PORT            10883
#define DEF_BROKER_KEEPALIVE       30
#define DEF_BROKER_USERNAME        "lingyun"
#define DEF_BROKER_PASSWD          "lingyun-emb"
#define MQTT_SYS_TOPIC             "$Sys/Studio/"
#define DEF_SUBTOPIC               MQTT_SYS_TOPIC"Downlink"
#define DEF_SUBQOS                 0
enum
{
    Qos0, /* 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息 */
    Qos1, /* 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息 */
    Qos2, /* Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次  */
};
typedef struct mqtt_ctx_s
{
    /* logger settings */
    char          logfile[128]; /* logger record file */
    int           loglevel;     /* logger level  */
    int           logsize;      /* logger file maxsize, oversize will rollback */
    /* Broker settings  */
    char          host[128];  /* MQTT broker server name  */
    int           port;       /* MQTT broker listen port  */
    char          uid[64];    /* username */
    char          pwd[64];    /* password */
    int           keepalive;  /* MQTT broker send PING message to subsciber/publisher keepalive timeout<seconds> */
    /* Subscriber settings */
    char          subTopic[256]; /* Subscriber topic */
    int           subQos;        /* Subscriber Qos  */
} mqtt_ctx_t;
extern int mqttd_parser_conf(const char *conf_file, mqtt_ctx_t *ctx, int debug);
#endif   /* ----- #ifndef _CONF_H_  ----- */
proj1_mqttd/etc/makefile
New file
@@ -0,0 +1,17 @@
PWD=$(shell pwd )
LIBNAME=$(shell basename ${PWD} )
PROJPATH=$(shell dirname ${PWD} )
CFLAGS+=-I${PROJPATH}
all: clean
    @rm -f *.o
    @${CROSS_COMPILE}gcc ${CFLAGS} -c *.c
    ${CROSS_COMPILE}ar -rcs  lib${LIBNAME}.a *.o
clean:
    @rm -f *.o
    @rm -f *.a
proj1_mqttd/etc/mqttd.conf
New file
@@ -0,0 +1,39 @@
[logger]
# 日志记录文件
file=/tmp/mqttd.log
# 日志级别: 0:Disable 1:Fatal 2:ERROR 3:warnning 4:Normal 5:Debug 6:Infor 7:Trace
level=4
# 日志回滚大小
size=1024
[broker]
# broker 服务器地址和端口号
hostname="master.iot-yun.com"
port=10883
# broker 认证连接的用户名和密码
username="lingyun"
password="lingyun-emb"
# broker给subsciber和publisher发送PING报文保持 keepalive 的时间周期,单位是秒
keepalive=30
# Qos0: 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息
# Qos1: 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息
# Qos2: Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次
[subsciber]
subTopic="$Sys/Studio/Downlink"
subQos=0
proj1_mqttd/lylib/cJSON.c
New file
@@ -0,0 +1,750 @@
/*
  Copyright (c) 2009 Dave Gamble
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
/* cJSON */
/* JSON parser in C. */
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"
static const char *ep;
const char *cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
    if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
    for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)    if(*s1 == 0)    return 0;
    return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
      size_t len;
      char* copy;
      len = strlen(str) + 1;
      if (!(copy = (char*)cJSON_malloc(len))) return 0;
      memcpy(copy,str,len);
      return copy;
}
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
    if (!hooks) { /* Reset hooks */
        cJSON_malloc = malloc;
        cJSON_free = free;
        return;
    }
    cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
    cJSON_free     = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
    cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
    if (node) memset(node,0,sizeof(cJSON));
    return node;
}
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
    cJSON *next;
    while (c)
    {
        next=c->next;
        if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
        if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
        if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
        cJSON_free(c);
        c=next;
    }
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
    double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
    if (*num=='-') sign=-1,num++;    /* Has sign? */
    if (*num=='0') num++;            /* is zero */
    if (*num>='1' && *num<='9')    do    n=(n*10.0)+(*num++ -'0');    while (*num>='0' && *num<='9');    /* Number? */
    if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;        do    n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}    /* Fractional part? */
    if (*num=='e' || *num=='E')        /* Exponent? */
    {    num++;if (*num=='+') num++;    else if (*num=='-') signsubscale=-1,num++;        /* With sign? */
        while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');    /* Number? */
    }
    n=sign*n*pow(10.0,(scale+subscale*signsubscale));    /* number = +/- number.fraction * 10^+/- exponent */
    item->valuedouble=n;
    item->valueint=(int)n;
    item->type=cJSON_Number;
    return num;
}
static int pow2gt (int x)    {    --x;    x|=x>>1;    x|=x>>2;    x|=x>>4;    x|=x>>8;    x|=x>>16;    return x+1;    }
typedef struct {char *buffer; int length; int offset; } printbuffer;
static char* ensure(printbuffer *p,int needed)
{
    char *newbuffer;int newsize;
    if (!p || !p->buffer) return 0;
    needed+=p->offset;
    if (needed<=p->length) return p->buffer+p->offset;
    newsize=pow2gt(needed);
    newbuffer=(char*)cJSON_malloc(newsize);
    if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
    if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
    cJSON_free(p->buffer);
    p->length=newsize;
    p->buffer=newbuffer;
    return newbuffer+p->offset;
}
static int update(printbuffer *p)
{
    char *str;
    if (!p || !p->buffer) return 0;
    str=p->buffer+p->offset;
    return p->offset+strlen(str);
}
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item,printbuffer *p)
{
    char *str=0;
    double d=item->valuedouble;
    if (d==0)
    {
        if (p)    str=ensure(p,2);
        else    str=(char*)cJSON_malloc(2);    /* special case for 0. */
        if (str) strcpy(str,"0");
    }
    else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
    {
        if (p)    str=ensure(p,21);
        else    str=(char*)cJSON_malloc(21);    /* 2^64+1 can be represented in 21 chars. */
        if (str)    sprintf(str,"%d",item->valueint);
    }
    else
    {
        if (p)    str=ensure(p,64);
        else    str=(char*)cJSON_malloc(64);    /* This is a nice tradeoff. */
        if (str)
        {
            if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
            else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)            sprintf(str,"%e",d);
            else                                                sprintf(str,"%f",d);
        }
    }
    return str;
}
static unsigned parse_hex4(const char *str)
{
    unsigned h=0;
    if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
    h=h<<4;str++;
    if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
    h=h<<4;str++;
    if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
    h=h<<4;str++;
    if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
    return h;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
    const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
    if (*str!='\"') {ep=str;return 0;}    /* not a string! */
    while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;    /* Skip escaped quotes. */
    out=(char*)cJSON_malloc(len+1);    /* This is how long we need for the string, roughly. */
    if (!out) return 0;
    ptr=str+1;ptr2=out;
    while (*ptr!='\"' && *ptr)
    {
        if (*ptr!='\\') *ptr2++=*ptr++;
        else
        {
            ptr++;
            switch (*ptr)
            {
                case 'b': *ptr2++='\b';    break;
                case 'f': *ptr2++='\f';    break;
                case 'n': *ptr2++='\n';    break;
                case 'r': *ptr2++='\r';    break;
                case 't': *ptr2++='\t';    break;
                case 'u':     /* transcode utf16 to utf8. */
                    uc=parse_hex4(ptr+1);ptr+=4;    /* get the unicode char. */
                    if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)    break;    /* check for invalid.    */
                    if (uc>=0xD800 && uc<=0xDBFF)    /* UTF16 surrogate pairs.    */
                    {
                        if (ptr[1]!='\\' || ptr[2]!='u')    break;    /* missing second-half of surrogate.    */
                        uc2=parse_hex4(ptr+3);ptr+=6;
                        if (uc2<0xDC00 || uc2>0xDFFF)        break;    /* invalid second-half of surrogate.    */
                        uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
                    }
                    len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
                    switch (len) {
                        case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                        case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                        case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                        case 1: *--ptr2 =(uc | firstByteMark[len]);
                    }
                    ptr2+=len;
                    break;
                default:  *ptr2++=*ptr; break;
            }
            ptr++;
        }
    }
    *ptr2=0;
    if (*ptr=='\"') ptr++;
    item->valuestring=out;
    item->type=cJSON_String;
    return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str,printbuffer *p)
{
    const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
    for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
    if (!flag)
    {
        len=ptr-str;
        if (p) out=ensure(p,len+3);
        else        out=(char*)cJSON_malloc(len+3);
        if (!out) return 0;
        ptr2=out;*ptr2++='\"';
        strcpy(ptr2,str);
        ptr2[len]='\"';
        ptr2[len+1]=0;
        return out;
    }
    if (!str)
    {
        if (p)    out=ensure(p,3);
        else    out=(char*)cJSON_malloc(3);
        if (!out) return 0;
        strcpy(out,"\"\"");
        return out;
    }
    ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
    if (p)    out=ensure(p,len+3);
    else    out=(char*)cJSON_malloc(len+3);
    if (!out) return 0;
    ptr2=out;ptr=str;
    *ptr2++='\"';
    while (*ptr)
    {
        if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
        else
        {
            *ptr2++='\\';
            switch (token=*ptr++)
            {
                case '\\':    *ptr2++='\\';    break;
                case '\"':    *ptr2++='\"';    break;
                case '\b':    *ptr2++='b';    break;
                case '\f':    *ptr2++='f';    break;
                case '\n':    *ptr2++='n';    break;
                case '\r':    *ptr2++='r';    break;
                case '\t':    *ptr2++='t';    break;
                default: sprintf(ptr2,"u%04x",token);ptr2+=5;    break;    /* escape and print */
            }
        }
    }
    *ptr2++='\"';*ptr2++=0;
    return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item,printbuffer *p)    {return print_string_ptr(item->valuestring,p);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
    const char *end=0;
    cJSON *c=cJSON_New_Item();
    ep=0;
    if (!c) return 0;       /* memory fail */
    end=parse_value(c,skip(value));
    if (!end)    {cJSON_Delete(c);return 0;}    /* parse failure. ep is set. */
    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
    if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
    if (return_parse_end) *return_parse_end=end;
    return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item)                {return print_value(item,0,1,0);}
char *cJSON_PrintUnformatted(cJSON *item)    {return print_value(item,0,0,0);}
char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
{
    printbuffer p;
    p.buffer=(char*)cJSON_malloc(prebuffer);
    p.length=prebuffer;
    p.offset=0;
    return print_value(item,0,fmt,&p);
    return p.buffer;
}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
    if (!value)                        return 0;    /* Fail on null. */
    if (!strncmp(value,"null",4))    { item->type=cJSON_NULL;  return value+4; }
    if (!strncmp(value,"false",5))    { item->type=cJSON_False; return value+5; }
    if (!strncmp(value,"true",4))    { item->type=cJSON_True; item->valueint=1;    return value+4; }
    if (*value=='\"')                { return parse_string(item,value); }
    if (*value=='-' || (*value>='0' && *value<='9'))    { return parse_number(item,value); }
    if (*value=='[')                { return parse_array(item,value); }
    if (*value=='{')                { return parse_object(item,value); }
    ep=value;return 0;    /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p)
{
    char *out=0;
    if (!item) return 0;
    if (p)
    {
        switch ((item->type)&255)
        {
            case cJSON_NULL:    {out=ensure(p,5);    if (out) strcpy(out,"null");    break;}
            case cJSON_False:    {out=ensure(p,6);    if (out) strcpy(out,"false");    break;}
            case cJSON_True:    {out=ensure(p,5);    if (out) strcpy(out,"true");    break;}
            case cJSON_Number:    out=print_number(item,p);break;
            case cJSON_String:    out=print_string(item,p);break;
            case cJSON_Array:    out=print_array(item,depth,fmt,p);break;
            case cJSON_Object:    out=print_object(item,depth,fmt,p);break;
        }
    }
    else
    {
        switch ((item->type)&255)
        {
            case cJSON_NULL:    out=cJSON_strdup("null");    break;
            case cJSON_False:    out=cJSON_strdup("false");break;
            case cJSON_True:    out=cJSON_strdup("true"); break;
            case cJSON_Number:    out=print_number(item,0);break;
            case cJSON_String:    out=print_string(item,0);break;
            case cJSON_Array:    out=print_array(item,depth,fmt,0);break;
            case cJSON_Object:    out=print_object(item,depth,fmt,0);break;
        }
    }
    return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
    cJSON *child;
    if (*value!='[')    {ep=value;return 0;}    /* not an array! */
    item->type=cJSON_Array;
    value=skip(value+1);
    if (*value==']') return value+1;    /* empty array. */
    item->child=child=cJSON_New_Item();
    if (!item->child) return 0;         /* memory fail */
    value=skip(parse_value(child,skip(value)));    /* skip any spacing, get the value. */
    if (!value) return 0;
    while (*value==',')
    {
        cJSON *new_item;
        if (!(new_item=cJSON_New_Item())) return 0;     /* memory fail */
        child->next=new_item;new_item->prev=child;child=new_item;
        value=skip(parse_value(child,skip(value+1)));
        if (!value) return 0;    /* memory fail */
    }
    if (*value==']') return value+1;    /* end of array */
    ep=value;return 0;    /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p)
{
    char **entries;
    char *out=0,*ptr,*ret;int len=5;
    cJSON *child=item->child;
    int numentries=0,i=0,fail=0;
    size_t tmplen=0;
    /* How many entries in the array? */
    while (child) numentries++,child=child->next;
    /* Explicitly handle numentries==0 */
    if (!numentries)
    {
        if (p)    out=ensure(p,3);
        else    out=(char*)cJSON_malloc(3);
        if (out) strcpy(out,"[]");
        return out;
    }
    if (p)
    {
        /* Compose the output array. */
        i=p->offset;
        ptr=ensure(p,1);if (!ptr) return 0;    *ptr='[';    p->offset++;
        child=item->child;
        while (child && !fail)
        {
            print_value(child,depth+1,fmt,p);
            p->offset=update(p);
            if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}
            child=child->next;
        }
        ptr=ensure(p,2);if (!ptr) return 0;    *ptr++=']';*ptr=0;
        out=(p->buffer)+i;
    }
    else
    {
        /* Allocate an array to hold the values for each */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        memset(entries,0,numentries*sizeof(char*));
        /* Retrieve all the results: */
        child=item->child;
        while (child && !fail)
        {
            ret=print_value(child,depth+1,fmt,0);
            entries[i++]=ret;
            if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
            child=child->next;
        }
        /* If we didn't fail, try to malloc the output string */
        if (!fail)    out=(char*)cJSON_malloc(len);
        /* If that fails, we fail. */
        if (!out) fail=1;
        /* Handle failure. */
        if (fail)
        {
            for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
            cJSON_free(entries);
            return 0;
        }
        /* Compose the output array. */
        *out='[';
        ptr=out+1;*ptr=0;
        for (i=0;i<numentries;i++)
        {
            tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;
            if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
            cJSON_free(entries[i]);
        }
        cJSON_free(entries);
        *ptr++=']';*ptr++=0;
    }
    return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
    cJSON *child;
    if (*value!='{')    {ep=value;return 0;}    /* not an object! */
    item->type=cJSON_Object;
    value=skip(value+1);
    if (*value=='}') return value+1;    /* empty array. */
    item->child=child=cJSON_New_Item();
    if (!item->child) return 0;
    value=skip(parse_string(child,skip(value)));
    if (!value) return 0;
    child->string=child->valuestring;child->valuestring=0;
    if (*value!=':') {ep=value;return 0;}    /* fail! */
    value=skip(parse_value(child,skip(value+1)));    /* skip any spacing, get the value. */
    if (!value) return 0;
    while (*value==',')
    {
        cJSON *new_item;
        if (!(new_item=cJSON_New_Item()))    return 0; /* memory fail */
        child->next=new_item;new_item->prev=child;child=new_item;
        value=skip(parse_string(child,skip(value+1)));
        if (!value) return 0;
        child->string=child->valuestring;child->valuestring=0;
        if (*value!=':') {ep=value;return 0;}    /* fail! */
        value=skip(parse_value(child,skip(value+1)));    /* skip any spacing, get the value. */
        if (!value) return 0;
    }
    if (*value=='}') return value+1;    /* end of array */
    ep=value;return 0;    /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
{
    char **entries=0,**names=0;
    char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
    cJSON *child=item->child;
    int numentries=0,fail=0;
    size_t tmplen=0;
    /* Count the number of entries. */
    while (child) numentries++,child=child->next;
    /* Explicitly handle empty object case */
    if (!numentries)
    {
        if (p) out=ensure(p,fmt?depth+4:3);
        else    out=(char*)cJSON_malloc(fmt?depth+4:3);
        if (!out)    return 0;
        ptr=out;*ptr++='{';
        if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
        *ptr++='}';*ptr++=0;
        return out;
    }
    if (p)
    {
        /* Compose the output: */
        i=p->offset;
        len=fmt?2:1;    ptr=ensure(p,len+1);    if (!ptr) return 0;
        *ptr++='{';    if (fmt) *ptr++='\n';    *ptr=0;    p->offset+=len;
        child=item->child;depth++;
        while (child)
        {
            if (fmt)
            {
                ptr=ensure(p,depth);    if (!ptr) return 0;
                for (j=0;j<depth;j++) *ptr++='\t';
                p->offset+=depth;
            }
            print_string_ptr(child->string,p);
            p->offset=update(p);
            len=fmt?2:1;
            ptr=ensure(p,len);    if (!ptr) return 0;
            *ptr++=':';if (fmt) *ptr++='\t';
            p->offset+=len;
            print_value(child,depth,fmt,p);
            p->offset=update(p);
            len=(fmt?1:0)+(child->next?1:0);
            ptr=ensure(p,len+1); if (!ptr) return 0;
            if (child->next) *ptr++=',';
            if (fmt) *ptr++='\n';*ptr=0;
            p->offset+=len;
            child=child->next;
        }
        ptr=ensure(p,fmt?(depth+1):2);     if (!ptr) return 0;
        if (fmt)    for (i=0;i<depth-1;i++) *ptr++='\t';
        *ptr++='}';*ptr=0;
        out=(p->buffer)+i;
    }
    else
    {
        /* Allocate space for the names and the objects */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        names=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!names) {cJSON_free(entries);return 0;}
        memset(entries,0,sizeof(char*)*numentries);
        memset(names,0,sizeof(char*)*numentries);
        /* Collect all the results into our arrays: */
        child=item->child;depth++;if (fmt) len+=depth;
        while (child)
        {
            names[i]=str=print_string_ptr(child->string,0);
            entries[i++]=ret=print_value(child,depth,fmt,0);
            if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
            child=child->next;
        }
        /* Try to allocate the output string */
        if (!fail)    out=(char*)cJSON_malloc(len);
        if (!out) fail=1;
        /* Handle failure */
        if (fail)
        {
            for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
            cJSON_free(names);cJSON_free(entries);
            return 0;
        }
        /* Compose the output: */
        *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
        for (i=0;i<numentries;i++)
        {
            if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
            tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;
            *ptr++=':';if (fmt) *ptr++='\t';
            strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
            if (i!=numentries-1) *ptr++=',';
            if (fmt) *ptr++='\n';*ptr=0;
            cJSON_free(names[i]);cJSON_free(entries[i]);
        }
        cJSON_free(names);cJSON_free(entries);
        if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
        *ptr++='}';*ptr++=0;
    }
    return out;
}
/* Get Array size/item / object item. */
int    cJSON_GetArraySize(cJSON *array)                            {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item)                {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)    {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                        {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)    {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void   cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item)    {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
void    cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                        {cJSON_AddItemToArray(array,create_reference(item));}
void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)            {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
    if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void   cJSON_DeleteItemFromArray(cJSON *array,int which)            {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
void   cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem)        {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}
    newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)        {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
    newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
    if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
cJSON *cJSON_CreateNull(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b)                    {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num)            {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string)    {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void)                    {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count)        {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
    cJSON *newitem,*cptr,*nptr=0,*newchild;
    /* Bail on bad ptr */
    if (!item) return 0;
    /* Create new item */
    newitem=cJSON_New_Item();
    if (!newitem) return 0;
    /* Copy over all vars */
    newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
    if (item->valuestring)    {newitem->valuestring=cJSON_strdup(item->valuestring);    if (!newitem->valuestring)    {cJSON_Delete(newitem);return 0;}}
    if (item->string)        {newitem->string=cJSON_strdup(item->string);            if (!newitem->string)        {cJSON_Delete(newitem);return 0;}}
    /* If non-recursive, then we're done! */
    if (!recurse) return newitem;
    /* Walk the ->next chain for the child. */
    cptr=item->child;
    while (cptr)
    {
        newchild=cJSON_Duplicate(cptr,1);        /* Duplicate (with recurse) each item in the ->next chain */
        if (!newchild) {cJSON_Delete(newitem);return 0;}
        if (nptr)    {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}    /* If newitem->child already set, then crosswire ->prev and ->next and move on */
        else        {newitem->child=newchild;nptr=newchild;}                    /* Set newitem->child and move to it */
        cptr=cptr->next;
    }
    return newitem;
}
void cJSON_Minify(char *json)
{
    char *into=json;
    while (*json)
    {
        if (*json==' ') json++;
        else if (*json=='\t') json++;    /* Whitespace characters. */
        else if (*json=='\r') json++;
        else if (*json=='\n') json++;
        else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;    /* double-slash comments, to end of line. */
        else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}    /* multiline comments. */
        else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */
        else *into++=*json++;            /* All other characters. */
    }
    *into=0;    /* and null-terminate. */
}
proj1_mqttd/lylib/cJSON.h
New file
@@ -0,0 +1,149 @@
/*
  Copyright (c) 2009 Dave Gamble
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON {
    struct cJSON *next,*prev;    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *child;        /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    int type;                    /* The type of the item, as above. */
    char *valuestring;            /* The item's string, if type==cJSON_String */
    int valueint;                /* The item's number, if type==cJSON_Number */
    double valuedouble;            /* The item's number, if type==cJSON_Number */
    char *string;                /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
      void *(*malloc_fn)(size_t sz);
      void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char  *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char  *cJSON_PrintUnformatted(cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
/* Delete a cJSON entity and all subentities. */
extern void   cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int      cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void    cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
extern void    cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item);    /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void   cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem);    /* Shifts pre-existing items to the right. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name)        cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b)    cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n)    cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)    cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val)            ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#define cJSON_SetNumberValue(object,val)        ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#ifdef __cplusplus
}
#endif
#endif
proj1_mqttd/lylib/comport.c
New file
@@ -0,0 +1,574 @@
/*  ********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  cp_comport.c
 *    Description:  It's the comport operate library.
 *
 *        Version:  2.0.0(10/17/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/17/2018 03:33:25 PM"
 *
 ********************************************************************************/
#include    "comport.h"
void set_settings(st_comport * comport, const char *settings);
/**************************************************************************************
 *  Description: Set the comport structure
 *   Input Args: dev_name:  The comport device name path, such as '/dev/ttyS3'
 *               baudrate:  The baudrate, such as 115200
 *               settings:  The databit,parity,stopbit,flowctrl settings, such as '8N1N'
 *  Output Args: NONE
 * Return Value: The st_comport structure pointer.
 *************************************************************************************/
st_comport *comport_init(const char *dev_name, int baudrate, const char *settings)
{
    st_comport *comport = NULL;
    if (NULL == (comport = (st_comport *) malloc(sizeof(st_comport))))
    {
        return NULL;
    }
    memset(comport, 0, sizeof(st_comport));
    comport->frag_size = 128;
    strncpy(comport->dev_name, dev_name, DEVNAME_LEN);
    comport->baudrate = baudrate;
    set_settings(comport, settings);
#ifdef  COM_DEBUG
    disp_settings(comport);
#endif
    return comport;
}
#ifdef  COM_DEBUG
void disp_settings(st_comport *comport)
{
    COM_PRINT("Device:\t\t\t\"%s\"\n", comport->dev_name);
    COM_PRINT("Baudrate:\t\t%ld\n", comport->baudrate);
    COM_PRINT("DataBit:\t\t\'%d\'\n", comport->databit);
    switch (comport->parity)
    {
      case 0:
          COM_PRINT("Parity:\t\t\t\'N\'\n");
          break;
      case 1:
          COM_PRINT("Parity:\t\t\t\'O\'\n");
          break;
      case 2:
          COM_PRINT("Parity:\t\t\t\'E\'\n");
          break;
      case 3:
          COM_PRINT("Parity:\t\t\t\'S\'\n");
          break;
    }
    COM_PRINT("StopBit:\t\t\'%ld\'\n", (long int)comport->stopbit);
    switch (comport->flowctrl)
    {
      case 0:
          COM_PRINT("FlowCtrl:\t\t\'N\'\n");
          break;
      case 1:
          COM_PRINT("FlowCtrl:\t\t\'S\'\n");
          break;
      case 2:
          COM_PRINT("FlowCtrl:\t\t\'H\'\n");
          break;
      case 3:
          COM_PRINT("FlowCtrl:\t\t\'B\'\n");
          break;
    }
    COM_PRINT("\n");
    return;
}
#endif
/**************************************************************************************
 *  Description: Set the comport databit,parity,stopbit,flowctrl into the comport structure
 *   Input Args: comport: the st_comport pointer
 *               settings: The databit/parity/stopbit/flowctrl settings as like "8N1N"
 *  Output Args: NONE
 * Return Value: NONE
 *************************************************************************************/
void set_settings(st_comport * comport, const char *settings)
{
    if(NULL==settings || NULL==comport)
        return ;
    switch (settings[0])        /* data bit */
    {
      case '7':
          comport->databit = 7;
          break;
      case '8':
      default:
          comport->databit = 8;
          break;
    }
    switch (settings[1])        /* parity */
    {
      case 'O':
      case 'o':
          comport->parity = 1;
          break;
      case 'E':
      case 'e':
          comport->parity = 2;
          break;
      case 'S':
      case 's':
          comport->parity = 3;
          break;
      case 'N':
      case 'n':
      default:
          comport->parity = 0;
          break;
    }
    switch (settings[2])        /* stop bit */
    {
      case '0':
          comport->stopbit = 0;
          break;
      case '1':
      default:
          comport->stopbit = 1;
          break;
    }
    switch (settings[3])        /* flow control */
    {
      case 'S':
      case 's':
          comport->flowctrl = 1;
          break;
      case 'H':
      case 'h':
          comport->flowctrl = 2;
          break;
      case 'B':
      case 'b':
          comport->flowctrl = 3;
          break;
      case 'N':
      case 'n':
      default:
          comport->flowctrl = 0;
          break;
    }
}
void comport_close(st_comport * comport)
{
    if (0 != comport->fd)
    {
        COM_PRINT("Close device \"%s\"\n", comport->dev_name);
        close(comport->fd);
    }
    comport->fd = -1;
}
void comport_term(st_comport * comport)
{
    if(NULL == comport)
        return;
    if ( comport->fd > 0 )
    {
        comport_close(comport);
    }
    memset(comport, 0x00, sizeof(st_comport));
    free(comport);
    return;
}
int comport_open(st_comport * comport)
{
    int retval = -1;
    struct termios old_cfg, new_cfg;
    int old_flags;
    long tmp;
    if(NULL==comport)
        return -1;
    comport_close(comport);
    /* Not a TTY device */
    if( !strstr(comport->dev_name, "tty"))
    {
        COM_PRINT("Open Not tty device \"%s\"\n", comport->dev_name);
        comport->fd = open(comport->dev_name, O_RDWR);
        retval = comport->fd<0 ? -2 : comport->fd;
        goto CleanUp;
    }
    comport->fd = open(comport->dev_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (comport->fd < 0)
    {
        retval = -3;
        goto CleanUp;
    }
    COM_PRINT("Open device \"%s\"\n", comport->dev_name);
    if ((-1 != (old_flags = fcntl(comport->fd, F_GETFL, 0)))
        && (-1 != fcntl(comport->fd, F_SETFL, old_flags & ~O_NONBLOCK)))
    {
        // Flush input and output
        if (-1 == tcflush(comport->fd, TCIOFLUSH))
        {
            retval = -4;
            goto CleanUp;
        }
    }
    else                        // Failure
    {
        retval = -5;
        goto CleanUp;
    }
    if (0 != tcgetattr(comport->fd, &old_cfg))
    {
        retval = -6;          // Failed to get Com settings
        goto CleanUp;
    }
    memset(&new_cfg, 0, sizeof(new_cfg));
    /*=====================================*/
    /*       Configure comport         */
    /*=====================================*/
    new_cfg.c_cflag &= ~CSIZE;
    new_cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    new_cfg.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    new_cfg.c_oflag &= ~(OPOST);
    /* Set the data bit */
    switch (comport->databit)
    {
      case 0x07:
          new_cfg.c_cflag |= CS7;
          break;
      case 0x06:
          new_cfg.c_cflag |= CS6;
          break;
      case 0x05:
          new_cfg.c_cflag |= CS5;
          break;
      default:
          new_cfg.c_cflag |= CS8;
          break;
    }
    /* Set the parity */
    switch (comport->parity)
    {
      case 0x01:               // Odd
          new_cfg.c_cflag |= (PARENB | PARODD);
          new_cfg.c_cflag |= (INPCK | ISTRIP);
          break;
      case 0x02:               // Even
          new_cfg.c_cflag |= PARENB;
          new_cfg.c_cflag &= ~PARODD;;
          new_cfg.c_cflag |= (INPCK | ISTRIP);
          break;
      case 0x03:
          new_cfg.c_cflag &= ~PARENB;
          new_cfg.c_cflag &= ~CSTOPB;
          break;
      default:
          new_cfg.c_cflag &= ~PARENB;
    }
    /* Set Stop bit */
    if (0x01 != comport->stopbit)
    {
        new_cfg.c_cflag |= CSTOPB;
    }
    else
    {
        new_cfg.c_cflag &= ~CSTOPB;
    }
    /* Set flow control */
    switch (comport->flowctrl)
    {
      case 1:                  // Software control
      case 3:
          new_cfg.c_cflag &= ~(CRTSCTS);
          new_cfg.c_iflag |= (IXON | IXOFF);
          break;
      case 2:                  // Hardware control
          new_cfg.c_cflag |= CRTSCTS;   // Also called CRTSCTS
          new_cfg.c_iflag &= ~(IXON | IXOFF);
          break;
      default:                 // NONE
          new_cfg.c_cflag &= ~(CRTSCTS);
          new_cfg.c_iflag &= ~(IXON | IXOFF);
          break;
    }
    /* Set baudrate */
    switch (comport->baudrate)
    {
      case 115200:
          tmp = B115200;
          break;
      case 57600:
          tmp = B57600;
          break;
      case 38400:
          tmp = B38400;
          break;
      case 19200:
          tmp = B19200;
          break;
      case 9600:
          tmp = B9600;
          break;
      case 4800:
          tmp = B4800;
          break;
      case 2400:
          tmp = B2400;
          break;
      case 1800:
          tmp = B1800;
          break;
      case 1200:
          tmp = B1200;
          break;
      case 600:
          tmp = B600;
          break;
      case 300:
          tmp = B300;
          break;
      case 200:
          tmp = B200;
          break;
      case 150:
          tmp = B150;
          break;
      case 134:
          tmp = B134;
          break;
      case 110:
          tmp = B110;
          break;
      case 75:
          tmp = B75;
          break;
      case 50:
          tmp = B50;
          break;
      default:
          tmp = B115200;
    }
    cfsetispeed(&new_cfg, tmp);
    cfsetispeed(&new_cfg, tmp);
    /* Set the Com port timeout settings */
    new_cfg.c_cc[VMIN] = 0;
    new_cfg.c_cc[VTIME] = 0;
    tcflush(comport->fd, TCIFLUSH);
    if (0 != tcsetattr(comport->fd, TCSANOW, &new_cfg))
    {
        retval = -7;          // Failed to set device com port settings
        goto CleanUp;
    }
    COM_PRINT("Connected device \"%s\".\n", comport->dev_name);
    retval = comport->fd;
CleanUp:
    COM_PRINT("Open device \"%s\" %s.\n", comport->dev_name, retval>0 ? "successfully" : "failure");
    return retval;
}
int comport_recv(st_comport * comport, char *buf, int buf_size, unsigned long timeout)
{
    int retval = 0;             // Function return value
    int iRet;
    fd_set stReadFds, stExcpFds;
    struct timeval stTime;
    if (NULL == buf || 0 >= buf_size)
    {
        COM_PRINT("%s() usage error.\n", __FUNCTION__);
        retval = -1;
        goto CleanUp;
    }
    if ( comport->fd < 0 )
    {
        COM_PRINT("%s() comport not connected.\n", __FUNCTION__);
        retval = -2;
        goto CleanUp;
    }
    //printf("bufsize=%d timeout=%lu\n", buf_size, timeout);
    FD_ZERO(&stReadFds);
    FD_ZERO(&stExcpFds);
    FD_SET(comport->fd, &stReadFds);
    FD_SET(comport->fd, &stExcpFds);
    if (0xFFFFFFFF != timeout)
    {
        stTime.tv_sec = (time_t) (timeout / 1000);
        stTime.tv_usec = (long)(1000 * (timeout % 1000));
        iRet = select(comport->fd + 1, &stReadFds, 0, &stExcpFds, &stTime);
        if (0 == iRet)
        {
            retval = 0;         // No data in Com port buffer
            goto CleanUp;
        }
        else if (0 < iRet)
        {
            if (0 != FD_ISSET(comport->fd, &stExcpFds))
            {
                retval = -6;  // Error during checking recv status
                COM_PRINT("Error checking recv status.\n");
                goto CleanUp;
            }
            if (0 == FD_ISSET(comport->fd, &stReadFds))
            {
                retval = 0;  // No incoming data
                COM_PRINT("No incoming data.\n");
                goto CleanUp;
            }
        }
        else
        {
            if (EINTR == errno)
            {
                COM_PRINT("catch interrupt signal.\n");
                retval = 0;  // Interrupted signal catched
            }
            else
            {
                COM_PRINT("Check recv status failure.\n");
                retval = -7;  // Error during checking recv status
            }
            goto CleanUp;
        }
    }
    usleep(10000); /* sleep for 10ms for data incoming */
    // Get data from Com port
    iRet = read(comport->fd, buf, buf_size);
    if (0 > iRet)
    {
        if (EINTR == errno)
            retval = 0;      // Interrupted signal catched
        else
            retval = -3;      // Failed to read Com port
        goto CleanUp;
    }
#if 0
    {
        int   i=0;
        printf("Receive %d bytes data: \n", iRet);
        for(i=0; i<iRet; i++)
        {
            printf("0x%02x ", buf[i]);
        }
        printf("\n");
    }
#endif
    retval = iRet;
  CleanUp:
    return retval;
}
int comport_send(st_comport * comport, char *buf, int send_bytes)
{
    char *ptr, *end;
    int retval = 0;
    int send = 0;
    if (NULL == buf || 0 >= send_bytes)
    {
        COM_PRINT("%s() Usage error.\n", __FUNCTION__);
        retval = -1;
        goto CleanUp;
    }
    if ( comport->fd < 0 )    // Comport not opened ?
    {
        retval = -3;
        COM_PRINT("Serail not connected.\n");
        goto CleanUp;
    }
    //printf("Send %s with %d bytes.\n", buf, send_bytes);
    // Large data, then slice them and send
    if (comport->frag_size < send_bytes)
    {
        ptr = buf;
        end = buf + send_bytes;
        do
        {
            // Large than frag_size
            if (comport->frag_size < (end - ptr))
            {
                send = write(comport->fd, ptr, comport->frag_size);
                if (0 >= send || comport->frag_size != send)
                {
                    retval = -4;
                    goto CleanUp;
                }
                ptr += comport->frag_size;
            }
            else                // Less than frag_size, maybe last fragmention.
            {
                send = write(comport->fd, ptr, (end - ptr));
                if (0 >= send || (end - ptr) != send)
                {
                    retval = -4;
                    goto CleanUp;
                }
                ptr += (end - ptr);
            }
        }
        while (ptr < end);
    }
    else                        // The send data is not large than a fragmention.
    {
        send = write(comport->fd, buf, send_bytes);
        if (0 >= send || send_bytes != send)
        {
            retval = -5;
            goto CleanUp;
        }
    }
  CleanUp:
    return retval;
}
proj1_mqttd/lylib/comport.h
New file
@@ -0,0 +1,106 @@
/*********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  comport.h
 *    Description:  This head file is for the common TTY/Serial port operator library
 *
 *        Version:  1.0.0(10/17/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/17/2018 03:33:25 PM"
 *
 ********************************************************************************/
#ifndef  __COMPORT_H_
#define  __COMPORT_H_
#include  <stdio.h>
#include  <stdlib.h>
#include  <unistd.h>
#include  <string.h>
#include  <getopt.h>
#include  <fcntl.h>
#include  <errno.h>
#include  <termios.h>
#include  <sys/stat.h>
#include  <sys/wait.h>
#include  <sys/types.h>
#include  <sys/stat.h>
#include  <sys/select.h>
#define BUF_64  64
#ifndef DEVNAME_LEN
#define DEVNAME_LEN          64
#endif
//#define COM_DEBUG
#ifdef  COM_DEBUG
#define COM_PRINT(format,args...) printf(format, ##args)
#else
#define COM_PRINT(format,args...) do{} while(0);
#endif
//#define msleep(m)               {struct timespec cSleep; cSleep.tv_sec = 0; cSleep.tv_nsec = m * 1000; nanosleep(&cSleep, 0);}
typedef struct _st_comport
{
    char           dev_name[DEVNAME_LEN];
    unsigned char  databit, parity, stopbit, flowctrl;
    long           baudrate;
    int            fd;
    int            frag_size;
} st_comport;
/*
 *  description: initialise the comport structure
 *
 *   input args: $dev_name:  The comport device name path, such as '/dev/ttyS3'
 *               $baudrate:  The baudrate, such as 115200
 *               $settings:  The databit,parity,stopbit,flowctrl settings, such as '8N1N'
 *
 * return value: The st_comport structure pointer, NULL means failure.
 */
st_comport *comport_init(const char *dev_name, int baudrate, const char *settings);
/*
 *  description: Open the comport specified by $comport
 *   input args: $comport:  corresponding comport point
 * return value: The comport opened file description, <0 means failure
 */
extern int  comport_open(st_comport * comport);
/*
 *  description: read data from $comport in $timeout <ms> to $buf no more than $buf_size bytes
 * return value: the actual read data bytes, <0: read failure
 */
extern int  comport_recv(st_comport * comport, char *buf, int buf_size, unsigned long timeout);
/*
 *  description: write $send_bytes bytes data from $buf to $comport
 * return value: 0: write ok  <0: write failure
 */
extern int  comport_send(st_comport * comport, char *buf, int send_bytes);
/*
 *  description: display current comport settings such as databit,parity,stopbit,flowctrl
 *   input args: $comport:  corresponding comport point
 */
//extern void disp_settings(st_comport * comport);
/*
 *  description: close comport
 *   input args: $comport:  corresponding comport point
 */
extern void comport_close(st_comport * comport);
/*
 *  description: terminat comport, close and free it
 *   input args: $comport:  corresponding comport point
 */
extern void comport_term(st_comport * comport);
#endif
proj1_mqttd/lylib/ini_dictionary.c
New file
@@ -0,0 +1,398 @@
/*-------------------------------------------------------------------------*/
/**
   @file    ini_dictionary.c
   @author  N. Devillard
   @brief   Implements a dictionary for string variables.
   This module implements a simple dictionary object, i.e. a list
   of string/string associations. This object is useful to store e.g.
   informations retrieved from a configuration file (ini files).
*/
/*--------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include "ini_dictionary.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/** Maximum value size for integers and doubles. */
#define MAXVALSZ    1024
/** Minimal allocated number of entries in a dictionary */
#define DICTMINSZ   128
/** Invalid key token */
#define DICT_INVALID_KEY    ((char*)-1)
/*---------------------------------------------------------------------------
                            Private functions
 ---------------------------------------------------------------------------*/
/* Doubles the allocated size associated to a pointer */
/* 'size' is the current allocated size. */
static void * mem_double(void * ptr, int size)
{
    void * newptr ;
    newptr = calloc(2*size, 1);
    if (newptr==NULL) {
        return NULL ;
    }
    memcpy(newptr, ptr, size);
    free(ptr);
    return newptr ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Duplicate a string
  @param    s String to duplicate
  @return   Pointer to a newly allocated string, to be freed with free()
  This is a replacement for strdup(). This implementation is provided
  for systems that do not have it.
 */
/*--------------------------------------------------------------------------*/
static char * xstrdup(const char * s)
{
    char * t ;
    if (!s)
        return NULL ;
    t = (char*)malloc(strlen(s)+1) ;
    if (t) {
        strcpy(t,s);
    }
    return t ;
}
/*---------------------------------------------------------------------------
                            Function codes
 ---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
  @brief    Compute the hash key for a string.
  @param    key     Character string to use for key.
  @return   1 unsigned int on at least 32 bits.
  This hash function has been taken from an Article in Dr Dobbs Journal.
  This is normally a collision-free function, distributing keys evenly.
  The key is stored anyway in the struct so that collision can be avoided
  by comparing the key itself in last resort.
 */
/*--------------------------------------------------------------------------*/
unsigned dictionary_hash(const char * key)
{
    int         len ;
    unsigned    hash ;
    int         i ;
    len = strlen(key);
    for (hash=0, i=0 ; i<len ; i++) {
        hash += (unsigned)key[i] ;
        hash += (hash<<10);
        hash ^= (hash>>6) ;
    }
    hash += (hash <<3);
    hash ^= (hash >>11);
    hash += (hash <<15);
    return hash ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Create a new dictionary object.
  @param    size    Optional initial size of the dictionary.
  @return   1 newly allocated dictionary objet.
  This function allocates a new dictionary object of given size and returns
  it. If you do not know in advance (roughly) the number of entries in the
  dictionary, give size=0.
 */
/*--------------------------------------------------------------------------*/
dictionary * dictionary_new(int size)
{
    dictionary  *   d ;
    /* If no size was specified, allocate space for DICTMINSZ */
    if (size<DICTMINSZ) size=DICTMINSZ ;
    if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
        return NULL;
    }
    d->size = size ;
    d->val  = (char **)calloc(size, sizeof(char*));
    d->key  = (char **)calloc(size, sizeof(char*));
    d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
    return d ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete a dictionary object
  @param    d   dictionary object to deallocate.
  @return   void
  Deallocate a dictionary object and all memory associated to it.
 */
/*--------------------------------------------------------------------------*/
void dictionary_del(dictionary * d)
{
    int     i ;
    if (d==NULL) return ;
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]!=NULL)
            free(d->key[i]);
        if (d->val[i]!=NULL)
            free(d->val[i]);
    }
    free(d->val);
    free(d->key);
    free(d->hash);
    free(d);
    return ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get a value from a dictionary.
  @param    d       dictionary object to search.
  @param    key     Key to look for in the dictionary.
  @param    def     Default value to return if key not found.
  @return   1 pointer to internally allocated character string.
  This function locates a key in a dictionary and returns a pointer to its
  value, or the passed 'def' pointer if no such key can be found in
  dictionary. The returned character pointer points to data internal to the
  dictionary object, you should not try to free it or modify it.
 */
/*--------------------------------------------------------------------------*/
char * dictionary_get(dictionary * d, const char * key, char * def)
{
    unsigned    hash ;
    int         i ;
    hash = dictionary_hash(key);
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]==NULL)
            continue ;
        /* Compare hash */
        if (hash==d->hash[i]) {
            /* Compare string, to avoid hash collisions */
            if (!strcmp(key, d->key[i])) {
                return d->val[i] ;
            }
        }
    }
    return def ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Set a value in a dictionary.
  @param    d       dictionary object to modify.
  @param    key     Key to modify or add.
  @param    val     Value to add.
  @return   int     0 if Ok, anything else otherwise
  If the given key is found in the dictionary, the associated value is
  replaced by the provided one. If the key cannot be found in the
  dictionary, it is added to it.
  It is Ok to provide a NULL value for val, but NULL values for the dictionary
  or the key are considered as errors: the function will return immediately
  in such a case.
  Notice that if you dictionary_set a variable to NULL, a call to
  dictionary_get will return a NULL value: the variable will be found, and
  its value (NULL) is returned. In other words, setting the variable
  content to NULL is equivalent to deleting the variable from the
  dictionary. It is not possible (in this implementation) to have a key in
  the dictionary without value.
  This function returns non-zero in case of failure.
 */
/*--------------------------------------------------------------------------*/
int dictionary_set(dictionary * d, const char * key, const char * val)
{
    int         i ;
    unsigned    hash ;
    if (d==NULL || key==NULL) return -1 ;
    /* Compute hash for this key */
    hash = dictionary_hash(key) ;
    /* Find if value is already in dictionary */
    if (d->n>0) {
        for (i=0 ; i<d->size ; i++) {
            if (d->key[i]==NULL)
                continue ;
            if (hash==d->hash[i]) { /* Same hash value */
                if (!strcmp(key, d->key[i])) {   /* Same key */
                    /* Found a value: modify and return */
                    if (d->val[i]!=NULL)
                        free(d->val[i]);
                    d->val[i] = val ? xstrdup(val) : NULL ;
                    /* Value has been modified: return */
                    return 0 ;
                }
            }
        }
    }
    /* Add a new value */
    /* See if dictionary needs to grow */
    if (d->n==d->size) {
        /* Reached maximum size: reallocate dictionary */
        d->val  = (char **)mem_double(d->val,  d->size * sizeof(char*)) ;
        d->key  = (char **)mem_double(d->key,  d->size * sizeof(char*)) ;
        d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
        if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
            /* Cannot grow dictionary */
            return -1 ;
        }
        /* Double size */
        d->size *= 2 ;
    }
    /* Insert key in the first empty slot. Start at d->n and wrap at
       d->size. Because d->n < d->size this will necessarily
       terminate. */
    for (i=d->n ; d->key[i] ; ) {
        if(++i == d->size) i = 0;
    }
    /* Copy key */
    d->key[i]  = xstrdup(key);
    d->val[i]  = val ? xstrdup(val) : NULL ;
    d->hash[i] = hash;
    d->n ++ ;
    return 0 ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete a key in a dictionary
  @param    d       dictionary object to modify.
  @param    key     Key to remove.
  @return   void
  This function deletes a key in a dictionary. Nothing is done if the
  key cannot be found.
 */
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, const char * key)
{
    unsigned    hash ;
    int         i ;
    if (key == NULL) {
        return;
    }
    hash = dictionary_hash(key);
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]==NULL)
            continue ;
        /* Compare hash */
        if (hash==d->hash[i]) {
            /* Compare string, to avoid hash collisions */
            if (!strcmp(key, d->key[i])) {
                /* Found key */
                break ;
            }
        }
    }
    if (i>=d->size)
        /* Key not found */
        return ;
    free(d->key[i]);
    d->key[i] = NULL ;
    if (d->val[i]!=NULL) {
        free(d->val[i]);
        d->val[i] = NULL ;
    }
    d->hash[i] = 0 ;
    d->n -- ;
    return ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Dump a dictionary to an opened file pointer.
  @param    d   Dictionary to dump
  @param    f   Opened file pointer.
  @return   void
  Dumps a dictionary onto an opened file pointer. Key pairs are printed out
  as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
  output file pointers.
 */
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out)
{
    int     i ;
    if (d==NULL || out==NULL) return ;
    if (d->n<1) {
        fprintf(out, "empty dictionary\n");
        return ;
    }
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]) {
            fprintf(out, "%20s\t[%s]\n",
                    d->key[i],
                    d->val[i] ? d->val[i] : "UNDEF");
        }
    }
    return ;
}
/* Test code */
#ifdef TESTDIC
#define NVALS 20000
int main(int argc, char *argv[])
{
    dictionary  *   d ;
    char    *   val ;
    int         i ;
    char        cval[90] ;
    /* Allocate dictionary */
    printf("allocating...\n");
    d = dictionary_new(0);
    /* Set values in dictionary */
    printf("setting %d values...\n", NVALS);
    for (i=0 ; i<NVALS ; i++) {
        sprintf(cval, "%04d", i);
        dictionary_set(d, cval, "salut");
    }
    printf("getting %d values...\n", NVALS);
    for (i=0 ; i<NVALS ; i++) {
        sprintf(cval, "%04d", i);
        val = dictionary_get(d, cval, DICT_INVALID_KEY);
        if (val==DICT_INVALID_KEY) {
            printf("cannot get value for key [%s]\n", cval);
        }
    }
    printf("unsetting %d values...\n", NVALS);
    for (i=0 ; i<NVALS ; i++) {
        sprintf(cval, "%04d", i);
        dictionary_unset(d, cval);
    }
    if (d->n != 0) {
        printf("error deleting values\n");
    }
    printf("deallocating...\n");
    dictionary_del(d);
    return 0 ;
}
#endif
/* vim: set ts=4 et sw=4 tw=75 */
proj1_mqttd/lylib/ini_dictionary.h
New file
@@ -0,0 +1,165 @@
/*-------------------------------------------------------------------------*/
/**
   @file    ini_dictionary.h
   @author  N. Devillard
   @brief   Implements a dictionary for string variables.
   This module implements a simple dictionary object, i.e. a list
   of string/string associations. This object is useful to store e.g.
   informations retrieved from a configuration file (ini files).
*/
/*--------------------------------------------------------------------------*/
#ifndef _INI_DICTIONARY_H_
#define _INI_DICTIONARY_H_
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*---------------------------------------------------------------------------
                                New types
 ---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
  @brief    Dictionary object
  This object contains a list of string/string associations. Each
  association is identified by a unique string key. Looking up values
  in the dictionary is speeded up by the use of a (hopefully collision-free)
  hash function.
 */
/*-------------------------------------------------------------------------*/
typedef struct _dictionary_ {
    int             n ;     /** Number of entries in dictionary */
    int             size ;  /** Storage size */
    char        **  val ;   /** List of string values */
    char        **  key ;   /** List of string keys */
    unsigned     *  hash ;  /** List of hash values for keys */
} dictionary ;
/*---------------------------------------------------------------------------
                            Function prototypes
 ---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
  @brief    Compute the hash key for a string.
  @param    key     Character string to use for key.
  @return   1 unsigned int on at least 32 bits.
  This hash function has been taken from an Article in Dr Dobbs Journal.
  This is normally a collision-free function, distributing keys evenly.
  The key is stored anyway in the struct so that collision can be avoided
  by comparing the key itself in last resort.
 */
/*--------------------------------------------------------------------------*/
unsigned dictionary_hash(const char * key);
/*-------------------------------------------------------------------------*/
/**
  @brief    Create a new dictionary object.
  @param    size    Optional initial size of the dictionary.
  @return   1 newly allocated dictionary objet.
  This function allocates a new dictionary object of given size and returns
  it. If you do not know in advance (roughly) the number of entries in the
  dictionary, give size=0.
 */
/*--------------------------------------------------------------------------*/
dictionary * dictionary_new(int size);
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete a dictionary object
  @param    d   dictionary object to deallocate.
  @return   void
  Deallocate a dictionary object and all memory associated to it.
 */
/*--------------------------------------------------------------------------*/
void dictionary_del(dictionary * vd);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get a value from a dictionary.
  @param    d       dictionary object to search.
  @param    key     Key to look for in the dictionary.
  @param    def     Default value to return if key not found.
  @return   1 pointer to internally allocated character string.
  This function locates a key in a dictionary and returns a pointer to its
  value, or the passed 'def' pointer if no such key can be found in
  dictionary. The returned character pointer points to data internal to the
  dictionary object, you should not try to free it or modify it.
 */
/*--------------------------------------------------------------------------*/
char * dictionary_get(dictionary * d, const char * key, char * def);
/*-------------------------------------------------------------------------*/
/**
  @brief    Set a value in a dictionary.
  @param    d       dictionary object to modify.
  @param    key     Key to modify or add.
  @param    val     Value to add.
  @return   int     0 if Ok, anything else otherwise
  If the given key is found in the dictionary, the associated value is
  replaced by the provided one. If the key cannot be found in the
  dictionary, it is added to it.
  It is Ok to provide a NULL value for val, but NULL values for the dictionary
  or the key are considered as errors: the function will return immediately
  in such a case.
  Notice that if you dictionary_set a variable to NULL, a call to
  dictionary_get will return a NULL value: the variable will be found, and
  its value (NULL) is returned. In other words, setting the variable
  content to NULL is equivalent to deleting the variable from the
  dictionary. It is not possible (in this implementation) to have a key in
  the dictionary without value.
  This function returns non-zero in case of failure.
 */
/*--------------------------------------------------------------------------*/
int dictionary_set(dictionary * vd, const char * key, const char * val);
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete a key in a dictionary
  @param    d       dictionary object to modify.
  @param    key     Key to remove.
  @return   void
  This function deletes a key in a dictionary. Nothing is done if the
  key cannot be found.
 */
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, const char * key);
/*-------------------------------------------------------------------------*/
/**
  @brief    Dump a dictionary to an opened file pointer.
  @param    d   Dictionary to dump
  @param    f   Opened file pointer.
  @return   void
  Dumps a dictionary onto an opened file pointer. Key pairs are printed out
  as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
  output file pointers.
 */
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out);
#endif
proj1_mqttd/lylib/iniparser.c
New file
@@ -0,0 +1,807 @@
/*-------------------------------------------------------------------------*/
/**
   @file    iniparser.c
   @author  N. Devillard
   @brief   Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
/*---------------------------- Includes ------------------------------------*/
#include <ctype.h>
#include "iniparser.h"
/*---------------------------- Defines -------------------------------------*/
#define ASCIILINESZ         (1024)
#define INI_INVALID_KEY     ((char*)-1)
/*---------------------------------------------------------------------------
                        Private to this module
 ---------------------------------------------------------------------------*/
/**
 * This enum stores the status for each parsed line (internal use only).
 */
typedef enum _line_status_ {
    LINE_UNPROCESSED,
    LINE_ERROR,
    LINE_EMPTY,
    LINE_COMMENT,
    LINE_SECTION,
    LINE_VALUE
} line_status ;
/*-------------------------------------------------------------------------*/
/**
  @brief    Convert a string to lowercase.
  @param    s   String to convert.
  @return   ptr to statically allocated string.
  This function returns a pointer to a statically allocated string
  containing a lowercased version of the input string. Do not free
  or modify the returned string! Since the returned string is statically
  allocated, it will be modified at each function call (not re-entrant).
 */
/*--------------------------------------------------------------------------*/
static char * strlwc(const char * s)
{
    static char l[ASCIILINESZ+1];
    int i ;
    if (s==NULL) return NULL ;
    memset(l, 0, ASCIILINESZ+1);
    i=0 ;
    while (s[i] && i<ASCIILINESZ) {
        l[i] = (char)tolower((int)s[i]);
        i++ ;
    }
    l[ASCIILINESZ]=(char)0;
    return l ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Remove blanks at the beginning and the end of a string.
  @param    s   String to parse.
  @return   ptr to statically allocated string.
  This function returns a pointer to a statically allocated string,
  which is identical to the input string, except that all blank
  characters at the end and the beg. of the string have been removed.
  Do not free or modify the returned string! Since the returned string
  is statically allocated, it will be modified at each function call
  (not re-entrant).
 */
/*--------------------------------------------------------------------------*/
static char * strstrip(const char * s)
{
    static char l[ASCIILINESZ+1];
    char * last ;
    if (s==NULL) return NULL ;
    while (isspace((int)*s) && *s) s++;
    memset(l, 0, ASCIILINESZ+1);
    strcpy(l, s);
    last = l + strlen(l);
    while (last > l) {
        if (!isspace((int)*(last-1)))
            break ;
        last -- ;
    }
    *last = (char)0;
    return (char*)l ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get number of sections in a dictionary
  @param    d   Dictionary to examine
  @return   int Number of sections found in dictionary
  This function returns the number of sections found in a dictionary.
  The test to recognize sections is done on the string stored in the
  dictionary: a section name is given as "section" whereas a key is
  stored as "section:key", thus the test looks for entries that do not
  contain a colon.
  This clearly fails in the case a section name contains a colon, but
  this should simply be avoided.
  This function returns -1 in case of error.
 */
/*--------------------------------------------------------------------------*/
int iniparser_getnsec(dictionary * d)
{
    int i ;
    int nsec ;
    if (d==NULL) return -1 ;
    nsec=0 ;
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]==NULL)
            continue ;
        if (strchr(d->key[i], ':')==NULL) {
            nsec ++ ;
        }
    }
    return nsec ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get name for section n in a dictionary.
  @param    d   Dictionary to examine
  @param    n   Section number (from 0 to nsec-1).
  @return   Pointer to char string
  This function locates the n-th section in a dictionary and returns
  its name as a pointer to a string statically allocated inside the
  dictionary. Do not free or modify the returned string!
  This function returns NULL in case of error.
 */
/*--------------------------------------------------------------------------*/
char * iniparser_getsecname(dictionary * d, int n)
{
    int i ;
    int foundsec ;
    if (d==NULL || n<0) return NULL ;
    foundsec=0 ;
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]==NULL)
            continue ;
        if (strchr(d->key[i], ':')==NULL) {
            foundsec++ ;
            if (foundsec>n)
                break ;
        }
    }
    if (foundsec<=n) {
        return NULL ;
    }
    return d->key[i] ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Dump a dictionary to an opened file pointer.
  @param    d   Dictionary to dump.
  @param    f   Opened file pointer to dump to.
  @return   void
  This function prints out the contents of a dictionary, one element by
  line, onto the provided file pointer. It is OK to specify @c stderr
  or @c stdout as output files. This function is meant for debugging
  purposes mostly.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dump(dictionary * d, FILE * f)
{
    int     i ;
    if (d==NULL || f==NULL) return ;
    for (i=0 ; i<d->size ; i++) {
        if (d->key[i]==NULL)
            continue ;
        if (d->val[i]!=NULL) {
            fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
        } else {
            fprintf(f, "[%s]=UNDEF\n", d->key[i]);
        }
    }
    return ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Save a dictionary to a loadable ini file
  @param    d   Dictionary to dump
  @param    f   Opened file pointer to dump to
  @return   void
  This function dumps a given dictionary into a loadable ini file.
  It is Ok to specify @c stderr or @c stdout as output files.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dump_ini(dictionary * d, FILE * f)
{
    int     i ;
    int     nsec ;
    char *  secname ;
    if (d==NULL || f==NULL) return ;
    nsec = iniparser_getnsec(d);
    if (nsec<1) {
        /* No section in file: dump all keys as they are */
        for (i=0 ; i<d->size ; i++) {
            if (d->key[i]==NULL)
                continue ;
            fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
        }
        return ;
    }
    for (i=0 ; i<nsec ; i++) {
        secname = iniparser_getsecname(d, i) ;
        iniparser_dumpsection_ini(d, secname, f) ;
    }
    fprintf(f, "\n");
    return ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Save a dictionary section to a loadable ini file
  @param    d   Dictionary to dump
  @param    s   Section name of dictionary to dump
  @param    f   Opened file pointer to dump to
  @return   void
  This function dumps a given section of a given dictionary into a loadable ini
  file.  It is Ok to specify @c stderr or @c stdout as output files.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
{
    int     j ;
    char    keym[ASCIILINESZ+1];
    int     seclen ;
    if (d==NULL || f==NULL) return ;
    if (! iniparser_find_entry(d, s)) return ;
    seclen  = (int)strlen(s);
    fprintf(f, "\n[%s]\n", s);
    sprintf(keym, "%s:", s);
    for (j=0 ; j<d->size ; j++) {
        if (d->key[j]==NULL)
            continue ;
        if (!strncmp(d->key[j], keym, seclen+1)) {
            fprintf(f,
                    "%-30s = %s\n",
                    d->key[j]+seclen+1,
                    d->val[j] ? d->val[j] : "");
        }
    }
    fprintf(f, "\n");
    return ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the number of keys in a section of a dictionary.
  @param    d   Dictionary to examine
  @param    s   Section name of dictionary to examine
  @return   Number of keys in section
 */
/*--------------------------------------------------------------------------*/
int iniparser_getsecnkeys(dictionary * d, char * s)
{
    int     seclen, nkeys ;
    char    keym[ASCIILINESZ+1];
    int j ;
    nkeys = 0;
    if (d==NULL) return nkeys;
    if (! iniparser_find_entry(d, s)) return nkeys;
    seclen  = (int)strlen(s);
    sprintf(keym, "%s:", s);
    for (j=0 ; j<d->size ; j++) {
        if (d->key[j]==NULL)
            continue ;
        if (!strncmp(d->key[j], keym, seclen+1))
            nkeys++;
    }
    return nkeys;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the number of keys in a section of a dictionary.
  @param    d   Dictionary to examine
  @param    s   Section name of dictionary to examine
  @return   pointer to statically allocated character strings
  This function queries a dictionary and finds all keys in a given section.
  Each pointer in the returned char pointer-to-pointer is pointing to
  a string allocated in the dictionary; do not free or modify them.
  This function returns NULL in case of error.
 */
/*--------------------------------------------------------------------------*/
char ** iniparser_getseckeys(dictionary * d, char * s)
{
    char **keys;
    int i, j ;
    char    keym[ASCIILINESZ+1];
    int     seclen, nkeys ;
    keys = NULL;
    if (d==NULL) return keys;
    if (! iniparser_find_entry(d, s)) return keys;
    nkeys = iniparser_getsecnkeys(d, s);
    keys = (char**) malloc(nkeys*sizeof(char*));
    seclen  = (int)strlen(s);
    sprintf(keym, "%s:", s);
    i = 0;
    for (j=0 ; j<d->size ; j++) {
        if (d->key[j]==NULL)
            continue ;
        if (!strncmp(d->key[j], keym, seclen+1)) {
            keys[i] = d->key[j];
            i++;
        }
    }
    return keys;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key
  @param    d       Dictionary to search
  @param    key     Key string to look for
  @param    def     Default value to return if key not found.
  @return   pointer to statically allocated character string
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the pointer passed as 'def' is returned.
  The returned char pointer is pointing to a string allocated in
  the dictionary, do not free or modify it.
 */
/*--------------------------------------------------------------------------*/
char * iniparser_getstring(dictionary * d, const char * key, char * def)
{
    char * lc_key ;
    char * sval ;
    if (d==NULL || key==NULL)
        return def ;
    lc_key = strlwc(key);
    sval = dictionary_get(d, lc_key, def);
    return sval ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to an int
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   integer
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
  Supported values for integers include the usual C notation
  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
  are supported. Examples:
  "42"      ->  42
  "042"     ->  34 (octal -> decimal)
  "0x42"    ->  66 (hexa  -> decimal)
  Warning: the conversion may overflow in various ways. Conversion is
  totally outsourced to strtol(), see the associated man page for overflow
  handling.
  Credits: Thanks to A. Becker for suggesting strtol()
 */
/*--------------------------------------------------------------------------*/
int iniparser_getint(dictionary * d, const char * key, int notfound)
{
    char    *   str ;
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
    if (str==INI_INVALID_KEY) return notfound ;
    return (int)strtol(str, NULL, 0);
}
int iniparser_getlong(dictionary * d, const char * key, int notfound)
{
    char    *   str ;
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
    if (str==INI_INVALID_KEY) return notfound ;
    return strtol(str, NULL, 0);
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to a double
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   double
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
 */
/*--------------------------------------------------------------------------*/
double iniparser_getdouble(dictionary * d, const char * key, double notfound)
{
    char    *   str ;
    str = iniparser_getstring(d, key, INI_INVALID_KEY);
    if (str==INI_INVALID_KEY) return notfound ;
    return atof(str);
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to a boolean
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   integer
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
  A true boolean is found if one of the following is matched:
  - A string starting with 'y'
  - A string starting with 'Y'
  - A string starting with 't'
  - A string starting with 'T'
  - A string starting with '1'
  A false boolean is found if one of the following is matched:
  - A string starting with 'n'
  - A string starting with 'N'
  - A string starting with 'f'
  - A string starting with 'F'
  - A string starting with '0'
  The notfound value returned if no boolean is identified, does not
  necessarily have to be 0 or 1.
 */
/*--------------------------------------------------------------------------*/
int iniparser_getboolean(dictionary * d, const char * key, int notfound)
{
    char    *   c ;
    int         ret ;
    c = iniparser_getstring(d, key, INI_INVALID_KEY);
    if (c==INI_INVALID_KEY) return notfound ;
    if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
        ret = 1 ;
    } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
        ret = 0 ;
    } else {
        ret = notfound ;
    }
    return ret;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Finds out if a given entry exists in a dictionary
  @param    ini     Dictionary to search
  @param    entry   Name of the entry to look for
  @return   integer 1 if entry exists, 0 otherwise
  Finds out if a given entry exists in the dictionary. Since sections
  are stored as keys with NULL associated values, this is the only way
  of querying for the presence of sections in a dictionary.
 */
/*--------------------------------------------------------------------------*/
int iniparser_find_entry(
    dictionary  *   ini,
    const char  *   entry
)
{
    int found=0 ;
    if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
        found = 1 ;
    }
    return found ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Set an entry in a dictionary.
  @param    ini     Dictionary to modify.
  @param    entry   Entry to modify (entry name)
  @param    val     New value to associate to the entry.
  @return   int 0 if Ok, -1 otherwise.
  If the given entry can be found in the dictionary, it is modified to
  contain the provided value. If it cannot be found, -1 is returned.
  It is Ok to set val to NULL.
 */
/*--------------------------------------------------------------------------*/
int iniparser_set(dictionary * ini, const char * entry, const char * val)
{
    return dictionary_set(ini, strlwc(entry), val) ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete an entry in a dictionary
  @param    ini     Dictionary to modify
  @param    entry   Entry to delete (entry name)
  @return   void
  If the given entry can be found, it is deleted from the dictionary.
 */
/*--------------------------------------------------------------------------*/
void iniparser_unset(dictionary * ini, const char * entry)
{
    dictionary_unset(ini, strlwc(entry));
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Load a single line from an INI file
  @param    input_line  Input line, may be concatenated multi-line input
  @param    section     Output space to store section
  @param    key         Output space to store key
  @param    value       Output space to store value
  @return   line_status value
 */
/*--------------------------------------------------------------------------*/
static line_status iniparser_line(
    char * input_line,
    char * section,
    char * key,
    char * value)
{
    line_status sta ;
    char        line[ASCIILINESZ+1];
    static char left_line[ASCIILINESZ+1];
    int         len, offset ;
    strcpy(line, strstrip(input_line));
    len = (int)strlen(line);
    sta = LINE_UNPROCESSED ;
    if (len<1) {
        /* Empty line */
        sta = LINE_EMPTY ;
        memset(input_line, 0, len);
    } else if (line[0]=='#' || line[0]==';') {
        /* Comment line */
        sta = LINE_COMMENT ;
        memset(input_line, 0, len);
    } else if (line[0]=='[') {
        /* Section name */
        sscanf(line, "[%[^]]", section);
        strcpy(section, strstrip(section));
        strcpy(section, strlwc(section));
        /* Left configure will go to next time to parser */
        offset = strlen(section) + 2;
        strcpy( left_line, strstrip(&(line[offset])) );
        strcpy( left_line, strstrip(left_line));
        if( strlen(left_line) > 0)
        {
            strcpy(input_line, left_line);
            strcat(input_line, "\n");
        }
        else
        {
            memset(input_line, 0, len);
        }
        sta = LINE_SECTION ;
    } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
           ||  sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2
           ||  sscanf (line, "%[^=] = %[^;#]",     key, value) == 2) {
        char      *ptr = NULL;
        /* Usual key=value, with or without comments */
        strcpy(key, strstrip(key));
        strcpy(key, strlwc(key));
        strcpy(value, strstrip(value));
        /*
         * sscanf cannot handle '' or "" as empty values
         * this is done here
         */
        if (!strncmp(value, "\"\"", 2) || (!strncmp(value, "''", 2)) ) {
            value[0]=0 ;
        }
        ptr = strchr(line, '=');
        if('\''==*(ptr+1) || '\"'==*(ptr+1))
        {
            offset = strlen(key)+strlen(value) + 1 + 2; /* Skip $key='$val' */
        }
        else
        {
            offset = strlen(key)+strlen(value) + 1; /* Skip $key=$val */
        }
        strcpy( left_line, strstrip(&(line[offset])) );
        if( strlen(left_line) > 0)
        {
            strcpy(input_line, left_line);
            strcat(input_line, "\n");
        }
        else
        {
            memset(input_line, 0, len);
        }
        sta = LINE_VALUE ;
    } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
           ||  sscanf(line, "%[^=] %[=]", key, value) == 2) {
        /*
         * Special cases:
         * key=
         * key=;
         * key=#
         */
        strcpy(key, strstrip(key));
        strcpy(key, strlwc(key));
        value[0]=0 ;
        sta = LINE_VALUE ;
    } else {
        /* Generate syntax error */
        sta = LINE_ERROR ;
        memset(input_line, 0, len);
    }
    return sta ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Parse an ini file and return an allocated dictionary object
  @param    ininame Name of the ini file to read.
  @return   Pointer to newly allocated dictionary
  This is the parser for ini files. This function is called, providing
  the name of the file to be read. It returns a dictionary object that
  should not be accessed directly, but through accessor functions
  instead.
  The returned dictionary must be freed using iniparser_freedict().
 */
/*--------------------------------------------------------------------------*/
dictionary * iniparser_load(const char * ininame)
{
    FILE * in ;
    char line    [ASCIILINESZ+1] ;
    char section [ASCIILINESZ+1] ;
    char key     [ASCIILINESZ+1] ;
    char tmp     [ASCIILINESZ+1] ;
    char val     [ASCIILINESZ+1] ;
    int  last=0 ;
    int  len ;
    int  lineno=0 ;
    int  errs=0;
    dictionary * dict ;
    if ((in=fopen(ininame, "r"))==NULL) {
        fprintf(stderr, "iniparser: cannot open %s\n", ininame);
        return NULL ;
    }
    dict = dictionary_new(0) ;
    if (!dict) {
        fclose(in);
        return NULL ;
    }
    memset(line,    0, ASCIILINESZ);
    memset(section, 0, ASCIILINESZ);
    memset(key,     0, ASCIILINESZ);
    memset(val,     0, ASCIILINESZ);
    last=0 ;
    while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
        lineno++ ;
CONTINUE_PARSER:
        len = (int)strlen(line)-1;
        if (len==0)
            continue;
        /* Safety check against buffer overflows */
        if (line[len]!='\n') {
            fprintf(stderr,
                    "iniparser: input line too long in %s (%d)\n",
                    ininame,
                    lineno);
            dictionary_del(dict);
            fclose(in);
            return NULL ;
        }
        /* Get rid of \n and spaces at end of line */
        while ((len>=0) &&
                ((line[len]=='\n') || (isspace(line[len])))) {
            line[len]=0 ;
            len-- ;
        }
        /* Detect multi-line */
        if (line[len]=='\\') {
            /* Multi-line value */
            last=len ;
            continue ;
        } else {
            last=0 ;
        }
        switch ( iniparser_line(line, section, key, val) ) {
            case LINE_EMPTY:
            case LINE_COMMENT:
            break ;
            case LINE_SECTION:
            errs = dictionary_set(dict, section, NULL);
            break ;
            case LINE_VALUE:
            sprintf(tmp, "%s:%s", section, key);
            errs = dictionary_set(dict, tmp, val) ;
            break ;
            case LINE_ERROR:
            fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
                    ininame,
                    lineno);
            fprintf(stderr, "-> %s\n", line);
            errs++ ;
            break;
            default:
            break ;
        }
        if( strlen(line) > 0)
        {
            goto CONTINUE_PARSER;
        }
        memset(line, 0, ASCIILINESZ);
        last=0;
        if (errs<0) {
            fprintf(stderr, "iniparser: memory allocation failure\n");
            break ;
        }
    }
    if (errs) {
        dictionary_del(dict);
        dict = NULL ;
    }
    fclose(in);
    return dict ;
}
/*-------------------------------------------------------------------------*/
/**
  @brief    Free all memory associated to an ini dictionary
  @param    d Dictionary to free
  @return   void
  Free all memory associated to an ini dictionary.
  It is mandatory to call this function before the dictionary object
  gets out of the current context.
 */
/*--------------------------------------------------------------------------*/
void iniparser_freedict(dictionary * d)
{
    dictionary_del(d);
}
/* vim: set ts=4 et sw=4 tw=75 */
proj1_mqttd/lylib/iniparser.h
New file
@@ -0,0 +1,308 @@
/*-------------------------------------------------------------------------*/
/**
   @file    cp_iniparser.h
   @author  N. Devillard
   @brief   Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
#ifndef _INIPARSER_H_
#define _INIPARSER_H_
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * The following #include is necessary on many Unixes but not Linux.
 * It is not needed for Windows platforms.
 * Uncomment it if needed.
 */
/* #include <unistd.h> */
#include "ini_dictionary.h"
/*-------------------------------------------------------------------------*/
/**
  @brief    Get number of sections in a dictionary
  @param    d   Dictionary to examine
  @return   int Number of sections found in dictionary
  This function returns the number of sections found in a dictionary.
  The test to recognize sections is done on the string stored in the
  dictionary: a section name is given as "section" whereas a key is
  stored as "section:key", thus the test looks for entries that do not
  contain a colon.
  This clearly fails in the case a section name contains a colon, but
  this should simply be avoided.
  This function returns -1 in case of error.
 */
/*--------------------------------------------------------------------------*/
int iniparser_getnsec(dictionary * d);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get name for section n in a dictionary.
  @param    d   Dictionary to examine
  @param    n   Section number (from 0 to nsec-1).
  @return   Pointer to char string
  This function locates the n-th section in a dictionary and returns
  its name as a pointer to a string statically allocated inside the
  dictionary. Do not free or modify the returned string!
  This function returns NULL in case of error.
 */
/*--------------------------------------------------------------------------*/
char * iniparser_getsecname(dictionary * d, int n);
/*-------------------------------------------------------------------------*/
/**
  @brief    Save a dictionary to a loadable ini file
  @param    d   Dictionary to dump
  @param    f   Opened file pointer to dump to
  @return   void
  This function dumps a given dictionary into a loadable ini file.
  It is Ok to specify @c stderr or @c stdout as output files.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dump_ini(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
  @brief    Save a dictionary section to a loadable ini file
  @param    d   Dictionary to dump
  @param    s   Section name of dictionary to dump
  @param    f   Opened file pointer to dump to
  @return   void
  This function dumps a given section of a given dictionary into a loadable ini
  file.  It is Ok to specify @c stderr or @c stdout as output files.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
/*-------------------------------------------------------------------------*/
/**
  @brief    Dump a dictionary to an opened file pointer.
  @param    d   Dictionary to dump.
  @param    f   Opened file pointer to dump to.
  @return   void
  This function prints out the contents of a dictionary, one element by
  line, onto the provided file pointer. It is OK to specify @c stderr
  or @c stdout as output files. This function is meant for debugging
  purposes mostly.
 */
/*--------------------------------------------------------------------------*/
void iniparser_dump(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the number of keys in a section of a dictionary.
  @param    d   Dictionary to examine
  @param    s   Section name of dictionary to examine
  @return   Number of keys in section
 */
/*--------------------------------------------------------------------------*/
int iniparser_getsecnkeys(dictionary * d, char * s);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the number of keys in a section of a dictionary.
  @param    d   Dictionary to examine
  @param    s   Section name of dictionary to examine
  @return   pointer to statically allocated character strings
  This function queries a dictionary and finds all keys in a given section.
  Each pointer in the returned char pointer-to-pointer is pointing to
  a string allocated in the dictionary; do not free or modify them.
  This function returns NULL in case of error.
 */
/*--------------------------------------------------------------------------*/
char ** iniparser_getseckeys(dictionary * d, char * s);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key
  @param    d       Dictionary to search
  @param    key     Key string to look for
  @param    def     Default value to return if key not found.
  @return   pointer to statically allocated character string
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the pointer passed as 'def' is returned.
  The returned char pointer is pointing to a string allocated in
  the dictionary, do not free or modify it.
 */
/*--------------------------------------------------------------------------*/
char * iniparser_getstring(dictionary * d, const char * key, char * def);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to an int
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   integer
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
  Supported values for integers include the usual C notation
  so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
  are supported. Examples:
  - "42"      ->  42
  - "042"     ->  34 (octal -> decimal)
  - "0x42"    ->  66 (hexa  -> decimal)
  Warning: the conversion may overflow in various ways. Conversion is
  totally outsourced to strtol(), see the associated man page for overflow
  handling.
  Credits: Thanks to A. Becker for suggesting strtol()
 */
/*--------------------------------------------------------------------------*/
int iniparser_getint(dictionary * d, const char * key, int notfound);
int iniparser_getlong(dictionary * d, const char * key, int notfound);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to a double
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   double
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
 */
/*--------------------------------------------------------------------------*/
double iniparser_getdouble(dictionary * d, const char * key, double notfound);
/*-------------------------------------------------------------------------*/
/**
  @brief    Get the string associated to a key, convert to a boolean
  @param    d Dictionary to search
  @param    key Key string to look for
  @param    notfound Value to return in case of error
  @return   integer
  This function queries a dictionary for a key. A key as read from an
  ini file is given as "section:key". If the key cannot be found,
  the notfound value is returned.
  A true boolean is found if one of the following is matched:
  - A string starting with 'y'
  - A string starting with 'Y'
  - A string starting with 't'
  - A string starting with 'T'
  - A string starting with '1'
  A false boolean is found if one of the following is matched:
  - A string starting with 'n'
  - A string starting with 'N'
  - A string starting with 'f'
  - A string starting with 'F'
  - A string starting with '0'
  The notfound value returned if no boolean is identified, does not
  necessarily have to be 0 or 1.
 */
/*--------------------------------------------------------------------------*/
int iniparser_getboolean(dictionary * d, const char * key, int notfound);
/*-------------------------------------------------------------------------*/
/**
  @brief    Set an entry in a dictionary.
  @param    ini     Dictionary to modify.
  @param    entry   Entry to modify (entry name)
  @param    val     New value to associate to the entry.
  @return   int 0 if Ok, -1 otherwise.
  If the given entry can be found in the dictionary, it is modified to
  contain the provided value. If it cannot be found, -1 is returned.
  It is Ok to set val to NULL.
 */
/*--------------------------------------------------------------------------*/
int iniparser_set(dictionary * ini, const char * entry, const char * val);
/*-------------------------------------------------------------------------*/
/**
  @brief    Delete an entry in a dictionary
  @param    ini     Dictionary to modify
  @param    entry   Entry to delete (entry name)
  @return   void
  If the given entry can be found, it is deleted from the dictionary.
 */
/*--------------------------------------------------------------------------*/
void iniparser_unset(dictionary * ini, const char * entry);
/*-------------------------------------------------------------------------*/
/**
  @brief    Finds out if a given entry exists in a dictionary
  @param    ini     Dictionary to search
  @param    entry   Name of the entry to look for
  @return   integer 1 if entry exists, 0 otherwise
  Finds out if a given entry exists in the dictionary. Since sections
  are stored as keys with NULL associated values, this is the only way
  of querying for the presence of sections in a dictionary.
 */
/*--------------------------------------------------------------------------*/
int iniparser_find_entry(dictionary * ini, const char * entry) ;
/*-------------------------------------------------------------------------*/
/**
  @brief    Parse an ini file and return an allocated dictionary object
  @param    ininame Name of the ini file to read.
  @return   Pointer to newly allocated dictionary
  This is the parser for ini files. This function is called, providing
  the name of the file to be read. It returns a dictionary object that
  should not be accessed directly, but through accessor functions
  instead.
  The returned dictionary must be freed using iniparser_freedict().
 */
/*--------------------------------------------------------------------------*/
dictionary * iniparser_load(const char * ininame);
/*-------------------------------------------------------------------------*/
/**
  @brief    Free all memory associated to an ini dictionary
  @param    d Dictionary to free
  @return   void
  Free all memory associated to an ini dictionary.
  It is mandatory to call this function before the dictionary object
  gets out of the current context.
 */
/*--------------------------------------------------------------------------*/
void iniparser_freedict(dictionary * d);
#endif
proj1_mqttd/lylib/klist.h
New file
@@ -0,0 +1,723 @@
/*********************************************************************************
 *      Copyright:  (C) 2012 Guo Wenxue <guowenxue@gmail.com>
 *                  All rights reserved.
 *
 *       Filename:  cp_list.h
 *    Description:  This file is copied from Linux kernel, which provide link list API.
 *
 *        Version:  1.0.0(08/09/2012~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "08/09/2012 02:24:34 AM"
 *
 ********************************************************************************/
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
#include <linux/stddef.h>
/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:   the type of the container struct this is embedded in.
 * @member: the name of the member within the struct.
 *
 */
#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({          \
    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})
/*
 * Architectures might want to move the poison pointer offset
 * into some well-recognized area such as 0xdead000000000000,
 * that is also not mappable by user-space exploits:
 */
#ifdef CONFIG_ILLEGAL_POINTER_VALUE
# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
#else
# define POISON_POINTER_DELTA 0
#endif
/*
 * These are non-NULL pointers that will result in page faults
 * under normal circumstances, used to verify that nobody uses
 * non-initialized list entries.
 */
#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
#ifndef ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCH
static inline void prefetch(const void *x) {;}
#endif
/*
 * Simple doubly linked list implementation.
 *
 * Some of the internal functions ("__xxx") are useful when
 * manipulating whole lists rather than single entries, as
 * sometimes we already know the next/prev entries and we can
 * generate better code by using them directly rather than
 * using the generic single-entry routines.
 */
struct list_head {
    struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}
/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}
/**
 * list_add - add a new entry
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}
/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
    __list_add(new, head->prev, head);
}
/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
    next->prev = prev;
    prev->next = next;
}
/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty() on entry does not return true after this, the entry is
 * in an undefined state.
 */
static inline void list_del(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = LIST_POISON1;
    entry->prev = LIST_POISON2;
}
/**
 * list_replace - replace old entry by new one
 * @old : the element to be replaced
 * @new : the new element to insert
 *
 * If @old was empty, it will be overwritten.
 */
static inline void list_replace(struct list_head *old,
                struct list_head *new)
{
    new->next = old->next;
    new->next->prev = new;
    new->prev = old->prev;
    new->prev->next = new;
}
static inline void list_replace_init(struct list_head *old,
                    struct list_head *new)
{
    list_replace(old, new);
    INIT_LIST_HEAD(old);
}
/**
 * list_del_init - deletes entry from list and reinitialize it.
 * @entry: the element to delete from the list.
 */
static inline void list_del_init(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    INIT_LIST_HEAD(entry);
}
/**
 * list_move - delete from one list and add as another's head
 * @list: the entry to move
 * @head: the head that will precede our entry
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
    __list_del(list->prev, list->next);
    list_add(list, head);
}
/**
 * list_move_tail - delete from one list and add as another's tail
 * @list: the entry to move
 * @head: the head that will follow our entry
 */
static inline void list_move_tail(struct list_head *list,
                  struct list_head *head)
{
    __list_del(list->prev, list->next);
    list_add_tail(list, head);
}
/**
 * list_is_last - tests whether @list is the last entry in list @head
 * @list: the entry to test
 * @head: the head of the list
 */
static inline int list_is_last(const struct list_head *list,
                const struct list_head *head)
{
    return list->next == head;
}
/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)
{
    return head->next == head;
}
/**
 * list_empty_careful - tests whether a list is empty and not being modified
 * @head: the list to test
 *
 * Description:
 * tests whether a list is empty _and_ checks that no other CPU might be
 * in the process of modifying either member (next or prev)
 *
 * NOTE: using list_empty_careful() without synchronization
 * can only be safe if the only activity that can happen
 * to the list entry is list_del_init(). Eg. it cannot be used
 * if another CPU could re-list_add() it.
 */
static inline int list_empty_careful(const struct list_head *head)
{
    struct list_head *next = head->next;
    return (next == head) && (next == head->prev);
}
/**
 * list_is_singular - tests whether a list has just one entry.
 * @head: the list to test.
 */
static inline int list_is_singular(const struct list_head *head)
{
    return !list_empty(head) && (head->next == head->prev);
}
static inline void __list_cut_position(struct list_head *list,
        struct list_head *head, struct list_head *entry)
{
    struct list_head *new_first = entry->next;
    list->next = head->next;
    list->next->prev = list;
    list->prev = entry;
    entry->next = list;
    head->next = new_first;
    new_first->prev = head;
}
/**
 * list_cut_position - cut a list into two
 * @list: a new list to add all removed entries
 * @head: a list with entries
 * @entry: an entry within head, could be the head itself
 *    and if so we won't cut the list
 *
 * This helper moves the initial part of @head, up to and
 * including @entry, from @head to @list. You should
 * pass on @entry an element you know is on @head. @list
 * should be an empty list or a list you do not care about
 * losing its data.
 *
 */
static inline void list_cut_position(struct list_head *list,
        struct list_head *head, struct list_head *entry)
{
    if (list_empty(head))
        return;
    if (list_is_singular(head) &&
        (head->next != entry && head != entry))
        return;
    if (entry == head)
        INIT_LIST_HEAD(list);
    else
        __list_cut_position(list, head, entry);
}
static inline void __list_splice(const struct list_head *list,
                 struct list_head *prev,
                 struct list_head *next)
{
    struct list_head *first = list->next;
    struct list_head *last = list->prev;
    first->prev = prev;
    prev->next = first;
    last->next = next;
    next->prev = last;
}
/**
 * list_splice - join two lists, this is designed for stacks
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(const struct list_head *list,
                struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head, head->next);
}
/**
 * list_splice_tail - join two lists, each list being a queue
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice_tail(struct list_head *list,
                struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head->prev, head);
}
/**
 * list_splice_init - join two lists and reinitialise the emptied list.
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 *
 * The list at @list is reinitialised
 */
static inline void list_splice_init(struct list_head *list,
                    struct list_head *head)
{
    if (!list_empty(list)) {
        __list_splice(list, head, head->next);
        INIT_LIST_HEAD(list);
    }
}
/**
 * list_splice_tail_init - join two lists and reinitialise the emptied list
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 *
 * Each of the lists is a queue.
 * The list at @list is reinitialised
 */
static inline void list_splice_tail_init(struct list_head *list,
                     struct list_head *head)
{
    if (!list_empty(list)) {
        __list_splice(list, head->prev, head);
        INIT_LIST_HEAD(list);
    }
}
/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)
/**
 * list_first_entry - get the first element from a list
 * @ptr:    the list head to take the element from.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 *
 * Note, that list is expected to be not empty.
 */
#define list_first_entry(ptr, type, member) \
    list_entry((ptr)->next, type, member)
/**
 * list_for_each    -    iterate over a list
 * @pos:    the &struct list_head to use as a loop cursor.
 * @head:    the head for your list.
 */
#define list_for_each(pos, head) \
    for (pos = (head)->next; prefetch(pos->next), pos != (head); \
        pos = pos->next)
/**
 * __list_for_each    -    iterate over a list
 * @pos:    the &struct list_head to use as a loop cursor.
 * @head:    the head for your list.
 *
 * This variant differs from list_for_each() in that it's the
 * simplest possible list iteration code, no prefetching is done.
 * Use this for code that knows the list to be very short (empty
 * or 1 entry) most of the time.
 */
#define __list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)
/**
 * list_for_each_prev    -    iterate over a list backwards
 * @pos:    the &struct list_head to use as a loop cursor.
 * @head:    the head for your list.
 */
#define list_for_each_prev(pos, head) \
    for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
        pos = pos->prev)
/**
 * list_for_each_safe - iterate over a list safe against removal of list entry
 * @pos:    the &struct list_head to use as a loop cursor.
 * @n:        another &struct list_head to use as temporary storage
 * @head:    the head for your list.
 */
#define list_for_each_safe(pos, n, head) \
    for (pos = (head)->next, n = pos->next; pos != (head); \
        pos = n, n = pos->next)
/**
 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
 * @pos:    the &struct list_head to use as a loop cursor.
 * @n:        another &struct list_head to use as temporary storage
 * @head:    the head for your list.
 */
#define list_for_each_prev_safe(pos, n, head) \
    for (pos = (head)->prev, n = pos->prev; \
         prefetch(pos->prev), pos != (head); \
         pos = n, n = pos->prev)
/**
 * list_for_each_entry    -    iterate over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */
#define list_for_each_entry(pos, head, member)                \
    for (pos = list_entry((head)->next, typeof(*pos), member);    \
         prefetch(pos->member.next), &pos->member != (head);    \
         pos = list_entry(pos->member.next, typeof(*pos), member))
/**
 * list_for_each_entry_reverse - iterate backwards over list of given type.
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */
#define list_for_each_entry_reverse(pos, head, member)            \
    for (pos = list_entry((head)->prev, typeof(*pos), member);    \
         prefetch(pos->member.prev), &pos->member != (head);    \
         pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
 * @pos:    the type * to use as a start point
 * @head:    the head of the list
 * @member:    the name of the list_struct within the struct.
 *
 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
 */
#define list_prepare_entry(pos, head, member) \
    ((pos) ? : list_entry(head, typeof(*pos), member))
/**
 * list_for_each_entry_continue - continue iteration over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Continue to iterate over list of given type, continuing after
 * the current position.
 */
#define list_for_each_entry_continue(pos, head, member)         \
    for (pos = list_entry(pos->member.next, typeof(*pos), member);    \
         prefetch(pos->member.next), &pos->member != (head);    \
         pos = list_entry(pos->member.next, typeof(*pos), member))
/**
 * list_for_each_entry_continue_reverse - iterate backwards from the given point
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Start to iterate over list of given type backwards, continuing after
 * the current position.
 */
#define list_for_each_entry_continue_reverse(pos, head, member)        \
    for (pos = list_entry(pos->member.prev, typeof(*pos), member);    \
         prefetch(pos->member.prev), &pos->member != (head);    \
         pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
 * list_for_each_entry_from - iterate over list of given type from the current point
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Iterate over list of given type, continuing from current position.
 */
#define list_for_each_entry_from(pos, head, member)            \
    for (; prefetch(pos->member.next), &pos->member != (head);    \
         pos = list_entry(pos->member.next, typeof(*pos), member))
/**
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @pos:    the type * to use as a loop cursor.
 * @n:        another type * to use as temporary storage
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */
#define list_for_each_entry_safe(pos, n, head, member)            \
    for (pos = list_entry((head)->next, typeof(*pos), member),    \
        n = list_entry(pos->member.next, typeof(*pos), member);    \
         &pos->member != (head);                    \
         pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
 * list_for_each_entry_safe_continue
 * @pos:    the type * to use as a loop cursor.
 * @n:        another type * to use as temporary storage
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Iterate over list of given type, continuing after current point,
 * safe against removal of list entry.
 */
#define list_for_each_entry_safe_continue(pos, n, head, member)         \
    for (pos = list_entry(pos->member.next, typeof(*pos), member),        \
        n = list_entry(pos->member.next, typeof(*pos), member);        \
         &pos->member != (head);                        \
         pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
 * list_for_each_entry_safe_from
 * @pos:    the type * to use as a loop cursor.
 * @n:        another type * to use as temporary storage
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Iterate over list of given type from current point, safe against
 * removal of list entry.
 */
#define list_for_each_entry_safe_from(pos, n, head, member)            \
    for (n = list_entry(pos->member.next, typeof(*pos), member);        \
         &pos->member != (head);                        \
         pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
 * list_for_each_entry_safe_reverse
 * @pos:    the type * to use as a loop cursor.
 * @n:        another type * to use as temporary storage
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * Iterate backwards over list of given type, safe against removal
 * of list entry.
 */
#define list_for_each_entry_safe_reverse(pos, n, head, member)        \
    for (pos = list_entry((head)->prev, typeof(*pos), member),    \
        n = list_entry(pos->member.prev, typeof(*pos), member);    \
         &pos->member != (head);                    \
         pos = n, n = list_entry(n->member.prev, typeof(*n), member))
/*
 * Double linked lists with a single pointer list head.
 * Mostly useful for hash tables where the two pointer list head is
 * too wasteful.
 * You lose the ability to access the tail in O(1).
 */
struct hlist_head {
    struct hlist_node *first;
};
struct hlist_node {
    struct hlist_node *next, **pprev;
};
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
    h->next = NULL;
    h->pprev = NULL;
}
static inline int hlist_unhashed(const struct hlist_node *h)
{
    return !h->pprev;
}
static inline int hlist_empty(const struct hlist_head *h)
{
    return !h->first;
}
static inline void __hlist_del(struct hlist_node *n)
{
    struct hlist_node *next = n->next;
    struct hlist_node **pprev = n->pprev;
    *pprev = next;
    if (next)
        next->pprev = pprev;
}
static inline void hlist_del(struct hlist_node *n)
{
    __hlist_del(n);
    n->next = LIST_POISON1;
    n->pprev = LIST_POISON2;
}
static inline void hlist_del_init(struct hlist_node *n)
{
    if (!hlist_unhashed(n)) {
        __hlist_del(n);
        INIT_HLIST_NODE(n);
    }
}
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
    struct hlist_node *first = h->first;
    n->next = first;
    if (first)
        first->pprev = &n->next;
    h->first = n;
    n->pprev = &h->first;
}
/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,
                    struct hlist_node *next)
{
    n->pprev = next->pprev;
    n->next = next;
    next->pprev = &n->next;
    *(n->pprev) = n;
}
static inline void hlist_add_after(struct hlist_node *n,
                    struct hlist_node *next)
{
    next->next = n->next;
    n->next = next;
    next->pprev = &n->next;
    if(next->next)
        next->next->pprev  = &next->next;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each(pos, head) \
    for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
         pos = pos->next)
#define hlist_for_each_safe(pos, n, head) \
    for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
         pos = n)
/**
 * hlist_for_each_entry    - iterate over list of given type
 * @tpos:    the type * to use as a loop cursor.
 * @pos:    the &struct hlist_node to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry(tpos, pos, head, member)             \
    for (pos = (head)->first;                     \
         pos && ({ prefetch(pos->next); 1;}) &&             \
        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
         pos = pos->next)
/**
 * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
 * @tpos:    the type * to use as a loop cursor.
 * @pos:    the &struct hlist_node to use as a loop cursor.
 * @member:    the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_continue(tpos, pos, member)         \
    for (pos = (pos)->next;                         \
         pos && ({ prefetch(pos->next); 1;}) &&             \
        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
         pos = pos->next)
/**
 * hlist_for_each_entry_from - iterate over a hlist continuing from current point
 * @tpos:    the type * to use as a loop cursor.
 * @pos:    the &struct hlist_node to use as a loop cursor.
 * @member:    the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_from(tpos, pos, member)             \
    for (; pos && ({ prefetch(pos->next); 1;}) &&             \
        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
         pos = pos->next)
/**
 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 * @tpos:    the type * to use as a loop cursor.
 * @pos:    the &struct hlist_node to use as a loop cursor.
 * @n:        another &struct hlist_node to use as temporary storage
 * @head:    the head for your list.
 * @member:    the name of the hlist_node within the struct.
 */
#define hlist_for_each_entry_safe(tpos, pos, n, head, member)         \
    for (pos = (head)->first;                     \
         pos && ({ n = pos->next; 1; }) &&                 \
        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
         pos = n)
#endif
proj1_mqttd/lylib/logger.c
New file
@@ -0,0 +1,364 @@
/*********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  logger.c
 *    Description:  This file is the linux infrastructural logger system library, which
 *                  is not thread safe.
 *
 *        Version:  1.0.0(08/08/2012~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "08/08/2018 04:24:01 PM"
 *
 ********************************************************************************/
#include "logger.h"
#define PRECISE_TIME_FACTOR 1000
static unsigned long log_rollback_size = LOG_ROLLBACK_NONE;
static st_logger _g_logger;
static st_logger *g_logger = &_g_logger;
char *log_str[LOG_LEVEL_MAX + 1] = { "", "F", "E", "W", "N", "D", "I", "T", "M" };
static char *log_time_format = "%Y-%m-%d %H:%M:%S";
static void logger_default_signal_handler(int sig)
{
    if (sig == SIGHUP)
    {
        signal(SIGHUP, logger_default_signal_handler);
        log_fatal("SIGHUP received - reopenning log file [%s]", g_logger->file);
        logger_reopen();
    }
}
static void logger_banner(char *prefix)
{
    fprintf(g_logger->fp, "%s log \"%s\" on level [%s] size [%lu], log system version %s\n",
            prefix, g_logger->file, log_str[g_logger->level], log_rollback_size / 1024, LOG_VERSION_STR);
#if 0
#ifdef LOG_FILE_LINE
    fprintf(g_logger->fp, " [Date]    [Time]   [Level] [PID/TID] [File/Line]  [Content]\n");
#else
    fprintf(g_logger->fp, " [Date]    [Time]   [Level] [PID/TID] [Content]\n");
#endif
#endif
    fprintf(g_logger->fp, "-----------------------------------------------------------------------------\n");
}
static void check_and_rollback(void)
{
    if (log_rollback_size != LOG_ROLLBACK_NONE)
    {
        long _curOffset = ftell(g_logger->fp);
        if ((_curOffset != -1) && (_curOffset >= log_rollback_size))
        {
            char cmd[512];
            snprintf(cmd, sizeof(cmd), "cp -f %s %s.roll", g_logger->file, g_logger->file);
            system(cmd);
            if (-1 == fseek(g_logger->fp, 0L, SEEK_SET))
                fprintf(g_logger->fp, "log rollback fseek failed \n");
            rewind(g_logger->fp);
            truncate(g_logger->file, 0);
            logger_banner("Already rollback");
        }
    }
}
int logger_init(char *filename, int level, int log_size)
{
    struct sigaction act;
    if( !filename || strlen(filename)<=0 )
    {
        fprintf(stderr, "%s() invalid input arguments\n", __FUNCTION__);
        return -1;
    }
    memset(g_logger, 0, sizeof(st_logger));
    strncpy(g_logger->file, filename, FILENAME_LEN);
    g_logger->level = level;
    g_logger->size = log_size;
    log_rollback_size = g_logger->size <= 0 ? LOG_ROLLBACK_NONE : g_logger->size*1024;    /* Unit KiB */
    /* logger to console, just need point to standard error */
    if (!strcmp(g_logger->file, DBG_LOG_FILE))
    {
        g_logger->fp = stderr;
        log_rollback_size = LOG_ROLLBACK_NONE;
        g_logger->flag |= LOGGER_CONSOLE;
        goto OUT;
    }
    g_logger->fp = fopen(g_logger->file, "a+");
    if ( !g_logger->fp )
    {
        fprintf(stderr, "Open log file \"%s\" failure\n", g_logger->file);
        return -2;
    }
OUT:
    act.sa_handler = logger_default_signal_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGHUP, &act, NULL);
    logger_banner("\nInitialize");
    return 0;
}
void logger_raw(const char *fmt, ...)
{
    va_list argp;
    if ( !g_logger->fp )
        return;
    check_and_rollback();
    va_start(argp, fmt);
    vfprintf(g_logger->fp, fmt, argp);
    va_end(argp);
}
void logger_term(void)
{
    if ( !g_logger->fp )
        return;
    logger_banner("\nTerminate");
    logger_raw("\n\n");
    fflush(g_logger->fp);
    fclose(g_logger->fp);
    g_logger->fp = NULL;
    memset(g_logger, 0, sizeof(*g_logger));
    return ;
}
int logger_reopen(void)
{
    int rc = 0;
    if (g_logger->flag & LOGGER_CONSOLE )
    {
        fflush(g_logger->fp);
        g_logger->fp = stderr;
        return 0;
    }
    if( g_logger->fp )
    {
        logger_banner("\nClose");
        fflush(g_logger->fp);
        g_logger->fp = fopen(g_logger->file, "a+");
        if ( !g_logger->fp )
            rc = -2;
    }
    else
    {
        rc = -3;
    }
    if (!rc)
    {
        logger_banner("\nReopen");
    }
    return rc;
}
static void logger_printout(char *level, char *fmt, va_list argp)
{
    char buf[MAX_LOG_MESSAGE_LEN];
    struct tm *local;
    struct timeval now;
    char timestr[256];
    pthread_t tid;
    check_and_rollback();
#ifdef MULTHREADS
    tid = pthread_self();
#else
    tid = getpid();
#endif
    gettimeofday(&now, NULL);
    local = localtime(&now.tv_sec);
    strftime(timestr, 256, log_time_format, local);
    vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
#ifdef DUMPLICATE_OUTPUT
    printf("%s.%03ld [%s] [%06lu]: %s",
           timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, tid, buf);
#endif
    if (g_logger->fp)
        fprintf(g_logger->fp, "%s.%03ld [%s] [%06lu]: %s", timestr, now.tv_usec / PRECISE_TIME_FACTOR,
                level, tid, buf);
    if (g_logger->fp)
        fflush(g_logger->fp);
}
static void logger_printout_line(char *level, char *fmt, char *file, int line, va_list argp)
{
    char buf[MAX_LOG_MESSAGE_LEN];
    struct tm *local;
    struct timeval now;
    char timestr[256];
    pthread_t tid;
    check_and_rollback();
#ifdef MULTHREADS
    tid = pthread_self();
#else
    tid = getpid();
#endif
    gettimeofday(&now, NULL);
    local = localtime(&now.tv_sec);
    strftime(timestr, 256, log_time_format, local);
    vsnprintf(buf, MAX_LOG_MESSAGE_LEN, fmt, argp);
#ifdef DUMPLICATE_OUTPUT
    printf("%s.%03ld [%s] [%06lu] (%s [%04d]) : %s",
           timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, tid, file, line, buf);
#endif
    if (g_logger->fp)
        fprintf(g_logger->fp, "%s.%03ld [%s] [%06lu] (%s [%04d]) : %s",
                timestr, now.tv_usec / PRECISE_TIME_FACTOR, level, tid, file, line, buf);
    if (g_logger->fp)
        fflush(g_logger->fp);
}
void logger_comm(int level, char *fmt, ...)
{
    va_list argp;
    if ( level > g_logger->level )
        return;
    va_start(argp, fmt);
    logger_printout(log_str[level], fmt, argp);
    va_end(argp);
}
void logger_line(int level, char *file, int line, char *fmt, ...)
{
    va_list argp;
    if ( level > g_logger->level )
        return;
    va_start(argp, fmt);
    logger_printout_line(log_str[level], fmt, file, line, argp);
    va_end(argp);
}
#define LINELEN 81
#define CHARS_PER_LINE 16
static char *print_char =
    "                "
    "                "
    " !\"#$%&'()*+,-./"
    "0123456789:;<=>?"
    "@ABCDEFGHIJKLMNO"
    "PQRSTUVWXYZ[\\]^_"
    "`abcdefghijklmno"
    "pqrstuvwxyz{|}~ "
    "                "
    "                "
    " ???????????????"
    "????????????????"
    "????????????????"
    "????????????????"
    "????????????????"
    "????????????????";
void logger_dump(int level, char *buf, int len)
{
    int rc;
    int idx;
    char prn[LINELEN];
    char lit[CHARS_PER_LINE + 2];
    char hc[4];
    short line_done = 1;
    if ( level > g_logger->level )
        return;
    rc = len;
    idx = 0;
    lit[CHARS_PER_LINE] = '\0';
    while (rc > 0)
    {
        if (line_done)
            snprintf(prn, LINELEN, "%08X: ", idx);
        do
        {
            unsigned char c = buf[idx];
            snprintf(hc, 4, "%02X ", c);
            strncat(prn, hc, LINELEN);
            lit[idx % CHARS_PER_LINE] = print_char[c];
        }
        while (--rc > 0 && (++idx % CHARS_PER_LINE != 0));
        line_done = (idx % CHARS_PER_LINE) == 0;
        if (line_done)
        {
#ifdef DUMPLICATE_OUTPUT
            printf("%s  %s\n", prn, lit);
#endif
            if (g_logger->fp)
                fprintf(g_logger->fp, "%s  %s\n", prn, lit);
        }
    }
    if (!line_done)
    {
        int ldx = idx % CHARS_PER_LINE;
        lit[ldx++] = print_char[(int)buf[idx]];
        lit[ldx] = '\0';
        while ((++idx % CHARS_PER_LINE) != 0)
            strncat(prn, "   ", LINELEN);
#ifdef DUMPLICATE_OUTPUT
        printf("%s  %s\n", prn, lit);
#endif
        if (g_logger->fp)
            fprintf(g_logger->fp, "%s  %s\n", prn, lit);
    }
}
proj1_mqttd/lylib/logger.h
New file
@@ -0,0 +1,104 @@
/********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  logger.h
 *    Description:  This file is the linux infrastructural logger system library
 *
 *        Version:  1.0.0(08/08/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "08/08/2018 05:16:56 PM"
 *
 ********************************************************************************/
#ifndef __LOGGER_H_
#define __LOGGER_H_
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/time.h>
#define LOG_VERSION_STR             "2.0.0"
#ifndef FILENAME_LEN
#define FILENAME_LEN                64
#endif
#define DEFAULT_LOGFILE             "logger.log"
#define DBG_LOG_FILE                "console"  /*  Debug mode log file is console */
#define LOG_ROLLBACK_SIZE           512    /* Default rollback log size  */
#define LOG_ROLLBACK_NONE           0      /* Set rollback size to 0 will not rollback  */
#define MAX_LOG_MESSAGE_LEN         0x1000
//#define DUMPLICATE_OUTPUT  /* Log to file and printf on console  */
#define LOG_FILE_LINE      /* Log the file and line */
enum
{
    LOG_LEVEL_DISB = 0,               /*  Disable "Debug" */
    LOG_LEVEL_FATAL,                  /*  Debug Level "Fatal" */
    LOG_LEVEL_ERROR,                  /*  Debug Level "ERROR" */
    LOG_LEVEL_WARN,                   /*  Debug Level "warnning" */
    LOG_LEVEL_NRML,                   /*  Debug Level "Normal" */
    LOG_LEVEL_DEBUG,                  /*  Debug Level "Debug" */
    LOG_LEVEL_INFO,                   /*  Debug Level "Information" */
    LOG_LEVEL_TRACE,                  /*  Debug Level "Trace" */
    LOG_LEVEL_MAX,
};
#define LOGGER_CONSOLE             1<<1
#define LOGGER_FILE                0<<1
#define LOGGER_LEVEL_OPT           1<<2 /*  The log level is sepcified by the command option */
typedef struct _st_logger
{
    unsigned char      flag;  /* This logger pointer is malloc() or passed by argument */
    char               file[FILENAME_LEN];
    int                level;
    int                size;
    FILE               *fp;
} st_logger;
extern int  logger_init(char *filename, int level, int log_size);
extern int  logger_reopen(void);
extern void logger_term(void);
extern void logger_comm(int level, char *fmt, ...);
extern void logger_line(int level, char *file, int line, char *fmt, ...);
extern void logger_dump(int level, char *buf, int len);
#ifdef LOG_FILE_LINE
#define log_trace(fmt, ...) logger_line(LOG_LEVEL_TRACE, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_info(fmt, ...)  logger_line(LOG_LEVEL_INFO,  __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_dbg(fmt, ...)   logger_line(LOG_LEVEL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_nrml(fmt, ...)  logger_line(LOG_LEVEL_NRML,  __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...)  logger_line(LOG_LEVEL_WARN,  __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_err(fmt, ...)   logger_line(LOG_LEVEL_ERROR, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define log_fatal(fmt, ...) logger_line(LOG_LEVEL_FATAL, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
#else
#define log_trace(fmt, ...) logger_comm(LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
#define log_info(fmt, ...)  logger_comm(tLOG_LEVEL_INFO,  fmt, ##__VA_ARGS__)
#define log_dbg(fmt, ...)   logger_comm(LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
#define log_nrml(fmt, ...)  logger_comm(LOG_LEVEL_NRML,  fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...)  logger_comm(LOG_LEVEL_WARN,  fmt, ##__VA_ARGS__)
#define log_err(fmt, ...)   logger_comm(LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
#define log_fatal(fmt, ...) logger_comm(LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__)
#endif
#endif /* __LOGGER_H_ */
proj1_mqttd/lylib/makefile
New file
@@ -0,0 +1,17 @@
PWD=$(shell pwd )
LIBNAME=$(shell basename ${PWD} )
PROJPATH=$(shell dirname ${PWD} )
CFLAGS+=-I${PROJPATH}
all: clean
    @rm -f *.o
    @${CROSS_COMPILE}gcc ${CFLAGS} -c *.c
    ${CROSS_COMPILE}ar -rcs  lib${LIBNAME}.a *.o
clean:
    @rm -f *.o
    @rm -f *.a
proj1_mqttd/lylib/proc.c
New file
@@ -0,0 +1,341 @@
/*********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  cp_proc.c
 *    Description:  This file is the process API
 *
 *        Version:  1.0.0(11/06/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "11/06/2018 09:19:02 PM"
 *
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "proc.h"
#include "logger.h"
st_sigproc     g_signal={0};
void proc_sighandler(int sig)
{
    switch(sig)
    {
        case SIGINT:
            log_warn("SIGINT - stopping\n");
            g_signal.stop = 1;
            break;
        case SIGTERM:
            //log_warn("SIGTERM - stopping\n");
            g_signal.stop = 1;
            break;
#if 0
        case SIGSEGV:
            log_err("SIGSEGV - stopping\n");
            if(g_signal.stop)
                exit(0);
            g_signal.stop = 1;
            break;
#endif
        case SIGPIPE:
            log_warn("SIGPIPE - warnning\n");
            g_signal.stop = 1;
            break;
        default:
            break;
    }
}
void install_proc_signal(void)
{
    struct sigaction sigact, sigign;
    log_nrml("Install default signal handler.\n");
    /*  Initialize the catch signal structure. */
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = proc_sighandler;
    /*  Setup the ignore signal. */
    sigemptyset(&sigign.sa_mask);
    sigign.sa_flags = 0;
    sigign.sa_handler = SIG_IGN;
    sigaction(SIGTERM, &sigact, 0); /*  catch terminate signal "kill" command */
    sigaction(SIGINT,  &sigact, 0); /*  catch interrupt signal CTRL+C */
    //sigaction(SIGSEGV, &sigact, 0); /*  catch segmentation faults  */
    sigaction(SIGPIPE, &sigact, 0); /*  catch broken pipe */
#if 0
    sigaction(SIGCHLD, &sigact, 0); /*  catch child process return */
    sigaction(SIGUSR2, &sigact, 0); /*  catch USER signal */
#endif
}
/* ****************************************************************************
 * FunctionName: daemonize
 * Description : Set the programe runs as daemon in background
 * Inputs      : nodir: DON'T change the work directory to / :  1:NoChange 0:Change
 *               noclose: close the opened file descrtipion or not 1:Noclose 0:Close
 * Output      : NONE
 * Return      : NONE
 * *****************************************************************************/
void daemonize(int nochdir, int noclose)
{
    int retval, fd;
    int i;
    /*  already a daemon */
    if (1 == getppid())
        return;
    /*  fork error */
    retval = fork();
    if (retval < 0) exit(1);
    /*  parent process exit */
    if (retval > 0)
        exit(0);
    /*  obtain a new process session group */
    setsid();
    if (!noclose)
    {
        /*  close all descriptors */
        for (i = getdtablesize(); i >= 0; --i)
        {
            //if (i != g_logPtr->fd)
                close(i);
        }
        /*  Redirect Standard input [0] to /dev/null */
        fd = open("/dev/null", O_RDWR);
        /* Redirect Standard output [1] to /dev/null */
        dup(fd);
        /* Redirect Standard error [2] to /dev/null */
        dup(fd);
    }
    umask(0);
    if (!nochdir)
        chdir("/");
    return;
}
/* ****************************************************************************
 * FunctionName: record_daemon_pid
 * Description : Record the running daemon program PID to the file "pid_file"
 * Inputs      : pid_file:The record PID file path
 * Output      : NONE
 * Return      : 0: Record successfully  Else: Failure
 * *****************************************************************************/
int record_daemon_pid(const char *pid_file)
{
    struct stat fStatBuf;
    int fd = -1;
    int mode = S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRWXU;
    char ipc_dir[64] = { 0 };
    strncpy(ipc_dir, pid_file, 64);
    /* dirname() will modify ipc_dir and save the result */
    dirname(ipc_dir);
    /* If folder pid_file PATH doesnot exist, then we will create it" */
    if (stat(ipc_dir, &fStatBuf) < 0)
    {
        if (mkdir(ipc_dir, mode) < 0)
        {
            log_fatal("cannot create %s: %s\n", ipc_dir, strerror(errno));
            return -1;
        }
        (void)chmod(ipc_dir, mode);
    }
    /*  Create the process running PID file */
    mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
    if ((fd = open(pid_file, O_RDWR | O_CREAT | O_TRUNC, mode)) >= 0)
    {
        char pid[PID_ASCII_SIZE];
        snprintf(pid, sizeof(pid), "%u\n", (unsigned)getpid());
        write(fd, pid, strlen(pid));
        close(fd);
        log_dbg("Record PID<%u> to file %s.\n", getpid(), pid_file);
    }
    else
    {
        log_fatal("cannot create %s: %s\n", pid_file, strerror(errno));
        return -1;
    }
    return 0;
}
/* ****************************************************************************
 * FunctionName: get_daemon_pid
 * Description : Get the daemon process PID from the PID record file "pid_file"
 * Inputs      : pid_file: the PID record file
 * Output      : NONE
 * Return      : pid_t: The daemon process PID number
 * *****************************************************************************/
pid_t get_daemon_pid(const char *pid_file)
{
    FILE *f;
    pid_t pid;
    if ((f = fopen(pid_file, "rb")) != NULL)
    {
        char pid_ascii[PID_ASCII_SIZE];
        (void)fgets(pid_ascii, PID_ASCII_SIZE, f);
        (void)fclose(f);
        pid = atoi(pid_ascii);
    }
    else
    {
        log_fatal("Can't open PID record file %s: %s\n", pid_file, strerror(errno));
        return -1;
    }
    return pid;
}
/* ****************************************************************************
 * FunctionName: check_daemon_running
 * Description : Check the daemon program already running or not
 * Inputs      : pid_file: The record running daemon program PID
 * Output      : NONE
 * Return      : 1: The daemon program alread running   0: Not running
 * *****************************************************************************/
int check_daemon_running(const char *pid_file)
{
    int retVal = -1;
    struct stat fStatBuf;
    retVal = stat(pid_file, &fStatBuf);
    if (0 == retVal)
    {
        pid_t pid = -1;
        printf("PID record file \"%s\" exist.\n", pid_file);
        pid = get_daemon_pid(pid_file);
        if (pid > 0)  /*  Process pid exist */
        {
            if ((retVal = kill(pid, 0)) == 0)
            {
                printf("Program with PID[%d] seems running.\n", pid);
                return 1;
            }
            else   /* Send signal to the old process get no reply. */
            {
                printf("Program with PID[%d] seems exit.\n", pid);
                remove(pid_file);
                return 0;
            }
        }
        else if (0 == pid)
        {
            printf("Can not read program PID form record file.\n");
            remove(pid_file);
            return 0;
        }
        else  /* Read pid from file "pid_file" failure */
        {
            printf("Read record file \"%s\" failure, maybe program still running.\n", pid_file);
            return 1;
        }
    }
    return 0;
}
/* ****************************************************************************
 * FunctionName: set_daemon_running
 * Description : Set the programe running as daemon if it's not running and record
 *               its PID to the pid_file.
 * Inputs      : pid_file: The record running daemon program PID
 * Output      : NONE
 * Return      : 0: Successfully. 1: Failure
 * *****************************************************************************/
int set_daemon_running(const char *pid_file)
{
    daemonize(0, 1);
    log_nrml("Program running as daemon [PID:%d].\n", getpid());
    if (record_daemon_pid(pid_file) < 0)
    {
        log_fatal("Record PID to file \"%s\" failure.\n", pid_file);
        return -2;
    }
    return 0;
}
int thread_start(pthread_t * thread_id, thread_function* thread_workbody, void *thread_arg)
{
    int        retval = 0;
    pthread_attr_t thread_attr;
    /* Initialize the thread  attribute */
    retval = pthread_attr_init(&thread_attr);
    if(retval)
        return -1;
    /* Set the stack size of the thread */
    retval = pthread_attr_setstacksize(&thread_attr, 120 * 1024);
    if(retval)
        goto CleanUp;
    /* Set thread to detached state:Don`t need pthread_join */
    retval = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
    if(retval)
        goto CleanUp;
    /* Create the thread */
    retval = pthread_create(thread_id, &thread_attr, thread_workbody, thread_arg);
    if(retval)
        goto CleanUp;
CleanUp:
    /* Destroy the  attributes  of  thread */
    pthread_attr_destroy(&thread_attr);
    return retval;
}
void exec_system_cmd(const char *format, ...)
{
    char                cmd[256];
    va_list             args;
    int                 done;
    memset(cmd, 0, sizeof(cmd));
    va_start(args, format);
    done = vsnprintf(cmd, sizeof(cmd), format, args);
    va_end(args);
    system(cmd);
}
proj1_mqttd/lylib/proc.h
New file
@@ -0,0 +1,52 @@
/********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  proc.h
 *    Description:  This head file is for Linux process API
 *
 *        Version:  1.0.0(11/06/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "11/06/2018 09:21:33 PM"
 *
 ********************************************************************************/
#ifndef __CP_PROC_H
#define __CP_PROC_H
#include <signal.h>
#define PID_ASCII_SIZE  11
typedef struct _st_sigproc
{
    int       signal;
    unsigned  stop;     /* 0: Not term  1: Stop  */
}  st_sigproc;
/* global variable for process or thread to exit  */
extern st_sigproc     g_signal;
/* install signal handler  */
extern void install_proc_signal(void);
/* record process PID into $pid_file for check_daemon_running() to check program running or not */
extern int record_daemon_pid(const char *pid_file);
/* check program already running or not
 * 1: The daemon program alread running   0: Not running
 */
extern int check_daemon_running(const char *pid_file);
/* set program running as daemon */
extern int set_daemon_running(const char *pid_file);
/* create a system command and excute it */
extern void exec_system_cmd(const char *format, ...);
/* create and start a thread to excute function pointed by $thread_workbody  */
typedef void *(thread_function) (void *thread_arg);
extern int thread_start(pthread_t * thread_id, thread_function * thread_workbody, void *thread_arg);
#endif
proj1_mqttd/main.c
New file
@@ -0,0 +1,304 @@
/*********************************************************************************
 *      Copyright:  (C) 2019 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file
 *
 *        Version:  1.0.0(29/01/19)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "29/01/19 15:34:41"
 *
 ********************************************************************************/
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <libgen.h>
#include <string.h>
#include <mosquitto.h>
#include "logger.h"
#include "cJSON.h"
#include "proc.h"
#include "conf.h"
#define PROG_VERSION               "v1.0.0"
#define DAEMON_PIDFILE             "/tmp/.mqtt.pid"
int check_set_program_running(int daemon);
void *mqtt_sub_worker(void *args);
static void program_usage(char *progname)
{
    printf("Usage: %s [OPTION]...\n", progname);
    printf(" %s is LingYun studio MQTT daemon program running on RaspberryPi\n", progname);
    printf("\nMandatory arguments to long options are mandatory for short options too:\n");
    printf(" -d[debug   ]  Running in debug mode\n");
    printf(" -c[conf    ]  Specify configure file\n");
    printf(" -h[help    ]  Display this help information\n");
    printf(" -v[version ]  Display the program version\n");
    printf("\n%s version %s\n", progname, PROG_VERSION);
    return;
}
int main (int argc, char **argv)
{
    float              temp;
    float              rh;
    int                daemon = 1;
    pthread_t          tid;
    mqtt_ctx_t         ctx;
    char               *conf_file=NULL;
    int                debug = 0;
    int                opt;
    char              *progname=NULL;
    struct option long_options[] = {
        {"conf", required_argument, NULL, 'c'},
        {"debug", no_argument, NULL, 'd'},
        {"version", no_argument, NULL, 'v'},
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };
    progname = (char *)basename(argv[0]);
    /* Parser the command line parameters */
    while ((opt = getopt_long(argc, argv, "c:dvh", long_options, NULL)) != -1)
    {
        switch (opt)
        {
            case 'c': /* Set configure file */
                conf_file = optarg;
                break;
            case 'd': /* Set debug running */
                daemon = 0;
                debug = 1;
                break;
            case 'v':  /* Get software version */
                printf("%s version %s\n", progname, PROG_VERSION);
                return 0;
            case 'h':  /* Get help information */
                program_usage(progname);
                return 0;
            default:
                break;
        }
    }
    if( !conf_file )
        debug = 1;
    if( mqttd_parser_conf(conf_file, &ctx, debug)<0 )
    {
        fprintf(stderr, "Parser mqtted configure file failure\n");
        return -2;
    }
    install_proc_signal();
    if( check_set_program_running(daemon) < 0 )
        goto OUT;
    if( !debug )
    mosquitto_lib_init();
    if( thread_start(&tid, mqtt_sub_worker, &ctx ) < 0 )
    {
        log_fatal("Start MQTT subsciber worker thread failure\n");
        goto OUT;
    }
    log_nrml("Start MQTT subsciber worker thread ok\n");
    while( ! g_signal.stop )
    {
        sleep(1);
        //log_nrml("Main control thread continue running\n");
    }
OUT:
    mosquitto_lib_cleanup();
    logger_term();
    return 0;
} /* ----- End of main() ----- */
int check_set_program_running(int daemon)
{
    if( check_daemon_running(DAEMON_PIDFILE) )
    {
        log_err("Program already running, process exit now");
        return -1;
    }
    if( daemon )
    {
        if( set_daemon_running(DAEMON_PIDFILE) < 0 )
        {
            log_err("set program running as daemon failure\n");
            return -2;
        }
    }
    else
    {
        if( record_daemon_pid(DAEMON_PIDFILE) < 0 )
        {
            log_err("record program running PID failure\n");
            return -3;
        }
    }
    return 0;
}
void sub_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
    mqtt_ctx_t             *ctx = (mqtt_ctx_t *)userdata;
    if( result )
    {
        log_err("Subscriber connect to broker server failed, rv=%d\n", result);
        return ;
    }
    log_nrml("Subscriber connect to broker server[%s:%d] successfully\n", ctx->host, ctx->port);
    mosquitto_subscribe(mosq, NULL, ctx->subTopic, ctx->subQos);
}
void sub_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)
{
    mqtt_ctx_t             *ctx = (mqtt_ctx_t *)userdata;
    log_warn("Subscriber disconnect to broker server[%s:%d], reason=%d\n", ctx->host, ctx->port, result);
}
void proc_json_items(cJSON *root)
{
    int                    i;
    char                  *value;
    cJSON                 *item;
    cJSON                 *array;
    if( !root )
    {
        log_err("Invalid input arguments $root\n");
        return ;
    }
    for( i=0; i<cJSON_GetArraySize(root); i++ )
    {
        item = cJSON_GetArrayItem(root, i);
        if( !item )
            break;
        /* if item is cJSON_Object, then recursive call proc_json */
        if( cJSON_Object == item->type )
        {
            proc_json_items(item);
        }
        else if( cJSON_Array == item->type )
        {
            /* Logic C920 camera control  */
            if( !strcasecmp(item->string, "camera") )
            {
                array = cJSON_GetArrayItem(item, 0);
                if( NULL != array )
                {
                    cJSON        *led_item;
                    if( NULL != (led_item=cJSON_GetObjectItem(array , "C920")) )
                    {
                        log_nrml("turn Logic C920 camera '%s'\n", led_item->valuestring);
                    }
                }
            }
        }
    }
}
void sub_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
    cJSON                 *root = NULL;
    char                  *out;
    if ( !message->payloadlen )
    {
        log_err("%s (null)\n", message->topic);
        return ;
    }
    log_nrml("Subscriber receive message: '%s'\n", message->payload);
    root = cJSON_Parse(message->payload);
    if( !root )
    {
        log_err("cJSON_Parse parser failure: %s\n", cJSON_GetErrorPtr());
        return ;
    }
    proc_json_items(root);
    cJSON_Delete(root); /* must delete it, or it will result memory leak */
    return ;
}
void *mqtt_sub_worker(void *args)
{
    mqtt_ctx_t             *ctx = (mqtt_ctx_t *)args;
    struct mosquitto       *mosq;
    bool                    session = true;
    mosq = mosquitto_new(NULL, session, ctx);
    if( !mosq )
    {
        log_err("mosquitto_new failure\n");
        return NULL;
    }
    /* set connnect to broker username and password  */
    if( strlen(ctx->uid)> 0  && strlen(ctx->pwd)> 0 )
        mosquitto_username_pw_set(mosq, ctx->uid, ctx->pwd);
    /* set callback functions */
    mosquitto_connect_callback_set(mosq, sub_connect_callback);
    mosquitto_disconnect_callback_set(mosq, sub_disconnect_callback);
    mosquitto_message_callback_set(mosq, sub_message_callback);
    while( !g_signal.stop )
    {
        /* connect to MQTT broker  */
        if( mosquitto_connect(mosq, ctx->host, ctx->port, ctx->keepalive) )
        {
            log_err("Subscriber connect to broker[%s:%d] failure: %s\n", ctx->host, ctx->port, strerror(errno));
            sleep(1);
            continue;
        }
        /* -1: use default timeout 1000ms  1: unused */
        mosquitto_loop_forever(mosq, -1, 1);
    }
    mosquitto_destroy(mosq);
    return NULL;
}
proj1_mqttd/makefile
New file
@@ -0,0 +1,73 @@
#*********************************************************************************
#      Copyright:  (C) 2012 Guo Wenxue<Email:guowenxue@gmail.com QQ:281143292>
#                  All rights reserved.
#
#       Filename:  Makefile
#    Description:  This Makefile used to compile all the C source code file in current
#                  folder to one excutable binary files.
#
#        Version:  1.0.0(10/08/2011~)
#                  Author:  Guo Wenxue <guowenxue@gmail.com>
#      ChangeLog:  1, Release initial version on "11/11/2011 01:29:33 PM"
#
#********************************************************************************/
IMAGE_NAME=mqttd
PWD=$(shell pwd)
INSTPATH=/usr/bin
CFLAGS+=-I${PWD}
#CFLAGS+=-Wall -Werror
MQTT_LIBPATH=mosquitto
LDFLAGS+=-lwiringPi
LDFLAGS+=-lpthread
VPATH= .
SRCS = $(wildcard ${VPATH}/*.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
CFLAGS+=-Ietc -Ilylib
LDFLAGS+=-Letc -letc -Llylib -llylib
LDFLAGS+=-lmosquitto -lpthread -lm
SRCFILES = $(wildcard *.c)
all: entry modules binary
entry:
    @echo " ";
    @echo " =========================================================";
    @echo " **        Compile \"${BINARIES}\" for ${ARCH}         ";
    @echo " =========================================================";
modules:
    make -C lylib
    make -C etc
    cd ${MQTT_LIBPATH} && bash build.sh
binary:  ${SRCFILES}
    $(CC) $(CFLAGS) -o ${IMAGE_NAME} $^ ${LDFLAGS}
    @echo " Compile over"
tag:
    @ctags --c-kinds=+defglmnstuvx --langmap=c:.c.h.ho.hem.het.hec.hev.him.hit.hic.hiv -R .
    @cscope -Rbq
install:
    @cp $(IMAGE_NAME) ${INSTPATH}
clean:
    @make clean -C etc
    @make clean -C lylib
    @rm -f version.h
    @rm -f *.o $(IMAGE_NAME)
    @rm -rf *.gdb *.a *.so *.elf*
distclean: clean
    @rm -f  tags cscope*
.PHONY: clean entry
proj1_mqttd/mosquitto/build.sh
New file
@@ -0,0 +1,37 @@
#!/bin/bash
MQTT_LIB=mosquitto-1.6.3
LIBPATH=/usr/local/lib/libmosquitto.so
if [ -f ${LIBPATH} ] ; then
    echo "${MQTT_LIB} already installed"
    exit 0;
fi
if [ ! -d $MQTT_LIB ]  ; then
    if [ ! -f ${MQTT_LIB}.tar.gz ] ; then
        wget https://mosquitto.org/files/source/${MQTT_LIB}.tar.gz
    fi
    if [ ! -f ${MQTT_LIB}.tar.gz ] ; then
        echo "## ERROR: MQTT Library ${MQTT_LIB}.tar.gz not exist or download failure!"
        exit 1;
    fi
    tar -xzf ${MQTT_LIB}.tar.gz
fi
if [ ! -d $MQTT_LIB ]  ; then
    echo "## ERROR: MQTT Library ${MQTT_LIB} not exist or decompress failure!"
    exit 2;
fi
cd $MQTT_LIB
make install
if [ $? != 0 ] ; then
    echo "ERROR: MQTT Library ${MQTT_LIB} failure!"
    exit 3;
fi
proj1_mqttd/mosquitto/mosquitto-1.6.3.tar.gz
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/CMakeLists.txt
New file
@@ -0,0 +1,118 @@
# This is a cmake script. Process it with the CMake gui or command line utility
# to produce makefiles / Visual Studio project files on Mac OS X and Windows.
#
# To configure the build options either use the CMake gui, or run the command
# line utility including the "-i" option.
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(mosquitto)
cmake_minimum_required(VERSION 2.8)
# Only for version 3 and up. cmake_policy(SET CMP0042 NEW)
set (VERSION 1.6.3)
add_definitions (-DCMAKE -DVERSION=\"${VERSION}\")
if (WIN32)
    add_definitions("-D_CRT_SECURE_NO_WARNINGS")
    add_definitions("-D_CRT_NONSTDC_NO_DEPRECATE")
endif (WIN32)
include(GNUInstallDirs)
option(WITH_TLS
    "Include SSL/TLS support?" ON)
option(WITH_TLS_PSK
    "Include TLS-PSK support (requires WITH_TLS)?" ON)
option(WITH_EC
    "Include Elliptic Curve support (requires WITH_TLS)?" ON)
if (WITH_TLS)
    find_package(OpenSSL REQUIRED)
    add_definitions("-DWITH_TLS")
    if (WITH_TLS_PSK)
        add_definitions("-DWITH_TLS_PSK")
    endif (WITH_TLS_PSK)
    if (WITH_EC)
        add_definitions("-DWITH_EC")
    endif (WITH_EC)
else (WITH_TLS)
    set (OPENSSL_INCLUDE_DIR "")
endif (WITH_TLS)
option(WITH_SOCKS "Include SOCKS5 support?" ON)
if (WITH_SOCKS)
    add_definitions("-DWITH_SOCKS")
endif (WITH_SOCKS)
option(WITH_SRV "Include SRV lookup support?" OFF)
option(WITH_THREADING "Include client library threading support?" ON)
if (WITH_THREADING)
    add_definitions("-DWITH_THREADING")
    if (WIN32)
        if (CMAKE_CL_64)
            set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x64\\pthreadVC2.lib)
        else (CMAKE_CL_64)
            set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib)
        endif (CMAKE_CL_64)
        set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include)
    else (WIN32)
        find_library(LIBPTHREAD pthread)
        if (LIBPTHREAD)
            set (PTHREAD_LIBRARIES pthread)
        else (LIBPTHREAD)
            set (PTHREAD_LIBRARIES "")
        endif()
        set (PTHREAD_INCLUDE_DIR "")
    endif (WIN32)
else (WITH_THREADING)
    set (PTHREAD_LIBRARIES "")
    set (PTHREAD_INCLUDE_DIR "")
endif (WITH_THREADING)
option(DOCUMENTATION "Build documentation?" ON)
option(WITH_DLT "Include DLT support?" OFF)
message(STATUS "WITH_DLT = ${WITH_DLT}")
if (WITH_DLT)
    #find_package(DLT REQUIRED)
    find_package(PkgConfig)
    pkg_check_modules(DLT "automotive-dlt >= 2.11")
    add_definitions("-DWITH_DLT")
endif (WITH_DLT)
# ========================================
# Include projects
# ========================================
add_subdirectory(lib)
add_subdirectory(client)
add_subdirectory(src)
if (DOCUMENTATION)
    add_subdirectory(man)
endif (DOCUMENTATION)
# ========================================
# Install config file
# ========================================
install(FILES mosquitto.conf aclfile.example pskfile.example pwfile.example DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/mosquitto")
# ========================================
# Install pkg-config files
# ========================================
configure_file(libmosquitto.pc.in libmosquitto.pc @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquitto.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
configure_file(libmosquittopp.pc.in libmosquittopp.pc @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquittopp.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
# ========================================
# Testing
# ========================================
enable_testing()
proj1_mqttd/mosquitto/mosquitto-1.6.3/CONTRIBUTING.md
New file
@@ -0,0 +1,92 @@
Contributing to Mosquitto
=========================
Thank you for your interest in this project.
Project description:
--------------------
The Mosquitto project has been created to provide a light weight, open-source
implementation, of an MQTT broker to allow new, existing, and emerging
applications for Machine-to-Machine (M2M) and Internet of Things (IoT).
- <https://mosquitto.org/>
- <https://projects.eclipse.org/projects/technology.mosquitto>
Source
------
The Mosquitto code is stored in a git repository.
- https://github.com/eclipse/mosquitto
You can contribute bugfixes and new features by sending pull requests through GitHub.
## Legal
In order for your contribution to be accepted, it must comply with the Eclipse
Foundation IP policy.
Please read the [Eclipse Foundation policy on accepting contributions via Git](http://wiki.eclipse.org/Development_Resources/Contributing_via_Git).
1. Sign the [Eclipse ECA](http://www.eclipse.org/legal/ECA.php)
    1. Register for an Eclipse Foundation User ID. You can register [here](https://accounts.eclipse.org/user/register).
    2. Log into the [Accounts Portal](https://accounts.eclipse.org/), and click on the '[Eclipse Contributor Agreement](https://accounts.eclipse.org/user/eca)' link.
2. Go to your [account settings](https://accounts.eclipse.org/user/edit) and add your GitHub username to your account.
3. Make sure that you _sign-off_ your Git commits in the following format:
  ``` Signed-off-by: John Smith <johnsmith@nowhere.com> ``` This is usually at the bottom of the commit message. You can automate this by adding the '-s' flag when you make the commits. e.g.   ```git commit -s -m "Adding a cool feature"```
4. Ensure that the email address that you make your commits with is the same one you used to sign up to the Eclipse Foundation website with.
## Contributing a change
1. [Fork the repository on GitHub](https://github.com/eclipse/mosquitto/fork)
2. Clone the forked repository onto your computer: ``` git clone
   https://github.com/<your username>/mosquitto.git ```
3. If you are adding a new feature, then create a new branch from the latest
   ```develop``` branch with ```git checkout -b YOUR_BRANCH_NAME
   origin/develop```
4. If you are fixing a bug, then create a new branch from the latest
   ```fixes``` branch with ```git checkout -b YOUR_BRANCH_NAME origin/fixes```
5. Make your changes
6. Ensure that all new and existing tests pass.
7. Commit the changes into the branch: ``` git commit -s ``` Make sure that
   your commit message is meaningful and describes your changes correctly.
8. If you have a lot of commits for the change, squash them into a single / few
   commits.
9. Push the changes in your branch to your forked repository.
10. Finally, go to
    [https://github.com/eclipse/mosquitto](https://github.com/eclipse/mosquitto)
    and create a pull request from your "YOUR_BRANCH_NAME" branch to the
    ```develop``` or ```fixes``` branch as appropriate to request review and
    merge of the commits in your pushed branch.
What happens next depends on the content of the patch. If it is 100% authored
by the contributor and is less than 1000 lines (and meets the needs of the
project), then it can be pulled into the main repository. If not, more steps
are required. These are detailed in the
[legal process poster](http://www.eclipse.org/legal/EclipseLegalProcessPoster.pdf).
Contact:
--------
Contact the project developers via the project's development
[mailing list](https://dev.eclipse.org/mailman/listinfo/mosquitto-dev).
Search for bugs:
----------------
This project uses [Github](https://github.com/eclipse/mosquitto/issues)
to track ongoing development and issues.
Create a new bug:
-----------------
Be sure to search for existing bugs before you create another one. Remember
that contributions are always welcome!
- [Create new Mosquitto bug](https://github.com/eclipse/mosquitto/issues)
proj1_mqttd/mosquitto/mosquitto-1.6.3/ChangeLog.txt
New file
@@ -0,0 +1,2175 @@
1.6.3 - 20190618
================
Broker:
- Fix detection of incoming v3.1/v3.1.1 bridges. Closes #1263.
- Fix default max_topic_alias listener config not being copied to the in-use
  listener when compiled without TLS support.
- Fix random number generation if compiling using `WITH_TLS=no` and on Linux
  with glibc >= 2.25. Without this fix, no random numbers would be generated
  for e.g. on broker client id generation, and so clients connecting expecting
  this feature would be unable to connect.
- Fix compilation problem related to `getrandom()` on non-glibc systems.
- Fix Will message for a persistent client incorrectly being sent when the
  client reconnects after a clean disconnect. Closes #1273.
- Fix Will message for a persistent client not being sent on disconnect.
  Closes #1273.
- Improve documentation around the upgrading of persistence files. Closes
  #1276.
- Add 'extern "C"' on mosquitto_broker.h and mosquitto_plugin.h for C++ plugin
  writing. Closes #1290.
- Fix persistent Websockets clients not receiving messages after they
  reconnect, having sent DISCONNECT on a previous session. Closes #1227.
- Disable TLS renegotiation. Client initiated renegotiation is considered to
  be a potential attack vector against servers. Closes #1257.
- Fix incorrect shared subscription topic '$shared'.
- Fix zero length client ids being rejected for MQTT v5 clients with clean
  start set to true.
- Fix MQTT v5 overlapping subscription behaviour. Clients now receive message
  from all matching subscriptions rather than the first one encountered, which
  ensures the maximum QoS requirement is met.
- Fix incoming/outgoing quota problems for QoS>0.
- Remove obsolete `store_clean_interval` from documentation.
- Fix v4 authentication plugin never calling psk_key_get.
Client library:
- Fix typo causing build error on Windows when building without TLS support.
  Closes #1264.
Clients:
- Fix -L url parsing when `/topic` part is missing.
- Stop some error messages being printed even when `--quiet` was used.
  Closes #1284.
- Fix mosquitto_pub exiting with error code 0 when an error occurred.
  Closes #1285.
- Fix mosquitto_pub not using the `-c` option. Closes #1273.
- Fix MQTT v5 clients not being able to specify a password without a username.
  Closes #1274.
- Fix `mosquitto_pub -l` not handling network failures. Closes #1152.
- Fix `mosquitto_pub -l` not handling zero length input. Closes #1302.
- Fix double free on exit in mosquitto_pub. Closes #1280.
Documentation:
- Remove references to Python binding and C++ wrapper in libmosquitto man
  page. Closes #1266.
Build:
- CLIENT_LDFLAGS now uses LDFLAGS. Closes #1294.
1.6.2 - 20190430
================
Broker:
- Fix memory access after free, leading to possible crash, when v5 client with
  Will message disconnects, where the Will message has as its first property
  one of `content-type`, `correlation-data`, `payload-format-indicator`, or
  `response-topic`.  Closes #1244.
- Fix build for WITH_TLS=no. Closes #1250.
- Fix Will message not allowing user-property properties.
- Fix broker originated messages (e.g. $SYS/broker/version) not being
  published when `check_retain_source` set to true. Closes #1245.
- Fix $SYS/broker/version being incorrectly expired after 60 seconds.
  Closes #1245.
Library:
- Fix crash after client has been unable to connect to a broker. This occurs
  when the client is exiting and is part of the final library cleanup routine.
  Closes #1246.
Clients:
- Fix -L url parsing. Closes #1248.
1.6.1 - 20190426
================
Broker:
- Document `memory_limit` option.
Clients:
- Fix compilation on non glibc systems due to missing sys/time.h header.
Build:
- Add `make check` target and document testing procedure. Closes #1230.
- Document bundled dependencies and how to disable. Closes #1231.
- Split CFLAGS and CPPFLAGS, and LDFLAGS and LDADD/LIBADD.
- test/unit now respects CPPFLAGS and LDFLAGS. Closes #1232.
- Don't call ldconfig in CMake scripts. Closes #1048.
- Use CMAKE_INSTALL_* variables when installing in CMake. Closes #1049.
1.6 - 20190417
==============
Broker features:
- Add support for MQTT v5
- Add support for OCSP stapling.
- Add support for ALPN on bridge TLS connections. Closes #924.
- Add support for Automotive DLT logging.
- Add TLS Engine support.
- Persistence file read/write performance improvements.
- General performance improvements.
- Add max_keepalive option, to allow a maximum keepalive value to be set for
  MQTT v5 clients only.
- Add `bind_interface` option which allows a listener to be bound to a
  specific network interface, in a similar fashion to the `bind_address` option.
  Linux only.
- Add improved bridge restart interval based on Decorrelated Jitter.
- Add `dhparamfile` option, to allow DH parameters to be loaded for Ephemeral
  DH support
- Disallow writing to $ topics where appropriate.
- Fix mosquitto_passwd crashing on corrupt password file. Closes #1207.
- Add explicit support for TLS v1.3.
- Drop support for TLS v1.0.
- Improved general support for broker generated client ids. Removed libuuid
  dependency.
- auto_id_prefix now defaults to 'auto-'.
- QoS 1 and 2 flow control improvements.
Client library features:
- Add support for MQTT v5
- Add mosquitto_subscribe_multiple() for sending subscriptions to multiple
  topics in one command.
- Add TLS Engine support.
- Add explicit support for TLS v1.3.
- Drop support for TLS v1.0.
- QoS 1 and 2 flow control improvements.
Client features:
- Add support for MQTT v5
- Add mosquitto_rr client, which can be used for "request-response" messaging,
  by sending a request message and awaiting a response.
- Add TLS Engine support.
- Add support for ALPN on TLS connections. Closes #924.
- Add -D option for all clients to specify MQTT v5 properties.
- Add -E to mosquitto_sub, which causes it to exit immediately after having
  its subscriptions acknowledged. Use with -c to create a durable client
  session without requiring a message to be received.
- Add --remove-retained to mosquitto_sub, which can be used to clear retained
  messages on a broker.
- Add --repeat and --repeat-delay to mosquitto_pub, which can be used to
  repeat single message publishes at a regular interval.
- -V now accepts `5, `311`, `31`, as well as `mqttv5` etc.
- Add explicit support for TLS v1.3.
- Drop support for TLS v1.0.
Broker fixes:
- Improve error reporting when creating listeners.
- Fix build on SmartOS due to missing IPV6_V6ONLY. Closes #1212.
Client library fixes
- Add missing `mosquitto_userdata()` function.
Client fixes:
- mosquitto_pub wouldn't always publish all messages when using `-l` and
  QoS>0. This has been fixed.
- mosquitto_sub was incorrectly encoding special characters when using %j
  output format. Closes #1220.
1.5.8 - 20190228
================
Broker:
- Fix clients being disconnected when ACLs are in use. This only affects the
  case where a client connects using a username, and the anonymous ACL list is
  defined but specific user ACLs are not defined. Closes #1162.
- Make error messages for missing config file clearer.
- Fix some Coverity Scan reported errors that could occur when the broker was
  already failing to start.
- Fix broken mosquitto_passwd on FreeBSD. Closes #1032.
- Fix delayed bridge local subscriptions causing missing messages.
  Closes #1174.
Library:
- Use higher resolution timer for random initialisation of client id
  generation. Closes #1177.
- Fix some Coverity Scan reported errors that could occur when the library was
  already quitting.
1.5.7 - 20190213
================
Broker:
- Fix build failure when using WITH_ADNS=yes
- Ensure that an error occurs if `per_listener_settings true` is given after
  other security options. Closes #1149.
- Fix include_dir not sorting config files before loading. This was partially
  fixed in 1.5 previously.
- Improve documentation around the `include_dir` option. Closes #1154.
- Fix case where old unreferenced msg_store messages were being saved to the
  persistence file, bloating its size unnecessarily. Closes #389.
Library:
- Fix `mosquitto_topic_matches_sub()` not returning MOSQ_ERR_INVAL for
  invalid subscriptions like `topic/#abc`. This only affects the return value,
  not the match/no match result, which was already correct.
Build:
- Don't require C99 compiler.
- Add rewritten build test script and remove some build warnings.
1.5.6 - 20190206
================
Security:
- CVE-2018-12551: If Mosquitto is configured to use a password file for
  authentication, any malformed data in the password file will be treated as
  valid. This typically means that the malformed data becomes a username and no
  password. If this occurs, clients can circumvent authentication and get access
  to the broker by using the malformed username. In particular, a blank line
  will be treated as a valid empty username. Other security measures are
  unaffected. Users who have only used the mosquitto_passwd utility to create
  and modify their password files are unaffected by this vulnerability.
  Affects version 1.0 to 1.5.5 inclusive.
- CVE-2018-12550: If an ACL file is empty, or has only blank lines or
  comments, then mosquitto treats the ACL file as not being defined, which
  means that no topic access is denied. Although denying access to all topics
  is not a useful configuration, this behaviour is unexpected and could lead
  to access being incorrectly granted in some circumstances. This is now
  fixed. Affects versions 1.0 to 1.5.5 inclusive.
- CVE-2018-12546. If a client publishes a retained message to a topic that
  they have access to, and then their access to that topic is revoked, the
  retained message will still be delivered to future subscribers. This
  behaviour may be undesirable in some applications, so a configuration option
  `check_retain_source` has been introduced to enforce checking of the
  retained message source on publish.
Broker:
- Fixed comment handling for config options that have optional arguments.
- Improved documentation around bridge topic remapping.
- Handle mismatched handshakes (e.g. QoS1 PUBLISH with QoS2 reply) properly.
- Fix spaces not being allowed in the bridge remote_username option. Closes
  #1131.
- Allow broker to always restart on Windows when using `log_dest file`. Closes
  #1080.
- Fix Will not being sent for Websockets clients. Closes #1143.
- Windows: Fix possible crash when client disconnects. Closes #1137.
- Fixed durable clients being unable to receive messages when offline, when
  per_listener_settings was set to true. Closes #1081.
- Add log message for the case where a client is disconnected for sending a
  topic with invalid UTF-8. Closes #1144.
Library:
- Fix TLS connections not working over SOCKS.
- Don't clear SSL context when TLS connection is closed, meaning if a user
  provided an external SSL_CTX they have less chance of leaking references.
Build:
- Fix comparison of boolean values in CMake build. Closes #1101.
- Fix compilation when openssl deprecated APIs are not available.
  Closes #1094.
- Man pages can now be built on any system. Closes #1139.
1.5.5 - 20181211
================
Security:
- If `per_listener_settings` is set to true, then the `acl_file` setting was
  ignored for the "default listener" only. This has been fixed. This does not
  affect any listeners defined with the `listener` option. Closes #1073.
  This is now tracked as CVE-2018-20145.
Broker:
- Add `socket_domain` option to allow listeners to disable IPv6 support.
  This is required to work around a problem in libwebsockets that means
  sockets only listen on IPv6 by default if IPv6 support is compiled in.
  Closes #1004.
- When using ADNS, don't ask for all network protocols when connecting,
  because this can lead to confusing "Protocol not supported" errors if the
  network is down. Closes #1062.
- Fix outgoing retained messages not being sent by bridges on initial
  connection. Closes #1040.
- Don't reload auth_opt_ options on reload, to match the behaviour of the
  other plugin options. Closes #1068.
- Print message on error when installing/uninstalling as a Windows service.
- All non-error connect/disconnect messages are controlled by the
  `connection_messages` option. Closes #772. Closes #613. Closes #537.
Library:
- Fix reconnect delay backoff behaviour. Closes #1027.
- Don't call on_disconnect() twice if keepalive tests fail. Closes #1067.
Client:
- Always print leading zeros in mosquitto_sub when output format is hex.
  Closes #1066.
Build:
- Fix building where TLS-PSK is not available. Closes #68.
1.5.4 - 20181108
================
Security:
- When using a TLS enabled websockets listener with "require_certificate"
  enabled, the mosquitto broker does not correctly verify client certificates.
  This is now fixed. All other security measures operate as expected, and in
  particular non-websockets listeners are not affected by this. Closes #996.
Broker:
- Process all pending messages even when a client has disconnected. This means
  a client that send a PUBLISH then DISCONNECT quickly, then disconnects will
  have its DISCONNECT message processed properly and so no Will will be sent.
  Closes #7.
- $SYS/broker/clients/disconnected should never be negative. Closes #287.
- Give better error message if a client sends a password without a username.
  Closes #1015.
- Fix bridge not honoring restart_timeout. Closes #1019.
- Don't disconnect a client if an auth plugin denies access to SUBSCRIBE.
  Closes #1016.
Library:
- Fix memory leak that occurred if mosquitto_reconnect() was used when TLS
  errors were present. Closes #592.
- Fix TLS connections when using an external event loop with
  mosquitto_loop_read() and mosquitto_write(). Closes #990.
Build:
- Fix clients not being compiled with threading support when using CMake.
  Closes #983.
- Header fixes for FreeBSD. Closes #977.
- Use _GNU_SOURCE to fix build errors in websockets and getaddrinfo usage.
  Closes #862 and #933.
- Fix builds on QNX 7.0.0. Closes #1018.
1.5.3 - 20180925
================
Security:
- Fix CVE-2018-12543. If a message is sent to Mosquitto with a topic that
  begins with $, but is not $SYS, then an assert that should be unreachable is
  triggered and Mosquitto will exit.
Broker:
- Elevate log level to warning for situation when socket limit is hit.
- Remove requirement to use `user root` in snap package config files.
- Fix retained messages not sent by bridges on outgoing topics at the first
  connection. Closes #701.
- Documentation fixes. Closes #520, #600.
- Fix duplicate clients being added to by_id hash before the old client was
  removed. Closes #645.
- Fix Windows version not starting if include_dir did not contain any files.
  Closes #566.
- When an authentication plugin denied access to a SUBSCRIBE, the client would
  be disconnected incorrectly. This has been fixed. Closes #1016.
Build:
- Various fixes to ease building.
1.5.2 - 20180919
================
Broker:
- Fix build when using WITH_ADNS=yes.
- Fix incorrect call to setsockopt() for TCP_NODELAY. Closes #941.
- Fix excessive CPU usage when the number of sockets exceeds the system limit.
  Closes #948.
- Fix for bridge connections when using WITH_ADNS=yes.
- Fix round_robin false behaviour. Closes #481.
- Fix segfault on HUP when bridges and security options are configured.
  Closes #965.
Library:
- Fix situation where username and password is used with SOCKS5 proxy. Closes
  #927.
- Fix SOCKS5 behaviour when passing IP addresses. Closes #927.
Build:
- Make it easier to build without bundled uthash.h using "WITH_BUNDLED_DEPS=no".
- Fix build with OPENSSL_NO_ENGINE. Closes #932.
1.5.1 - 20180816
================
Broker:
- Fix plugin cleanup function not being called on exit of the broker.
  Closes #900.
- Print more OpenSSL errors when loading certificates/keys fail.
- Use AF_UNSPEC etc. instead of PF_UNSPEC to comply with POSIX. Closes #863.
- Remove use of AI_ADDRCONFIG, which means the broker can be used on systems
  where only the loopback interface is defined. Closes #869, Closes #901.
- Fix IPv6 addresses not being able to be used as bridge addresses.
  Closes #886.
- All clients now time out if they exceed their keepalive*1.5, rather than
  just reach it. This was inconsistent in two places.
- Fix segfault on startup if bridge CA certificates could not be read.
  Closes #851.
- Fix problem opening listeners on Pi caused by unsigned char being default.
  Found via #849.
- ACL patterns that do not contain either %c or %u now produce a warning in
  the log. Closes #209.
- Fix bridge publishing failing when per_listener_settings was true. Closes
  #860.
- Fix `use_identity_as_username true` not working. Closes #833.
- Fix UNSUBACK messages not being logged. Closes #903.
- Fix possible endian issue when reading the `memory_limit` option.
- Fix building for libwebsockets < 1.6.
- Fix accessor functions for username and client id when used in plugin auth
  check.
Library:
- Fix some places where return codes were incorrect, including to the
  on_disconnect() callback. This has resulted in two new error codes,
  MOSQ_ERR_KEEPALIVE and MOSQ_ERR_LOOKUP.
- Fix connection problems when mosquitto_loop_start() was called before
  mosquitto_connect_async(). Closes #848.
Clients:
- When compiled using WITH_TLS=no, the default port was incorrectly being set
  to -1. This has been fixed.
- Fix compiling on Mac OS X <10.12. Closes #813 and #240.
Build:
- Fixes for building on NetBSD. Closes #258.
- Fixes for building on FreeBSD.
- Add support for compiling with static libwebsockets library.
1.5 - 20180502
==============
Security:
- Fix memory leak that could be caused by a malicious CONNECT packet. This
  does not yet have a CVE assigned. Closes #533493 (on Eclipse bugtracker)
Broker features:
- Add per_listener_settings to allow authentication and access control to be
  per listener.
- Add limited support for reloading listener settings. This allows settings
  for an already defined listener to be reloaded, but port numbers must not be
  changed.
- Add ability to deny access to SUBSCRIBE messages as well as the current
  read/write accesses. Currently for auth plugins only.
- Reduce calls to malloc through the use of UHPA.
- Outgoing messages with QoS>1 are no longer retried after a timeout period.
  Messages will be retried when a client reconnects.  This change in behaviour
  can be justified by considering when the timeout may have occurred.
  * If a connection is unreliable and has dropped, but without one end
    noticing, the messages will be retried on reconnection. Sending
    additional PUBLISH or PUBREL would not have changed anything.
  * If a client is overloaded/unable to respond/has a slow connection then
    sending additional PUBLISH or PUBREL would not help the client catch
    up. Once the backlog has cleared the client will respond. If it is not
    able to catch up, sending additional duplicates would not help either.
- Add use_subject_as_username option for certificate based client
  authentication to use the entire certificate subject as a username, rather
  than just the CN. Closes #469467.
- Change sys tree printing output. This format shouldn't be relied upon and
  may change at any time. Closes #470246.
- Minimum supported libwebsockets version is now 1.3.
- Add systemd startup notification and services. Closes #471053.
- Reduce unnecessary malloc and memcpy when receiving a message and storing
  it. Closes #470258.
- Support for Windows XP has been dropped.
- Bridge connections now default to using MQTT v3.1.1.
- mosquitto_db_dump tool can now output some stats on clients.
- Perform utf-8 validation on incoming will, subscription and unsubscription
  topics.
- new $SYS/broker/store/messages/count (deprecates $SYS/broker/messages/stored)
- new $SYS/broker/store/messages/bytes
- max_queued_bytes feature to limit queues by real size rather than
  than just message count. Closes Eclipse #452919 or Github #100
- Add support for bridges to be configured to only send notifications to the
  local broker.
- Add set_tcp_nodelay option to allow Nagle's algorithm to be disabled on
  client sockets. Closes #433.
- The behaviour of allow_anonymous has changed. In the old behaviour, the
  default if not set was to allow anonymous access. The new behaviour is to
  default is to allow anonymous access unless another security option is set.
  For example, if password_file is set and allow_anonymous is not set, then
  anonymous access will be denied. It is still possible to allow anonymous
  access by setting it explicitly.
Broker fixes:
- Fix UNSUBSCRIBE with no topic is accepted on MQTT 3.1.1. Closes #665.
- Produce an error if two bridges share the same local_clientid.
- Miscellaneous fixes on Windows.
- queue_qos0_messages was not observing max_queued_** limits
- When using the include_dir configuration option sort the files
  alphabetically before loading them.  Closes #17.
- IPv6 is no longer disabled for websockets listeners.
- Remove all build timestamp information including $SYS/broker/timestamp.
  Close #651.
- Correctly handle incoming strings that contain a NULL byte. Closes #693.
- Use constant time memcmp for password comparisons.
- Fix incorrect PSK key being used if it had leading zeroes.
- Fix memory leak if a client provided a username/password for a listener with
  use_identity_as_username configured.
- Fix use_identity_as_username not working on websockets clients.
- Don't crash if an auth plugin returns MOSQ_ERR_AUTH for a username check on
  a websockets client. Closes #490.
- Fix 08-ssl-bridge.py test when using async dns lookups. Closes #507.
- Lines in the config file are no longer limited to 1024 characters long.
  Closes #652.
- Fix $SYS counters of messages and bytes sent when message is sent over
  a Websockets. Closes #250.
- Fix upgrade_outgoing_qos for retained message. Closes #534.
- Fix CONNACK message not being sent for unauthorised connect on websockets.
  Closes #8.
- Maximum connections on Windows increased to 2048.
- When a client with an in-use client-id connects, if the old client has a
  will, send the will message. Closes #26.
- Fix parsing of configuration options that end with a space. Closes #804.
Client library features:
- Outgoing messages with QoS>1 are no longer retried after a timeout period.
  Messages will be retried when a client reconnects.
- DNS-SRV support is now disabled by default.
- Add mosquitto_subscribe_simple() This is a helper function to make
  retrieving messages from a broker very straightforward. Examples of its use
  are in examples/subscribe_simple.
- Add mosquitto_subscribe_callback() This is a helper function to make
  processing messages from a broker very straightforward. An example of its use
  is in examples/subscribe_simple.
- Connections now default to using MQTT v3.1.1.
- Add mosquitto_validate_utf8() to check whether a string is valid UTF-8
  according to the UTF-8 spec and to the additional restrictions imposed by
  the MQTT spec.
- Topic inputs are checked for UTF-8 validity.
- Add mosquitto_userdata function to allow retrieving the client userdata
  member variable. Closes #111.
- Add mosquitto_pub_topic_check2(), mosquitto_sub_topic_check2(), and
  mosquitto_topic_matches_sub2() which are identical to the similarly named
  functions but also take length arguments.
- Add mosquitto_connect_with_flags_callback_set(), which allows a second
  connect callback to be used which also exposes the connect flags parameter.
  Closes #738 and #128.
- Add MOSQ_OPT_SSL_CTX option to allow a user specified SSL_CTX to be used
  instead of the one generated by libmosquitto. This allows greater control
  over what options can be set. Closes #715.
- Add MOSQ_OPT_SSL_CTX_WITH_DEFAULTS to work with MOSQ_OPT_SSL_CTX and have
  the default libmosquitto SSL_CTX configuration applied to the user provided
  SSL_CTX. Closes #567.
Client library fixes:
- Fix incorrect PSK key being used if it had leading zeroes.
- Initialise "result" variable as soon as possible in
  mosquitto_topic_matches_sub. Closes #654.
- No need to close socket again if setting non-blocking failed. Closes #649.
- Fix mosquitto_topic_matches_sub() not correctly matching foo/bar against
  foo/+/#. Closes #670.
- SNI host support added.
Client features:
- Add -F to mosquitto_sub to allow the user to choose the output format.
- Add -U to mosquitto_sub for unsubscribing from topics.
- Add -c (clean session) to mosquitto_pub.
- Add --retained-only to mosquitto_sub to exit after receiving all retained
  messages.
- Add -W to allow mosquitto_sub to stop processing incoming messages after a
  timeout.
- Connections now default to using MQTT v3.1.1.
- Default to using port 8883 when using TLS.
- mosquitto_sub doesn't continue to keep connecting if CONNACK tells it the
  connection was refused.
Client fixes:
- Correctly handle empty files with "mosquitto_pub -l". Closes #676.
Build:
- Add WITH_STRIP option (defaulting to "no") that when set to "yes" will strip
  executables and shared libraries when installing.
- Add WITH_STATIC_LIBRARIES (defaulting to "no") that when set to "yes" will
  build and install static versions of the client libraries.
- Don't run TLS-PSK tests if TLS-PSK disabled at compile time. Closes #636.
- Support for openssl versions 1.0.0 and 1.0.1 has been removed as these are
  no longer supported by openssl.
Documentation:
- Replace mentions of deprecated 'c_rehash' with 'openssl rehash'.
1.4.15 - 20180228
=================
Security:
- Fix CVE-2017-7652. If a SIGHUP is sent to the broker when there are no more
  file descriptors, then opening the configuration file will fail and security
  settings will be set back to their default values.
- Fix CVE-2017-7651. Unauthenticated clients can cause excessive memory use by
  setting "remaining length" to be a large value. This is now mitigated by
  limiting the size of remaining length to valid values. A "memory_limit"
  configuration option has also been added to allow the overall memory used by
  the broker to be limited.
Broker:
- Use constant time memcmp for password comparisons.
- Fix incorrect PSK key being used if it had leading zeroes.
- Fix memory leak if a client provided a username/password for a listener with
  use_identity_as_username configured.
- Fix use_identity_as_username not working on websockets clients.
- Don't crash if an auth plugin returns MOSQ_ERR_AUTH for a username check on
  a websockets client. Closes #490.
- Fix 08-ssl-bridge.py test when using async dns lookups. Closes #507.
- Lines in the config file are no longer limited to 1024 characters long.
  Closes #652.
- Fix $SYS counters of messages and bytes sent when message is sent over
  a Websockets. Closes #250.
- Fix upgrade_outgoing_qos for retained message. Closes #534.
- Fix CONNACK message not being sent for unauthorised connect on websockets.
  Closes #8.
Client library:
- Fix incorrect PSK key being used if it had leading zeroes.
- Initialise "result" variable as soon as possible in
  mosquitto_topic_matches_sub. Closes #654.
- No need to close socket again if setting non-blocking failed. Closes #649.
- Fix mosquitto_topic_matches_sub() not correctly matching foo/bar against
  foo/+/#. Closes #670.
Clients:
- Correctly handle empty files with "mosquitto_pub -l". Closes #676.
Build:
- Don't run TLS-PSK tests if TLS-PSK disabled at compile time. Closes #636.
1.4.14 - 20170710
=================
Broker:
- Fix regression from 1.4.13 where persistence data was not being saved.
1.4.13 - 20170627
=================
Security:
- Fix CVE-2017-9868. The persistence file was readable by all local users,
  potentially allowing sensitive information to be leaked.
  This can also be fixed administratively, by restricting access to the
  directory in which the persistence file is stored.
Broker:
- Fix for poor websockets performance.
- Fix lazy bridges not timing out for idle_timeout. Closes #417.
- Fix problems with large retained messages over websockets. Closes #427.
- Set persistence file to only be readable by owner, except on Windows. Closes
  #468.
- Fix CONNECT check for reserved=0, as per MQTT v3.1.1 check MQTT-3.1.2-3.
- When the broker stop, wills for any connected clients are now "sent". Closes
  #477.
- Auth plugins can be configured to disable the check for +# in
  usernames/client ids with the auth_plugin_deny_special_chars option.
  Partially closes #462.
- Restrictions for CVE-2017-7650 have been relaxed - '/' is allowed in
  usernames/client ids. Remainder of fix for #462.
Clients:
- Don't use / in auto-generated client ids.
1.4.12 - 20170528
=================
Security:
- Fix CVE-2017-7650, which allows clients with username or client id set to
  '#' or '+' to bypass pattern based ACLs or third party plugins. The fix
  denies message sending or receiving of messages for clients with a '#' or
  '+' in their username or client id and if the message is subject to a
  pattern ACL check or plugin check.
  Patches for other versions are available at
  https://mosquitto.org/files/cve/2017-7650/
Broker:
- Fix mosquitto.db from becoming corrupted due to client messages being
  persisted with no stored message. Closes #424.
- Fix bridge not restarting properly. Closes #428.
- Fix unitialized memory in gets_quiet on Windows. Closes #426.
- Fix building with WITH_ADNS=no for systems that don't use glibc. Closes
  #415.
- Fixes to readme.md.
- Fix deprecation warning for OpenSSL 1.1. PR #416.
- Don't segfault on duplicate bridge names. Closes #446.
- Fix CVE-2017-7650.
1.4.11 - 20170220
=================
Broker:
- Fix crash when "lazy" type bridge attempts to reconnect. Closes #259.
- maximum_connections now applies to websockets listeners. Closes #271.
- Allow bridges to use TLS with IPv6.
- Don't error on zero length persistence files. Closes #316.
- For http only websockets clients, close files served over http in all cases
  when the client disconnects. Closes #354.
- Fix error message when websockets http_dir directory does not exist.
- Improve password utility error message. Closes #379.
Clients:
- Use of --ciphers no longer requires you to also pass --tls-version.
  Closes #380.
Client library:
- Clients can now use TLS with IPv6.
- Fix potential socket leakage when reconnecting. Closes #304.
- Fix potential negative timeout being passed to pselect. Closes #329.
1.4.10 - 20160816
=================
Broker:
- Fix TLS operation with websockets listeners and libwebsockts 2.x. Closes
  #186.
- Don't disconnect client on HUP before reading the pending data. Closes #7.
- Fix some $SYS messages being incorrectly persisted. Closes #191.
- Support OpenSSL 1.1.0.
- Call fsync after persisting data to ensure it is correctly written. Closes
  #189.
- Fix persistence saving of subscription QoS on big-endian machines.
- Fix will retained flag handling on Windows. Closes #222.
- Broker now displays an error if it is unable to open the log file. Closes
  #234.
Client library:
- Support OpenSSL 1.1.0.
- Fixed the C++ library not allowing SOCKS support to be used. Closes #198.
- Fix memory leak when verifying a server certificate with a subjectAltName
  section. Closes #237.
Build:
- Don't attempt to install docs when WITH_DOCS=no. Closes #184.
1.4.9 - 20160603
================
Broker:
- Ensure websockets clients that previously connected with clean session set
  to false have their queued messages delivered immediately on reconnecting.
  Closes #476314.
- Reconnecting client with clean session set to false doesn't start with mid=1
  again.
- Will topic isn't truncated by one byte when using a mount_point any more.
- Network errors are printed correctly on Windows.
- Fix incorrect $SYS heap memory reporting when using ACLs.
- Bridge config parameters couldn't contain a space, this has been fixed.
  Closes #150.
- Fix saving of persistence messages that start with a '/'. Closes #151.
- Fix reconnecting for bridges that use TLS on Windows. Closes #154.
- Broker and bridges can now cope with unknown incoming PUBACK, PUBREC,
  PUBREL, PUBCOMP without disconnecting. Closes #57.
- Fix websockets listeners not being able to bind to an IP address. Closes
  #170.
- mosquitto_passwd utility now correctly deals with unknown command line
  arguments in all cases. Closes #169.
- Fix publishing of $SYS/broker/clients/maximum
- Fix order of #includes in lib/send_mosq.c to ensure struct mosquitto doesn't
  differ between source files when websockets is being used. Closes #180.
- Fix possible rare crash when writing out persistence file and a client has
  incomplete messages inflight that it has been denied the right to publish.
Client library:
- Fix the case where a message received just before the keepalive timer
  expired would cause the client to miss the keepalive timer.
- Return value of pthread_create is now checked.
- _mosquitto_destroy should not cancel threads that weren't created by
  libmosquitto. Closes #166.
- Clients can now cope with unknown incoming PUBACK, PUBREC, PUBREL, PUBCOMP
  without disconnecting. Closes #57.
- Fix mosquitto_topic_matches_sub() reporting matches on some invalid
   subscriptions.
Clients:
- Handle some unchecked malloc() calls. Closes #1.
Build:
- Fix string quoting in CMakeLists.txt. Closes #4.
- Fix building on Visual Studio 2015. Closes #136.
1.4.8 - 20160214
================
Broker:
- Wills published by clients connected to a listener with mount_point defined
  now correctly obey the mount point. This was a potential security risk
  because it allowed clients to publish messages outside of their restricted
  mount point. This is only affects brokers where the mount_point option is in
  use. Closes #487178.
- Fix detection of broken connections on Windows. Closes #485143.
- Close stdin etc. when daemonised. Closes #485589.
- Fix incorrect detection of FreeBSD and OpenBSD. Closes #485131.
Client library:
- mosq->want_write should be cleared immediately before a call to SSL_write,
  to allow clients using mosquitto_want_write() to get accurate results.
1.4.7 - 20151221
================
Broker:
- Fix support for libwebsockets 1.22.
1.4.6 - 20151220
================
Broker:
- Add support for libwebsockets 1.6.
Client library:
- Fix _mosquitto_socketpair() on Windows, reducing the chance of delays when
  publishing. Closes #483979.
Clients:
- Fix "mosquitto_pub -l" stripping the final character on a line. Closes
  #483981.
1.4.5 - 20151108
================
Broker:
- Fix possible memory leak if bridge using SSL attempts to connect to a
  host that is not up.
- Free unused topic tree elements (fix in 1.4.3 was incomplete). Closes
  #468987.
Clients:
- "mosquitto_pub -l" now no longer limited to 1024 byte lines. Closes #478917.
1.4.4 - 20150916
================
Broker:
- Don't leak sockets when outgoing bridge with multiple addresses cannot
  connect. Closes #477571.
- Fix cross compiling of websockets. Closes #475807.
- Fix memory free related crashes on openwrt. Closes #475707.
- Fix excessive calls to message retry check.
1.4.3 - 20150818
================
Broker:
- Fix incorrect bridge notification on initial connection. Closes #467096.
- Build fixes for OpenBSD.
- Fix incorrect behaviour for autosave_interval, most noticable for
  autosave_interval=1. Closes #465438.
- Fix handling of outgoing QoS>0 messages for bridges that could not be sent
  because the bridge connection was down.
- Free unused topic tree elements. Closes #468987.
- Fix some potential memory leaks. Closes #470253.
- Fix potential crash on libwebsockets error.
Client library:
- Add missing error strings to mosquitto_strerror.
- Handle fragmented TLS packets without a delay. Closes #470660.
- Fix incorrect loop timeout being chosen when using threaded interface and
  keepalive = 0. Closes #471334.
- Increment inflight messages count correctly. Closes #474935.
Clients:
- Report error string on connection failure rather than error code.
1.4.2 - 20150507
================
Broker:
- Fix bridge prefixes only working for the first outgoing message. Closes
  #464437.
- Fix incorrect bridge connection notifications on local broker.
- Fix persistent db writing on Windows. Closes #464779.
- ACLs are now checked before sending a will message.
- Fix possible crash when using bridges on Windows. Closes #465384.
- Fix parsing of auth_opt_ arguments with extra spaces/tabs.
- Broker will return CONNACK rc=5 when a username/password is not authorised.
  This was being incorrectly set as rc=4.
- Fix handling of payload lengths>4096 with websockets.
Client library:
- Inflight message count wasn't being decreased for outgoing messages using
  QoS 2, meaning that only up to 20 QoS 2 messages could be sent. This has
  been fixed. Closes #464436.
- Fix CMake dependencies for C++ wrapper building. Closes #463884.
- Fix possibility of select() being called with a socket that is >FD_SETSIZE.
  This is a fix for #464632 that will be followed up by removing the select()
  call in a future version.
- Fix calls to mosquitto_connect*_async() not completing.
1.4.1 - 20150403
================
Broker:
- Fix possible crash under heavy network load. Closes #463241.
- Fix possible crash when using pattern ACLs.
- Fix problems parsing config strings with multiple leading spaces. Closes
  #462154.
- Websockets clients are now periodically disconnected if they have not
  maintained their keepalive timer. Closes #461619.
- Fix possible minor memory leak on acl parsing.
Client library:
- Inflight limits should only apply to outgoing messages. Closes #461620.
- Fix reconnect bug on Windows. Closes #463000.
- Return -1 on error from mosquitto_socket(). Closes #461705.
- Fix crash on multiple calls to mosquitto_lib_init/mosquitto_lib_cleanup.
  Closes #462780.
- Allow longer paths on Windows. Closes #462781.
- Make _mosquitto_mid_generate() thread safe. Closes #463479.
1.4 - 20150218
==============
Important changes:
- Websockets support in the broker.
- Bridge behaviour on the local broker has changed due to the introduction of
  the local_* options. This may affect you if you are using authentication
  and/or ACLs with bridges.
- The default TLS behaviour has changed to accept all of TLS v1.2, v1.1 and
  v1.0, rather than only only one version of the protocol. It is still
  possible to restrict a listener to a single version of TLS.
- The Python client has been removed now that the Eclipse Paho Python client
  has had a release.
- When a durable client reconnects, its queued messages are now checked
  against ACLs in case of a change in username/ACL state since it last
  connected.
- New use_username_as_clientid option on the broker, for preventing hijacking
  of a client id.
- The client library and clients now have experimental SOCKS5 support.
- Wildcard TLS certificates are now supported for bridges and clients.
- The clients have support for config files with default options.
- Client and client libraries have support for MQTT v3.1.1.
- Bridge support for MQTT v3.1.1.
Broker:
- Websockets support in the broker.
- Add local_clientid, local_username, local_password for bridge connections to
  authenticate to the local broker.
- Default TLS mode now accepts TLS v1.2, v1.1 and v1.0.
- Support for ECDHE-ECDSA family ciphers.
- Fix bug #1324411, which could have had unexpected consequences for delayed
  messages in rare circumstances.
- Add support for "session present" in CONNACK messages for MQTT v3.1.1.
- Remove strict protocol #ifdefs.
- Change $SYS/broker/clients/active -> $SYS/broker/clients/connected
- Change $SYS/broker/clients/inactive -> $SYS/broker/clients/disconnected
- When a durable client reconnects, its queued messages are now checked
  against ACLs in case of a change in username/ACL state since it last
  connected.
- libuuid is used to generate client ids, where it is available, when an MQTT
  v3.1.1 client connects with a zero length client id.
- Anonymous clients are no longer accidently disconnected from the broker
  after a SIGHUP.
- mosquitto_passwd now supports -b (batch mode) to allow the password to be
  provided at the command line.
- Removed $SYS/broker/changeset. This was intended for use with debugging, but
  in practice is of no use.
- Add support for use_username_as_clientid which can be used with
  authentication to restrict ownership of client ids and hence prevent one
  client disconnecting another by using the same client id.
- When "require_certificate" was false, the broker was incorrectly asking for
  a certificate (but not checking it). This caused problems with some clients
  and has been fixed so the broker no longer asks.
- When using syslog logging on non-Windows OSs, it is now possible to specify
  the logging facility to one of local0-7 instead of the default "daemon".
- The bridge_attempt_unsubscribe option has been added, to allow the sending
  of UNSUBSCRIBE requests to be disabled for topics with "out" direction.
  Closes bug #456899.
- Wildcard TLS certificates are now supported for bridges.
- Support for "hour" client expiration lengths for the
  persistent_client_expiration option. Closes bug #425835.
- Bridge support for MQTT v3.1.1.
- Root privileges are now dropped after starting listeners and loading
  certificates/private keys, to allow private keys to have their permissions
  restricted to the root user only. Closes bug #452914.
- Usernames and topics given in ACL files can now include a space. Closes bug
  #431780.
- Fix hang if pattern acl contains a %u but an anonymous client connect.
  Closes bug #455402.
- Fix man page installation with cmake. Closes bug #458843.
- When using "log_dest file" the output file is now flushed periodically.
Clients:
- Both clients can now load default configuration options from a file.
- Add -C option to mosquitto_sub to allow the client to quit after receiving a
  certain count of messages. Closes bug #453850.
- Add --proxy SOCKS5 support for both clients.
- Pub client supports setting its keepalive. Closes bug #454852.
- Add support for config files with default options.
- Add support for MQTT v3.1.1.
Client library:
- Add experimental SOCKS5 support.
- mosquitto_loop_forever now quits after a fatal error, rather than blindly
  retrying.
- SRV support is now not compiled in by default.
- Wildcard TLS certificates are now supported.
- mosquittopp now has a virtual destructor. Closes bug #452915.
- Add support for MQTT v3.1.1.
- Don't quit mosquitto_loop_forever() if broker not available on first
  connect. Closes bug #453293, but requires more work.
1.3.5 - 20141008
================
Broker:
- Fix possible memory leak when using a topic that has a leading slash. Fixes
  bug #1360985.
- Fix saving persistent database on Windows.
- Temporarily disable ACL checks on subscriptions when using MQTT v3.1.1. This
  is due to the complexity of checking wildcard ACLs against wildcard
  subscriptions. This does not have a negative impact on security because
  checks are still made before a message is sent to a client.
  Fixes bug #1374291.
- When using -v and the broker receives a SIGHUP, verbose logging was being
  disabled. This has been fixed.
Client library:
- Fix mutex being incorrectly passed by value. Fixes bug #1373785.
1.3.4 - 20140806
================
Broker:
- Don't ask client for certificate when require_certificate is false.
- Backout incomplete functionality that was incorrectly included in 1.3.2.
1.3.3 - 20140801
================
Broker:
- Fix incorrect handling of anonymous bridges on the local broker.
1.3.2 - 20140713
================
Broker:
- Don't allow access to clients when authenticating if a security plugin
  returns an application error. Fixes bug #1340782.
- Ensure that bridges verify certificates by default when using TLS.
- Fix possible crash when using pattern ACLs that do not include a %u and
  clients that connect without a username.
- Fix subscriptions being deleted when clients subscribed to a topic beginning
  with a $ but that is not $SYS.
- When a durable client reconnects, its queued messages are now checked
  against ACLs in case of a change in username/ACL state since it last
  connected.
- Fix bug #1324411, which could have had unexpected consequences for delayed
  messages in rare circumstances.
- Anonymous clients are no longer accidently disconnected from the broker
  after a SIGHUP.
Client library:
- Fix topic matching edge case.
- Fix callback deadlocks after calling mosquitto_disconnect(), when using the
  threaded interfaces. Closes bug #1313725.
- Fix SRV support when building with CMake.
- Remove strict protocol #ifdefs.
General:
- Use $(STRIP) for stripping binaries when installing, to allow easier cross
  compilation.
1.3.1 - 20140324
================
Broker:
- Prevent possible crash on client reconnect. Closes bug #1294108.
- Don't accept zero length unsubscription strings (MQTT v3.1.1 fix)
- Don't accept QoS 3 (MQTT v3.1.1 fix)
- Don't disconnect clients immediately on HUP to give chance for all data to
  be read.
- Reject invalid un/subscriptions e.g. foo/+bar #/bar.
- Take more care not to disconnect clients that are sending large messages.
Client library:
- Fix socketpair code on the Mac.
- Fix compilation for WITH_THREADING=no.
- Break out of select() when calling mosquitto_loop_stop().
- Reject invalid un/subscriptions e.g. foo/+bar #/bar.
- Add mosquitto_threaded_set().
Clients:
- Fix keepalive value on mosquitto_pub.
- Fix possibility of mosquitto_pub not exiting after sending messages when
  using -l.
1.3 - 20140316
==============
Broker:
- The broker no longer ignores the auth_plugin_init() return value.
- Accept SSLv2/SSLv3 HELLOs when using TLSv1, whilst keeping SSLv2 and SSLv3
  disabled. This increases client compatibility without sacrificing security.
- The $SYS tree can now be disabled at runtime as well as at compile time.
- When remapping bridged topics, only check for matches when the message
  direction is correct. This allows two identical topics to be remapped
  differently for both in and out.
- Change "$SYS/broker/heap/current size" to "$SYS/broker/heap/current" for
  easier parsing.
- Change "$SYS/broker/heap/maximum size" to "$SYS/broker/heap/maximum" for
  easier parsing.
- Topics are no longer normalised from e.g a///topic to a/topic. This matches
  the behaviour as clarified by the Oasis MQTT spec. This will lead to
  unexpected behaviour if you were using topics of this form.
- Log when outgoing messages for a client begin to drop off the end of the
  queue.
- Bridge clients are recognised as bridges even after reloading from
  persistence.
- Basic support for MQTT v3.1.1. This does not include being able to bridge to
  an MQTT v3.1.1 broker.
- Username is displayed in log if present when a client connects.
- Support for 0 length client ids (v3.1.1 only) that result in automatically
  generated client ids on the broker (see option allow_zero_length_clientid).
- Ability to set the prefix of automatically generated client ids (see option
  auto_id_prefix).
- Add support for TLS session resumption.
- When using TLS, the server now chooses the cipher to use when negotiating
  with the client.
- Weak TLS ciphers are now disabled by default.
Client library:
- Fix support for Python 2.6, 3.0, 3.1.
- Add support for un/subscribing to multiple topics at once in un/subscribe().
- Clients now close their socket after sending DISCONNECT.
- Python client now contains its version number.
- C library mosquitto_want_write() now supports TLS clients.
- Fix possible memory leak in C/C++ library when communicating with
  a broker that doesn't follow the spec.
- Return strerror() through mosquitto_strerror() to make error printing
  easier.
- Topics are no longer normalised from e.g a///topic to a/topic. This matches
  the behaviour as clarified by the Oasis MQTT spec. This will lead to
  unexpected behaviour if you were using topics of this form.
- Add support for SRV lookups.
- Break out of select() on publish(), subscribe() etc. when using the threaded
  interface. Fixes bug #1270062.
- Handle incoming and outgoing messages separately. Fixes bug #1263172.
- Don't terminate threads on mosquitto_destroy() when a client is not using
  the threaded interface but does use their own thread. Fixes bug #1291473.
Clients:
- Add --ciphers to allow specifying which TLS ciphers to support.
- Add support for SRV lookups.
- Add -N to sub client to suppress printing of EOL after the payload.
- Add -T to sub client to suppress printing of a topic hierarchy.
1.2.3 - 20131202
================
Broker:
- Don't always attempt to call read() for SSL clients, irrespective of whether
  they were ready to read or not. Reduces syscalls significantly.
- Possible memory leak fixes.
- Further fix for bug #1226040: multiple retained messages being delivered for
  subscriptions ending in #.
- Fix bridge reconnections when using multiple bridge addresses.
Client library:
- Fix possible memory leak in C/C++ library when communicating with
  a broker that doesn't follow the spec.
- Block in Python loop_stop() until all messages are sent, as the
  documentation states should happen.
- Fix for asynchronous connections on Windows. Closes bug #1249202.
- Module version is now available in mosquitto.py.
Clients:
- mosquitto_sub now uses fwrite() instead of printf() to output messages, so
  messages with NULL characters aren't truncated.
1.2.2 - 20131021
================
Broker:
- Fix compliance with max_inflight_messages when a non-clean session client
  reconnects. Closes one of the issues on bug #1237389.
Client library:
- Fix incorrect inflight message accounting, which caused messages to go
  unsent. Partial fix for bug #1237351.
- Fix potential memory corruption when sending QoS>0 messages at a high rate
  using the threaded interface. Further fix for #1237351.
- Fix incorrect delay scaling when exponential_backoff=true in
  mosquitto_reconnect_delay_set().
- Some pep8 fixes for Python.
1.2.1 - 20130918
================
Broker:
- The broker no longer ignores the auth_plugin_init() return value. Closes
  bug #1215084.
- Use RTLD_GLOBAL when opening authentication plugins on posix systems. Fixes
  resolving of symbols in libraries used by authentication plugins.
- Add/fix some config documentation.
- Fix ACLs for topics with $SYS.
- Clients loaded from the persistence file on startup were not being added to
  the client hash, causing subtle problems when the client reconnected,
  including ACLs failing. This has been fixed.
- Add note to mosquitto-tls man page stating that certificates need to be
  unique. Closes bug #1221285.
- Fix incorrect retained message delivery when using wildcard subs in some
  circumstances. Fixes bug #1226040.
Client library:
- Fix support for Python 2.6, 3.0, 3.1.
- Fix TLS subjectAltName verification and segfaults.
- Handle EAGAIN in Python on Windows. Closes bug #1220004.
- Fix compilation when using WITH_TLS=no.
- Don't fail reconnecting in Python when broker is temporarily unavailable.
1.2 - 20130708
==============
Broker:
- Replace O(n) username lookup on CONNECT with a roughly O(1) hashtable version.
- It is now possible to disable $SYS at compile time.
- Add dropped publish messages to load tree in $SYS. Closes bug #1183318.
- Add support for logging SUBSCRIBE/UNSUBSCRIBE events.
- Add "log_dest file" logging support.
- Auth plugin ACL check function now passes the client id as well as username
  and password.
- The queue_qos0_messages option wasn't working correctly, this has now been
  fixed. Closes bug #1125200.
- Don't drop all messages for disconnected durable clients when
  max_queued_messages=0.
- Add support for "log_type all".
- Add support for "-v" option on the command line to provide the equivalent of
  "log_type all" without needing a config file.
- Add the "upgrade_outgoing_qos" option, a non-standard feature.
- Persistence data is now written to a temporary file which is atomically
  renamed on completion, so a crash during writing will not produce a corrupt
  file.
- mosquitto.conf is now installed as mosquitto.conf.example
- Configuration file errors are now reported with filename and line number.
- The broker now uses a monotonic clock if available, to avoid changes in time
  causing client disconnections or message retries.
- Clean session and keepalive status are now display the log when a client
  connects.
- Add support for TLSv1.2 and TLSv1.1.
- Clients that connect with zero length will topics are now rejected.
- Add the ability to set a maximum allowed PUBLISH payload size.
- Fix an ACL with topic "#" incorrectly granting access to $SYS.
- Fix retained messages incorrectly being set on wildcard topics, leading to
  duplicate retained messages being sent on subscription. Closes bug #1116233.
- Don't discard listener values when no "port" option given. Closes bug
  #1131406.
- Client password check was always failing when security was being reapplied
  after a config reload. This meant that all clients were being disconnected.
  This has been fixed.
- Fix build when WITH_TLS=no. Closes bug #1174971.
- Fix single outgoing packets not being sent in a timely fashion if they were
  not sent in one call to write(). Closes bug #1176796.
- Fix remapping of messages for clients connected to a listener with
  mount_point set. Closes bug #1180765.
- Fix duplicate retained messages being sent for some wildcard patterns.
- If a client connects with a will topic to which they do not have write
  access, they are now disconnected with CONNACK "not authorised".
- Fix retained messages on topic foo being incorrectly delivered to
  subscriptions of /#
- Fix handling of SSL errors on SSL_accept().
- Fix handling of QoS 2 messages on client reconnect.
- Drop privileges now sets supplementary groups correctly.
- Fix load reporting interval (is now 60s).
- Be strict with malformed PUBLISH packets - clients are now disconnected
  rather than the packet discarded. This goes inline with future OASIS spec
  changes and makes other changes more straightforward.
- Process incoming messages denied by ACL properly so that clients don't keep
  resending them.
- Add support for round_robin bridge option.
- Add bridge support for verifying remote server certificate subject against
  the remote hostname.
- Fix problem with out of order calls to free() when restarting a lazy bridge.
- The broker now attempts to resolve bind_address and bridge addresses
  immediately when parsing the config file in order to detect invalid hosts.
- Bridges now set their notification state before attempting to connect, so if
  they fail to connect the state can still be seen.
- Fix bridge notification payload length - no need to send a null byte.
- mosquitto_passwd utility now reports errors more clearly.
- Fix "mosquitto_passwd -U".
Client library:
- Add support for TLSv1.2 and TLSv1.1, except for on the Python module.
- Add support for verifying remote server certificate subject against the
  remote hostname.
- Add mosquitto_reconnect_async() support and make asynchronous connections
  truely asynchronous rather than simply deferred. DNS lookups are still
  blocking, so asynchronous connections require an IP address instead of
  hostname.
- Allow control of reconnection timeouts in mosquitto_loop_forever() and after
  mosquitto_loop_start() by using mosquitto_reconnect_delay_set().
- Fix building on Android NDK.
- Re-raise unhandled errors in Python so as not to provide confusing error
  messages later on.
- Python module supports IPv6 connections.
- mosquitto_sub_topic_tokenise() was behaving incorrectly if the last topic
  hierarchy had only a single character. This has been fixed. Closes bug
  #1163348.
- Fix possible crash after disconnects when using the threaded interface with
  TLS.
- Allow build/install without Python. Closes bug #1174972.
- Add support for binding connection to a local interface.
- Implement maximum inflight messages handling.
- Fix Python client not handling will_payload==None.
- Fix potential memory leak when setting username/password.
- Fix handling of QoS 2 messages on reconnect.
- Improve handling of mosquitto_disconnect() with threaded mode.
Clients:
- Add support for TLSv1.2 and TLSv1.1.
- Sub client can now suppress printing of messages with the retain bit set.
- Add support for binding connection to a local interface.
- Implement maximum inflight messages handling for the pub client.
1.1.3 - 20130211
================
Broker:
- mosquitto_passwd utility now uses tmpfile() to generate its temporary data
  storage file. It also creates a backup file that can be used to recover data
  if an errors occur.
Other:
- Build script fixes to help packaging on Debian.
1.1.2 - 20130130
================
Client library:
- Fix tls_cert_reqs not being set to SSL_VERIFY_PEER by default. This meant
  that clients were not verifying the server certificate when connecting over
  TLS. This affects the C, C++ and Python libraries.
1.1.1 - 20130116
================
Broker:
- Fix crash on reload if using acl patterns.
Client library:
- Fix static C++ functions not being exported on Windows. Fixes bug #1098256.
1.1 - 20121219
==============
Broker:
- Add $SYS/broker/messages/dropped
- Add $SYS/broker/clients/expired
- Replace $SYS/broker/+/per second/+ with moving average versions published at
  $SYS/broker/load/#
- Add $SYS/broker/load/sockets/+ and $SYS/broker/load/connections/+
- Documentation on password file format has been fixed.
- Disable SSL compression. This reduces memory usage significantly and removes
  the possibility of CRIME type attacks.
- Enable SSL_MODE_RELEASE_BUFFERS mode to reduce SSL memory usage further.
- Add allow_duplicate_messages option.
- ACL files can now have comment lines with # as the first character.
- Display message on startup about which config is being loaded.
- Fix max_inflight_messages and max_queued_messages not being applied.
- Fix documentation error in mosquitto.conf.
- Ensure that QoS 2 queued messages are sent out in a timely manner.
- Local bridges now act on clean_session correctly.
- Local bridges with clean_session==false now remove unused subscriptions on
  broker restart.
- The $SYS/broker/heap/# messages now no longer include "bytes" as part of the
  string for ease of use.
Client library:
- Free memory used by OpenSSL in mosquitto_lib_cleanup() where possible.
- Change WebSocket subprotocol name to mqttv3.1 to make future changes easier
  and for compatibility with other implementations.
- mosquitto_loop_read() and mosquitto_loop_write() now handle errors
  themselves rather than having mosquitto_loop() handle their errors. This
  makes using them in a separate event loop more straightforward.
- Add mosquitto_loop_forever() / loop_forever() function call to make simple
  clients easier.
- Disable SSL compression. This reduces memory usage significantly and removes
  the possibility of CRIME type attacks.
- Enable SSL_MODE_RELEASE_BUFFERS mode to reduce SSL memory usage further.
- mosquitto_tls_set() will now return an error or raise an exception
  immediately if the CA certificate or client certificate/key cannot be
  accessed.
- Fix potential memory leaks on connection failures.
- Don't produce return error from mosquitto_loop() if a system call is
  interrupted. This prevents disconnects/reconnects in threaded mode and
  simplifies non-threaded client handling.
- Ignore SIGPIPE to prevent unnecessary client quits in threaded mode.
- Fix document error for mosquitto_message_retry_set().
- Fix mosquitto_topic_matches_sub() for subscriptions with + as the final
  character. Fixes bug #1085797.
- Rename all "obj" parameters to "userdata" for consistency with other
  libraries.
- Reset errno before network read/write to ensure EAGAIN isn't mistakenly
  returned.
- The message queue length is now tracked and used to determine the maximum
  number of packets to process at once. This removes the need for the
  max_packets parameter which is now unused.
- Fix incorrect error value in Python error_string() function. Fixes bug
  #1086777.
- Reset last message in/out timer in Python module when we send a PINGREQ.
  Fixes too-early disconnects.
Clients:
- Clients now display their own version number and library version number in
  their help messages.
- Fix "mosquitto_pub -l -q 2" disconnecting before all messages were
  transmitted.
- Fix potential out-of-bounds array access with client ids. Fixes bug
  #1083182.
Other:
- mosquitto_passwd can now convert password files with plain text files to
  hashed versions.
1.0.5 - 20121103
================
Broker:
- Fix crash when the broker has use_identity_as_username set to true but a
  client connects without a certificate.
- mosquitto_passwd should only be installed if WITH_TLS=yes.
Library:
- Use symbolic errno values rather than numbers in Python module to avoid
  cross platform issues (incorrect errno on Mac OS).
Other:
- Build script fixes for FreeBSD.
1.0.4 - 20121017
================
Broker:
- Deal with poll() POLLIN/POLLOUT before POLL[RD]HUP to correctly handle the
  case where a client sends data and immediately closes its socket.
Library:
- Fix memory leak with messages of QoS=2. Fixes bug #1064981.
- Fix potential thread synchronisation problem with outgoing packets in the
  Python module. Fixes bug #1064977.
Clients:
- Fix "mosquitto_sub -l" incorrectly only sending one message per second.
1.0.3 - 20120927
================
Broker:
- Fix loading of psk files.
- Don't return an error when reloading config if an ACL file isn't defined.
  This was preventing psk files being reloaded.
- Clarify meaning of $SYS/broker/clients/total in mosquitto(8) man page.
- Clarify meaning of $SYS/broker/messages/stored in mosquitto(8) man page.
- Fix non-retained message delivery when subscribing to #.
- Fix retained message delivery for subs to foo/# with retained messages at
  foo.
- Include the filename in password/acl file loading errors.
Library:
- Fix possible AttributeError when self._sock == None in Python module.
- Fix reconnecting after a timeout in Python module.
- Fix reconnecting when there were outgoing packets in the queue in the Python
  module.
- Fix problem with mutex initialisation causing crashes on some Windows
  installations.
1.0.2 - 20120919
================
Broker:
- If the broker was configured for persistence, a durable client had a
  subscription to topics in $SYS/# and had messages in its queue when the
  broker restarted, then the persistent database would have messages missing
  and so the broker would not restart properly. This has been fixed.
Library:
- Fix threading problem on some systems.
Tests:
- Close socket after 08-ssl-connect-no-auth-wrong-ca.py test to prevent
  subsequent tests having problems.
Build scripts:
- Install pskfile.example in CMake. Fixes bug #1037504.
Other:
- Fix db_dump parameter printing message store and sub chunks.
1.0.1 - 20120815
================
Broker:
- Fix default log_dest when running as a Windows service.
Client library:
- Fix incorrect parameters in Python on_log() callback call. Fixes bug
  #1036818.
Clients:
- Clients now don't display TLS/TLS-PSK usage help if they don't support it.
Build scripts:
- Fix TLS-PSK support in the CMake build files.
- Fix man page installation in the CMake build files.
- Fix SYSCONFDIR in cmake on *nix when installing to /usr. Fixes bug #1036908.
Documentation:
- Fix mqtt/MQTT capitalisation in man pages.
- Update compiling.txt.
- Fix incorrect callback docs in mosquitto.py. Fixes bug #1036607.
- Fix various doc typos and remove obsolete script. Fixes bug #1037088.
1.0 - 20120814
==============
Broker:
- Add SSL/TLS support.
- Add TLS-PSK support, providing a simpler encryption method for constrained
  devices.
- Passwords are now salted+hashed if compiled with WITH_TLS (recommended).
- Add mosquitto_passwd for handling password files.
- Add $SYS/broker/publish/messages/{sent|received} to show the number of
  PUBLISH messages sent/received.
- Add $SYS/broker/publish/bytes/{sent|received} to show the number of
  PUBLISH bytes sent/received.
- Add reload parameter for security init/cleanup functions.
- Add option for expiring disconnected persistent clients.
- Add option for queueing of QoS 0 messages when persistent clients are
  disconnected.
- Enforce client id limits in the broker (only when WITH_STRICT_PROTOCOL is
  defined).
- Fix reloading of log configuration.
- Add support for try_private config option for bridge connections.
- Add support for autosave_on_changes config option.
- Add support for include_dir config option.
- Add support for topic remapping.
- Usernames were being lost when a non clean-session client reconnected,
  potentially causing problems with ACLs. This has been fixed.
- Significant improvement to memory handling on Windows.
- Bridges with outgoing topics will now set the retain flag correctly so that
  messages will be retained on the remote broker.
- Incoming bridge connections are now detected by checking if bit 8 of the
  protocol version number is set. This requires support from the remote broker.
- Add support for notification_topic option.
- Add $SYS/broker/subscriptions/count and $SYS/broker/retained messages/count.
- Add restart_timeout to control the amount of time an automatic bridge will
  wait before reconnecting.
- Overlapping subscriptions are now handled properly. Fixes bug #928538.
- Fix reloading of persistence_file and persistence_location.
- Fix broker crash on incorrect protocol number.
- Fix missing COMPAT_ECONNRESET define on Windows.
- Clients that had disconnected were not always being detected immediately on
  Linux. This has been fixed.
- Don't save $SYS messages to the on-disk persistent db. All $SYS messages
  should be reconstructed on a restart. This means bridge connection
  notifications will now be correct on a restart.
- Fix reloading of bridge clients from the persistent db. This means that
  outgoing bridged topics should always work.
- Local bridges are now no longer restricted by local ACLs.
- Discard publish messages with zero length topics.
- Drop to "mosquitto" user even if no config file specified.
- Don't incorrectly allow topic access if ACL patterns but no normal ACL rules
  are defined.
Client library:
- Add SSL/TLS support.
- Add TLS-PSK support, providing a simpler encryption method for constrained
  devices.
- Add javascript/websockets client library.
- Add "struct mosquitto *mosq" parameter for all callbacks in the client
  library. This is a binary incompatible change so the soversion of the
  libraries has been incremented. The new parameter should make it easier to
  use callbacks in practice.
- Add mosquitto_want_write() for use when using own select() loop with
  mosquitto_socket().
- Add mosquitto_connect_async() to provide a non-blocking connect client call.
- Add mosquitto_user_data_set() to allow user data pointer to be updated.
- Add "int rc" parameter to disconnect callback to indicate whether disconnect
  was unexpected or the result of calling mosquitto_disconnect().
- Add mosquitto_strerror() for obtaining a string description of error numbers.
- Add mosquitto_connack_string() for obtaining a string description of MQTT
  connection results.
- Add mosquitto_will_clear() and change mosquitto_will_set() to only set the
  will.
- Add mosquitto_sub_topic_tokenise() and mosquitto_sub_topic_tokens_free()
  utility functions to tokenise a subscription/topic string into a string
  array.
- Add mosquitto_topic_matches_sub() to check whether a topic matches a
  subscription.
- Replaced mosquitto_log_init() with mosquitto_log_callback_set() to allow
  clients to decide what to do with log messages.
- Client will now disconnect itself from the broker if it doesn't receive a
  PINGRESP in the keepalive period after sending a PINGREQ.
- Client will now send a PINGREQ if it has not received a message from the
  broker in keepalive seconds.
- mosquitto_new() will now generate a random client id if the id parameter is
  NULL.
- Added max_packets to mosquitto_loop(), mosquitto_loop_read() and
  mosquitto_loop_write() to control the maximum number of packets that are
  handled per call.
- Payload parameters are now void * instead of uint8_t *.
- The clean_session parameter has been moved from mosquitto_connect() to
  mosquitto_new() because it is a client parameter rather than a connection
  parameter.
- Functions now use int instead of uint*_t where possible.
- mosquitto_new() now sets errno to indicate failure type.
- Return MOSQ_ERR_INVAL on zero length topic.
- Fix automatic client id generation on Windows.
- mosquitto_loop_misq() can now return MOSQ_ERR_NO_CONN.
- Compile static library as well as dynamic library with default makefiles.
- Rename C++ namespace from mosquittopp to mosqpp to remove ambiguity.
- C++ lib_init(), lib_version() and lib_cleanup() are now in the mosqpp
  namespace directly, not mosquittopp class members.
- The Python library is now written in pure Python and so no longer depends on
  libmosquitto.
- The Python library includes SSL/TLS support.
- The Python library should now be compatible with Python 3.
Other:
- Fix db_dump reading of retained messages.
- Add example of logging all messages to mysql.
- Add C++ client example.
- Fix potential buffer overflow in pub/sub clients.
- Add "make binary" target that doesn't make documents.
- Add "--help" arguments to pub/sub clients.
- Fix building on Solaris.
0.15 - 20120205
===============
- Add support for $SYS/broker/clients/maximum and $SYS/broker/clients/active
  topics.
- Add support for $SYS messages/byte per second received/sent topics.
- Updated mosquitto man page - $SYS hierarchy and signal support were out of
  date.
- Auto generated pub/sub client ids now include the hostname.
- Tool for dumping persistent DB contents is available in src/db_dump. It isn't
  installed by default.
- Enforce topic length checks in client library.
- Implement "once" and "lazy" bridge start types.
- Add new return type MOSQ_ERR_ERRNO to indicate that the errno variable should
  be checked for the real error code.
- Add support for connection_messages config option.
- mosquitto_sub will now refuse to run if the -c option (disable clean session)
  is given and no client id is provided.
- mosquitto_pub now gives more useful error messages on invalid input or other
  error conditions.
- Fix Python will_set() true/True typo.
- Fix messages to topic "a/b" incorrectly matching on a subscription "a" if
  another subscription "a/#" exists.
0.14.4 - 20120106
=================
- Fix local bridge notification messages.
- Fix return values for more internal library calls.
- Fix incorrect out of memory checks in library and broker.
- Never time out local bridge connections.
0.14.3 - 20111210
=================
- Fix potential crash when client connects with an invalid CONNECT packet.
- Fix incorrect invalid socket comparison on Windows.
- Server shouldn't crash when a message is published to foo/ when a
  subscription to foo/# exists (bug #901697).
- SO_REUSEADDR doesn't work the same on Windows, so don't use it.
- Cygwin builds now support Windows service features.
- Fix $SYS/broker/bytes/sent reporting.
0.14.2 - 20111123
=================
- Add uninstall target for libs.
- Don't try to write packet whilst in a callback.
0.14.1 - 20111117
=================
- Fix Python sytax errors (bug #891673).
0.14 - 20111116
===============
- Add support for matching ACLs based on client id and username.
- Add a Windows installer file (NSIS based).
- Add native support for running the broker as a Windows service. This is the
  default when installed using the new installer.
- Fix client count for listeners. When clients disconnect, decrement the
  count. Allow max_connections to work again.
- Attempt to send all packets immediately upon being queued. This will result
  in more immediate network communication in many cases.
- Log IP address when reporting CONNACK packets if the client id isn't yet
  known.
- Fix payload length calculation in python will_set function.
- Fix Python publish and will_set functions for payload=None.
- Fix keepalive value being lost when reconnecting a client (bug #880863).
- Persistence file writing now uses portable file functions, so the Cygwin
  broker build should no longer be necessary.
- Duplicate code between the client and broker side has been reduced.
- Queued messages for clients reconnecting with clean_session=false set were
  not being sent until the next message for that client was received. This has
  been fixed (bug #890724).
- Fix subscriptions to # incorrectly matching against topics beginning with /
0.13 - 20110920
===============
- Implement bridge state notification messages.
- Save client last used mid in persistent database (DB version number bumped).
- Expose message id in Python MosquittoMessage.
- It is now possible to set the topic QoS level for bridges.
- Python MosquittoMessage payload parameter is now a Python string, not a
  ctypes object which makes it much easier to use.
- Fix queueing of messages for disconnected clients. The max_queued_messages
  option is now obeyed.
- C++ library is now in its own namespace, mosquittopp.
- Add support for adding log message timestamps in the broker.
- Fix missing mosquitto_username_pw_set() python binding.
- Fix keepalive timeout for reconnecting non clean-session clients. Prevents
  immediate disconnection on reconnection.
- Fix subscription wildcard matching - a subscription of +/+ will now match
  against /foo
- Fix subscription wildcard matching - a subscription of foo/# will now match
  against foo
- When restoring persistent database, clients should be set to non
  clean-session or their subscriptions will be immediately removed.
- Fix SUBACK payload for multiple topic subscriptions.
- Don't send retained messages when a client subscribes to a topic it is
  already subscribed to.
0.12 - 20110725
===============
- Reload (most) configuration on SIGHUP.
- Memory tracking is no longer compiled in the client library.
- Add --help option to mosquitto to display usage.
- Add --id-prefix option to clients to allow easier use with brokers that are
  using the clientid_prefix option.
- Fix compilation on QNX.
- Add -P as a synonym argument for --pw in the clients.
- Fix python MosquittoMessage payload parameter. This is now returned as a
  pointer to an array of c_uint8 values so binary data is handled correctly.
  If a string is needed, use msg.payload_str
- Fix memory leaks on client authentication.
- If password_file is not defined then clients can now connect even if they
  use a username/password.
- Add mosquitto_reconnect() to the client library.
- Add option for compiling with liberal protocol compliance support (enabled
  by default).
- Fix problems with clients reconnecting and old messages remaining in the
  message store.
- Display both ip and client id in the log message when a client connects.
  Change the socket connection message to make it more obvious that it is just
  a socket connection being made (bug #801135).
- Fix retained message delivery where a subscription contains a +.
- Be more lenient when reloading persistent database to reduce errors with
  empty retained messages.
0.11.3 - 20110707
=================
- Don't complain and quit if persistence_file option is given (bug #802423).
- Initialise listeners correctly when clients with duplicate client ids
  connect. Bug #801678.
- Memory tracking is now disabled for Symbian builds due to lack of malloc.h.
- Fix memory tracking compilation for kFreeBSD.
- Python callbacks can now be used with class member functions.
- Fix persistent database writing of client message chunks which caused
  errors when restoring (bug #798164).
0.11.2 - 20110626
=================
- Don't free contexts in mqtt3_context_disconnect() (bug #799688 / #801678).
- Only free will if present when freeing a client context.
0.11.1 - 20110620
=================
- Fix buffer overrun when checking for + and # in topics (bug #799688).
- Pub client now quits if publish fails.
0.11 - 20110619
===============
- Removed all old sqlite code.
- Remove client id limit in clients.
- Implemented $SYS/broker/heap/maximum size
- Implemented $SYS/broker/clients/inactive to show the number of disconnected
  non-clean session clients.
- $SYS/broker/heap/current size and maximum size messages now include "bytes"
  to match rsmb message format.
- Implemented the retained_persistence config file option - a synonym of the
  "persistence" option.
- Added security_external.c to broker source to make it easier for third
  parties to add support for their existing username/password and ACL database
  for security checks. See external_security_checks.txt.
- $SYS messages are now only republished when their value changes.
- Windows native broker now responds to command line arguments.
- Simplify client disconnecting so wills gets sent in all cases (bug #792468).
- Clients now have a --quiet option.
- The on_disconnect() callback will always be called now, even if the client
  has disconnected unexpectedly.
- Always close persistent DB file after restoring.
- Return error code when exiting the clients.
- mosquitto_publish() now returns MOSQ_ERR_INVAL if the topic contains + or #
- mosquitto now silently rejects published messages with + or # in the topic.
- max_connections is now a per-listener setting instead of global.
- Connection count is now reduced when clients disconnect (bug #797983).
0.10.2 - 20110106
=================
- Don't abort when connecting if the first connection fails. This is important
  on e.g. Windows 7, where IPV6 is offered as the first choice but may not be
  available.
- Deal with long logging messages properly (bug #785882).
- Fix library compilation on Symbian - no pselect() available.
- Don't stop processing subscriptions on received messages after a
  subscription with # matches. (bug #791206).
0.10.1 - 20110512
=================
- Fix Windows compilation.
- Fix mosquitto.py on Windows - call lib init/cleanup.
- Don't abort when connecting if given an unknown address type (assuming an
  IPv4 or IPv6 address is given).
0.10 - 20110429
===============
- Implement support for the password_file option and accompanying
  authentication requirements in the broker.
- Implement topic Access Control Lists.
- mosquitto_will_set() and mosquitto_publish() now return
  MOSQ_ERR_PAYLOAD_SIZE if the payload is too large (>268,435,455 bytes).
- Bridge support can now be disabled at compile time.
- Group together network writes for outgoing packets - don't send single byte
  writes!
- Add support for clientid_prefixes variable.
- Add support for the clientid config variable for controlling bridge client
  ids.
- Remove 32-bit database ID support because htobe64() no longer used.
- Multiple client subscriptions to the same topic result in only a single
  subscription. Bug #744077.
0.9.3 - 20110310
================
- Set retained message status for QoS 2 messages (bug #726535).
- Only abort with an error when opening listening sockets if no address family
  is available, rather than aborting when any address family is not available.
- Don't clean queued messages when a non clean session client reconnects.
- Make mosquitto.py compatible with Python <2.6.
- Fix mosquitto.h header includes for Windows.
0.9.2 - 20110208
================
- Only send a single DISCONNECT command when using -l in the pub client.
- Set QoS=1 on PUBREL commands to meet protocol spec.
- Don't leak sockets on connection failure in the library.
- Install man pages when building under cmake.
- Fix crash bug on malformed CONNECT message.
- Clients are now rejected if their socket peer name cannot be obtained on
  connection.
- Fix a number of potential problems caused when a client with a duplicate id
  connects.
- Install mosquitto.conf under cmake.
0.9.1 - 20101203
================
- Add missing code for parsing the "bind_address" configuration option.
- Fix missing include when compiling with tcp-wrappers support.
- Add linker version script for C library to control exported functions.
0.9 - 20101114
==============
- Client and message data is now stored in memory with custom routines rather
  than a sqlite database. This removes the dependencies on sqlite, pcre and
  sqlite3-pcre. It also means that the persistent database format has had to
  be reimplemented in a custom format. Optional support for importing old
  sqlite databases is provided.
- Added IPv6 support for mosquitto and the clients.
- Provide username and password support for the clients and client libraries.
  This is part of the new MQTT v3.1 spec.
- The broker supports the username and password connection flags, but will not
  do anything with the username and password.
- Python callback functions now optionally take an extra argument which will
  return the user object passed to the Mosquitto() constructor, or the calling
  python object itself if nothing was given to Mosquitto().
- Remove the mosquitto command line option "-i interface".
- Remove the mosquitto.conf "interface" variable.
- Add support for the listener config variable (replaces the interface
  variable)
- Add support for the bind_address config variable.
- Change the port config variable behaviour to match that of rsmb (applies to
  the default listener only, can be given just once).
- Fix QoS 2 protocol compliance - stop sending duplicate messages and handle
  timeouts correctly. Fixes bug #598290.
- Set retain flag correctly for outgoing messages. It should only be set for
  messages sent in response to a subscribe command (ie. stale data).
- Fix bug in returning correct CONNACK result to on_connect client callback.
- Don't send client will if it is disconnected for exceeding its keepalive
  timer.
- Fix client library unsubscribe function incorrectly sending a SUBSCRIBE
  command when it should be UNSUBSCRIBE.
- Fix max_inflight_messages and max_queued_messages operation. These
  parameters now apply only to QoS 1 and 2 messages and are used regardless of
  the client connection state.
- mosquitto.conf now installed to /etc/mosquitto/mosquitto.conf instead of
  /etc/mosquitto.conf. The /etc/mosquitto/ directory will be used for password
  and access control files in the future.
- Give the compile time option of using 32-bit integers for the database IDs
  instead of 64-bit integers. This is useful where htobe64()/be64toh() are not
  available or for embedded systems for example.
- The DUP bit is now set correctly when resending PUBREL messages.
- A port to Windows native has been partially completed. This currently drops a
  number of features, including the ability to change configuration parameters
  and persistent storage.
0.8.3 - 20101004
================
- Fix QoS 2 protocol compliance - stop sending duplicate messages and handle
  timeouts correctly. Fixes bug #598290. (backported from future 0.9 code)
0.8.2 - 20100815
================
- Fix default loop() timeout value in mosquitto.py. Previous value was 0,
  causing high cpu load.
- Fix message handling problem in client library when more than one message was
  in the client queue.
- Fix the logic used to determine whether a QoS>0 message needs to be retried.
- Fix the Python sub.py example so that it quits on error.
0.8.1 - 20100812
================
- Improve python interface
- Fix incorrect return value from message delete function
- Use logging function to print error messages in clients.
- Fix python installation script DESTDIR.
- Fix library destination path for 64-bit machines.
0.8 - 20100807
==============
- Topics starting with a / are treated as distinct to those not starting with
  a /. For example, /topic/path is different to topic/path. This matches the
  behaviour of rsmb.
- Correctly calculate the will QoS on a new client connection (bug #597451).
- Add "addresses" configuration file variable as an alias of "address", for
  better rsmb compatibility.
- Bridge clean_session setting is now false, to give more sensible behaviour
  and be more compatible with rsmb.
- Add cleansession variable for configuring bridges.
- Add keepalive_interval variable for bridges.
- Remove default topic subscription for mosquitto_sub because the old
  behaviour was too confusing.
- Added a C client library, which the pub and sub clients now use.
- Added a C++ client library (bound to the C library).
- Added a Python client library (bound to the C library).
- Added CMake build scripts to allow the library and clients (not the broker)
  to be compiled natively on Windows.
0.7 - 20100615
==============
- mosquitto_pub can now send null (zero length) messages.
- Don't store QoS=0 messages for disconnected clients with subscriptions of
  QoS>0.
- accept() all available sockets when new clients are connecting, rather than
  just one.
- Add option to print debug messages in pub and sub clients.
- hg revision is now exported via $SYS/broker/changeset
- Send Will when client exceeds keepalive timer and is disconnected.
- Check to see if a client has a will before sending it.
- Correctly deal with clients connecting with the same id multiple times.
- Add compile time option to disable heap memory tracking.
- Use poll() instead of select() to allow >1024 clients.
- Implement max_connections.
- Run VACUUM on in-memory database on receiving SIGUSR2.
- Fix bridge keepalive timeouts and reconnects.
- Don't attempt to drop root privileges when running on Windows as this isn't
  well supported (bug #586231).
0.6.1 - 20100506
================
- Fix DB auto upgrade for messages table.
0.6 - 20100505
==============
- Basic support for connecting multiple MQTT brokers together (bridging).
- mosquitto_sub can now subscribe to multiple topics (limited to a global QoS).
- mosquitto_pub can now send a file as a message.
- mosquitto_pub can now read all of stdin and send it as a message.
- mosquitto_pub can now read stdin and send each line as a message.
- mosquitto will now correctly run VACUUM on the persistent database on exit.
- Implement a more efficient database design, so that only one copy of each
  message is held in the database, rather than one per subscribed client.
- Add the store_cleanup_interval config option for dealing with the internal
  message store.
- Add support for disabling "clean session" for the sub client.
- Add support for automatic upgrading of the mosquitto DB from v1 to v2.
- Add persistence_file config option to allow changing the filename of the
  persistence database. This allows multiple mosquitto DBs to be stored in the
  same location whilst keeping persistence_location compatible with rsmb.
- Don't store QoS=0 messages for disconnected clients. Fixes bug #572608. This
  wasn't correctly fixed in version 0.5.
- Don't disconnect clients if they send a PUBLISH with zero length payload
  (bug #573610).
- If a retained message is received with a zero length payload, the retained
  message for that topic is deleted.
- Send through zero length messages.
- Produce a warning on unsupported rsmb options instead of quitting.
- Describe clean session flag in the mqtt man page.
- Implement the max_inflight_messages and max_queued_messages features in the
  broker.
0.5.4 - 20100311
================
- Fix memory allocation in mqtt3_fix_sub_topic() (bug #531861).
- Remove accidental limit of 100 client connections.
- Fix mosquitto_pub handling of messages with QoS>0 (bug #537061).
0.5.3 - 20100303
================
- Will messages are now only sent when a client disconnects unexpectedly.
- Fix all incoming topics/subscriptions that start with a / or contain
  multiple / in a row (//).
- Do actually disconnect client when it sends an empty subscription/topic string.
- Add missing $SYS/broker/clients/total to man page.
0.5.2 - 20100302
================
- Always update last backup time, so that the backup doesn't run every time
  through the main loop once autosave_interval has been reached.
- Report $SYS/broker/uptime in the same format as rsmb.
- Make mandatory options obvious in usage output and man page of mosquitto_pub.
  Fixes bug #529990.
- Treat subscriptions with a trailing slash correctly. This should fix bugs
  #530369 and #530099.
0.5.1 - 20100227
================
- Must daemonise before pid file is written.
0.5 - 20100227
==============
- No longer store QoS=0 messages for disconnected clients that do not have
  clean start set.
- Rename msg_timeout option to retry_interval for better rsmb compatibility.
- Change persistence behaviour. The database is now stored in memory even if
  persistence is enabled. It is written to disk when mosquitto exits and also at
  periodic intervals as defined by the new autosave_interval option.
- The writing of the persistence database may be forced by sending mosquitto
  the SIGUSR1 signal.
- Clients that do not send CONNECT as their first command are now
  disconnected.
- Boolean configuration values may now be specified with true/false as well as
  1/0.
- Log message on CONNECT with invalid protocol or protocol version.
- Default sqlite3-pcre path on Linux is now /usr/lib/sqlite3/pcre.so to match
  future sqlite3-pcre packages.
- Add mosquitto_sub and mosquitto_pub, simple clients for subscribe/publish.
- Add man pages for clients.
- Add general man page on mqtt.
- Root privileges are now dropped only after attempting to write a pid file
  (if configured). This means that the pid file can be written to /var/run/
  directly and should fix bug #523183.
0.4.2 - 20100203
================
- Fix segfault on client connect with invalid protocol name/version.
0.4.1 - 20100112
===============
- Fix regex used for finding retained messages to send on new subscription.
0.4 - 20100105
==============
- Added support for wildcard subscriptions using + and #.
- All network operations are now non-blocking and can cope with partial
  packets, meaning that networking should be a lot more reliable.
- Total messsages/bytes sent/received are now available in $SYS.
- Improved logging information - use client ip address and id instead of
  socket number.
- Broker build timestamp is available in $SYS.
- Keepalive==0 is now correctly treated as "never disconnect".
- Fixed manpage installation.
- Fixed incorrect $SYS hierarchy locations in documentation and code.
- Debug type log messages are no longer sent to "topics".
- Default logging destination no longer includes "topics" to prevent possible
  error logging to the db before it is initialised.
- Periodic $SYS messages can now be disabled.
- stdout and stderr are flushed when logging to them to give more timely
  updates.
- dup is now set correctly when resending messages.
- Database format bumped due to topic column naming fix.
0.3 - 20091217
==============
- The port option in the configuration file and --port command line argument
  may now be given any number of times to make mosquitto listen on multiple
  sockets.
- Add new config file and command line option "interface" to specify an
  interface to listen on, rather than all interfaces.
- Added host access control through tcp-wrappers support.
- Set SO_REUSEADDR on the listening socket so restart is much quicker.
- Added support for tracking current heap memory usage - this is published on
  the topic "$SYS/broker/heap/current size"
- Added code for logging to stderr, stdout, syslog and topics.
- Added logging to numerous places - still plenty of scope for more.
0.2 - 20091204
==============
- Replaced the command line option --foreground with --daemon, swapping the
  default behaviour.
- Added the command line option --config-file, to specify a config file to
  load.  If this is not given, no config file is load and the default options
  are used.
- Added the command line option --port for specifying the port to listen on.
  This overrides values in the config file.
- Don't use persistence by default.
- Default behaviour is now more sane when run by a normal user with no command
  line options (combination of above changes).
- Added option user to config file, defaulting to a value of mosquitto. If
  this value isn't blank and mosquitto is started by root, then it will drop
  privileges by changing to the user and its primary group. This replaces the
  current behaviour of refusing to start if run by root.
- Fix non-persistent mode, which would never work in the previous release.
- Added information on default values of msg_timeout and sys_interval to the
  mosquitto.conf man page. (closes bug #492045).
proj1_mqttd/mosquitto/mosquitto-1.6.3/LICENSE.txt
New file
@@ -0,0 +1,2 @@
This project is dual licensed under the Eclipse Public License 1.0 and the
Eclipse Distribution License 1.0 as described in the epl-v10 and edl-v10 files.
proj1_mqttd/mosquitto/mosquitto-1.6.3/Makefile
New file
@@ -0,0 +1,130 @@
include config.mk
DIRS=lib client src
DOCDIRS=man
DISTDIRS=man
DISTFILES= \
    client/ \
    examples/ \
    installer/ \
    lib/ \
    logo/ \
    man/ \
    misc/ \
    security/ \
    service/ \
    src/ \
    test/ \
    \
    CMakeLists.txt \
    CONTRIBUTING.md \
    ChangeLog.txt \
    LICENSE.txt \
    Makefile \
    about.html \
    aclfile.example \
    compiling.txt \
    config.h \
    config.mk \
    edl-v10 \
    epl-v10 \
    libmosquitto.pc.in \
    libmosquittopp.pc.in \
    mosquitto.conf \
    notice.html \
    pskfile.example \
    pwfile.example \
    readme-windows.txt \
    readme.md
.PHONY : all mosquitto api docs binary check clean reallyclean test install uninstall dist sign copy localdocker
all : $(MAKE_ALL)
api :
    mkdir -p api p
    naturaldocs -o HTML api -i lib -p p
    rm -rf p
docs :
    set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d}; done
binary : mosquitto
mosquitto :
ifeq ($(UNAME),Darwin)
    $(error Please compile using CMake on Mac OS X)
endif
    set -e; for d in ${DIRS}; do $(MAKE) -C $${d}; done
clean :
    set -e; for d in ${DIRS}; do $(MAKE) -C $${d} clean; done
    set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} clean; done
    $(MAKE) -C test clean
reallyclean :
    set -e; for d in ${DIRS}; do $(MAKE) -C $${d} reallyclean; done
    set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} reallyclean; done
    $(MAKE) -C test reallyclean
    -rm -f *.orig
check : test
test : mosquitto
    $(MAKE) -C test test
ptest : mosquitto
    $(MAKE) -C test ptest
utest : mosquitto
    $(MAKE) -C test utest
install : mosquitto
    set -e; for d in ${DIRS}; do $(MAKE) -C $${d} install; done
ifeq ($(WITH_DOCS),yes)
    set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} install; done
endif
    $(INSTALL) -d "${DESTDIR}/etc/mosquitto"
    $(INSTALL) -m 644 mosquitto.conf "${DESTDIR}/etc/mosquitto/mosquitto.conf.example"
    $(INSTALL) -m 644 aclfile.example "${DESTDIR}/etc/mosquitto/aclfile.example"
    $(INSTALL) -m 644 pwfile.example "${DESTDIR}/etc/mosquitto/pwfile.example"
    $(INSTALL) -m 644 pskfile.example "${DESTDIR}/etc/mosquitto/pskfile.example"
uninstall :
    set -e; for d in ${DIRS}; do $(MAKE) -C $${d} uninstall; done
    rm -f "${DESTDIR}/etc/mosquitto/mosquitto.conf.example"
    rm -f "${DESTDIR}/etc/mosquitto/aclfile.example"
    rm -f "${DESTDIR}/etc/mosquitto/pwfile.example"
    rm -f "${DESTDIR}/etc/mosquitto/pskfile.example"
dist : reallyclean
    set -e; for d in ${DISTDIRS}; do $(MAKE) -C $${d} dist; done
    mkdir -p dist/mosquitto-${VERSION}
    cp -r ${DISTFILES} dist/mosquitto-${VERSION}/
    cd dist; tar -zcf mosquitto-${VERSION}.tar.gz mosquitto-${VERSION}/
sign : dist
    cd dist; gpg --detach-sign -a mosquitto-${VERSION}.tar.gz
copy : sign
    cd dist; scp mosquitto-${VERSION}.tar.gz mosquitto-${VERSION}.tar.gz.asc mosquitto:site/mosquitto.org/files/source/
    cd dist; scp *.html mosquitto:site/mosquitto.org/man/
    scp ChangeLog.txt mosquitto:site/mosquitto.org/
coverage :
    lcov --capture --directory . --output-file coverage.info
    genhtml coverage.info --output-directory out
localdocker : reallyclean
    set -e; for d in ${DISTDIRS}; do $(MAKE) -C $${d} dist; done
    rm -rf dockertmp/
    mkdir -p dockertmp/mosquitto-${VERSION}
    cp -r ${DISTFILES} dockertmp/mosquitto-${VERSION}/
    cd dockertmp/; tar -zcf mosq.tar.gz mosquitto-${VERSION}/
    cp dockertmp/mosq.tar.gz docker/local
    rm -rf dockertmp/
    cd docker/local && docker build .
proj1_mqttd/mosquitto/mosquitto-1.6.3/about.html
New file
@@ -0,0 +1,44 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p><em>May 8, 2014</em></p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content").  Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL") and Eclipse Distribution License Version 1.0 ("EDL").
A copy of the EPL is available at
<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
and a copy of the EDL is available at
<a href="http://www.eclipse.org/org/documents/edl-v10.php">http://www.eclipse.org/org/documents/edl-v10.php</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content.  Check the Redistributor's license that was
provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
        <h3>Third Party Content</h3>
        <p>The Content includes items that have been sourced from third parties as set out below. If you
        did not receive this Content directly from the Eclipse Foundation, the following is provided
        for informational purposes only, and you should look to the Redistributor's license for
        terms and conditions of use.</p>
        <h4>libwebsockets 2.4.2</h4>
        <p>This project makes use of the libwebsockets library.</p>
        <p>The use of libwebsockets is based on the terms and conditions of the
        LGPL 2.1 with some specific exceptions.
        <a href="https://github.com/warmcat/libwebsockets/blob/v2.4.2/LICENSE">https://github.com/warmcat/libwebsockets/blob/v2.4.2/LICENSE</a></p>
        <p>When libwebsockets is distributed with the project, it is being used
        subject to the Static Linking Exception (Section 2) of the License. As
        a result, the content is not subject to the LGPL 2.1.</p>
</body></html>
proj1_mqttd/mosquitto/mosquitto-1.6.3/aclfile.example
New file
@@ -0,0 +1,9 @@
# This affects access control for clients with no username.
topic read $SYS/#
# This only affects clients with username "roger".
user roger
topic foo/bar
# This affects all clients.
pattern write $SYS/broker/connection/%c/state
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/CMakeLists.txt
New file
@@ -0,0 +1,29 @@
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
            ${STDBOOL_H_PATH} ${STDINT_H_PATH} ${PTHREAD_INCLUDE_DIR}
            ${OPENSSL_INCLUDE_DIR})
link_directories(${mosquitto_BINARY_DIR}/lib)
set(shared_src client_shared.c client_shared.h client_props.c)
if (WITH_SRV)
    add_definitions("-DWITH_SRV")
endif (WITH_SRV)
add_executable(mosquitto_pub pub_client.c pub_shared.c ${shared_src})
add_executable(mosquitto_sub sub_client.c sub_client_output.c ${shared_src})
add_executable(mosquitto_rr rr_client.c pub_shared.c sub_client_output.c ${shared_src})
target_link_libraries(mosquitto_pub libmosquitto)
target_link_libraries(mosquitto_sub libmosquitto)
target_link_libraries(mosquitto_rr libmosquitto)
if (QNX)
    target_link_libraries(mosquitto_pub socket)
    target_link_libraries(mosquitto_sub socket)
    target_link_libraries(mosquitto_rr socket)
endif()
install(TARGETS mosquitto_pub RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS mosquitto_sub RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(TARGETS mosquitto_rr RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/Makefile
New file
@@ -0,0 +1,82 @@
include ../config.mk
.PHONY: all install uninstall reallyclean clean static static_pub static_sub static_rr
ifeq ($(WITH_SHARED_LIBRARIES),yes)
SHARED_DEP:=../lib/libmosquitto.so.${SOVERSION}
endif
ifeq ($(WITH_SHARED_LIBRARIES),yes)
ALL_DEPS:= mosquitto_pub mosquitto_sub mosquitto_rr
else
ifeq ($(WITH_STATIC_LIBRARIES),yes)
ALL_DEPS:= static_pub static_sub static_rr
endif
endif
all : ${ALL_DEPS}
static : static_pub static_sub static_rr
    # This makes mosquitto_pub/sub/rr versions that are statically linked with
    # libmosquitto only.
static_pub : pub_client.o pub_shared.o client_props.o client_shared.o ../lib/libmosquitto.a
    ${CROSS_COMPILE}${CC} $^ -o mosquitto_pub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
static_sub : sub_client.o sub_client_output.o client_props.o client_shared.o ../lib/libmosquitto.a
    ${CROSS_COMPILE}${CC} $^ -o mosquitto_sub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
static_rr : rr_client.o client_props.o client_shared.o pub_shared.o sub_client_output.o ../lib/libmosquitto.a
    ${CROSS_COMPILE}${CC} $^ -o mosquitto_rr ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
mosquitto_pub : pub_client.o pub_shared.o client_shared.o client_props.o
    ${CROSS_COMPILE}${CC} $(CLIENT_LDFLAGS) $^ -o $@ $(CLIENT_LDADD)
mosquitto_sub : sub_client.o sub_client_output.o client_shared.o client_props.o
    ${CROSS_COMPILE}${CC} $(CLIENT_LDFLAGS) $^ -o $@ $(CLIENT_LDADD)
mosquitto_rr : rr_client.o client_shared.o client_props.o pub_shared.o sub_client_output.o
    ${CROSS_COMPILE}${CC} $(CLIENT_LDFLAGS) $^ -o $@ $(CLIENT_LDADD)
pub_client.o : pub_client.c ${SHARED_DEP}
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
pub_shared.o : pub_shared.c ${SHARED_DEP}
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
sub_client.o : sub_client.c ${SHARED_DEP}
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
sub_client_output.o : sub_client_output.c ${SHARED_DEP}
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
rr_client.o : rr_client.c ${SHARED_DEP}
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
client_shared.o : client_shared.c client_shared.h
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
client_props.o : client_props.c client_shared.h
    ${CROSS_COMPILE}${CC} $(CLIENT_CPPFLAGS) $(CLIENT_CFLAGS) -c $< -o $@
../lib/libmosquitto.so.${SOVERSION} :
    $(MAKE) -C ../lib
../lib/libmosquitto.a :
    $(MAKE) -C ../lib libmosquitto.a
install : all
    $(INSTALL) -d "${DESTDIR}$(prefix)/bin"
    $(INSTALL) ${STRIP_OPTS} mosquitto_pub "${DESTDIR}${prefix}/bin/mosquitto_pub"
    $(INSTALL) ${STRIP_OPTS} mosquitto_sub "${DESTDIR}${prefix}/bin/mosquitto_sub"
    $(INSTALL) ${STRIP_OPTS} mosquitto_rr "${DESTDIR}${prefix}/bin/mosquitto_rr"
uninstall :
    -rm -f "${DESTDIR}${prefix}/bin/mosquitto_pub"
    -rm -f "${DESTDIR}${prefix}/bin/mosquitto_sub"
    -rm -f "${DESTDIR}${prefix}/bin/mosquitto_rr"
reallyclean : clean
clean :
    -rm -f *.o mosquitto_pub mosquitto_sub mosquitto_rr *.gcda *.gcno
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_props.c
New file
@@ -0,0 +1,193 @@
/*
Copyright (c) 2018 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 "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#include <strings.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#define strncasecmp _strnicmp
#endif
#include "mosquitto.h"
#include "mqtt_protocol.h"
#include "client_shared.h"
enum prop_type
{
    PROP_TYPE_BYTE,
    PROP_TYPE_INT16,
    PROP_TYPE_INT32,
    PROP_TYPE_BINARY,
    PROP_TYPE_STRING,
    PROP_TYPE_STRING_PAIR
};
/* This parses property inputs. It should work for any command type, but is limited at the moment.
 *
 * Format:
 *
 * command property value
 * command property key value
 *
 * Example:
 *
 * publish message-expiry-interval 32
 * connect user-property key value
 */
int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx)
{
    char *cmdname = NULL, *propname = NULL;
    char *key = NULL, *value = NULL;
    int cmd, identifier, type;
    mosquitto_property **proplist;
    int rc;
    /* idx now points to "command" */
    if((*idx)+2 > argc-1){
        /* Not enough args */
        fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
        return MOSQ_ERR_INVAL;
    }
    cmdname = argv[*idx];
    if(mosquitto_string_to_command(cmdname, &cmd)){
        fprintf(stderr, "Error: Invalid command given in --property argument.\n\n");
        return MOSQ_ERR_INVAL;
    }
    propname = argv[(*idx)+1];
    if(mosquitto_string_to_property_info(propname, &identifier, &type)){
        fprintf(stderr, "Error: Invalid property name given in --property argument.\n\n");
        return MOSQ_ERR_INVAL;
    }
    if(mosquitto_property_check_command(cmd, identifier)){
        fprintf(stderr, "Error: %s property not allow for %s in --property argument.\n\n", propname, cmdname);
        return MOSQ_ERR_INVAL;
    }
    if(identifier == MQTT_PROP_USER_PROPERTY){
        if((*idx)+3 > argc-1){
            /* Not enough args */
            fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
            return MOSQ_ERR_INVAL;
        }
        key = argv[(*idx)+2];
        value = argv[(*idx)+3];
        (*idx) += 3;
    }else{
        value = argv[(*idx)+2];
        (*idx) += 2;
    }
    switch(cmd){
        case CMD_CONNECT:
            proplist = &cfg->connect_props;
            break;
        case CMD_PUBLISH:
            if(identifier == MQTT_PROP_TOPIC_ALIAS){
                cfg->have_topic_alias = true;
            }
            if(identifier == MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
                fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
                return MOSQ_ERR_INVAL;
            }
            proplist = &cfg->publish_props;
            break;
        case CMD_SUBSCRIBE:
            if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER && identifier != MQTT_PROP_USER_PROPERTY){
                fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
                return MOSQ_ERR_NOT_SUPPORTED;
            }
            proplist = &cfg->subscribe_props;
            break;
        case CMD_UNSUBSCRIBE:
            proplist = &cfg->unsubscribe_props;
            break;
        case CMD_DISCONNECT:
            proplist = &cfg->disconnect_props;
            break;
        case CMD_AUTH:
            fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
            return MOSQ_ERR_NOT_SUPPORTED;
        case CMD_WILL:
            proplist = &cfg->will_props;
            break;
        case CMD_PUBACK:
        case CMD_PUBREC:
        case CMD_PUBREL:
        case CMD_PUBCOMP:
        case CMD_SUBACK:
        case CMD_UNSUBACK:
            fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
            return MOSQ_ERR_NOT_SUPPORTED;
        default:
            return MOSQ_ERR_INVAL;
    }
    switch(type){
        case MQTT_PROP_TYPE_BYTE:
            rc = mosquitto_property_add_byte(proplist, identifier, atoi(value));
            break;
        case MQTT_PROP_TYPE_INT16:
            rc = mosquitto_property_add_int16(proplist, identifier, atoi(value));
            break;
        case MQTT_PROP_TYPE_INT32:
            rc = mosquitto_property_add_int32(proplist, identifier, atoi(value));
            break;
        case MQTT_PROP_TYPE_VARINT:
            rc = mosquitto_property_add_varint(proplist, identifier, atoi(value));
            break;
        case MQTT_PROP_TYPE_BINARY:
            rc = mosquitto_property_add_binary(proplist, identifier, value, strlen(value));
            break;
        case MQTT_PROP_TYPE_STRING:
            rc = mosquitto_property_add_string(proplist, identifier, value);
            break;
        case MQTT_PROP_TYPE_STRING_PAIR:
            rc = mosquitto_property_add_string_pair(proplist, identifier, key, value);
            break;
        default:
            return MOSQ_ERR_INVAL;
    }
    if(rc){
        fprintf(stderr, "Error adding property %s %d\n", propname, type);
        return rc;
    }
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_props.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.c
New file
@@ -0,0 +1,1449 @@
/*
Copyright (c) 2014-2019 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 "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#include <strings.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#define strncasecmp _strnicmp
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
#ifdef WITH_SOCKS
static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url);
#endif
static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]);
static int check_format(const char *str)
{
    int i;
    int len;
    len = strlen(str);
    for(i=0; i<len; i++){
        if(str[i] == '%'){
            if(i == len-1){
                // error
                fprintf(stderr, "Error: Incomplete format specifier.\n");
                return 1;
            }else{
                if(str[i+1] == '%'){
                    // Print %, ignore
                }else if(str[i+1] == 'I'){
                    // ISO 8601 date+time
                }else if(str[i+1] == 'l'){
                    // payload length
                }else if(str[i+1] == 'm'){
                    // mid
                }else if(str[i+1] == 'p'){
                    // payload
                }else if(str[i+1] == 'q'){
                    // qos
                }else if(str[i+1] == 'r'){
                    // retain
                }else if(str[i+1] == 't'){
                    // topic
                }else if(str[i+1] == 'j'){
                    // JSON output, escaped payload
                }else if(str[i+1] == 'J'){
                    // JSON output, assuming JSON payload
                }else if(str[i+1] == 'U'){
                    // Unix time+nanoseconds
                }else if(str[i+1] == 'x' || str[i+1] == 'X'){
                    // payload in hex
                }else{
                    fprintf(stderr, "Error: Invalid format specifier '%c'.\n", str[i+1]);
                    return 1;
                }
                i++;
            }
        }else if(str[i] == '@'){
            if(i == len-1){
                // error
                fprintf(stderr, "Error: Incomplete format specifier.\n");
                return 1;
            }
            i++;
        }else if(str[i] == '\\'){
            if(i == len-1){
                // error
                fprintf(stderr, "Error: Incomplete escape specifier.\n");
                return 1;
            }else{
                switch(str[i+1]){
                    case '\\': // '\'
                    case '0':  // 0 (NULL)
                    case 'a':  // alert
                    case 'e':  // escape
                    case 'n':  // new line
                    case 'r':  // carriage return
                    case 't':  // horizontal tab
                    case 'v':  // vertical tab
                        break;
                    default:
                        fprintf(stderr, "Error: Invalid escape specifier '%c'.\n", str[i+1]);
                        return 1;
                }
                i++;
            }
        }
    }
    return 0;
}
void init_config(struct mosq_config *cfg, int pub_or_sub)
{
    memset(cfg, 0, sizeof(*cfg));
    cfg->port = -1;
    cfg->max_inflight = 20;
    cfg->keepalive = 60;
    cfg->clean_session = true;
    cfg->eol = true;
    cfg->repeat_count = 1;
    cfg->repeat_delay.tv_sec = 0;
    cfg->repeat_delay.tv_usec = 0;
    if(pub_or_sub == CLIENT_RR){
        cfg->protocol_version = MQTT_PROTOCOL_V5;
        cfg->msg_count = 1;
    }else{
        cfg->protocol_version = MQTT_PROTOCOL_V311;
    }
}
void client_config_cleanup(struct mosq_config *cfg)
{
    int i;
    free(cfg->id);
    free(cfg->id_prefix);
    free(cfg->host);
    free(cfg->file_input);
    free(cfg->message);
    free(cfg->topic);
    free(cfg->bind_address);
    free(cfg->username);
    free(cfg->password);
    free(cfg->will_topic);
    free(cfg->will_payload);
    free(cfg->format);
    free(cfg->response_topic);
#ifdef WITH_TLS
    free(cfg->cafile);
    free(cfg->capath);
    free(cfg->certfile);
    free(cfg->keyfile);
    free(cfg->ciphers);
    free(cfg->tls_alpn);
    free(cfg->tls_version);
    free(cfg->tls_engine);
    free(cfg->tls_engine_kpass_sha1);
    free(cfg->keyform);
#  ifdef FINAL_WITH_TLS_PSK
    free(cfg->psk);
    free(cfg->psk_identity);
#  endif
#endif
    if(cfg->topics){
        for(i=0; i<cfg->topic_count; i++){
            free(cfg->topics[i]);
        }
        free(cfg->topics);
    }
    if(cfg->filter_outs){
        for(i=0; i<cfg->filter_out_count; i++){
            free(cfg->filter_outs[i]);
        }
        free(cfg->filter_outs);
    }
    if(cfg->unsub_topics){
        for(i=0; i<cfg->unsub_topic_count; i++){
            free(cfg->unsub_topics[i]);
        }
        free(cfg->unsub_topics);
    }
#ifdef WITH_SOCKS
    free(cfg->socks5_host);
    free(cfg->socks5_username);
    free(cfg->socks5_password);
#endif
    mosquitto_property_free_all(&cfg->connect_props);
    mosquitto_property_free_all(&cfg->publish_props);
    mosquitto_property_free_all(&cfg->subscribe_props);
    mosquitto_property_free_all(&cfg->unsubscribe_props);
    mosquitto_property_free_all(&cfg->disconnect_props);
    mosquitto_property_free_all(&cfg->will_props);
}
int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[])
{
    int rc;
    FILE *fptr;
    char line[1024];
    int count;
    char *loc = NULL;
    int len;
    char *args[3];
#ifndef WIN32
    char *env;
#else
    char env[1024];
#endif
    args[0] = NULL;
    init_config(cfg, pub_or_sub);
    /* Default config file */
#ifndef WIN32
    env = getenv("XDG_CONFIG_HOME");
    if(env){
        len = strlen(env) + strlen("/mosquitto_pub") + 1;
        loc = malloc(len);
        if(!loc){
            err_printf(cfg, "Error: Out of memory.\n");
            return 1;
        }
        if(pub_or_sub == CLIENT_PUB){
            snprintf(loc, len, "%s/mosquitto_pub", env);
        }else if(pub_or_sub == CLIENT_SUB){
            snprintf(loc, len, "%s/mosquitto_sub", env);
        }else{
            snprintf(loc, len, "%s/mosquitto_rr", env);
        }
        loc[len-1] = '\0';
    }else{
        env = getenv("HOME");
        if(env){
            len = strlen(env) + strlen("/.config/mosquitto_pub") + 1;
            loc = malloc(len);
            if(!loc){
                err_printf(cfg, "Error: Out of memory.\n");
                return 1;
            }
            if(pub_or_sub == CLIENT_PUB){
                snprintf(loc, len, "%s/.config/mosquitto_pub", env);
            }else if(pub_or_sub == CLIENT_SUB){
                snprintf(loc, len, "%s/.config/mosquitto_sub", env);
            }else{
                snprintf(loc, len, "%s/.config/mosquitto_rr", env);
            }
            loc[len-1] = '\0';
        }
    }
#else
    rc = GetEnvironmentVariable("USERPROFILE", env, 1024);
    if(rc > 0 && rc < 1024){
        len = strlen(env) + strlen("\\mosquitto_pub.conf") + 1;
        loc = malloc(len);
        if(!loc){
            err_printf(cfg, "Error: Out of memory.\n");
            return 1;
        }
        if(pub_or_sub == CLIENT_PUB){
            snprintf(loc, len, "%s\\mosquitto_pub.conf", env);
        }else if(pub_or_sub == CLIENT_SUB){
            snprintf(loc, len, "%s\\mosquitto_sub.conf", env);
        }else{
            snprintf(loc, len, "%s\\mosquitto_rr.conf", env);
        }
        loc[len-1] = '\0';
    }
#endif
    if(loc){
        fptr = fopen(loc, "rt");
        if(fptr){
            while(fgets(line, 1024, fptr)){
                if(line[0] == '#') continue; /* Comments */
                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);
    }
    /* 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;
    }
    if(cfg->will_retain && !cfg->will_topic){
        fprintf(stderr, "Error: Will retain given, but no will topic given.\n");
        return 1;
    }
#ifdef WITH_TLS
    if((cfg->certfile && !cfg->keyfile) || (cfg->keyfile && !cfg->certfile)){
        fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is set.\n");
        return 1;
    }
    if((cfg->keyform && !cfg->keyfile)){
        fprintf(stderr, "Error: If keyform is set, keyfile must be also specified.\n");
        return 1;
    }
    if((cfg->tls_engine_kpass_sha1 && (!cfg->keyform || !cfg->tls_engine))){
        fprintf(stderr, "Error: when using tls-engine-kpass-sha1, both tls-engine and keyform must also be provided.\n");
        return 1;
    }
#endif
#ifdef FINAL_WITH_TLS_PSK
    if((cfg->cafile || cfg->capath) && cfg->psk){
        fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n");
        return 1;
    }
    if(cfg->psk && !cfg->psk_identity){
        fprintf(stderr, "Error: --psk-identity required if --psk used.\n");
        return 1;
    }
#endif
    if(cfg->clean_session == false && (cfg->id_prefix || !cfg->id)){
        fprintf(stderr, "Error: You must provide a client id if you are using the -c option.\n");
        return 1;
    }
    if(pub_or_sub == CLIENT_SUB){
        if(cfg->topic_count == 0){
            fprintf(stderr, "Error: You must specify a topic to subscribe to.\n");
            return 1;
        }
    }
    if(!cfg->host){
        cfg->host = strdup("localhost");
        if(!cfg->host){
            err_printf(cfg, "Error: Out of memory.\n");
            return 1;
        }
    }
    rc = mosquitto_property_check_all(CMD_CONNECT, cfg->connect_props);
    if(rc){
        err_printf(cfg, "Error in CONNECT properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    rc = mosquitto_property_check_all(CMD_PUBLISH, cfg->publish_props);
    if(rc){
        err_printf(cfg, "Error in PUBLISH properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    rc = mosquitto_property_check_all(CMD_SUBSCRIBE, cfg->subscribe_props);
    if(rc){
        err_printf(cfg, "Error in SUBSCRIBE properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, cfg->unsubscribe_props);
    if(rc){
        err_printf(cfg, "Error in UNSUBSCRIBE properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    rc = mosquitto_property_check_all(CMD_DISCONNECT, cfg->disconnect_props);
    if(rc){
        err_printf(cfg, "Error in DISCONNECT properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    rc = mosquitto_property_check_all(CMD_WILL, cfg->will_props);
    if(rc){
        err_printf(cfg, "Error in Will properties: %s\n", mosquitto_strerror(rc));
        return 1;
    }
    return MOSQ_ERR_SUCCESS;
}
int cfg_add_topic(struct mosq_config *cfg, int type, char *topic, const char *arg)
{
    if(mosquitto_validate_utf8(topic, strlen(topic))){
        fprintf(stderr, "Error: Malformed UTF-8 in %s argument.\n\n", arg);
        return 1;
    }
    if(type == CLIENT_PUB || type == CLIENT_RR){
        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(type == CLIENT_RESPONSE_TOPIC){
        if(mosquitto_pub_topic_check(topic) == MOSQ_ERR_INVAL){
            fprintf(stderr, "Error: Invalid response topic '%s', does it contain '+' or '#'?\n", topic);
            return 1;
        }
        cfg->response_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){
            err_printf(cfg, "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[])
{
    int i;
    float f;
    for(i=1; i<argc; i++){
        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++;
#ifdef WITH_TLS
        }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++;
#endif
        }else if(!strcmp(argv[i], "-C")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }else{
                if(i==argc-1){
                    fprintf(stderr, "Error: -C argument given but no count specified.\n\n");
                    return 1;
                }else{
                    cfg->msg_count = atoi(argv[i+1]);
                    if(cfg->msg_count < 1){
                        fprintf(stderr, "Error: Invalid message count \"%d\".\n\n", cfg->msg_count);
                        return 1;
                    }
                }
                i++;
            }
        }else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--disable-clean-session")){
            cfg->clean_session = false;
        }else if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")){
            cfg->debug = true;
        }else if(!strcmp(argv[i], "-D") || !strcmp(argv[i], "--property")){
            i++;
            if(cfg_parse_property(cfg, argc, argv, &i)){
                return 1;
            }
            cfg->protocol_version = MQTT_PROTOCOL_V5;
        }else if(!strcmp(argv[i], "-e")){
            if(pub_or_sub != CLIENT_RR){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: -e argument given but no response topic specified.\n\n");
                return 1;
            }else{
                if(cfg_add_topic(cfg, CLIENT_RESPONSE_TOPIC, argv[i+1], "-e")){
                    return 1;
                }
            }
            i++;
        }else if(!strcmp(argv[i], "-E")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }
            cfg->exit_after_sub = 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]);
                if(!cfg->file_input){
                    err_printf(cfg, "Error: Out of memory.\n");
                    return 1;
                }
            }
            i++;
        }else if(!strcmp(argv[i], "-F")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: -F argument given but no format specified.\n\n");
                return 1;
            }else{
                cfg->format = strdup(argv[i+1]);
                if(!cfg->format){
                    fprintf(stderr, "Error: Out of memory.\n");
                    return 1;
                }
                if(check_format(cfg->format)){
                    return 1;
                }
            }
            i++;
        }else if(!strcmp(argv[i], "--help")){
            return 2;
        }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++;
#ifdef WITH_TLS
        }else if(!strcmp(argv[i], "--insecure")){
            cfg->insecure = true;
#endif
        }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++;
#ifdef WITH_TLS
        }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], "--keyform")){
            if(i==argc-1){
                fprintf(stderr, "Error: --keyform argument given but no keyform specified.\n\n");
                return 1;
            }else{
                cfg->keyform = strdup(argv[i+1]);
            }
            i++;
#endif
        }else if(!strcmp(argv[i], "-L") || !strcmp(argv[i], "--url")){
            if(i==argc-1){
                fprintf(stderr, "Error: -L 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;
                    cfg->port = 1883;
                } 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, '/');
                if(!topic){
                    fprintf(stderr, "Error: Invalid URL for -L argument specified - topic missing.\n");
                    return 1;
                }
                *topic++ = 0;
                if(cfg_add_topic(cfg, pub_or_sub, topic, "-L topic"))
                    return 1;
                tmp = strchr(url, '@');
                if(tmp) {
                    *tmp++ = 0;
                    char *colon = strchr(url, ':');
                    if(colon) {
                        *colon = 0;
                        cfg->password = strdup(colon + 1);
                    }
                    cfg->username = strdup(url);
                    url = tmp;
                }
                cfg->host = url;
                tmp = strchr(url, ':');
                if(tmp) {
                    *tmp++ = 0;
                    cfg->port = atoi(tmp);
                }
                /* Now we've removed the port, time to get the host on the heap */
                cfg->host = strdup(cfg->host);
            }
            i++;
        }else if(!strcmp(argv[i], "-l") || !strcmp(argv[i], "--stdin-line")){
            if(pub_or_sub != CLIENT_PUB){
                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], "-N")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }
            cfg->eol = false;
        }else 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");
                return 1;
            }else{
                cfg->port = 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], "-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++;
#ifdef WITH_SOCKS
        }else if(!strcmp(argv[i], "--proxy")){
            if(i==argc-1){
                fprintf(stderr, "Error: --proxy argument given but no proxy url specified.\n\n");
                return 1;
            }else{
                if(mosquitto__parse_socks_url(cfg, argv[i+1])){
                    return 1;
                }
                i++;
            }
#endif
#ifdef FINAL_WITH_TLS_PSK
        }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++;
#endif
        }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_PUB){
                goto unknown_option;
            }
            cfg->retain = 1;
        }else if(!strcmp(argv[i], "-R")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }
            cfg->no_retain = true;
            cfg->sub_opts |= MQTT_SUB_OPT_SEND_RETAIN_NEVER;
        }else if(!strcmp(argv[i], "--remove-retained")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }
            cfg->remove_retained = true;
        }else if(!strcmp(argv[i], "--repeat")){
            if(pub_or_sub != CLIENT_PUB){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: --repeat argument given but no count specified.\n\n");
                return 1;
            }else{
                cfg->repeat_count = atoi(argv[i+1]);
                if(cfg->repeat_count < 1){
                    fprintf(stderr, "Error: --repeat argument must be >0.\n\n");
                    return 1;
                }
            }
            i++;
        }else if(!strcmp(argv[i], "--repeat-delay")){
            if(pub_or_sub != CLIENT_PUB){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: --repeat-delay argument given but no time specified.\n\n");
                return 1;
            }else{
                f = atof(argv[i+1]);
                if(f < 0.0f){
                    fprintf(stderr, "Error: --repeat-delay argument must be >=0.0.\n\n");
                    return 1;
                }
                f *= 1.0e6;
                cfg->repeat_delay.tv_sec = (int)f/1e6;
                cfg->repeat_delay.tv_usec = (int)f%1000000;
            }
            i++;
        }else if(!strcmp(argv[i], "--retain-as-published")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }
            cfg->sub_opts |= MQTT_SUB_OPT_RETAIN_AS_PUBLISHED;
        }else if(!strcmp(argv[i], "--retained-only")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }
            cfg->retained_only = true;
        }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;
            }
#ifdef WITH_SRV
        }else if(!strcmp(argv[i], "-S")){
            cfg->use_srv = true;
#endif
        }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(cfg_add_topic(cfg, pub_or_sub, argv[i + 1], "-t"))
                    return 1;
                i++;
            }
        }else if(!strcmp(argv[i], "-T") || !strcmp(argv[i], "--filter-out")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: -T argument given but no topic filter specified.\n\n");
                return 1;
            }else{
                if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){
                    fprintf(stderr, "Error: Malformed UTF-8 in -T argument.\n\n");
                    return 1;
                }
                if(mosquitto_sub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){
                    fprintf(stderr, "Error: Invalid filter topic '%s', are all '+' and '#' wildcards correct?\n", argv[i+1]);
                    return 1;
                }
                cfg->filter_out_count++;
                cfg->filter_outs = realloc(cfg->filter_outs, cfg->filter_out_count*sizeof(char *));
                if(!cfg->filter_outs){
                    fprintf(stderr, "Error: Out of memory.\n");
                    return 1;
                }
                cfg->filter_outs[cfg->filter_out_count-1] = strdup(argv[i+1]);
            }
            i++;
#ifdef WITH_TLS
        }else if(!strcmp(argv[i], "--tls-alpn")){
            if(i==argc-1){
                fprintf(stderr, "Error: --tls-alpn argument given but no protocol specified.\n\n");
                return 1;
            }else{
                cfg->tls_alpn = strdup(argv[i+1]);
            }
            i++;
        }else if(!strcmp(argv[i], "--tls-engine")){
            if(i==argc-1){
                fprintf(stderr, "Error: --tls-engine argument given but no engine_id specified.\n\n");
                return 1;
            }else{
                cfg->tls_engine = strdup(argv[i+1]);
            }
            i++;
        }else if(!strcmp(argv[i], "--tls-engine-kpass-sha1")){
            if(i==argc-1){
                fprintf(stderr, "Error: --tls-engine-kpass-sha1 argument given but no kpass sha1 specified.\n\n");
                return 1;
            }else{
                cfg->tls_engine_kpass_sha1 = 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++;
#endif
        }else if(!strcmp(argv[i], "-U") || !strcmp(argv[i], "--unsubscribe")){
            if(pub_or_sub != CLIENT_SUB){
                goto unknown_option;
            }
            if(i==argc-1){
                fprintf(stderr, "Error: -U argument given but no unsubscribe topic specified.\n\n");
                return 1;
            }else{
                if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){
                    fprintf(stderr, "Error: Malformed UTF-8 in -U argument.\n\n");
                    return 1;
                }
                if(mosquitto_sub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){
                    fprintf(stderr, "Error: Invalid unsubscribe topic '%s', are all '+' and '#' wildcards correct?\n", argv[i+1]);
                    return 1;
                }
                cfg->unsub_topic_count++;
                cfg->unsub_topics = realloc(cfg->unsub_topics, cfg->unsub_topic_count*sizeof(char *));
                if(!cfg->unsub_topics){
                    fprintf(stderr, "Error: Out of memory.\n");
                    return 1;
                }
                cfg->unsub_topics[cfg->unsub_topic_count-1] = 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], "-V") || !strcmp(argv[i], "--protocol-version")){
            if(i==argc-1){
                fprintf(stderr, "Error: --protocol-version argument given but no version specified.\n\n");
                return 1;
            }else{
                if(!strcmp(argv[i+1], "mqttv31") || !strcmp(argv[i+1], "31")){
                    cfg->protocol_version = MQTT_PROTOCOL_V31;
                }else if(!strcmp(argv[i+1], "mqttv311") || !strcmp(argv[i+1], "311")){
                    cfg->protocol_version = MQTT_PROTOCOL_V311;
                }else if(!strcmp(argv[i+1], "mqttv5") || !strcmp(argv[i+1], "5")){
                    cfg->protocol_version = MQTT_PROTOCOL_V5;
                }else{
                    fprintf(stderr, "Error: Invalid protocol version argument given.\n\n");
                    return 1;
                }
                i++;
            }
        }else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }
            cfg->verbose = 1;
        }else if(!strcmp(argv[i], "-W")){
            if(pub_or_sub == CLIENT_PUB){
                goto unknown_option;
            }else{
                if(i==argc-1){
                    fprintf(stderr, "Error: -W argument given but no timeout specified.\n\n");
                    return 1;
                }else{
                    cfg->timeout = atoi(argv[i+1]);
                    if(cfg->timeout < 1){
                        fprintf(stderr, "Error: Invalid timeout \"%d\".\n\n", cfg->msg_count);
                        return 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{
                if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){
                    fprintf(stderr, "Error: Malformed UTF-8 in --will-topic argument.\n\n");
                    return 1;
                }
                if(mosquitto_pub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){
                    fprintf(stderr, "Error: Invalid will topic '%s', does it contain '+' or '#'?\n", argv[i+1]);
                    return 1;
                }
                cfg->will_topic = strdup(argv[i+1]);
            }
            i++;
        }else{
            goto unknown_option;
        }
    }
    return MOSQ_ERR_SUCCESS;
unknown_option:
    fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]);
    return 1;
}
int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
{
#if defined(WITH_TLS) || defined(WITH_SOCKS)
    int rc;
#endif
    mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, cfg->protocol_version);
    if(cfg->will_topic && mosquitto_will_set_v5(mosq, cfg->will_topic,
                cfg->will_payloadlen, cfg->will_payload, cfg->will_qos,
                cfg->will_retain, cfg->will_props)){
        err_printf(cfg, "Error: Problem setting will.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
    cfg->will_props = NULL;
    if((cfg->username || cfg->password) && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){
        err_printf(cfg, "Error: Problem setting username and/or password.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
#ifdef WITH_TLS
    if(cfg->cafile || cfg->capath){
        rc = mosquitto_tls_set(mosq, cfg->cafile, cfg->capath, cfg->certfile, cfg->keyfile, NULL);
        if(rc){
            if(rc == MOSQ_ERR_INVAL){
                err_printf(cfg, "Error: Problem setting TLS options: File not found.\n");
            }else{
                err_printf(cfg, "Error: Problem setting TLS options: %s.\n", mosquitto_strerror(rc));
            }
            mosquitto_lib_cleanup();
            return 1;
        }
    }
    if(cfg->insecure && mosquitto_tls_insecure_set(mosq, true)){
        err_printf(cfg, "Error: Problem setting TLS insecure option.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
    if(cfg->tls_engine && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE, cfg->tls_engine)){
        err_printf(cfg, "Error: Problem setting TLS engine, is %s a valid engine?\n", cfg->tls_engine);
        mosquitto_lib_cleanup();
        return 1;
    }
    if(cfg->keyform && mosquitto_string_option(mosq, MOSQ_OPT_TLS_KEYFORM, cfg->keyform)){
        err_printf(cfg, "Error: Problem setting key form, it must be one of 'pem' or 'engine'.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
    if(cfg->tls_engine_kpass_sha1 && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ENGINE_KPASS_SHA1, cfg->tls_engine_kpass_sha1)){
        err_printf(cfg, "Error: Problem setting TLS engine key pass sha, is it a 40 character hex string?\n");
        mosquitto_lib_cleanup();
        return 1;
    }
    if(cfg->tls_alpn && mosquitto_string_option(mosq, MOSQ_OPT_TLS_ALPN, cfg->tls_alpn)){
        err_printf(cfg, "Error: Problem setting TLS ALPN protocol.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
#  ifdef FINAL_WITH_TLS_PSK
    if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
        err_printf(cfg, "Error: Problem setting TLS-PSK options.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
#  endif
    if((cfg->tls_version || cfg->ciphers) && mosquitto_tls_opts_set(mosq, 1, cfg->tls_version, cfg->ciphers)){
        err_printf(cfg, "Error: Problem setting TLS options, check the options are valid.\n");
        mosquitto_lib_cleanup();
        return 1;
    }
#endif
    mosquitto_max_inflight_messages_set(mosq, cfg->max_inflight);
#ifdef WITH_SOCKS
    if(cfg->socks5_host){
        rc = mosquitto_socks5_set(mosq, cfg->socks5_host, cfg->socks5_port, cfg->socks5_username, cfg->socks5_password);
        if(rc){
            mosquitto_lib_cleanup();
            return rc;
        }
    }
#endif
    return MOSQ_ERR_SUCCESS;
}
int client_id_generate(struct mosq_config *cfg)
{
    if(cfg->id_prefix){
        cfg->id = malloc(strlen(cfg->id_prefix)+10);
        if(!cfg->id){
            err_printf(cfg, "Error: Out of memory.\n");
            mosquitto_lib_cleanup();
            return 1;
        }
        snprintf(cfg->id, strlen(cfg->id_prefix)+10, "%s%d", cfg->id_prefix, getpid());
    }
    return MOSQ_ERR_SUCCESS;
}
int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
{
#ifndef WIN32
    char *err;
#else
    char err[1024];
#endif
    int rc;
    int port;
    if(cfg->port < 0){
#ifdef WITH_TLS
        if(cfg->cafile || cfg->capath
#  ifdef FINAL_WITH_TLS_PSK
                || cfg->psk
#  endif
                ){
            port = 8883;
        }else
#endif
        {
            port = 1883;
        }
    }else{
        port = cfg->port;
    }
#ifdef WITH_SRV
    if(cfg->use_srv){
        rc = mosquitto_connect_srv(mosq, cfg->host, cfg->keepalive, cfg->bind_address);
    }else{
        rc = mosquitto_connect_bind_v5(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address, cfg->connect_props);
    }
#else
    rc = mosquitto_connect_bind_v5(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address, cfg->connect_props);
#endif
    if(rc>0){
        if(rc == MOSQ_ERR_ERRNO){
#ifndef WIN32
            err = strerror(errno);
#else
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL);
#endif
            err_printf(cfg, "Error: %s\n", err);
        }else{
            err_printf(cfg, "Unable to connect (%s).\n", mosquitto_strerror(rc));
        }
        mosquitto_lib_cleanup();
        return rc;
    }
    return MOSQ_ERR_SUCCESS;
}
#ifdef WITH_SOCKS
/* Convert %25 -> %, %3a, %3A -> :, %40 -> @ */
static int mosquitto__urldecode(char *str)
{
    int i, j;
    int len;
    if(!str) return 0;
    if(!strchr(str, '%')) return 0;
    len = strlen(str);
    for(i=0; i<len; i++){
        if(str[i] == '%'){
            if(i+2 >= len){
                return 1;
            }
            if(str[i+1] == '2' && str[i+2] == '5'){
                str[i] = '%';
                len -= 2;
                for(j=i+1; j<len; j++){
                    str[j] = str[j+2];
                }
                str[j] = '\0';
            }else if(str[i+1] == '3' && (str[i+2] == 'A' || str[i+2] == 'a')){
                str[i] = ':';
                len -= 2;
                for(j=i+1; j<len; j++){
                    str[j] = str[j+2];
                }
                str[j] = '\0';
            }else if(str[i+1] == '4' && str[i+2] == '0'){
                str[i] = ':';
                len -= 2;
                for(j=i+1; j<len; j++){
                    str[j] = str[j+2];
                }
                str[j] = '\0';
            }else{
                return 1;
            }
        }
    }
    return 0;
}
static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url)
{
    char *str;
    size_t i;
    char *username = NULL, *password = NULL, *host = NULL, *port = NULL;
    char *username_or_host = NULL;
    size_t start;
    size_t len;
    bool have_auth = false;
    int port_int;
    if(!strncmp(url, "socks5h://", strlen("socks5h://"))){
        str = url + strlen("socks5h://");
    }else{
        err_printf(cfg, "Error: Unsupported proxy protocol: %s\n", url);
        return 1;
    }
    // socks5h://username:password@host:1883
    // socks5h://username:password@host
    // socks5h://username@host:1883
    // socks5h://username@host
    // socks5h://host:1883
    // socks5h://host
    start = 0;
    for(i=0; i<strlen(str); i++){
        if(str[i] == ':'){
            if(i == start){
                goto cleanup;
            }
            if(have_auth){
                /* Have already seen a @ , so this must be of form
                 * socks5h://username[:password]@host:port */
                if(host){
                    /* Already seen a host, must be malformed. */
                    goto cleanup;
                }
                len = i-start;
                host = malloc(len + 1);
                if(!host){
                    err_printf(cfg, "Error: Out of memory.\n");
                    goto cleanup;
                }
                memcpy(host, &(str[start]), len);
                host[len] = '\0';
                start = i+1;
            }else if(!username_or_host){
                /* Haven't seen a @ before, so must be of form
                 * socks5h://host:port or
                 * socks5h://username:password@host[:port] */
                len = i-start;
                username_or_host = malloc(len + 1);
                if(!username_or_host){
                    err_printf(cfg, "Error: Out of memory.\n");
                    goto cleanup;
                }
                memcpy(username_or_host, &(str[start]), len);
                username_or_host[len] = '\0';
                start = i+1;
            }
        }else if(str[i] == '@'){
            if(i == start){
                goto cleanup;
            }
            have_auth = true;
            if(username_or_host){
                /* Must be of form socks5h://username:password@... */
                username = username_or_host;
                username_or_host = NULL;
                len = i-start;
                password = malloc(len + 1);
                if(!password){
                    err_printf(cfg, "Error: Out of memory.\n");
                    goto cleanup;
                }
                memcpy(password, &(str[start]), len);
                password[len] = '\0';
                start = i+1;
            }else{
                /* Haven't seen a : yet, so must be of form
                 * socks5h://username@... */
                if(username){
                    /* Already got a username, must be malformed. */
                    goto cleanup;
                }
                len = i-start;
                username = malloc(len + 1);
                if(!username){
                    err_printf(cfg, "Error: Out of memory.\n");
                    goto cleanup;
                }
                memcpy(username, &(str[start]), len);
                username[len] = '\0';
                start = i+1;
            }
        }
    }
    /* Deal with remainder */
    if(i > start){
        len = i-start;
        if(host){
            /* Have already seen a @ , so this must be of form
             * socks5h://username[:password]@host:port */
            port = malloc(len + 1);
            if(!port){
                err_printf(cfg, "Error: Out of memory.\n");
                goto cleanup;
            }
            memcpy(port, &(str[start]), len);
            port[len] = '\0';
        }else if(username_or_host){
            /* Haven't seen a @ before, so must be of form
             * socks5h://host:port */
            host = username_or_host;
            username_or_host = NULL;
            port = malloc(len + 1);
            if(!port){
                err_printf(cfg, "Error: Out of memory.\n");
                goto cleanup;
            }
            memcpy(port, &(str[start]), len);
            port[len] = '\0';
        }else{
            host = malloc(len + 1);
            if(!host){
                err_printf(cfg, "Error: Out of memory.\n");
                goto cleanup;
            }
            memcpy(host, &(str[start]), len);
            host[len] = '\0';
        }
    }
    if(!host){
        err_printf(cfg, "Error: Invalid proxy.\n");
        goto cleanup;
    }
    if(mosquitto__urldecode(username)){
        goto cleanup;
    }
    if(mosquitto__urldecode(password)){
        goto cleanup;
    }
    if(port){
        port_int = atoi(port);
        if(port_int < 1 || port_int > 65535){
            err_printf(cfg, "Error: Invalid proxy port %d\n", port_int);
            goto cleanup;
        }
        free(port);
    }else{
        port_int = 1080;
    }
    cfg->socks5_username = username;
    cfg->socks5_password = password;
    cfg->socks5_host = host;
    cfg->socks5_port = port_int;
    return 0;
cleanup:
    if(username_or_host) free(username_or_host);
    if(username) free(username);
    if(password) free(password);
    if(host) free(host);
    if(port) free(port);
    return 1;
}
#endif
void err_printf(const struct mosq_config *cfg, const char *fmt, ...)
{
    va_list va;
    if(cfg->quiet) return;
    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.h
New file
@@ -0,0 +1,131 @@
/*
Copyright (c) 2014-2019 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.
*/
#ifndef CLIENT_CONFIG_H
#define CLIENT_CONFIG_H
#include <stdio.h>
#ifdef WIN32
#  include <winsock2.h>
#else
#  include <sys/time.h>
#endif
/* pub_client.c modes */
#define MSGMODE_NONE 0
#define MSGMODE_CMD 1
#define MSGMODE_STDIN_LINE 2
#define MSGMODE_STDIN_FILE 3
#define MSGMODE_FILE 4
#define MSGMODE_NULL 5
#define CLIENT_PUB 1
#define CLIENT_SUB 2
#define CLIENT_RR 3
#define CLIENT_RESPONSE_TOPIC 4
struct mosq_config {
    char *id;
    char *id_prefix;
    int protocol_version;
    int keepalive;
    char *host;
    int port;
    int qos;
    bool retain;
    int pub_mode; /* pub, rr */
    char *file_input; /* pub, rr */
    char *message; /* pub, rr */
    long msglen; /* pub, rr */
    char *topic; /* pub, rr */
    char *bind_address;
    int repeat_count; /* pub */
    struct timeval repeat_delay; /* pub */
#ifdef WITH_SRV
    bool use_srv;
#endif
    bool debug;
    bool quiet;
    unsigned int max_inflight;
    char *username;
    char *password;
    char *will_topic;
    char *will_payload;
    long will_payloadlen;
    int will_qos;
    bool will_retain;
#ifdef WITH_TLS
    char *cafile;
    char *capath;
    char *certfile;
    char *keyfile;
    char *ciphers;
    bool insecure;
    char *tls_alpn;
    char *tls_version;
    char *tls_engine;
    char *tls_engine_kpass_sha1;
    char *keyform;
#  ifdef FINAL_WITH_TLS_PSK
    char *psk;
    char *psk_identity;
#  endif
#endif
    bool clean_session;
    char **topics; /* sub */
    int topic_count; /* sub */
    bool exit_after_sub; /* sub */
    bool no_retain; /* sub */
    bool retained_only; /* sub */
    bool remove_retained; /* sub */
    char **filter_outs; /* sub */
    int filter_out_count; /* sub */
    char **unsub_topics; /* sub */
    int unsub_topic_count; /* sub */
    bool verbose; /* sub */
    bool eol; /* sub */
    int msg_count; /* sub */
    char *format; /* sub */
    int timeout; /* sub */
    int sub_opts; /* sub */
#ifdef WITH_SOCKS
    char *socks5_host;
    int socks5_port;
    char *socks5_username;
    char *socks5_password;
#endif
    mosquitto_property *connect_props;
    mosquitto_property *publish_props;
    mosquitto_property *subscribe_props;
    mosquitto_property *unsubscribe_props;
    mosquitto_property *disconnect_props;
    mosquitto_property *will_props;
    bool have_topic_alias; /* pub */
    char *response_topic; /* rr */
};
int client_config_load(struct mosq_config *config, int pub_or_sub, int argc, char *argv[]);
void client_config_cleanup(struct mosq_config *cfg);
int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg);
int client_id_generate(struct mosq_config *cfg);
int client_connect(struct mosquitto *mosq, struct mosq_config *cfg);
int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx);
void err_printf(const struct mosq_config *cfg, const char *fmt, ...);
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/client_shared.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_client.c
New file
@@ -0,0 +1,537 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/time.h>
#include <time.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#include <mqtt_protocol.h>
#include <mosquitto.h>
#include "client_shared.h"
#include "pub_shared.h"
/* 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 bool first_publish = true;
static int last_mid = -1;
static int last_mid_sent = -1;
static char *line_buf = NULL;
static int line_buf_len = 1024;
static bool disconnect_sent = false;
static int publish_count = 0;
static bool ready_for_repeat = false;
#ifdef WIN32
static uint64_t next_publish_tv;
static void set_repeat_time(void)
{
    uint64_t ticks = GetTickCount64();
    next_publish_tv = ticks + cfg.repeat_delay.tv_sec*1000 + cfg.repeat_delay.tv_usec/1000;
}
static int check_repeat_time(void)
{
    uint64_t ticks = GetTickCount64();
    if(ticks > next_publish_tv){
        return 1;
    }else{
        return 0;
    }
}
#else
static struct timeval next_publish_tv;
static void set_repeat_time(void)
{
    gettimeofday(&next_publish_tv, NULL);
    next_publish_tv.tv_sec += cfg.repeat_delay.tv_sec;
    next_publish_tv.tv_usec += cfg.repeat_delay.tv_usec;
    next_publish_tv.tv_sec += next_publish_tv.tv_usec/1e6;
    next_publish_tv.tv_usec = next_publish_tv.tv_usec%1000000;
}
static int check_repeat_time(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    if(tv.tv_sec > next_publish_tv.tv_sec){
        return 1;
    }else if(tv.tv_sec == next_publish_tv.tv_sec
            && tv.tv_usec > next_publish_tv.tv_usec){
        return 1;
    }
    return 0;
}
#endif
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties)
{
    UNUSED(mosq);
    UNUSED(obj);
    UNUSED(rc);
    UNUSED(properties);
    status = STATUS_DISCONNECTED;
}
int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain)
{
    ready_for_repeat = false;
    if(cfg.protocol_version == MQTT_PROTOCOL_V5 && cfg.have_topic_alias && first_publish == false){
        return mosquitto_publish_v5(mosq, mid, NULL, payloadlen, payload, qos, retain, cfg.publish_props);
    }else{
        first_publish = false;
        return mosquitto_publish_v5(mosq, mid, topic, payloadlen, payload, qos, retain, cfg.publish_props);
    }
}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties)
{
    int rc = MOSQ_ERR_SUCCESS;
    UNUSED(obj);
    UNUSED(flags);
    UNUSED(properties);
    if(!result){
        switch(cfg.pub_mode){
            case MSGMODE_CMD:
            case MSGMODE_FILE:
            case MSGMODE_STDIN_FILE:
                rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
                break;
            case MSGMODE_NULL:
                rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
                break;
            case MSGMODE_STDIN_LINE:
                status = STATUS_CONNACK_RECVD;
                break;
        }
        if(rc){
            switch(rc){
                case MOSQ_ERR_INVAL:
                    err_printf(&cfg, "Error: Invalid input. Does your topic contain '+' or '#'?\n");
                    break;
                case MOSQ_ERR_NOMEM:
                    err_printf(&cfg, "Error: Out of memory when trying to publish message.\n");
                    break;
                case MOSQ_ERR_NO_CONN:
                    err_printf(&cfg, "Error: Client not connected when trying to publish.\n");
                    break;
                case MOSQ_ERR_PROTOCOL:
                    err_printf(&cfg, "Error: Protocol error when communicating with broker.\n");
                    break;
                case MOSQ_ERR_PAYLOAD_SIZE:
                    err_printf(&cfg, "Error: Message payload is too large.\n");
                    break;
                case MOSQ_ERR_QOS_NOT_SUPPORTED:
                    err_printf(&cfg, "Error: Message QoS not supported on broker, try a lower QoS.\n");
                    break;
            }
            mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
        }
    }else{
        if(result){
            if(cfg.protocol_version == MQTT_PROTOCOL_V5){
                err_printf(&cfg, "%s\n", mosquitto_reason_string(result));
            }else{
                err_printf(&cfg, "%s\n", mosquitto_connack_string(result));
            }
        }
    }
}
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties)
{
    UNUSED(obj);
    UNUSED(properties);
    last_mid_sent = mid;
    if(reason_code > 127){
        err_printf(&cfg, "Warning: Publish %d failed: %s.\n", mid, mosquitto_reason_string(reason_code));
    }
    publish_count++;
    if(cfg.pub_mode == MSGMODE_STDIN_LINE){
        if(mid == last_mid){
            mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
            disconnect_sent = true;
        }
    }else if(publish_count < cfg.repeat_count){
        ready_for_repeat = true;
        set_repeat_time();
    }else if(disconnect_sent == false){
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
        disconnect_sent = true;
    }
}
int pub_shared_init(void)
{
    line_buf = malloc(line_buf_len);
    if(!line_buf){
        err_printf(&cfg, "Error: Out of memory.\n");
        return 1;
    }
    return 0;
}
int pub_shared_loop(struct mosquitto *mosq)
{
    int read_len;
    int pos;
    int rc, rc2;
    char *buf2;
    int buf_len_actual;
    int mode;
    int loop_delay = 1000;
    bool stdin_finished = false;
    if(cfg.repeat_count > 1 && (cfg.repeat_delay.tv_sec == 0 || cfg.repeat_delay.tv_usec != 0)){
        loop_delay = cfg.repeat_delay.tv_usec / 2000;
    }
    mode = cfg.pub_mode;
    if(mode == MSGMODE_STDIN_LINE){
        mosquitto_loop_start(mosq);
        stdin_finished = false;
    }
    do{
        if(mode == MSGMODE_STDIN_LINE){
            if(status == STATUS_CONNACK_RECVD){
                pos = 0;
                read_len = line_buf_len;
                while(status == STATUS_CONNACK_RECVD && fgets(&line_buf[pos], read_len, stdin)){
                    buf_len_actual = strlen(line_buf);
                    if(line_buf[buf_len_actual-1] == '\n'){
                        line_buf[buf_len_actual-1] = '\0';
                        rc2 = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, line_buf, cfg.qos, cfg.retain);
                        if(rc2){
                            err_printf(&cfg, "Error: Publish returned %d, disconnecting.\n", rc2);
                            mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
                        }
                        break;
                    }else{
                        line_buf_len += 1024;
                        pos += 1023;
                        read_len = 1024;
                        buf2 = realloc(line_buf, line_buf_len);
                        if(!buf2){
                            err_printf(&cfg, "Error: Out of memory.\n");
                            return MOSQ_ERR_NOMEM;
                        }
                        line_buf = buf2;
                    }
                }
                if(feof(stdin)){
                    if(mid_sent == -1){
                        /* Empty file */
                        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
                        disconnect_sent = true;
                        status = STATUS_DISCONNECTING;
                    }else{
                        last_mid = mid_sent;
                        status = STATUS_WAITING;
                    }
                    stdin_finished = true;
                }else if(status == STATUS_DISCONNECTED){
                    /* Not end of stdin, so we've lost our connection and must
                     * reconnect */
                }
            }else if(status == STATUS_WAITING){
                if(last_mid_sent == last_mid && disconnect_sent == false){
                    mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
                    disconnect_sent = true;
                }
#ifdef WIN32
                Sleep(100);
#else
                struct timespec ts;
                ts.tv_sec = 0;
                ts.tv_nsec = 100000000;
                nanosleep(&ts, NULL);
#endif
            }
            rc = MOSQ_ERR_SUCCESS;
        }else{
            rc = mosquitto_loop(mosq, loop_delay, 1);
            if(ready_for_repeat && check_repeat_time()){
                rc = 0;
                switch(cfg.pub_mode){
                    case MSGMODE_CMD:
                    case MSGMODE_FILE:
                    case MSGMODE_STDIN_FILE:
                        rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
                        break;
                    case MSGMODE_NULL:
                        rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
                        break;
                    case MSGMODE_STDIN_LINE:
                        break;
                }
                if(rc){
                    err_printf(&cfg, "Error sending repeat publish: %s", mosquitto_strerror(rc));
                }
            }
        }
    }while(rc == MOSQ_ERR_SUCCESS && stdin_finished == false);
    if(mode == MSGMODE_STDIN_LINE){
        mosquitto_loop_stop(mosq, false);
    }
    if(status == STATUS_DISCONNECTED){
        return MOSQ_ERR_SUCCESS;
    }else{
        return rc;
    }
}
void pub_shared_cleanup(void)
{
    free(line_buf);
}
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);
    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");
    printf("                     [-c] [-k keepalive] [-q qos] [-r] [--repeat N] [--repeat-delay time]\n");
#ifdef WITH_SRV
    printf("                     [-A bind_address] [-S]\n");
#else
    printf("                     [-A bind_address]\n");
#endif
    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");
    printf("                       [--tls-alpn protocol]\n");
    printf("                       [--tls-engine engine] [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef FINAL_WITH_TLS_PSK
    printf("                     [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
#ifdef WITH_SOCKS
    printf("                     [--proxy socks-url]\n");
#endif
    printf("                     [--property command identifier value]\n");
    printf("                     [-D command identifier value]\n");
    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(" -D : Define MQTT v5 properties. See the documentation for more details.\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");
    printf(" -k : keep alive in seconds for this client. Defaults to 60.\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(" -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");
    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\n");
    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");
#ifdef WITH_SRV
    printf(" -S : use SRV lookups to determine which host to connect to.\n");
#endif
    printf(" -t : mqtt topic to publish to.\n");
    printf(" -u : provide a username\n");
    printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
    printf("      Can be mqttv5, mqttv311 or mqttv31. Defaults to mqttv311.\n");
    printf(" --help : display this message.\n");
    printf(" --repeat : if publish mode is -f, -m, or -s, then repeat the publish N times.\n");
    printf(" --repeat-delay : if using --repeat, wait time seconds between publishes. Defaults to 0.\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(" --keyform : keyfile type, can be either \"pem\" or \"engine\".\n");
    printf(" --ciphers : openssl compatible list of TLS ciphers to support.\n");
    printf(" --tls-version : TLS protocol version, can be one of tlsv1.3 tlsv1.2 or tlsv1.1.\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");
    printf(" --tls-engine : If set, enables the use of a TLS engine device.\n");
    printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
#  ifdef FINAL_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
#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");
#endif
    printf("\nSee https://mosquitto.org/ for more information.\n\n");
}
int main(int argc, char *argv[])
{
    struct mosquitto *mosq = NULL;
    int rc;
    mosquitto_lib_init();
    if(pub_shared_init()) return 1;
    memset(&cfg, 0, sizeof(struct mosq_config));
    rc = client_config_load(&cfg, CLIENT_PUB, argc, argv);
    if(rc){
        if(rc == 2){
            /* --help */
            print_usage();
        }else{
            fprintf(stderr, "\nUse 'mosquitto_pub --help' to see usage.\n");
        }
        goto cleanup;
    }
#ifndef WITH_THREADING
    if(cfg.pub_mode == MSGMODE_STDIN_LINE){
        fprintf(stderr, "Error: '-l' mode not available, threading support has not been compiled in.\n");
        goto cleanup;
    }
#endif
    if(cfg.pub_mode == MSGMODE_STDIN_FILE){
        if(load_stdin()){
            err_printf(&cfg, "Error loading input from stdin.\n");
            goto cleanup;
        }
    }else if(cfg.file_input){
        if(load_file(cfg.file_input)){
            err_printf(&cfg, "Error loading input file \"%s\".\n", cfg.file_input);
            goto cleanup;
        }
    }
    if(!cfg.topic || cfg.pub_mode == MSGMODE_NONE){
        fprintf(stderr, "Error: Both topic and message must be supplied.\n");
        print_usage();
        goto cleanup;
    }
    if(client_id_generate(&cfg)){
        goto cleanup;
    }
    mosq = mosquitto_new(cfg.id, cfg.clean_session, NULL);
    if(!mosq){
        switch(errno){
            case ENOMEM:
                err_printf(&cfg, "Error: Out of memory.\n");
                break;
            case EINVAL:
                err_printf(&cfg, "Error: Invalid id.\n");
                break;
        }
        goto cleanup;
    }
    if(cfg.debug){
        mosquitto_log_callback_set(mosq, my_log_callback);
    }
    mosquitto_connect_v5_callback_set(mosq, my_connect_callback);
    mosquitto_disconnect_v5_callback_set(mosq, my_disconnect_callback);
    mosquitto_publish_v5_callback_set(mosq, my_publish_callback);
    if(client_opts_set(mosq, &cfg)){
        goto cleanup;
    }
    rc = client_connect(mosq, &cfg);
    if(rc){
        goto cleanup;
    }
    rc = pub_shared_loop(mosq);
    if(cfg.message && cfg.pub_mode == MSGMODE_FILE){
        free(cfg.message);
        cfg.message = NULL;
    }
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();
    client_config_cleanup(&cfg);
    pub_shared_cleanup();
    if(rc){
        err_printf(&cfg, "Error: %s\n", mosquitto_strerror(rc));
    }
    return rc;
cleanup:
    mosquitto_lib_cleanup();
    client_config_cleanup(&cfg);
    pub_shared_cleanup();
    return 1;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_client.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.c
New file
@@ -0,0 +1,126 @@
/*
Copyright (c) 2009-2018 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 "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <time.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
#include "pub_shared.h"
/* Global variables for use in callbacks. See sub_client.c for an example of
 * using a struct to hold variables for use in callbacks. */
int mid_sent = -1;
int status = STATUS_CONNECTING;
struct mosq_config cfg;
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
    UNUSED(mosq);
    UNUSED(obj);
    UNUSED(level);
    printf("%s\n", str);
}
int load_stdin(void)
{
    long pos = 0, rlen;
    char buf[1024];
    char *aux_message = NULL;
    cfg.pub_mode = MSGMODE_STDIN_FILE;
    while(!feof(stdin)){
        rlen = fread(buf, 1, 1024, stdin);
        aux_message = realloc(cfg.message, pos+rlen);
        if(!aux_message){
            err_printf(&cfg, "Error: Out of memory.\n");
            free(cfg.message);
            return 1;
        } else
        {
            cfg.message = aux_message;
        }
        memcpy(&(cfg.message[pos]), buf, rlen);
        pos += rlen;
    }
    cfg.msglen = pos;
    if(!cfg.msglen){
        err_printf(&cfg, "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){
        err_printf(&cfg, "Error: Unable to open file \"%s\".\n", filename);
        return 1;
    }
    cfg.pub_mode = MSGMODE_FILE;
    fseek(fptr, 0, SEEK_END);
    cfg.msglen = ftell(fptr);
    if(cfg.msglen > 268435455){
        fclose(fptr);
        err_printf(&cfg, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename);
        return 1;
    }else if(cfg.msglen == 0){
        fclose(fptr);
        err_printf(&cfg, "Error: File \"%s\" is empty.\n", filename);
        return 1;
    }else if(cfg.msglen < 0){
        fclose(fptr);
        err_printf(&cfg, "Error: Unable to determine size of file \"%s\".\n", filename);
        return 1;
    }
    fseek(fptr, 0, SEEK_SET);
    cfg.message = malloc(cfg.msglen);
    if(!cfg.message){
        fclose(fptr);
        err_printf(&cfg, "Error: Out of memory.\n");
        return 1;
    }
    pos = 0;
    while(pos < cfg.msglen){
        rlen = fread(&(cfg.message[pos]), sizeof(char), cfg.msglen-pos, fptr);
        pos += rlen;
    }
    fclose(fptr);
    return 0;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.h
New file
@@ -0,0 +1,43 @@
/*
Copyright (c) 2009-2018 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.
*/
#ifndef PUB_SHARED_H
#define PUB_SHARED_H
#define STATUS_CONNECTING 0
#define STATUS_CONNACK_RECVD 1
#define STATUS_WAITING 2
#define STATUS_DISCONNECTING 3
#define STATUS_DISCONNECTED 4
extern int mid_sent;
extern int status;
extern struct mosq_config cfg;
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties);
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties);
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties);
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str);
int load_stdin(void);
int load_file(const char *filename);
int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain);
int pub_shared_init(void);
int pub_shared_loop(struct mosquitto *mosq);
void pub_shared_cleanup(void);
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_shared.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/pub_test_properties
New file
@@ -0,0 +1,26 @@
LD_LIBRARY_PATH=../lib ./mosquitto_pub \
    \
    -t asdf -V mqttv5 -m '{"key":"value"}' \
    \
    -D connect authentication-data password \
    -D connect authentication-method something \
    -D connect maximum-packet-size 0191 \
    -D connect receive-maximum 1000 \
    -D connect request-problem-information 1 \
    -D connect request-response-information 1 \
    -D connect session-expiry-interval 39 \
    -D connect topic-alias-maximum 123 \
    -D connect user-property connect up \
    \
    -D publish content-type application/json \
    -D publish correlation-data some-data \
    -D publish message-expiry-interval 59 \
    -D publish payload-format-indicator 1 \
    -D publish response-topic /dev/null \
    -D publish topic-alias 4 \
    -D publish user-property publish up \
    \
    -D disconnect reason-string "reason" \
    -D disconnect session-expiry-interval 40 \
    -D disconnect user-property disconnect up
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/rr_client.c
New file
@@ -0,0 +1,370 @@
/*
Copyright (c) 2009-2018 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 "config.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef WIN32
#include <unistd.h>
#include <signal.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
#include "pub_shared.h"
enum rr__state {
    rr_s_new,
    rr_s_connected,
    rr_s_subscribed,
    rr_s_ready_to_publish,
    rr_s_wait_for_response,
    rr_s_disconnect
};
static enum rr__state client_state = rr_s_new;
struct mosq_config cfg;
bool process_messages = true;
int msg_count = 0;
struct mosquitto *mosq = NULL;
#ifndef WIN32
void my_signal_handler(int signum)
{
    if(signum == SIGALRM){
        process_messages = false;
        mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
    }
}
#endif
void print_message(struct mosq_config *cfg, const struct mosquitto_message *message);
int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain)
{
    return mosquitto_publish_v5(mosq, mid, topic, payloadlen, payload, qos, retain, cfg.publish_props);
}
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message, const mosquitto_property *properties)
{
    print_message(&cfg, message);
    switch(cfg.pub_mode){
        case MSGMODE_CMD:
        case MSGMODE_FILE:
        case MSGMODE_STDIN_FILE:
        case MSGMODE_NULL:
            client_state = rr_s_disconnect;
            break;
        case MSGMODE_STDIN_LINE:
            client_state = rr_s_ready_to_publish;
            break;
    }
    /* FIXME - check all below
    if(process_messages == false) return;
    if(cfg.retained_only && !message->retain && process_messages){
        process_messages = false;
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
        return;
    }
    if(message->retain && cfg.no_retain) return;
    if(cfg.filter_outs){
        for(i=0; i<cfg.filter_out_count; i++){
            mosquitto_topic_matches_sub(cfg.filter_outs[i], message->topic, &res);
            if(res) return;
        }
    }
    //print_message(&cfg, message);
    if(cfg.msg_count>0){
        msg_count++;
        if(cfg.msg_count == msg_count){
            process_messages = false;
            mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
        }
    }
    */
}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties)
{
    if(!result){
        client_state = rr_s_connected;
        mosquitto_subscribe_v5(mosq, NULL, cfg.response_topic, cfg.qos, 0, cfg.subscribe_props);
    }else{
        client_state = rr_s_disconnect;
        if(result){
            err_printf(&cfg, "%s\n", mosquitto_connack_string(result));
        }
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
    }
}
void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
    if(granted_qos[0] < 128){
        client_state = rr_s_ready_to_publish;
    }else{
        client_state = rr_s_disconnect;
        err_printf(&cfg, "%s\n", mosquitto_reason_string(granted_qos[0]));
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
    }
}
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties)
{
    client_state = rr_s_wait_for_response;
}
void print_usage(void)
{
    int major, minor, revision;
    mosquitto_lib_version(&major, &minor, &revision);
    printf("mosquitto_rr is an mqtt client that can be used to publish a request message and wait for a response.\n");
    printf("             Defaults to MQTT v5, where the Request-Response feature will be used, but v3.1.1 can also be used\n");
    printf("             with v3.1.1 brokers.\n");
    printf("mosquitto_rr version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision);
    printf("Usage: mosquitto_rr {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL} -e response-topic\n");
    printf("                    [-c] [-k keepalive] [-q qos] [-R]\n");
    printf("                    [-F format]\n");
#ifndef WIN32
    printf("                    [-W timeout_secs]\n");
#endif
#ifdef WITH_SRV
    printf("                    [-A bind_address] [-S]\n");
#else
    printf("                    [-A bind_address]\n");
#endif
    printf("                    [-i id] [-I id_prefix]\n");
    printf("                    [-d] [-N] [--quiet] [-v]\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");
    printf("                      [--tls-alpn protocol]\n");
    printf("                      [--tls-engine engine] [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef FINAL_WITH_TLS_PSK
    printf("                     [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
#ifdef WITH_SOCKS
    printf("                    [--proxy socks-url]\n");
#endif
    printf("                    [-D command identifier value]\n");
    printf("       mosquitto_rr --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(" -D : Define MQTT v5 properties. See the documentation for more details.\n");
    printf(" -F : output format.\n");
    printf(" -h : mqtt host to connect to. Defaults to localhost.\n");
    printf(" -i : id to use for this client. Defaults to mosquitto_rr_ appended with the process id.\n");
    printf(" -k : keep alive in seconds for this client. Defaults to 60.\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(" -N : do not add an end of line character when printing the payload.\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\n");
    printf(" -q : quality of service level to use for communications. Defaults to 0.\n");
    printf(" -R : do not print stale messages (those with retain set).\n");
#ifdef WITH_SRV
    printf(" -S : use SRV lookups to determine which host to connect to.\n");
#endif
    printf(" -t : mqtt response topic to subscribe to. May be repeated multiple times.\n");
    printf(" -u : provide a username\n");
    printf(" -v : print received messages verbosely.\n");
    printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
    printf("      Defaults to 5.\n");
#ifndef WIN32
    printf(" -W : Specifies a timeout in seconds how long to wait for a response.\n");
#endif
    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
#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");
#endif
    printf("\nSee https://mosquitto.org/ for more information.\n\n");
}
int main(int argc, char *argv[])
{
    int rc;
#ifndef WIN32
        struct sigaction sigact;
#endif
    memset(&cfg, 0, sizeof(struct mosq_config));
    mosquitto_lib_init();
    rc = client_config_load(&cfg, CLIENT_RR, argc, argv);
    if(rc){
        if(rc == 2){
            /* --help */
            print_usage();
        }else{
            fprintf(stderr, "\nUse 'mosquitto_rr --help' to see usage.\n");
        }
        goto cleanup;
    }
    if(!cfg.topic || cfg.pub_mode == MSGMODE_NONE || !cfg.response_topic){
        fprintf(stderr, "Error: All of topic, message, and response topic must be supplied.\n");
        fprintf(stderr, "\nUse 'mosquitto_rr --help' to see usage.\n");
        goto cleanup;
    }
    rc = mosquitto_property_add_string(&cfg.publish_props, MQTT_PROP_RESPONSE_TOPIC, cfg.response_topic);
    if(rc){
        fprintf(stderr, "Error adding property RESPONSE_TOPIC.\n");
        goto cleanup;
    }
    rc = mosquitto_property_check_all(CMD_PUBLISH, cfg.publish_props);
    if(rc){
        err_printf(&cfg, "Error in PUBLISH properties: Duplicate response topic.\n");
        goto cleanup;
    }
    if(client_id_generate(&cfg)){
        goto cleanup;
    }
    mosq = mosquitto_new(cfg.id, cfg.clean_session, &cfg);
    if(!mosq){
        switch(errno){
            case ENOMEM:
                err_printf(&cfg, "Error: Out of memory.\n");
                break;
            case EINVAL:
                err_printf(&cfg, "Error: Invalid id and/or clean_session.\n");
                break;
        }
        goto cleanup;
    }
    if(client_opts_set(mosq, &cfg)){
        goto cleanup;
    }
    if(cfg.debug){
        mosquitto_log_callback_set(mosq, my_log_callback);
    }
    mosquitto_connect_v5_callback_set(mosq, my_connect_callback);
    mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
    mosquitto_message_v5_callback_set(mosq, my_message_callback);
    rc = client_connect(mosq, &cfg);
    if(rc){
        goto cleanup;
    }
#ifndef WIN32
    sigact.sa_handler = my_signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    if(sigaction(SIGALRM, &sigact, NULL) == -1){
        perror("sigaction");
        goto cleanup;
    }
    if(cfg.timeout){
        alarm(cfg.timeout);
    }
#endif
    do{
        rc = mosquitto_loop(mosq, -1, 1);
        if(client_state == rr_s_ready_to_publish){
            client_state = rr_s_wait_for_response;
            switch(cfg.pub_mode){
                case MSGMODE_CMD:
                case MSGMODE_FILE:
                case MSGMODE_STDIN_FILE:
                    rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
                    break;
                case MSGMODE_NULL:
                    rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
                    break;
                case MSGMODE_STDIN_LINE:
                    /* FIXME */
                    break;
            }
        }
    }while(rc == MOSQ_ERR_SUCCESS && client_state != rr_s_disconnect);
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();
    if(cfg.msg_count>0 && rc == MOSQ_ERR_NO_CONN){
        rc = 0;
    }
    client_config_cleanup(&cfg);
    if(rc){
        fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
    }
    return rc;
cleanup:
    mosquitto_lib_cleanup();
    client_config_cleanup(&cfg);
    return 1;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_client.c
New file
@@ -0,0 +1,367 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef WIN32
#include <unistd.h>
#include <signal.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
struct mosq_config cfg;
bool process_messages = true;
int msg_count = 0;
struct mosquitto *mosq = NULL;
int last_mid = 0;
#ifndef WIN32
void my_signal_handler(int signum)
{
    if(signum == SIGALRM){
        process_messages = false;
        mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
    }
}
#endif
void print_message(struct mosq_config *cfg, const struct mosquitto_message *message);
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties)
{
    UNUSED(obj);
    UNUSED(reason_code);
    UNUSED(properties);
    if(process_messages == false && (mid == last_mid || last_mid == 0)){
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
    }
}
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message, const mosquitto_property *properties)
{
    int i;
    bool res;
    UNUSED(obj);
    UNUSED(properties);
    if(process_messages == false) return;
    if(cfg.remove_retained && message->retain){
        mosquitto_publish(mosq, &last_mid, message->topic, 0, NULL, 1, true);
    }
    if(cfg.retained_only && !message->retain && process_messages){
        process_messages = false;
        if(last_mid == 0){
            mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
        }
        return;
    }
    if(message->retain && cfg.no_retain) return;
    if(cfg.filter_outs){
        for(i=0; i<cfg.filter_out_count; i++){
            mosquitto_topic_matches_sub(cfg.filter_outs[i], message->topic, &res);
            if(res) return;
        }
    }
    print_message(&cfg, message);
    if(cfg.msg_count>0){
        msg_count++;
        if(cfg.msg_count == msg_count){
            process_messages = false;
            if(last_mid == 0){
                mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
            }
        }
    }
}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties)
{
    int i;
    UNUSED(obj);
    UNUSED(flags);
    UNUSED(properties);
    if(!result){
        mosquitto_subscribe_multiple(mosq, NULL, cfg.topic_count, cfg.topics, cfg.qos, cfg.sub_opts, cfg.subscribe_props);
        for(i=0; i<cfg.unsub_topic_count; i++){
            mosquitto_unsubscribe_v5(mosq, NULL, cfg.unsub_topics[i], cfg.unsubscribe_props);
        }
    }else{
        if(result){
            if(cfg.protocol_version == MQTT_PROTOCOL_V5){
                err_printf(&cfg, "%s\n", mosquitto_reason_string(result));
            }else{
                err_printf(&cfg, "%s\n", mosquitto_connack_string(result));
            }
        }
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
    }
}
void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
    int i;
    UNUSED(obj);
    if(!cfg.quiet) printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
    for(i=1; i<qos_count; i++){
        if(!cfg.quiet) printf(", %d", granted_qos[i]);
    }
    if(!cfg.quiet) printf("\n");
    if(cfg.exit_after_sub){
        mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
    }
}
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
    UNUSED(mosq);
    UNUSED(obj);
    UNUSED(level);
    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 set of topics 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 {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL [-t topic]}\n");
    printf("                     [-c] [-k keepalive] [-q qos]\n");
    printf("                     [-C msg_count] [-E] [-R] [--retained-only] [--remove-retained] [-T filter_out] [-U topic ...]\n");
    printf("                     [-F format]\n");
#ifndef WIN32
    printf("                     [-W timeout_secs]\n");
#endif
#ifdef WITH_SRV
    printf("                     [-A bind_address] [-S]\n");
#else
    printf("                     [-A bind_address]\n");
#endif
    printf("                     [-i id] [-I id_prefix]\n");
    printf("                     [-d] [-N] [--quiet] [-v]\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");
    printf("                       [--tls-alpn protocol]\n");
    printf("                       [--tls-engine engine] [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef FINAL_WITH_TLS_PSK
    printf("                     [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
#ifdef WITH_SOCKS
    printf("                     [--proxy socks-url]\n");
#endif
    printf("                     [-D command identifier value]\n");
    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(" -C : disconnect and exit after receiving the 'msg_count' messages.\n");
    printf(" -d : enable debug messages.\n");
    printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n");
    printf(" -E : Exit once all subscriptions have been acknowledged by the broker.\n");
    printf(" -F : output format.\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(" -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(" -N : do not add an end of line character when printing the payload.\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\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");
#ifdef WITH_SRV
    printf(" -S : use SRV lookups to determine which host to connect to.\n");
#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(" -u : provide a username\n");
    printf(" -U : unsubscribe from a topic. May be repeated.\n");
    printf(" -v : print published messages verbosely.\n");
    printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
    printf("      Can be mqttv5, mqttv311 or mqttv31. Defaults to mqttv311.\n");
#ifndef WIN32
    printf(" -W : Specifies a timeout in seconds how long to process incoming MQTT messages.\n");
#endif
    printf(" --help : display this message.\n");
    printf(" --quiet : don't print error messages.\n");
    printf(" --retained-only : only handle messages with the retained flag set, and exit when the\n");
    printf("                   first non-retained message is received.\n");
    printf(" --remove-retained : send a message to the server to clear any received retained messages\n");
    printf("                     Use -T to filter out messages you do not want to be cleared.\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(" --keyform : keyfile type, can be either \"pem\" or \"engine\".\n");
    printf(" --ciphers : openssl compatible list of TLS ciphers to support.\n");
    printf(" --tls-version : TLS protocol version, can be one of tlsv1.3 tlsv1.2 or tlsv1.1.\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");
    printf(" --tls-engine : If set, enables the use of a SSL engine device.\n");
    printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
#ifdef FINAL_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
#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");
#endif
    printf("\nSee https://mosquitto.org/ for more information.\n\n");
}
int main(int argc, char *argv[])
{
    int rc;
#ifndef WIN32
        struct sigaction sigact;
#endif
    memset(&cfg, 0, sizeof(struct mosq_config));
    mosquitto_lib_init();
    rc = client_config_load(&cfg, CLIENT_SUB, argc, argv);
    if(rc){
        if(rc == 2){
            /* --help */
            print_usage();
        }else{
            fprintf(stderr, "\nUse 'mosquitto_sub --help' to see usage.\n");
        }
        goto cleanup;
    }
    if(cfg.no_retain && cfg.retained_only){
        fprintf(stderr, "\nError: Combining '-R' and '--retained-only' makes no sense.\n");
        goto cleanup;
    }
    if(client_id_generate(&cfg)){
        goto cleanup;
    }
    mosq = mosquitto_new(cfg.id, cfg.clean_session, &cfg);
    if(!mosq){
        switch(errno){
            case ENOMEM:
                err_printf(&cfg, "Error: Out of memory.\n");
                break;
            case EINVAL:
                err_printf(&cfg, "Error: Invalid id and/or clean_session.\n");
                break;
        }
        goto cleanup;
    }
    if(client_opts_set(mosq, &cfg)){
        goto cleanup;
    }
    if(cfg.debug){
        mosquitto_log_callback_set(mosq, my_log_callback);
        mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
    }
    mosquitto_connect_v5_callback_set(mosq, my_connect_callback);
    mosquitto_message_v5_callback_set(mosq, my_message_callback);
    rc = client_connect(mosq, &cfg);
    if(rc){
        goto cleanup;
    }
#ifndef WIN32
    sigact.sa_handler = my_signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    if(sigaction(SIGALRM, &sigact, NULL) == -1){
        perror("sigaction");
        goto cleanup;
    }
    if(cfg.timeout){
        alarm(cfg.timeout);
    }
#endif
    rc = mosquitto_loop_forever(mosq, -1, 1);
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();
    if(cfg.msg_count>0 && rc == MOSQ_ERR_NO_CONN){
        rc = 0;
    }
    client_config_cleanup(&cfg);
    if(rc){
        fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
    }
    return rc;
cleanup:
    mosquitto_lib_cleanup();
    client_config_cleanup(&cfg);
    return 1;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_client_output.c
New file
@@ -0,0 +1,336 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef WIN32
#include <unistd.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#ifdef __APPLE__
#  include <sys/time.h>
#endif
#include <mosquitto.h>
#include "client_shared.h"
extern struct mosq_config cfg;
static int get_time(struct tm **ti, long *ns)
{
#ifdef WIN32
    SYSTEMTIME st;
#elif defined(__APPLE__)
    struct timeval tv;
#else
    struct timespec ts;
#endif
    time_t s;
#ifdef WIN32
    s = time(NULL);
    GetLocalTime(&st);
    *ns = st.wMilliseconds*1000000L;
#elif defined(__APPLE__)
    gettimeofday(&tv, NULL);
    s = tv.tv_sec;
    *ns = tv.tv_usec*1000;
#else
    if(clock_gettime(CLOCK_REALTIME, &ts) != 0){
        err_printf(&cfg, "Error obtaining system time.\n");
        return 1;
    }
    s = ts.tv_sec;
    *ns = ts.tv_nsec;
#endif
    *ti = localtime(&s);
    if(!(*ti)){
        err_printf(&cfg, "Error obtaining system time.\n");
        return 1;
    }
    return 0;
}
static void write_payload(const unsigned char *payload, int payloadlen, int hex)
{
    int i;
    if(hex == 0){
        (void)fwrite(payload, 1, payloadlen, stdout);
    }else if(hex == 1){
        for(i=0; i<payloadlen; i++){
            fprintf(stdout, "%02x", payload[i]);
        }
    }else if(hex == 2){
        for(i=0; i<payloadlen; i++){
            fprintf(stdout, "%02X", payload[i]);
        }
    }
}
static void write_json_payload(const char *payload, int payloadlen)
{
    int i;
    for(i=0; i<payloadlen; i++){
        if(payload[i] == '"' || payload[i] == '\\' || (payload[i] >=0 && payload[i] < 32)){
            printf("\\u%04x", payload[i]);
        }else{
            fputc(payload[i], stdout);
        }
    }
}
static void json_print(const struct mosquitto_message *message, const struct tm *ti, bool escaped)
{
    char buf[100];
    strftime(buf, 100, "%s", ti);
    printf("{\"tst\":%s,\"topic\":\"%s\",\"qos\":%d,\"retain\":%d,\"payloadlen\":%d,", buf, message->topic, message->qos, message->retain, message->payloadlen);
    if(message->qos > 0){
        printf("\"mid\":%d,", message->mid);
    }
    if(escaped){
        fputs("\"payload\":\"", stdout);
        write_json_payload(message->payload, message->payloadlen);
        fputs("\"}", stdout);
    }else{
        fputs("\"payload\":", stdout);
        write_payload(message->payload, message->payloadlen, 0);
        fputs("}", stdout);
    }
}
static void formatted_print(const struct mosq_config *lcfg, const struct mosquitto_message *message)
{
    int len;
    int i;
    struct tm *ti = NULL;
    long ns;
    char strf[3];
    char buf[100];
    len = strlen(lcfg->format);
    for(i=0; i<len; i++){
        if(lcfg->format[i] == '%'){
            if(i < len-1){
                i++;
                switch(lcfg->format[i]){
                    case '%':
                        fputc('%', stdout);
                        break;
                    case 'I':
                        if(!ti){
                            if(get_time(&ti, &ns)){
                                err_printf(lcfg, "Error obtaining system time.\n");
                                return;
                            }
                        }
                        if(strftime(buf, 100, "%FT%T%z", ti) != 0){
                            fputs(buf, stdout);
                        }
                        break;
                    case 'j':
                        if(!ti){
                            if(get_time(&ti, &ns)){
                                err_printf(lcfg, "Error obtaining system time.\n");
                                return;
                            }
                        }
                        json_print(message, ti, true);
                        break;
                    case 'J':
                        if(!ti){
                            if(get_time(&ti, &ns)){
                                err_printf(lcfg, "Error obtaining system time.\n");
                                return;
                            }
                        }
                        json_print(message, ti, false);
                        break;
                    case 'l':
                        printf("%d", message->payloadlen);
                        break;
                    case 'm':
                        printf("%d", message->mid);
                        break;
                    case 'p':
                        write_payload(message->payload, message->payloadlen, 0);
                        break;
                    case 'q':
                        fputc(message->qos + 48, stdout);
                        break;
                    case 'r':
                        if(message->retain){
                            fputc('1', stdout);
                        }else{
                            fputc('0', stdout);
                        }
                        break;
                    case 't':
                        fputs(message->topic, stdout);
                        break;
                    case 'U':
                        if(!ti){
                            if(get_time(&ti, &ns)){
                                err_printf(lcfg, "Error obtaining system time.\n");
                                return;
                            }
                        }
                        if(strftime(buf, 100, "%s", ti) != 0){
                            printf("%s.%09ld", buf, ns);
                        }
                        break;
                    case 'x':
                        write_payload(message->payload, message->payloadlen, 1);
                        break;
                    case 'X':
                        write_payload(message->payload, message->payloadlen, 2);
                        break;
                }
            }
        }else if(lcfg->format[i] == '@'){
            if(i < len-1){
                i++;
                if(lcfg->format[i] == '@'){
                    fputc('@', stdout);
                }else{
                    if(!ti){
                        if(get_time(&ti, &ns)){
                            err_printf(lcfg, "Error obtaining system time.\n");
                            return;
                        }
                    }
                    strf[0] = '%';
                    strf[1] = lcfg->format[i];
                    strf[2] = 0;
                    if(lcfg->format[i] == 'N'){
                        printf("%09ld", ns);
                    }else{
                        if(strftime(buf, 100, strf, ti) != 0){
                            fputs(buf, stdout);
                        }
                    }
                }
            }
        }else if(lcfg->format[i] == '\\'){
            if(i < len-1){
                i++;
                switch(lcfg->format[i]){
                    case '\\':
                        fputc('\\', stdout);
                        break;
                    case '0':
                        fputc('\0', stdout);
                        break;
                    case 'a':
                        fputc('\a', stdout);
                        break;
                    case 'e':
                        fputc('\033', stdout);
                        break;
                    case 'n':
                        fputc('\n', stdout);
                        break;
                    case 'r':
                        fputc('\r', stdout);
                        break;
                    case 't':
                        fputc('\t', stdout);
                        break;
                    case 'v':
                        fputc('\v', stdout);
                        break;
                }
            }
        }else{
            fputc(lcfg->format[i], stdout);
        }
    }
    if(lcfg->eol){
        fputc('\n', stdout);
    }
    fflush(stdout);
}
void print_message(struct mosq_config *cfg, const struct mosquitto_message *message)
{
    if(cfg->format){
        formatted_print(cfg, message);
    }else if(cfg->verbose){
        if(message->payloadlen){
            printf("%s ", message->topic);
            write_payload(message->payload, message->payloadlen, false);
            if(cfg->eol){
                printf("\n");
            }
        }else{
            if(cfg->eol){
                printf("%s (null)\n", message->topic);
            }
        }
        fflush(stdout);
    }else{
        if(message->payloadlen){
            write_payload(message->payload, message->payloadlen, false);
            if(cfg->eol){
                printf("\n");
            }
            fflush(stdout);
        }
    }
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/client/sub_test_properties
New file
@@ -0,0 +1,31 @@
LD_LIBRARY_PATH=../lib ./mosquitto_sub \
    \
    -V mqttv5 -C 10 -t \$SYS/# -v -U unsub --will-topic will --will-payload '{"key":"value"}' \
    \
    -D connect authentication-data password \
    -D connect authentication-method something \
    -D connect maximum-packet-size 0191 \
    -D connect receive-maximum 1000 \
    -D connect request-problem-information 1 \
    -D connect request-response-information 1 \
    -D connect session-expiry-interval 39 \
    -D connect topic-alias-maximum 123 \
    -D connect user-property connect up \
    \
    -D will content-type application/json \
    -D will correlation-data some-data \
    -D will message-expiry-interval 59 \
    -D will payload-format-indicator 1 \
    -D will response-topic /dev/null \
    -D will user-property will up \
    -D will will-delay-interval 100 \
    \
    -D subscribe subscription-identifier 1 \
    -D subscribe user-property subscribe up \
    \
    -D unsubscribe user-property unsubscribe up \
    \
    -D disconnect reason-string "reason" \
    -D disconnect session-expiry-interval 40 \
    -D disconnect user-property disconnect up
proj1_mqttd/mosquitto/mosquitto-1.6.3/compiling.txt
New file
@@ -0,0 +1,20 @@
The following packages can be used to add features to mosquitto. All of them
are optional.
* openssl
* c-ares (for DNS-SRV support, disabled by default)
* tcp-wrappers (optional, package name libwrap0-dev)
* libwebsockets (optional, disabled by default, version 1.3 and above)
* On Windows, a pthreads library is required if threading support is to be
  included.
To compile, run "make", but also see the file config.mk for more details on the
various options that can be compiled in.
Where possible use the Makefiles to compile. This is particularly relevant for
the client libraries as symbol information will be included.  Use cmake to
compile on Windows or Mac.
If you have any questions, problems or suggestions (particularly related to
installing on a more unusual device like a plug-computer) then please get in
touch using the details in readme.txt.
proj1_mqttd/mosquitto/mosquitto-1.6.3/config.h
New file
@@ -0,0 +1,69 @@
#ifndef CONFIG_H
#define CONFIG_H
/* ============================================================
 * Platform options
 * ============================================================ */
#ifdef __APPLE__
#  define __DARWIN_C_SOURCE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__SYMBIAN32__) || defined(__QNX__)
#  define _XOPEN_SOURCE 700
#  define __BSD_VISIBLE 1
#  define HAVE_NETINET_IN_H
#else
#  define _XOPEN_SOURCE 700
#  define _DEFAULT_SOURCE 1
#  define _POSIX_C_SOURCE 200809L
#endif
#define _GNU_SOURCE
#define OPENSSL_LOAD_CONF
/* ============================================================
 * Compatibility defines
 * ============================================================ */
#if defined(_MSC_VER) && _MSC_VER < 1900
#  define snprintf sprintf_s
#  define EPROTO ECONNABORTED
#endif
#ifdef WIN32
#  ifndef strcasecmp
#    define strcasecmp strcmpi
#  endif
#  define strtok_r strtok_s
#  define strerror_r(e, b, l) strerror_s(b, l, e)
#endif
#define uthash_malloc(sz) mosquitto__malloc(sz)
#define uthash_free(ptr,sz) mosquitto__free(ptr)
#ifdef WITH_TLS
#  include <openssl/opensslconf.h>
#  if defined(WITH_TLS_PSK) && !defined(OPENSSL_NO_PSK)
#    define FINAL_WITH_TLS_PSK
#  endif
#endif
#ifdef __COVERITY__
#  include <stdint.h>
/* These are "wrong", but we don't use them so it doesn't matter */
#  define _Float32 uint32_t
#  define _Float32x uint32_t
#  define _Float64 uint64_t
#  define _Float64x uint64_t
#  define _Float128 uint64_t
#endif
#define UNUSED(A) (void)(A)
/* Android Bionic libpthread implementation doesn't have pthread_cancel */
#ifndef ANDROID
#  define HAVE_PTHREAD_CANCEL
#endif
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/config.mk
New file
@@ -0,0 +1,314 @@
# =============================================================================
# User configuration section.
#
# These options control compilation on all systems apart from Windows and Mac
# OS X. Use CMake to compile on Windows and Mac.
#
# Largely, these are options that are designed to make mosquitto run more
# easily in restrictive environments by removing features.
#
# Modify the variable below to enable/disable features.
#
# Can also be overriden at the command line, e.g.:
#
# make WITH_TLS=no
# =============================================================================
# Uncomment to compile the broker with tcpd/libwrap support.
#WITH_WRAP:=yes
# Comment out to disable SSL/TLS support in the broker and client.
# Disabling this will also mean that passwords must be stored in plain text. It
# is strongly recommended that you only disable WITH_TLS if you are not using
# password authentication at all.
WITH_TLS:=yes
# Comment out to disable TLS/PSK support in the broker and client. Requires
# WITH_TLS=yes.
# This must be disabled if using openssl < 1.0.
WITH_TLS_PSK:=yes
# Comment out to disable client threading support.
WITH_THREADING:=yes
# Comment out to remove bridge support from the broker. This allow the broker
# to connect to other brokers and subscribe/publish to topics. You probably
# want to leave this included unless you want to save a very small amount of
# memory size and CPU time.
WITH_BRIDGE:=yes
# Comment out to remove persistent database support from the broker. This
# allows the broker to store retained messages and durable subscriptions to a
# file periodically and on shutdown. This is usually desirable (and is
# suggested by the MQTT spec), but it can be disabled if required.
WITH_PERSISTENCE:=yes
# Comment out to remove memory tracking support from the broker. If disabled,
# mosquitto won't track heap memory usage nor export '$SYS/broker/heap/current
# size', but will use slightly less memory and CPU time.
WITH_MEMORY_TRACKING:=yes
# Compile with database upgrading support? If disabled, mosquitto won't
# automatically upgrade old database versions.
# Not currently supported.
#WITH_DB_UPGRADE:=yes
# Comment out to remove publishing of the $SYS topic hierarchy containing
# information about the broker state.
WITH_SYS_TREE:=yes
# Build with systemd support. If enabled, mosquitto will notify systemd after
# initialization. See README in service/systemd/ for more information.
WITH_SYSTEMD:=no
# Build with SRV lookup support.
WITH_SRV:=no
# Build with websockets support on the broker.
WITH_WEBSOCKETS:=no
# Use elliptic keys in broker
WITH_EC:=yes
# Build man page documentation by default.
WITH_DOCS:=yes
# Build with client support for SOCK5 proxy.
WITH_SOCKS:=yes
# Strip executables and shared libraries on install.
WITH_STRIP:=no
# Build static libraries
WITH_STATIC_LIBRARIES:=no
# Build shared libraries
WITH_SHARED_LIBRARIES:=yes
# Build with async dns lookup support for bridges (temporary). Requires glibc.
#WITH_ADNS:=yes
# Build with epoll support.
WITH_EPOLL:=yes
# Build with bundled uthash.h
WITH_BUNDLED_DEPS:=yes
# Build with coverage options
WITH_COVERAGE:=no
# =============================================================================
# End of user configuration
# =============================================================================
# Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto64.nsi
VERSION=1.6.3
# Client library SO version. Bump if incompatible API/ABI changes are made.
SOVERSION=1
# Man page generation requires xsltproc and docbook-xsl
XSLTPROC=xsltproc --nonet
# For html generation
DB_HTML_XSL=man/html.xsl
#MANCOUNTRIES=en_GB
UNAME:=$(shell uname -s)
ifeq ($(UNAME),SunOS)
    ifeq ($(CC),cc)
        CFLAGS?=-O
    else
        CFLAGS?=-Wall -ggdb -O2
    endif
else
    CFLAGS?=-Wall -ggdb -O2
endif
STATIC_LIB_DEPS:=
LIB_CPPFLAGS=$(CPPFLAGS) -I. -I.. -I../lib -I../src/deps
LIB_CFLAGS:=$(CFLAGS)
LIB_CXXFLAGS:=$(CXXFLAGS)
LIB_LDFLAGS:=$(LDFLAGS)
LIB_LIBADD:=$(LIBADD)
BROKER_CPPFLAGS:=$(LIB_CPPFLAGS)
BROKER_CFLAGS:=${CFLAGS} -DVERSION="\"${VERSION}\"" -DWITH_BROKER
BROKER_LDFLAGS:=${LDFLAGS}
BROKER_LDADD:=
CLIENT_CPPFLAGS:=$(CPPFLAGS) -I.. -I../lib
CLIENT_CFLAGS:=${CFLAGS} -DVERSION="\"${VERSION}\""
CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib
CLIENT_LDADD:=
PASSWD_LDADD:=
ifneq ($(or $(findstring $(UNAME),FreeBSD), $(findstring $(UNAME),OpenBSD), $(findstring $(UNAME),NetBSD)),)
    BROKER_LDADD:=$(BROKER_LDADD) -lm
else
    BROKER_LDADD:=$(BROKER_LDADD) -ldl -lm
endif
ifeq ($(UNAME),Linux)
    BROKER_LDADD:=$(BROKER_LDADD) -lrt
    BROKER_LDFLAGS:=$(BROKER_LDFLAGS) -Wl,--dynamic-list=linker.syms
    LIB_LIBADD:=$(LIB_LIBADD) -lrt
endif
ifeq ($(WITH_SHARED_LIBRARIES),yes)
    CLIENT_LDADD:=${CLIENT_LDADD} ../lib/libmosquitto.so.${SOVERSION}
endif
ifeq ($(UNAME),SunOS)
    ifeq ($(CC),cc)
        LIB_CFLAGS:=$(LIB_CFLAGS) -xc99 -KPIC
    else
        LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC
    endif
    ifeq ($(CXX),CC)
        LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -KPIC
    else
        LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC
    endif
else
    LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC
    LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC
endif
ifneq ($(UNAME),SunOS)
    LIB_LDFLAGS:=$(LIB_LDFLAGS) -Wl,--version-script=linker.version -Wl,-soname,libmosquitto.so.$(SOVERSION)
endif
ifeq ($(UNAME),QNX)
    BROKER_LDADD:=$(BROKER_LDADD) -lsocket
    LIB_LIBADD:=$(LIB_LIBADD) -lsocket
endif
ifeq ($(WITH_WRAP),yes)
    BROKER_LDADD:=$(BROKER_LDADD) -lwrap
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_WRAP
endif
ifeq ($(WITH_TLS),yes)
    BROKER_LDADD:=$(BROKER_LDADD) -lssl -lcrypto
    LIB_LIBADD:=$(LIB_LIBADD) -lssl -lcrypto
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_TLS
    LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_TLS
    PASSWD_LDADD:=$(PASSWD_LDADD) -lcrypto
    CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_TLS
    STATIC_LIB_DEPS:=$(STATIC_LIB_DEPS) -lssl -lcrypto
    ifeq ($(WITH_TLS_PSK),yes)
        BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_TLS_PSK
        LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_TLS_PSK
        CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_TLS_PSK
    endif
endif
ifeq ($(WITH_THREADING),yes)
    LIB_LIBADD:=$(LIB_LIBADD) -lpthread
    LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_THREADING
    CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_THREADING
    STATIC_LIB_DEPS:=$(STATIC_LIB_DEPS) -lpthread
endif
ifeq ($(WITH_SOCKS),yes)
    LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_SOCKS
    CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_SOCKS
endif
ifeq ($(WITH_BRIDGE),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_BRIDGE
endif
ifeq ($(WITH_PERSISTENCE),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_PERSISTENCE
endif
ifeq ($(WITH_MEMORY_TRACKING),yes)
    ifneq ($(UNAME),SunOS)
        BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_MEMORY_TRACKING
    endif
endif
ifeq ($(WITH_SYS_TREE),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_SYS_TREE
endif
ifeq ($(WITH_SYSTEMD),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_SYSTEMD
    BROKER_LDADD:=$(BROKER_LDADD) -lsystemd
endif
ifeq ($(WITH_SRV),yes)
    LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_SRV
    LIB_LIBADD:=$(LIB_LIBADD) -lcares
    CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_SRV
    STATIC_LIB_DEPS:=$(STATIC_LIB_DEPS) -lcares
endif
ifeq ($(UNAME),SunOS)
    BROKER_LDADD:=$(BROKER_LDADD) -lsocket -lnsl
    LIB_LIBADD:=$(LIB_LIBADD) -lsocket -lnsl
endif
ifeq ($(WITH_EC),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_EC
endif
ifeq ($(WITH_ADNS),yes)
    BROKER_LDADD:=$(BROKER_LDADD) -lanl
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_ADNS
endif
MAKE_ALL:=mosquitto
ifeq ($(WITH_DOCS),yes)
    MAKE_ALL:=$(MAKE_ALL) docs
endif
ifeq ($(WITH_WEBSOCKETS),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_WEBSOCKETS
    BROKER_LDADD:=$(BROKER_LDADD) -lwebsockets
endif
ifeq ($(WITH_WEBSOCKETS),static)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_WEBSOCKETS
    BROKER_LDADD:=$(BROKER_LDADD) -static -lwebsockets
endif
INSTALL?=install
prefix?=/usr/local
incdir?=${prefix}/include
libdir?=${prefix}/lib${LIB_SUFFIX}
localedir?=${prefix}/share/locale
mandir?=${prefix}/share/man
STRIP?=strip
ifeq ($(WITH_STRIP),yes)
    STRIP_OPTS?=-s --strip-program=${CROSS_COMPILE}${STRIP}
endif
ifeq ($(WITH_EPOLL),yes)
    ifeq ($(UNAME),Linux)
        BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_EPOLL
    endif
endif
ifeq ($(WITH_BUNDLED_DEPS),yes)
    BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -Ideps
endif
ifeq ($(WITH_COVERAGE),yes)
    BROKER_CFLAGS:=$(BROKER_CFLAGS) -coverage
    BROKER_LDFLAGS:=$(BROKER_LDFLAGS) -coverage
    LIB_CFLAGS:=$(LIB_CFLAGS) -coverage
    LIB_LDFLAGS:=$(LIB_LDFLAGS) -coverage
    CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -coverage
    CLIENT_LDFLAGS:=$(CLIENT_LDFLAGS) -coverage
endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.in.out
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.out
New file
Diff too large
proj1_mqttd/mosquitto/mosquitto-1.6.3/cscope.po.out
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/edl-v10
New file
@@ -0,0 +1,31 @@
Eclipse Distribution License - v 1.0
Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
  Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
  Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
  Neither the name of the Eclipse Foundation, Inc. nor the names of its
  contributors may be used to endorse or promote products derived from this
  software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
proj1_mqttd/mosquitto/mosquitto-1.6.3/epl-v10
New file
@@ -0,0 +1,221 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
  a) in the case of the initial Contributor, the initial code and
     documentation distributed under this Agreement, and
  b) in the case of each subsequent Contributor:
     i) changes to the Program, and
     ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from a
Contributor if it was added to the Program by such Contributor itself or anyone
acting on such Contributor's behalf. Contributions do not include additions to
the Program which: (i) are separate modules of software distributed in
conjunction with the Program under their own license agreement, and (ii) are
not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
  a) Subject to the terms of this Agreement, each Contributor hereby grants
     Recipient a non-exclusive, worldwide, royalty-free copyright license to
     reproduce, prepare derivative works of, publicly display, publicly
     perform, distribute and sublicense the Contribution of such Contributor,
     if any, and such derivative works, in source code and object code form.
  b) Subject to the terms of this Agreement, each Contributor hereby grants
     Recipient a non-exclusive, worldwide, royalty-free patent license under
     Licensed Patents to make, use, sell, offer to sell, import and otherwise
     transfer the Contribution of such Contributor, if any, in source code and
     object code form. This patent license shall apply to the combination of the
     Contribution and the Program if, at the time the Contribution is added by the
     Contributor, such addition of the Contribution causes such combination to be
     covered by the Licensed Patents. The patent license shall not apply to any
     other combinations which include the Contribution. No hardware per se is
     licensed hereunder.
  c) Recipient understands that although each Contributor grants the licenses
     to its Contributions set forth herein, no assurances are provided by any
     Contributor that the Program does not infringe the patent or other
     intellectual property rights of any other entity. Each Contributor disclaims
     any liability to Recipient for claims brought by any other entity based on
     infringement of intellectual property rights or otherwise. As a condition to
     exercising the rights and licenses granted hereunder, each Recipient hereby
     assumes sole responsibility to secure any other intellectual property rights
     needed, if any. For example, if a third party patent license is required to
     allow Recipient to distribute the Program, it is Recipient's responsibility
     to acquire that license before distributing the Program.
  d) Each Contributor represents that to its knowledge it has sufficient
     copyright rights in its Contribution, if any, to grant the copyright license
     set forth in this Agreement.
3. REQUIREMENTS
  A Contributor may choose to distribute the Program in object code form under
  its own license agreement, provided that:
  a) it complies with the terms and conditions of this Agreement; and
  b) its license agreement:
     i) effectively disclaims on behalf of all Contributors all warranties and
        conditions, express and implied, including warranties or conditions of
        title and non-infringement, and implied warranties or conditions of
        merchantability and fitness for a particular purpose;
    ii) effectively excludes on behalf of all Contributors all liability for
        damages, including direct, indirect, special, incidental and consequential
        damages, such as lost profits;
   iii) states that any provisions which differ from this Agreement are offered
        by that Contributor alone and not by any other party; and
    iv) states that source code for the Program is available from such
        Contributor, and informs licensees how to obtain it in a reasonable manner
        on or through a medium customarily used for software exchange.
  When the Program is made available in source code form:
    a) it must be made available under this Agreement; and
    b) a copy of this Agreement must be included with each copy of the Program.
  Contributors may not remove or alter any copyright notices contained within
  the Program.
  Each Contributor must identify itself as the originator of its Contribution,
  if any, in a manner that reasonably allows subsequent Recipients to identify
  the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
  Commercial distributors of software may accept certain responsibilities with
  respect to end users, business partners and the like. While this license is
  intended to facilitate the commercial use of the Program, the Contributor who
  includes the Program in a commercial product offering should do so in a
  manner which does not create potential liability for other Contributors.
  Therefore, if a Contributor includes the Program in a commercial product
  offering, such Contributor ("Commercial Contributor") hereby agrees to defend
  and indemnify every other Contributor ("Indemnified Contributor") against any
  losses, damages and costs (collectively "Losses") arising from claims,
  lawsuits and other legal actions brought by a third party against the
  Indemnified Contributor to the extent caused by the acts or omissions of such
  Commercial Contributor in connection with its distribution of the Program in
  a commercial product offering. The obligations in this section do not apply
  to any claims or Losses relating to any actual or alleged intellectual
  property infringement. In order to qualify, an Indemnified Contributor must:
  a) promptly notify the Commercial Contributor in writing of such claim, and
  b) allow the Commercial Contributor to control, and cooperate with the
  Commercial Contributor in, the defense and any related settlement
  negotiations. The Indemnified Contributor may participate in any such claim
  at its own expense.
  For example, a Contributor might include the Program in a commercial product
  offering, Product X. That Contributor is then a Commercial Contributor. If
  that Commercial Contributor then makes performance claims, or offers
  warranties related to Product X, those performance claims and warranties are
  such Commercial Contributor's responsibility alone. Under this section, the
  Commercial Contributor would have to defend claims against the other
  Contributors related to those performance claims and warranties, and if a
  court requires any other Contributor to pay any damages as a result, the
  Commercial Contributor must pay those damages.
5. NO WARRANTY
  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
  AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
  EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
  CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
  PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
  appropriateness of using and distributing the Program and assumes all risks
  associated with its exercise of rights under this Agreement , including but
  not limited to the risks and costs of program errors, compliance with
  applicable laws, damage to or loss of data, programs or equipment, and
  unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
  CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
  LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
  EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
  OF SUCH DAMAGES.
7. GENERAL
  If any provision of this Agreement is invalid or unenforceable under
  applicable law, it shall not affect the validity or enforceability of the
  remainder of the terms of this Agreement, and without further action by the
  parties hereto, such provision shall be reformed to the minimum extent
  necessary to make such provision valid and enforceable.
  If Recipient institutes patent litigation against any entity (including a
  cross-claim or counterclaim in a lawsuit) alleging that the Program itself
  (excluding combinations of the Program with other software or hardware)
  infringes such Recipient's patent(s), then such Recipient's rights granted
  under Section 2(b) shall terminate as of the date such litigation is filed.
  All Recipient's rights under this Agreement shall terminate if it fails to
  comply with any of the material terms or conditions of this Agreement and
  does not cure such failure in a reasonable period of time after becoming
  aware of such noncompliance. If all Recipient's rights under this Agreement
  terminate, Recipient agrees to cease use and distribution of the Program as
  soon as reasonably practicable. However, Recipient's obligations under this
  Agreement and any licenses granted by Recipient relating to the Program shall
  continue and survive.
  Everyone is permitted to copy and distribute copies of this Agreement, but in
  order to avoid inconsistency the Agreement is copyrighted and may only be
  modified in the following manner. The Agreement Steward reserves the right to
  publish new versions (including revisions) of this Agreement from time to
  time. No one other than the Agreement Steward has the right to modify this
  Agreement. The Eclipse Foundation is the initial Agreement Steward. The
  Eclipse Foundation may assign the responsibility to serve as the Agreement
  Steward to a suitable separate entity. Each new version of the Agreement will
  be given a distinguishing version number. The Program (including
  Contributions) may always be distributed subject to the version of the
  Agreement under which it was received. In addition, after a new version of
  the Agreement is published, Contributor may elect to distribute the Program
  (including its Contributions) under the new version. Except as expressly
  stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
  licenses to the intellectual property of any Contributor under this
  Agreement, whether expressly, by implication, estoppel or otherwise. All
  rights in the Program not expressly granted under this Agreement are
  reserved.
  This Agreement is governed by the laws of the State of New York and the
  intellectual property laws of the United States of America. No party to this
  Agreement will bring a legal action under this Agreement more than one year
  after the cause of action arose. Each party waives its rights to a jury trial
  in any resulting litigation.
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/mysql_log/Makefile
New file
@@ -0,0 +1,15 @@
CFLAGS=-Wall -ggdb
LDFLAGS=../../lib/libmosquitto.so.1 -lmysqlclient
.PHONY: all clean
all : mosquitto_mysql_log
mosquitto_mysql_log : mysql_log.o
    ${CC} $^ -o $@ ${LDFLAGS}
mysql_log.o : mysql_log.c
    ${CC} -c $^ -o $@ ${CFLAGS} -I../../lib
clean :
    -rm -f *.o mosquitto_mysql_log
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/mysql_log/mysql_log.c
New file
@@ -0,0 +1,123 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
#ifndef WIN32
#  include <unistd.h>
#else
#  include <process.h>
#  define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mysql/mysql.h>
#define db_host "localhost"
#define db_username "mqtt_log"
#define db_password "password"
#define db_database "mqtt_log"
#define db_port 3306
#define db_query "INSERT INTO mqtt_log (topic, payload) VALUES (?,?)"
#define mqtt_host "localhost"
#define mqtt_port 1883
static int run = 1;
static MYSQL_STMT *stmt = NULL;
void handle_signal(int s)
{
    run = 0;
}
void connect_callback(struct mosquitto *mosq, void *obj, int result)
{
}
void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    MYSQL_BIND bind[2];
    memset(bind, 0, sizeof(bind));
    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = message->topic;
    bind[0].buffer_length = strlen(message->topic);
    // Note: payload is normally a binary blob and could contains
    // NULL byte. This sample does not handle it and assume payload is a
    // string.
    bind[1].buffer_type = MYSQL_TYPE_STRING;
    bind[1].buffer = message->payload;
    bind[1].buffer_length = message->payloadlen;
    mysql_stmt_bind_param(stmt, bind);
    mysql_stmt_execute(stmt);
}
int main(int argc, char *argv[])
{
    MYSQL *connection;
    my_bool reconnect = true;
    char clientid[24];
    struct mosquitto *mosq;
    int rc = 0;
    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
    mysql_library_init(0, NULL, NULL);
    mosquitto_lib_init();
    connection = mysql_init(NULL);
    if(connection){
        mysql_options(connection, MYSQL_OPT_RECONNECT, &reconnect);
        connection = mysql_real_connect(connection, db_host, db_username, db_password, db_database, db_port, NULL, 0);
        if(connection){
            stmt = mysql_stmt_init(connection);
            mysql_stmt_prepare(stmt, db_query, strlen(db_query));
            memset(clientid, 0, 24);
            snprintf(clientid, 23, "mysql_log_%d", getpid());
            mosq = mosquitto_new(clientid, true, connection);
            if(mosq){
                mosquitto_connect_callback_set(mosq, connect_callback);
                mosquitto_message_callback_set(mosq, message_callback);
                rc = mosquitto_connect(mosq, mqtt_host, mqtt_port, 60);
                mosquitto_subscribe(mosq, NULL, "#", 0);
                while(run){
                    rc = mosquitto_loop(mosq, -1, 1);
                    if(run && rc){
                        sleep(20);
                        mosquitto_reconnect(mosq);
                    }
                }
                mosquitto_destroy(mosq);
            }
            mysql_stmt_close(stmt);
            mysql_close(connection);
        }else{
            fprintf(stderr, "Error: Unable to connect to database.\n");
            printf("%s\n", mysql_error(connection));
            rc = 1;
        }
    }else{
        fprintf(stderr, "Error: Unable to start mysql.\n");
        rc = 1;
    }
    mysql_library_end();
    mosquitto_lib_cleanup();
    return rc;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/Makefile
New file
@@ -0,0 +1,29 @@
include ../../config.mk
.PHONY: all
all : sub_callback sub_single sub_multiple
sub_callback : callback.o
    ${CROSS_COMPILE}${CC} $^ -o $@ ../../lib/libmosquitto.so.${SOVERSION}
sub_single : single.o
    ${CROSS_COMPILE}${CC} $^ -o $@ ../../lib/libmosquitto.so.${SOVERSION}
sub_multiple : multiple.o
    ${CROSS_COMPILE}${CC} $^ -o $@ ../../lib/libmosquitto.so.${SOVERSION}
callback.o : callback.c ../../lib/libmosquitto.so.${SOVERSION}
    ${CROSS_COMPILE}${CC} -c $< -o $@ -I../../lib ${CFLAGS}
single.o : single.c ../../lib/libmosquitto.so.${SOVERSION}
    ${CROSS_COMPILE}${CC} -c $< -o $@ -I../../lib ${CFLAGS}
multiple.o : multiple.c ../../lib/libmosquitto.so.${SOVERSION}
    ${CROSS_COMPILE}${CC} -c $< -o $@ -I../../lib ${CFLAGS}
../../lib/libmosquitto.so.${SOVERSION} :
    $(MAKE) -C ../../lib
clean :
    -rm -f *.o sub_single sub_multiple
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/callback.c
New file
@@ -0,0 +1,34 @@
#include <stdlib.h>
#include <stdio.h>
#include "mosquitto.h"
int on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg)
{
    printf("%s %s (%d)\n", msg->topic, (const char *)msg->payload, msg->payloadlen);
    return 0;
}
int main(int argc, char *argv[])
{
    int rc;
    mosquitto_lib_init();
    rc = mosquitto_subscribe_callback(
            on_message, NULL,
            "irc/#", 0,
            "test.mosquitto.org", 1883,
            NULL, 60, true,
            NULL, NULL,
            NULL, NULL);
    if(rc){
        printf("Error: %s\n", mosquitto_strerror(rc));
    }
    mosquitto_lib_cleanup();
    return rc;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/multiple.c
New file
@@ -0,0 +1,39 @@
#include <stdlib.h>
#include <stdio.h>
#include "mosquitto.h"
#define COUNT 3
int main(int argc, char *argv[])
{
    int rc;
    int i;
    struct mosquitto_message *msg;
    mosquitto_lib_init();
    rc = mosquitto_subscribe_simple(
            &msg, COUNT, true,
            "irc/#", 0,
            "test.mosquitto.org", 1883,
            NULL, 60, true,
            NULL, NULL,
            NULL, NULL);
    if(rc){
        printf("Error: %s\n", mosquitto_strerror(rc));
        mosquitto_lib_cleanup();
        return rc;
    }
    for(i=0; i<COUNT; i++){
        printf("%s %s\n", msg[i].topic, (char *)msg[i].payload);
        mosquitto_message_free_contents(&msg[i]);
    }
    free(msg);
    mosquitto_lib_cleanup();
    return 0;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/subscribe_simple/single.c
New file
@@ -0,0 +1,33 @@
#include <stdlib.h>
#include <stdio.h>
#include "mosquitto.h"
int main(int argc, char *argv[])
{
    int rc;
    struct mosquitto_message *msg;
    mosquitto_lib_init();
    rc = mosquitto_subscribe_simple(
            &msg, 1, true,
            "irc/#", 0,
            "test.mosquitto.org", 1883,
            NULL, 60, true,
            NULL, NULL,
            NULL, NULL);
    if(rc){
        printf("Error: %s\n", mosquitto_strerror(rc));
        mosquitto_lib_cleanup();
        return rc;
    }
    printf("%s %s\n", msg->topic, (char *)msg->payload);
    mosquitto_message_free(&msg);
    mosquitto_lib_cleanup();
    return 0;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/Makefile
New file
@@ -0,0 +1,18 @@
CFLAGS=-Wall -ggdb -I../../lib -I../../lib/cpp
LDFLAGS=-L../../lib ../../lib/cpp/libmosquittopp.so.1 ../../lib/libmosquitto.so.1
.PHONY: all clean
all : mqtt_temperature_conversion
mqtt_temperature_conversion : main.o temperature_conversion.o
    ${CXX} $^ -o $@ ${LDFLAGS}
main.o : main.cpp
    ${CXX} -c $^ -o $@ ${CFLAGS}
temperature_conversion.o : temperature_conversion.cpp
    ${CXX} -c $^ -o $@ ${CFLAGS}
clean :
    -rm -f *.o mqtt_temperature_conversion
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/main.cpp
New file
@@ -0,0 +1,17 @@
#include "temperature_conversion.h"
int main(int argc, char *argv[])
{
    class mqtt_tempconv *tempconv;
    int rc;
    mosqpp::lib_init();
    tempconv = new mqtt_tempconv("tempconv", "localhost", 1883);
    tempconv->loop_forever();
    mosqpp::lib_cleanup();
    return 0;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/readme.txt
New file
@@ -0,0 +1,6 @@
This is a simple example of the C++ library mosquittopp.
It is a client that subscribes to the topic temperature/celsius which should
have temperature data in text form being published to it. It reads this data as
a Celsius temperature, converts to Farenheit and republishes on
temperature/farenheit.
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/temperature_conversion.cpp
New file
@@ -0,0 +1,49 @@
#include <cstdio>
#include <cstring>
#include "temperature_conversion.h"
#include <mosquittopp.h>
mqtt_tempconv::mqtt_tempconv(const char *id, const char *host, int port) : mosquittopp(id)
{
    int keepalive = 60;
    /* Connect immediately. This could also be done by calling
     * mqtt_tempconv->connect(). */
    connect(host, port, keepalive);
};
mqtt_tempconv::~mqtt_tempconv()
{
}
void mqtt_tempconv::on_connect(int rc)
{
    printf("Connected with code %d.\n", rc);
    if(rc == 0){
        /* Only attempt to subscribe on a successful connect. */
        subscribe(NULL, "temperature/celsius");
    }
}
void mqtt_tempconv::on_message(const struct mosquitto_message *message)
{
    double temp_celsius, temp_farenheit;
    char buf[51];
    if(!strcmp(message->topic, "temperature/celsius")){
        memset(buf, 0, 51*sizeof(char));
        /* Copy N-1 bytes to ensure always 0 terminated. */
        memcpy(buf, message->payload, 50*sizeof(char));
        temp_celsius = atof(buf);
        temp_farenheit = temp_celsius*9.0/5.0 + 32.0;
        snprintf(buf, 50, "%f", temp_farenheit);
        publish(NULL, "temperature/farenheit", strlen(buf), buf);
    }
}
void mqtt_tempconv::on_subscribe(int mid, int qos_count, const int *granted_qos)
{
    printf("Subscription succeeded.\n");
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/examples/temperature_conversion/temperature_conversion.h
New file
@@ -0,0 +1,17 @@
#ifndef TEMPERATURE_CONVERSION_H
#define TEMPERATURE_CONVERSION_H
#include <mosquittopp.h>
class mqtt_tempconv : public mosqpp::mosquittopp
{
    public:
        mqtt_tempconv(const char *id, const char *host, int port);
        ~mqtt_tempconv();
        void on_connect(int rc);
        void on_message(const struct mosquitto_message *message);
        void on_subscribe(int mid, int qos_count, const int *granted_qos);
};
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/installer/mosquitto.nsi
New file
@@ -0,0 +1,128 @@
; NSIS installer script for mosquitto
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
; For environment variable code
!include "WinMessages.nsh"
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 1.6.3
OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
InstallDir "$PROGRAMFILES\mosquitto"
;--------------------------------
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
; Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
; Installer sections
Section "Files" SecInstall
    SectionIn RO
    SetOutPath "$INSTDIR"
    File "..\build\src\Release\mosquitto.exe"
    File "..\build\src\Release\mosquitto_passwd.exe"
    File "..\build\client\Release\mosquitto_pub.exe"
    File "..\build\client\Release\mosquitto_sub.exe"
    File "..\build\lib\Release\mosquitto.dll"
    File "..\build\lib\cpp\Release\mosquittopp.dll"
    File "..\aclfile.example"
    File "..\ChangeLog.txt"
    File "..\mosquitto.conf"
    File "..\pwfile.example"
    File "..\readme.md"
    File "..\readme-windows.txt"
    ;File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll"
    File "C:\OpenSSL-Win32\bin\libssl-1_1.dll"
    File "C:\OpenSSL-Win32\bin\libcrypto-1_1.dll"
    File "..\edl-v10"
    File "..\epl-v10"
    SetOutPath "$INSTDIR\devel"
    File "..\lib\mosquitto.h"
    File "..\build\lib\Release\mosquitto.lib"
    File "..\lib\cpp\mosquittopp.h"
    File "..\build\lib\cpp\Release\mosquittopp.lib"
    File "..\src\mosquitto_plugin.h"
    WriteUninstaller "$INSTDIR\Uninstall.exe"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayName" "Eclipse Mosquitto MQTT broker"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "HelpLink" "https://mosquitto.org/"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "URLInfoAbout" "https://mosquitto.org/"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayVersion" "${VERSION}"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoModify" "1"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoRepair" "1"
    WriteRegExpandStr ${env_hklm} MOSQUITTO_DIR $INSTDIR
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
Section "Service" SecService
    ExecWait '"$INSTDIR\mosquitto.exe" install'
SectionEnd
Section "Uninstall"
    ExecWait '"$INSTDIR\mosquitto.exe" uninstall'
    Delete "$INSTDIR\mosquitto.exe"
    Delete "$INSTDIR\mosquitto_passwd.exe"
    Delete "$INSTDIR\mosquitto_pub.exe"
    Delete "$INSTDIR\mosquitto_sub.exe"
    Delete "$INSTDIR\mosquitto.dll"
    Delete "$INSTDIR\mosquittopp.dll"
    Delete "$INSTDIR\aclfile.example"
    Delete "$INSTDIR\ChangeLog.txt"
    Delete "$INSTDIR\mosquitto.conf"
    Delete "$INSTDIR\pwfile.example"
    Delete "$INSTDIR\readme.txt"
    Delete "$INSTDIR\readme-windows.txt"
    ;Delete "$INSTDIR\pthreadVC2.dll"
    Delete "$INSTDIR\libssl-1_1.dll"
    Delete "$INSTDIR\libcrypto-1_1.dll"
    Delete "$INSTDIR\edl-v10"
    Delete "$INSTDIR\epl-v10"
    Delete "$INSTDIR\devel\mosquitto.h"
    Delete "$INSTDIR\devel\mosquitto.lib"
    Delete "$INSTDIR\devel\mosquittopp.h"
    Delete "$INSTDIR\devel\mosquittopp.lib"
    Delete "$INSTDIR\devel\mosquitto_plugin.h"
    Delete "$INSTDIR\Uninstall.exe"
    RMDir "$INSTDIR"
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto"
    DeleteRegValue ${env_hklm} MOSQUITTO_DIR
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
LangString DESC_SecService ${LANG_ENGLISH} "Install mosquitto as a Windows service?"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
    !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
proj1_mqttd/mosquitto/mosquitto-1.6.3/installer/mosquitto64.nsi
New file
@@ -0,0 +1,129 @@
; NSIS installer script for mosquitto
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
; For environment variable code
!include "WinMessages.nsh"
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 1.6.3
OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
!include "x64.nsh"
InstallDir "$PROGRAMFILES64\mosquitto"
;--------------------------------
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
; Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
; Installer sections
Section "Files" SecInstall
    SectionIn RO
    SetOutPath "$INSTDIR"
    File "..\build64\src\Release\mosquitto.exe"
    File "..\build64\src\Release\mosquitto_passwd.exe"
    File "..\build64\client\Release\mosquitto_pub.exe"
    File "..\build64\client\Release\mosquitto_sub.exe"
    File "..\build64\lib\Release\mosquitto.dll"
    File "..\build64\lib\cpp\Release\mosquittopp.dll"
    File "..\aclfile.example"
    File "..\ChangeLog.txt"
    File "..\mosquitto.conf"
    File "..\pwfile.example"
    File "..\readme.md"
    File "..\readme-windows.txt"
    ;File "C:\pthreads\Pre-built.2\dll\x64\pthreadVC2.dll"
    File "C:\OpenSSL-Win64\bin\libssl-1_1-x64.dll"
    File "C:\OpenSSL-Win64\bin\libcrypto-1_1-x64.dll"
    File "..\edl-v10"
    File "..\epl-v10"
    SetOutPath "$INSTDIR\devel"
    File "..\lib\mosquitto.h"
    File "..\build64\lib\Release\mosquitto.lib"
    File "..\lib\cpp\mosquittopp.h"
    File "..\build64\lib\cpp\Release\mosquittopp.lib"
    File "..\src\mosquitto_plugin.h"
    WriteUninstaller "$INSTDIR\Uninstall.exe"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "DisplayName" "Eclipse Mosquitto MQTT broker (64 bit)"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "HelpLink" "https://mosquitto.org/"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "URLInfoAbout" "https://mosquitto.org/"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "DisplayVersion" "${VERSION}"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "NoModify" "1"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "NoRepair" "1"
    WriteRegExpandStr ${env_hklm} MOSQUITTO_DIR $INSTDIR
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
Section "Service" SecService
    ExecWait '"$INSTDIR\mosquitto.exe" install'
SectionEnd
Section "Uninstall"
    ExecWait '"$INSTDIR\mosquitto.exe" uninstall'
    Delete "$INSTDIR\mosquitto.exe"
    Delete "$INSTDIR\mosquitto_passwd.exe"
    Delete "$INSTDIR\mosquitto_pub.exe"
    Delete "$INSTDIR\mosquitto_sub.exe"
    Delete "$INSTDIR\mosquitto.dll"
    Delete "$INSTDIR\mosquittopp.dll"
    Delete "$INSTDIR\aclfile.example"
    Delete "$INSTDIR\ChangeLog.txt"
    Delete "$INSTDIR\mosquitto.conf"
    Delete "$INSTDIR\pwfile.example"
    Delete "$INSTDIR\readme.txt"
    Delete "$INSTDIR\readme-windows.txt"
    ;Delete "$INSTDIR\pthreadVC2.dll"
    Delete "$INSTDIR\libssl-1_1-x64.dll"
    Delete "$INSTDIR\libcrypto-1_1-x64.dll"
    Delete "$INSTDIR\edl-v10"
    Delete "$INSTDIR\epl-v10"
    Delete "$INSTDIR\devel\mosquitto.h"
    Delete "$INSTDIR\devel\mosquitto.lib"
    Delete "$INSTDIR\devel\mosquittopp.h"
    Delete "$INSTDIR\devel\mosquittopp.lib"
    Delete "$INSTDIR\devel\mosquitto_plugin.h"
    Delete "$INSTDIR\Uninstall.exe"
    RMDir "$INSTDIR"
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64"
    DeleteRegValue ${env_hklm} MOSQUITTO_DIR
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
LangString DESC_SecService ${LANG_ENGLISH} "Install mosquitto as a Windows service?"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
    !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/CMakeLists.txt
New file
@@ -0,0 +1,113 @@
option(WITH_STATIC_LIBRARIES "Build static versions of the libmosquitto/pp libraries?" OFF)
option(WITH_PIC "Build the static library with PIC (Position Independent Code) enabled archives?" OFF)
add_subdirectory(cpp)
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
            ${mosquitto_SOURCE_DIR}/src/deps
            ${STDBOOL_H_PATH} ${STDINT_H_PATH}
            ${OPENSSL_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR})
link_directories(${mosquitto_SOURCE_DIR}/lib)
set(C_SRC
    actions.c
    callbacks.c
    connect.c
    handle_auth.c
    handle_connack.c
    handle_disconnect.c
    handle_ping.c
    handle_pubackcomp.c
    handle_publish.c
    handle_pubrec.c
    handle_pubrel.c
    handle_suback.c
    handle_unsuback.c
    helpers.c
    logging_mosq.c logging_mosq.h
    loop.c
    memory_mosq.c memory_mosq.h
    messages_mosq.c messages_mosq.h
    mosquitto.c mosquitto.h
    mosquitto_internal.h
    mqtt_protocol.h
    net_mosq_ocsp.c net_mosq.c net_mosq.h
    options.c
    packet_datatypes.c
    packet_mosq.c packet_mosq.h
    property_mosq.c property_mosq.h
    read_handle.c read_handle.h
    send_connect.c
    send_disconnect.c
    send_mosq.c
    send_publish.c
    send_subscribe.c
    send_unsubscribe.c
    send_mosq.c send_mosq.h
    socks_mosq.c
    srv_mosq.c
    thread_mosq.c
    time_mosq.c
    tls_mosq.c
    utf8_mosq.c
    util_mosq.c util_topic.c util_mosq.h
    will_mosq.c will_mosq.h)
set (LIBRARIES ${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES})
if (UNIX AND NOT APPLE)
    find_library(LIBRT rt)
    if (LIBRT)
        set (LIBRARIES ${LIBRARIES} rt)
    endif (LIBRT)
endif (UNIX AND NOT APPLE)
if (WIN32)
    set (LIBRARIES ${LIBRARIES} ws2_32)
endif (WIN32)
if (WITH_SRV)
    # Simple detect c-ares
    find_path(ARES_HEADER ares.h)
    if (ARES_HEADER)
        add_definitions("-DWITH_SRV")
        set (LIBRARIES ${LIBRARIES} cares)
    else (ARES_HEADER)
        message(WARNING "c-ares library not found.")
    endif (ARES_HEADER)
endif (WITH_SRV)
add_library(libmosquitto SHARED ${C_SRC})
set_target_properties(libmosquitto PROPERTIES
    POSITION_INDEPENDENT_CODE 1
)
target_link_libraries(libmosquitto ${LIBRARIES})
set_target_properties(libmosquitto PROPERTIES
    OUTPUT_NAME mosquitto
    VERSION ${VERSION}
    SOVERSION 1
)
install(TARGETS libmosquitto RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
if (WITH_STATIC_LIBRARIES)
    add_library(libmosquitto_static STATIC ${C_SRC})
    if (WITH_PIC)
        set_target_properties(libmosquitto_static PROPERTIES
            POSITION_INDEPENDENT_CODE 1
        )
    endif (WITH_PIC)
    target_link_libraries(libmosquitto_static ${LIBRARIES})
    set_target_properties(libmosquitto_static PROPERTIES
        OUTPUT_NAME mosquitto
        VERSION ${VERSION}
    )
    target_compile_definitions(libmosquitto_static PUBLIC "LIBMOSQUITTO_STATIC")
    install(TARGETS libmosquitto_static ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif (WITH_STATIC_LIBRARIES)
install(FILES mosquitto.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/Makefile
New file
@@ -0,0 +1,220 @@
include ../config.mk
.PHONY : really clean install
MOSQ_OBJS=mosquitto.o \
          actions.o \
          callbacks.o \
          connect.o \
          handle_auth.o \
          handle_connack.o \
          handle_disconnect.o \
          handle_ping.o \
          handle_pubackcomp.o \
          handle_publish.o \
          handle_pubrec.o \
          handle_pubrel.o \
          handle_suback.o \
          handle_unsuback.o \
          helpers.o \
          logging_mosq.o \
          loop.o \
          memory_mosq.o \
          messages_mosq.o \
          net_mosq_ocsp.o \
          net_mosq.o \
          options.o \
          packet_datatypes.o \
          packet_mosq.o \
          property_mosq.o \
          read_handle.o \
          send_connect.o \
          send_disconnect.o \
          send_mosq.o \
          send_publish.o \
          send_subscribe.o \
          send_unsubscribe.o \
          socks_mosq.o \
          srv_mosq.o \
          thread_mosq.o \
          time_mosq.o \
          tls_mosq.o \
          utf8_mosq.o \
          util_mosq.o \
          util_topic.o \
          will_mosq.o
ALL_DEPS:=
ifeq ($(WITH_SHARED_LIBRARIES),yes)
    ALL_DEPS+=libmosquitto.so.${SOVERSION}
endif
ifeq ($(WITH_STATIC_LIBRARIES),yes)
    ALL_DEPS+=libmosquitto.a
endif
all : ${ALL_DEPS}
ifeq ($(WITH_SHARED_LIBRARIES),yes)
    $(MAKE) -C cpp
endif
install : all
    $(INSTALL) -d "${DESTDIR}${libdir}/"
ifeq ($(WITH_SHARED_LIBRARIES),yes)
    $(INSTALL) ${STRIP_OPTS} libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}"
    ln -sf libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so"
endif
ifeq ($(WITH_STATIC_LIBRARIES),yes)
    $(INSTALL) ${STRIP_OPTS} libmosquitto.a "${DESTDIR}${libdir}/libmosquitto.a"
endif
    $(INSTALL) -d "${DESTDIR}${incdir}/"
    $(INSTALL) mosquitto.h "${DESTDIR}${incdir}/mosquitto.h"
    $(INSTALL) -d "${DESTDIR}${libdir}/pkgconfig"
    $(INSTALL) -m644 ../libmosquitto.pc.in "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc"
    sed -i -e "s#@CMAKE_INSTALL_PREFIX@#${prefix}#" -e "s#@VERSION@#${VERSION}#" "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc"
ifeq ($(WITH_SHARED_LIBRARIES),yes)
    $(MAKE) -C cpp install
endif
uninstall :
    -rm -f "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}"
    -rm -f "${DESTDIR}${libdir}/libmosquitto.so"
    -rm -f "${DESTDIR}${libdir}/libmosquitto.a"
    -rm -f "${DESTDIR}${incdir}/mosquitto.h"
reallyclean : clean
clean :
    -rm -f *.o libmosquitto.so.${SOVERSION} libmosquitto.so libmosquitto.a *.gcno *.gcda
    $(MAKE) -C cpp clean
libmosquitto.so.${SOVERSION} : ${MOSQ_OBJS}
    ${CROSS_COMPILE}$(CC) -shared $(LIB_LDFLAGS) $^ -o $@ ${LIB_LIBADD}
libmosquitto.a : ${MOSQ_OBJS}
    ${CROSS_COMPILE}$(AR) cr $@ $^
mosquitto.o : mosquitto.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
actions.o : actions.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
callbacks.o : callbacks.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
connect.o : connect.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_auth.o : handle_auth.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_connack.o : handle_connack.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_disconnect.o : handle_disconnect.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_publish.o : handle_publish.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_ping.o : handle_ping.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_pubackcomp.o : handle_pubackcomp.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_pubrec.o : handle_pubrec.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_pubrel.o : handle_pubrel.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_suback.o : handle_suback.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
handle_unsuback.o : handle_unsuback.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
helpers.o : helpers.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
logging_mosq.o : logging_mosq.c logging_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
loop.o : loop.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
messages_mosq.o : messages_mosq.c messages_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
memory_mosq.o : memory_mosq.c memory_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
net_mosq_ocsp.o : net_mosq_ocsp.c net_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
net_mosq.o : net_mosq.c net_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
options.o : options.c mosquitto.h mosquitto_internal.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
packet_datatypes.o : packet_datatypes.c packet_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
packet_mosq.o : packet_mosq.c packet_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
property_mosq.o : property_mosq.c property_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
read_handle.o : read_handle.c read_handle.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_connect.o : send_connect.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_disconnect.o : send_disconnect.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_mosq.o : send_mosq.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_publish.o : send_publish.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_subscribe.o : send_subscribe.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
send_unsubscribe.o : send_unsubscribe.c send_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
socks_mosq.o : socks_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
srv_mosq.o : srv_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
thread_mosq.o : thread_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
time_mosq.o : time_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
tls_mosq.o : tls_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
utf8_mosq.o : utf8_mosq.c
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
util_mosq.o : util_mosq.c util_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
util_topic.o : util_topic.c util_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
will_mosq.o : will_mosq.c will_mosq.h
    ${CROSS_COMPILE}$(CC) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -c $< -o $@
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/actions.c
New file
@@ -0,0 +1,260 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include <string.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "send_mosq.h"
#include "util_mosq.h"
int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
    return mosquitto_publish_v5(mosq, mid, topic, payloadlen, payload, qos, retain, NULL);
}
int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain, const mosquitto_property *properties)
{
    struct mosquitto_message_all *message;
    uint16_t local_mid;
    const mosquitto_property *p;
    const mosquitto_property *outgoing_properties = NULL;
    mosquitto_property local_property;
    bool have_topic_alias;
    int rc;
    int tlen = 0;
    uint32_t remaining_length;
    if(!mosq || qos<0 || qos>2) return MOSQ_ERR_INVAL;
    if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
    if(qos > mosq->maximum_qos) return MOSQ_ERR_QOS_NOT_SUPPORTED;
    if(properties){
        if(properties->client_generated){
            outgoing_properties = properties;
        }else{
            memcpy(&local_property, properties, sizeof(mosquitto_property));
            local_property.client_generated = true;
            local_property.next = NULL;
            outgoing_properties = &local_property;
        }
        rc = mosquitto_property_check_all(CMD_PUBLISH, outgoing_properties);
        if(rc) return rc;
    }
    if(!topic || STREMPTY(topic)){
        if(topic) topic = NULL;
        if(mosq->protocol == mosq_p_mqtt5){
            p = outgoing_properties;
            have_topic_alias = false;
            while(p){
                if(p->identifier == MQTT_PROP_TOPIC_ALIAS){
                    have_topic_alias = true;
                    break;
                }
                p = p->next;
            }
            if(have_topic_alias == false){
                return MOSQ_ERR_INVAL;
            }
        }else{
            return MOSQ_ERR_INVAL;
        }
    }else{
        tlen = strlen(topic);
        if(mosquitto_validate_utf8(topic, tlen)) return MOSQ_ERR_MALFORMED_UTF8;
        if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE;
        if(mosquitto_pub_topic_check(topic) != MOSQ_ERR_SUCCESS){
            return MOSQ_ERR_INVAL;
        }
    }
    if(mosq->maximum_packet_size > 0){
        remaining_length = 1 + 2+tlen + payloadlen + property__get_length_all(outgoing_properties);
        if(qos > 0){
            remaining_length++;
        }
        if(packet__check_oversize(mosq, remaining_length)){
            return MOSQ_ERR_OVERSIZE_PACKET;
        }
    }
    local_mid = mosquitto__mid_generate(mosq);
    if(mid){
        *mid = local_mid;
    }
    if(qos == 0){
        return send__publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false, outgoing_properties, NULL, 0);
    }else{
        message = mosquitto__calloc(1, sizeof(struct mosquitto_message_all));
        if(!message) return MOSQ_ERR_NOMEM;
        message->next = NULL;
        message->timestamp = mosquitto_time();
        message->msg.mid = local_mid;
        if(topic){
            message->msg.topic = mosquitto__strdup(topic);
            if(!message->msg.topic){
                message__cleanup(&message);
                return MOSQ_ERR_NOMEM;
            }
        }
        if(payloadlen){
            message->msg.payloadlen = payloadlen;
            message->msg.payload = mosquitto__malloc(payloadlen*sizeof(uint8_t));
            if(!message->msg.payload){
                message__cleanup(&message);
                return MOSQ_ERR_NOMEM;
            }
            memcpy(message->msg.payload, payload, payloadlen*sizeof(uint8_t));
        }else{
            message->msg.payloadlen = 0;
            message->msg.payload = NULL;
        }
        message->msg.qos = qos;
        message->msg.retain = retain;
        message->dup = false;
        pthread_mutex_lock(&mosq->msgs_out.mutex);
        message->state = mosq_ms_invalid;
        message__queue(mosq, message, mosq_md_out);
        pthread_mutex_unlock(&mosq->msgs_out.mutex);
        return MOSQ_ERR_SUCCESS;
    }
}
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos)
{
    return mosquitto_subscribe_multiple(mosq, mid, 1, (char *const *const)&sub, qos, 0, NULL);
}
int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties)
{
    return mosquitto_subscribe_multiple(mosq, mid, 1, (char *const *const)&sub, qos, options, properties);
}
int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties)
{
    const mosquitto_property *outgoing_properties = NULL;
    mosquitto_property local_property;
    int i;
    int rc;
    uint32_t remaining_length = 0;
    int slen;
    if(!mosq || !sub_count || !sub) return MOSQ_ERR_INVAL;
    if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
    if(qos < 0 || qos > 2) return MOSQ_ERR_INVAL;
    if((options & 0x30) == 0x30 || (options & 0xC0) != 0) return MOSQ_ERR_INVAL;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
    if(properties){
        if(properties->client_generated){
            outgoing_properties = properties;
        }else{
            memcpy(&local_property, properties, sizeof(mosquitto_property));
            local_property.client_generated = true;
            local_property.next = NULL;
            outgoing_properties = &local_property;
        }
        rc = mosquitto_property_check_all(CMD_SUBSCRIBE, outgoing_properties);
        if(rc) return rc;
    }
    for(i=0; i<sub_count; i++){
        if(mosquitto_sub_topic_check(sub[i])) return MOSQ_ERR_INVAL;
        slen = strlen(sub[i]);
        if(mosquitto_validate_utf8(sub[i], slen)) return MOSQ_ERR_MALFORMED_UTF8;
        remaining_length += 2+slen + 1;
    }
    if(mosq->maximum_packet_size > 0){
        remaining_length += 2 + property__get_length_all(outgoing_properties);
        if(packet__check_oversize(mosq, remaining_length)){
            return MOSQ_ERR_OVERSIZE_PACKET;
        }
    }
    return send__subscribe(mosq, mid, sub_count, sub, qos|options, outgoing_properties);
}
int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub)
{
    return mosquitto_unsubscribe_multiple(mosq, mid, 1, (char *const *const)&sub, NULL);
}
int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties)
{
    return mosquitto_unsubscribe_multiple(mosq, mid, 1, (char *const *const)&sub, properties);
}
int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties)
{
    const mosquitto_property *outgoing_properties = NULL;
    mosquitto_property local_property;
    int rc;
    int i;
    uint32_t remaining_length = 0;
    int slen;
    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
    if(properties){
        if(properties->client_generated){
            outgoing_properties = properties;
        }else{
            memcpy(&local_property, properties, sizeof(mosquitto_property));
            local_property.client_generated = true;
            local_property.next = NULL;
            outgoing_properties = &local_property;
        }
        rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, outgoing_properties);
        if(rc) return rc;
    }
    for(i=0; i<sub_count; i++){
        if(mosquitto_sub_topic_check(sub[i])) return MOSQ_ERR_INVAL;
        slen = strlen(sub[i]);
        if(mosquitto_validate_utf8(sub[i], slen)) return MOSQ_ERR_MALFORMED_UTF8;
        remaining_length += 2+slen;
    }
    if(mosq->maximum_packet_size > 0){
        remaining_length += 2 + property__get_length_all(outgoing_properties);
        if(packet__check_oversize(mosq, remaining_length)){
            return MOSQ_ERR_OVERSIZE_PACKET;
        }
    }
    return send__unsubscribe(mosq, mid, sub_count, sub, outgoing_properties);
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/actions.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/alias_mosq.c
New file
@@ -0,0 +1,85 @@
/*
Copyright (c) 2019 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 "config.h"
#include "mosquitto.h"
#include "alias_mosq.h"
#include "memory_mosq.h"
int alias__add(struct mosquitto *mosq, const char *topic, int alias)
{
    int i;
    struct mosquitto__alias *aliases;
    for(i=0; i<mosq->alias_count; i++){
        if(mosq->aliases[i].alias == alias){
            mosquitto__free(mosq->aliases[i].topic);
            mosq->aliases[i].topic = mosquitto__strdup(topic);
            if(mosq->aliases[i].topic){
                return MOSQ_ERR_SUCCESS;
            }else{
                return MOSQ_ERR_NOMEM;
            }
        }
    }
    /* New alias */
    aliases = mosquitto__realloc(mosq->aliases, sizeof(struct mosquitto__alias)*(mosq->alias_count+1));
    if(!aliases) return MOSQ_ERR_NOMEM;
    mosq->aliases = aliases;
    mosq->aliases[mosq->alias_count].alias = alias;
    mosq->aliases[mosq->alias_count].topic = mosquitto__strdup(topic);
    if(!mosq->aliases[mosq->alias_count].topic){
        return MOSQ_ERR_NOMEM;
    }
    mosq->alias_count++;
    return MOSQ_ERR_SUCCESS;
}
int alias__find(struct mosquitto *mosq, char **topic, int alias)
{
    int i;
    for(i=0; i<mosq->alias_count; i++){
        if(mosq->aliases[i].alias == alias){
            *topic = mosquitto__strdup(mosq->aliases[i].topic);
            if(*topic){
                return MOSQ_ERR_SUCCESS;
            }else{
                return MOSQ_ERR_NOMEM;
            }
        }
    }
    return MOSQ_ERR_INVAL;
}
void alias__free_all(struct mosquitto *mosq)
{
    int i;
    for(i=0; i<mosq->alias_count; i++){
        mosquitto__free(mosq->aliases[i].topic);
    }
    mosquitto__free(mosq->aliases);
    mosq->aliases = NULL;
    mosq->alias_count = 0;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/alias_mosq.h
New file
@@ -0,0 +1,26 @@
/*
Copyright (c) 2019 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.
*/
#ifndef ALIAS_MOSQ_H
#define ALIAS_MOSQ_H
#include "mosquitto_internal.h"
int alias__add(struct mosquitto *mosq, const char *topic, int alias);
int alias__find(struct mosquitto *mosq, char **topic, int alias);
void alias__free_all(struct mosquitto *mosq);
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/callbacks.c
New file
@@ -0,0 +1,120 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include "mosquitto.h"
#include "mosquitto_internal.h"
void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_connect = on_connect;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_connect_with_flags = on_connect;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_connect_v5 = on_connect;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_disconnect = on_disconnect;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_disconnect_v5 = on_disconnect;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_publish = on_publish;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *props))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_publish_v5 = on_publish;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_message = on_message;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *props))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_message_v5 = on_message;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_subscribe = on_subscribe;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_subscribe_v5 = on_subscribe;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_unsubscribe = on_unsubscribe;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *props))
{
    pthread_mutex_lock(&mosq->callback_mutex);
    mosq->on_unsubscribe_v5 = on_unsubscribe;
    pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *))
{
    pthread_mutex_lock(&mosq->log_callback_mutex);
    mosq->on_log = on_log;
    pthread_mutex_unlock(&mosq->log_callback_mutex);
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/callbacks.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/connect.c
New file
@@ -0,0 +1,330 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include <string.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "messages_mosq.h"
#include "memory_mosq.h"
#include "packet_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "send_mosq.h"
#include "socks_mosq.h"
#include "util_mosq.h"
static char alphanum[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mosquitto_property *properties);
static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address);
static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address)
{
    int i;
    int rc;
    if(!mosq) return MOSQ_ERR_INVAL;
    if(!host || port <= 0) return MOSQ_ERR_INVAL;
    if(mosq->id == NULL && (mosq->protocol == mosq_p_mqtt31 || mosq->protocol == mosq_p_mqtt311)){
        mosq->id = (char *)mosquitto__calloc(24, sizeof(char));
        if(!mosq->id){
            return MOSQ_ERR_NOMEM;
        }
        mosq->id[0] = 'm';
        mosq->id[1] = 'o';
        mosq->id[2] = 's';
        mosq->id[3] = 'q';
        mosq->id[4] = '/';
        rc = util__random_bytes(&mosq->id[5], 18);
        if(rc) return rc;
        for(i=5; i<23; i++){
            mosq->id[i] = alphanum[(mosq->id[i]&0x7F)%(sizeof(alphanum)-1)];
        }
    }
    mosquitto__free(mosq->host);
    mosq->host = mosquitto__strdup(host);
    if(!mosq->host) return MOSQ_ERR_NOMEM;
    mosq->port = port;
    mosquitto__free(mosq->bind_address);
    if(bind_address){
        mosq->bind_address = mosquitto__strdup(bind_address);
        if(!mosq->bind_address) return MOSQ_ERR_NOMEM;
    }
    mosq->keepalive = keepalive;
    mosq->msgs_in.inflight_quota = mosq->msgs_in.inflight_maximum;
    mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum;
    if(mosq->sockpairR != INVALID_SOCKET){
        COMPAT_CLOSE(mosq->sockpairR);
        mosq->sockpairR = INVALID_SOCKET;
    }
    if(mosq->sockpairW != INVALID_SOCKET){
        COMPAT_CLOSE(mosq->sockpairW);
        mosq->sockpairW = INVALID_SOCKET;
    }
    if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){
        log__printf(mosq, MOSQ_LOG_WARNING,
                "Warning: Unable to open socket pair, outgoing publish commands may be delayed.");
    }
    return MOSQ_ERR_SUCCESS;
}
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive)
{
    return mosquitto_connect_bind(mosq, host, port, keepalive, NULL);
}
int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address)
{
    return mosquitto_connect_bind_v5(mosq, host, port, keepalive, bind_address, NULL);
}
int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties)
{
    int rc;
    if(properties){
        rc = mosquitto_property_check_all(CMD_CONNECT, properties);
        if(rc) return rc;
    }
    rc = mosquitto__connect_init(mosq, host, port, keepalive, bind_address);
    if(rc) return rc;
    pthread_mutex_lock(&mosq->state_mutex);
    mosq->state = mosq_cs_new;
    pthread_mutex_unlock(&mosq->state_mutex);
    return mosquitto__reconnect(mosq, true, properties);
}
int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive)
{
    return mosquitto_connect_bind_async(mosq, host, port, keepalive, NULL);
}
int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address)
{
    int rc = mosquitto__connect_init(mosq, host, port, keepalive, bind_address);
    if(rc) return rc;
    pthread_mutex_lock(&mosq->state_mutex);
    mosq->state = mosq_cs_connect_async;
    pthread_mutex_unlock(&mosq->state_mutex);
    return mosquitto__reconnect(mosq, false, NULL);
}
int mosquitto_reconnect_async(struct mosquitto *mosq)
{
    return mosquitto__reconnect(mosq, false, NULL);
}
int mosquitto_reconnect(struct mosquitto *mosq)
{
    return mosquitto__reconnect(mosq, true, NULL);
}
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mosquitto_property *properties)
{
    const mosquitto_property *outgoing_properties = NULL;
    mosquitto_property local_property;
    int rc;
    struct mosquitto__packet *packet;
    if(!mosq) return MOSQ_ERR_INVAL;
    if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
    if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
    if(properties){
        if(properties->client_generated){
            outgoing_properties = properties;
        }else{
            memcpy(&local_property, properties, sizeof(mosquitto_property));
            local_property.client_generated = true;
            local_property.next = NULL;
            outgoing_properties = &local_property;
        }
        rc = mosquitto_property_check_all(CMD_CONNECT, outgoing_properties);
        if(rc) return rc;
    }
    pthread_mutex_lock(&mosq->state_mutex);
#ifdef WITH_SOCKS
    if(mosq->socks5_host){
        mosq->state = mosq_cs_socks5_new;
    }else
#endif
    {
        mosq->state = mosq_cs_new;
    }
    pthread_mutex_unlock(&mosq->state_mutex);
    pthread_mutex_lock(&mosq->msgtime_mutex);
    mosq->last_msg_in = mosquitto_time();
    mosq->next_msg_out = mosq->last_msg_in + mosq->keepalive;
    pthread_mutex_unlock(&mosq->msgtime_mutex);
    mosq->ping_t = 0;
    packet__cleanup(&mosq->in_packet);
    pthread_mutex_lock(&mosq->current_out_packet_mutex);
    pthread_mutex_lock(&mosq->out_packet_mutex);
    if(mosq->out_packet && !mosq->current_out_packet){
        mosq->current_out_packet = mosq->out_packet;
        mosq->out_packet = mosq->out_packet->next;
    }
    while(mosq->current_out_packet){
        packet = mosq->current_out_packet;
        /* Free data and reset values */
        mosq->current_out_packet = mosq->out_packet;
        if(mosq->out_packet){
            mosq->out_packet = mosq->out_packet->next;
        }
        packet__cleanup(packet);
        mosquitto__free(packet);
    }
    pthread_mutex_unlock(&mosq->out_packet_mutex);
    pthread_mutex_unlock(&mosq->current_out_packet_mutex);
    message__reconnect_reset(mosq);
    if(mosq->sock != INVALID_SOCKET){
        net__socket_close(mosq); //close socket
    }
#ifdef WITH_SOCKS
    if(mosq->socks5_host){
        rc = net__socket_connect(mosq, mosq->socks5_host, mosq->socks5_port, mosq->bind_address, blocking);
    }else
#endif
    {
        pthread_mutex_lock(&mosq->state_mutex);
        mosq->state = mosq_cs_connecting;
        pthread_mutex_unlock(&mosq->state_mutex);
        rc = net__socket_connect(mosq, mosq->host, mosq->port, mosq->bind_address, blocking);
    }
    if(rc>0){
        return rc;
    }
#ifdef WITH_SOCKS
    if(mosq->socks5_host){
        return socks5__send(mosq);
    }else
#endif
    {
        return send__connect(mosq, mosq->keepalive, mosq->clean_start, outgoing_properties);
    }
}
int mosquitto_disconnect(struct mosquitto *mosq)
{
    return mosquitto_disconnect_v5(mosq, 0, NULL);
}
int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties)
{
    const mosquitto_property *outgoing_properties = NULL;
    mosquitto_property local_property;
    int rc;
    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
    if(properties){
        if(properties->client_generated){
            outgoing_properties = properties;
        }else{
            memcpy(&local_property, properties, sizeof(mosquitto_property));
            local_property.client_generated = true;
            local_property.next = NULL;
            outgoing_properties = &local_property;
        }
        rc = mosquitto_property_check_all(CMD_DISCONNECT, outgoing_properties);
        if(rc) return rc;
    }
    pthread_mutex_lock(&mosq->state_mutex);
    mosq->state = mosq_cs_disconnecting;
    pthread_mutex_unlock(&mosq->state_mutex);
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
    return send__disconnect(mosq, reason_code, outgoing_properties);
}
void do_client_disconnect(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties)
{
    pthread_mutex_lock(&mosq->state_mutex);
    mosq->state = mosq_cs_disconnecting;
    pthread_mutex_unlock(&mosq->state_mutex);
    net__socket_close(mosq);
    /* Free data and reset values */
    pthread_mutex_lock(&mosq->out_packet_mutex);
    mosq->current_out_packet = mosq->out_packet;
    if(mosq->out_packet){
        mosq->out_packet = mosq->out_packet->next;
        if(!mosq->out_packet){
            mosq->out_packet_last = NULL;
        }
    }
    pthread_mutex_unlock(&mosq->out_packet_mutex);
    pthread_mutex_lock(&mosq->msgtime_mutex);
    mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
    pthread_mutex_unlock(&mosq->msgtime_mutex);
    pthread_mutex_lock(&mosq->callback_mutex);
    if(mosq->on_disconnect){
        mosq->in_callback = true;
        mosq->on_disconnect(mosq, mosq->userdata, reason_code);
        mosq->in_callback = false;
    }
    if(mosq->on_disconnect_v5){
        mosq->in_callback = true;
        mosq->on_disconnect_v5(mosq, mosq->userdata, reason_code, properties);
        mosq->in_callback = false;
    }
    pthread_mutex_unlock(&mosq->callback_mutex);
    pthread_mutex_unlock(&mosq->current_out_packet_mutex);
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/connect.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/CMakeLists.txt
New file
@@ -0,0 +1,40 @@
include_directories(${mosquitto_SOURCE_DIR}/lib ${mosquitto_SOURCE_DIR}/lib/cpp
            ${STDBOOL_H_PATH} ${STDINT_H_PATH})
link_directories(${mosquitto_BINARY_DIR}/lib)
set(CPP_SRC mosquittopp.cpp mosquittopp.h)
add_library(mosquittopp SHARED ${CPP_SRC})
set_target_properties(mosquittopp PROPERTIES
    POSITION_INDEPENDENT_CODE 1
)
target_link_libraries(mosquittopp libmosquitto)
set_target_properties(mosquittopp PROPERTIES
    VERSION ${VERSION}
    SOVERSION 1
)
install(TARGETS mosquittopp RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
if (WITH_STATIC_LIBRARIES)
    add_library(mosquittopp_static STATIC
        ${C_SRC}
        ${CPP_SRC}
    )
    if (WITH_PIC)
        set_target_properties(mosquittopp_static PROPERTIES
            POSITION_INDEPENDENT_CODE 1
        )
    endif (WITH_PIC)
    target_link_libraries(mosquittopp_static ${LIBRARIES})
    set_target_properties(mosquittopp_static PROPERTIES
        OUTPUT_NAME mosquittopp
        VERSION ${VERSION}
    )
    target_compile_definitions(mosquittopp_static PUBLIC "LIBMOSQUITTO_STATIC")
    install(TARGETS mosquittopp_static ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif (WITH_STATIC_LIBRARIES)
install(FILES mosquittopp.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/Makefile
New file
@@ -0,0 +1,48 @@
include ../../config.mk
ifneq ($(UNAME),SunOS)
    LIB_LDFLAGS:=$(LDFLAGS) -Wl,-soname,libmosquittopp.so.${SOVERSION}
endif
.PHONY : clean install
ALL_DEPS=libmosquittopp.so.${SOVERSION}
ifeq ($(WITH_STATIC_LIBRARIES),yes)
    ALL_DEPS+=libmosquittopp.a
endif
all : ${ALL_DEPS}
install : all
    $(INSTALL) -d "${DESTDIR}${libdir}/"
    $(INSTALL) ${STRIP_OPTS} libmosquittopp.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquittopp.so.${SOVERSION}"
    ln -sf libmosquittopp.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquittopp.so"
ifeq ($(WITH_STATIC_LIBRARIES),yes)
    $(INSTALL) libmosquittopp.a "${DESTDIR}${libdir}/libmosquittopp.a"
    ${CROSS_COMPILE}${STRIP} -g --strip-unneeded "${DESTDIR}${libdir}/libmosquittopp.a"
endif
    $(INSTALL) -d "${DESTDIR}${incdir}/"
    $(INSTALL) mosquittopp.h "${DESTDIR}${incdir}/mosquittopp.h"
    $(INSTALL) -d "${DESTDIR}${libdir}/pkgconfig/"
    $(INSTALL) -m644 ../../libmosquittopp.pc.in "${DESTDIR}${libdir}/pkgconfig/libmosquittopp.pc"
    sed -i -e "s#@CMAKE_INSTALL_PREFIX@#${prefix}#" -e "s#@VERSION@#${VERSION}#" "${DESTDIR}${libdir}/pkgconfig/libmosquittopp.pc"
uninstall :
    -rm -f "${DESTDIR}${libdir}/libmosquittopp.so.${SOVERSION}"
    -rm -f "${DESTDIR}${libdir}/libmosquittopp.so"
    -rm -f "${DESTDIR}${libdir}/libmosquittopp.a"
    -rm -f "${DESTDIR}${incdir}/mosquittopp.h"
clean :
    -rm -f *.o libmosquittopp.so.${SOVERSION} libmosquittopp.a
libmosquittopp.so.${SOVERSION} : mosquittopp.o
    ${CROSS_COMPILE}$(CXX) -shared $(LIB_LDFLAGS) $< -o $@ ../libmosquitto.so.${SOVERSION} $(LIB_LIDADD)
libmosquittopp.a : mosquittopp.o
    ${CROSS_COMPILE}$(AR) cr $@ $^
mosquittopp.o : mosquittopp.cpp mosquittopp.h
    ${CROSS_COMPILE}$(CXX) $(LIB_CPPFLAGS) $(LIB_CXXFLAGS) -c $< -o $@
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/libmosquittopp.so.1
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.cpp
New file
@@ -0,0 +1,381 @@
/*
Copyright (c) 2010-2019 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 <cstdlib>
#include <mosquitto.h>
#include <mosquittopp.h>
#define UNUSED(A) (void)(A)
namespace mosqpp {
static void on_connect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_connect(rc);
}
static void on_connect_with_flags_wrapper(struct mosquitto *mosq, void *userdata, int rc, int flags)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_connect_with_flags(rc, flags);
}
static void on_disconnect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_disconnect(rc);
}
static void on_publish_wrapper(struct mosquitto *mosq, void *userdata, int mid)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_publish(mid);
}
static void on_message_wrapper(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_message(message);
}
static void on_subscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_subscribe(mid, qos_count, granted_qos);
}
static void on_unsubscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_unsubscribe(mid);
}
static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
    class mosquittopp *m = (class mosquittopp *)userdata;
    UNUSED(mosq);
    m->on_log(level, str);
}
int lib_version(int *major, int *minor, int *revision)
{
    if(major) *major = LIBMOSQUITTO_MAJOR;
    if(minor) *minor = LIBMOSQUITTO_MINOR;
    if(revision) *revision = LIBMOSQUITTO_REVISION;
    return LIBMOSQUITTO_VERSION_NUMBER;
}
int lib_init()
{
    return mosquitto_lib_init();
}
int lib_cleanup()
{
    return mosquitto_lib_cleanup();
}
const char* strerror(int mosq_errno)
{
    return mosquitto_strerror(mosq_errno);
}
const char* connack_string(int connack_code)
{
    return mosquitto_connack_string(connack_code);
}
int sub_topic_tokenise(const char *subtopic, char ***topics, int *count)
{
    return mosquitto_sub_topic_tokenise(subtopic, topics, count);
}
int sub_topic_tokens_free(char ***topics, int count)
{
    return mosquitto_sub_topic_tokens_free(topics, count);
}
int topic_matches_sub(const char *sub, const char *topic, bool *result)
{
    return mosquitto_topic_matches_sub(sub, topic, result);
}
int validate_utf8(const char *str, int len)
{
    return mosquitto_validate_utf8(str, len);
}
int subscribe_simple(
        struct mosquitto_message **messages,
        int msg_count,
        bool retained,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls)
{
    return mosquitto_subscribe_simple(
            messages, msg_count, retained,
            topic, qos,
            host, port, client_id, keepalive, clean_session,
            username, password,
            will, tls);
}
mosqpp_EXPORT int subscribe_callback(
        int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
        void *userdata,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls)
{
    return mosquitto_subscribe_callback(
            callback, userdata,
            topic, qos,
            host, port, client_id, keepalive, clean_session,
            username, password,
            will, tls);
}
mosquittopp::mosquittopp(const char *id, bool clean_session)
{
    m_mosq = mosquitto_new(id, clean_session, this);
    mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
    mosquitto_connect_with_flags_callback_set(m_mosq, on_connect_with_flags_wrapper);
    mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
    mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
    mosquitto_message_callback_set(m_mosq, on_message_wrapper);
    mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
    mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
    mosquitto_log_callback_set(m_mosq, on_log_wrapper);
}
mosquittopp::~mosquittopp()
{
    mosquitto_destroy(m_mosq);
}
int mosquittopp::reinitialise(const char *id, bool clean_session)
{
    int rc;
    rc = mosquitto_reinitialise(m_mosq, id, clean_session, this);
    if(rc == MOSQ_ERR_SUCCESS){
        mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
        mosquitto_connect_with_flags_callback_set(m_mosq, on_connect_with_flags_wrapper);
        mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
        mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
        mosquitto_message_callback_set(m_mosq, on_message_wrapper);
        mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
        mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
        mosquitto_log_callback_set(m_mosq, on_log_wrapper);
    }
    return rc;
}
int mosquittopp::connect(const char *host, int port, int keepalive)
{
    return mosquitto_connect(m_mosq, host, port, keepalive);
}
int mosquittopp::connect(const char *host, int port, int keepalive, const char *bind_address)
{
    return mosquitto_connect_bind(m_mosq, host, port, keepalive, bind_address);
}
int mosquittopp::connect_async(const char *host, int port, int keepalive)
{
    return mosquitto_connect_async(m_mosq, host, port, keepalive);
}
int mosquittopp::connect_async(const char *host, int port, int keepalive, const char *bind_address)
{
    return mosquitto_connect_bind_async(m_mosq, host, port, keepalive, bind_address);
}
int mosquittopp::reconnect()
{
    return mosquitto_reconnect(m_mosq);
}
int mosquittopp::reconnect_async()
{
    return mosquitto_reconnect_async(m_mosq);
}
int mosquittopp::disconnect()
{
    return mosquitto_disconnect(m_mosq);
}
int mosquittopp::socket()
{
    return mosquitto_socket(m_mosq);
}
int mosquittopp::will_set(const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
    return mosquitto_will_set(m_mosq, topic, payloadlen, payload, qos, retain);
}
int mosquittopp::will_clear()
{
    return mosquitto_will_clear(m_mosq);
}
int mosquittopp::username_pw_set(const char *username, const char *password)
{
    return mosquitto_username_pw_set(m_mosq, username, password);
}
int mosquittopp::publish(int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
    return mosquitto_publish(m_mosq, mid, topic, payloadlen, payload, qos, retain);
}
void mosquittopp::reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff)
{
    mosquitto_reconnect_delay_set(m_mosq, reconnect_delay, reconnect_delay_max, reconnect_exponential_backoff);
}
int mosquittopp::max_inflight_messages_set(unsigned int max_inflight_messages)
{
    return mosquitto_max_inflight_messages_set(m_mosq, max_inflight_messages);
}
void mosquittopp::message_retry_set(unsigned int message_retry)
{
    mosquitto_message_retry_set(m_mosq, message_retry);
}
int mosquittopp::subscribe(int *mid, const char *sub, int qos)
{
    return mosquitto_subscribe(m_mosq, mid, sub, qos);
}
int mosquittopp::unsubscribe(int *mid, const char *sub)
{
    return mosquitto_unsubscribe(m_mosq, mid, sub);
}
int mosquittopp::loop(int timeout, int max_packets)
{
    return mosquitto_loop(m_mosq, timeout, max_packets);
}
int mosquittopp::loop_misc()
{
    return mosquitto_loop_misc(m_mosq);
}
int mosquittopp::loop_read(int max_packets)
{
    return mosquitto_loop_read(m_mosq, max_packets);
}
int mosquittopp::loop_write(int max_packets)
{
    return mosquitto_loop_write(m_mosq, max_packets);
}
int mosquittopp::loop_forever(int timeout, int max_packets)
{
    return mosquitto_loop_forever(m_mosq, timeout, max_packets);
}
int mosquittopp::loop_start()
{
    return mosquitto_loop_start(m_mosq);
}
int mosquittopp::loop_stop(bool force)
{
    return mosquitto_loop_stop(m_mosq, force);
}
bool mosquittopp::want_write()
{
    return mosquitto_want_write(m_mosq);
}
int mosquittopp::opts_set(enum mosq_opt_t option, void *value)
{
    return mosquitto_opts_set(m_mosq, option, value);
}
int mosquittopp::threaded_set(bool threaded)
{
    return mosquitto_threaded_set(m_mosq, threaded);
}
void mosquittopp::user_data_set(void *userdata)
{
    mosquitto_user_data_set(m_mosq, userdata);
}
int mosquittopp::socks5_set(const char *host, int port, const char *username, const char *password)
{
    return mosquitto_socks5_set(m_mosq, host, port, username, password);
}
int mosquittopp::tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata))
{
    return mosquitto_tls_set(m_mosq, cafile, capath, certfile, keyfile, pw_callback);
}
int mosquittopp::tls_opts_set(int cert_reqs, const char *tls_version, const char *ciphers)
{
    return mosquitto_tls_opts_set(m_mosq, cert_reqs, tls_version, ciphers);
}
int mosquittopp::tls_insecure_set(bool value)
{
    return mosquitto_tls_insecure_set(m_mosq, value);
}
int mosquittopp::tls_psk_set(const char *psk, const char *identity, const char *ciphers)
{
    return mosquitto_tls_psk_set(m_mosq, psk, identity, ciphers);
}
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.h
New file
@@ -0,0 +1,146 @@
/*
Copyright (c) 2010-2019 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.
*/
#ifndef MOSQUITTOPP_H
#define MOSQUITTOPP_H
#ifdef _WIN32
#    ifdef mosquittopp_EXPORTS
#        define mosqpp_EXPORT  __declspec(dllexport)
#    else
#        define mosqpp_EXPORT  __declspec(dllimport)
#    endif
#else
#    define mosqpp_EXPORT
#endif
#if defined(__GNUC__) || defined(__clang__)
#  define DEPRECATED __attribute__ ((deprecated))
#else
#  define DEPRECATED
#endif
#include <cstdlib>
#include <mosquitto.h>
#include <time.h>
namespace mosqpp {
mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno);
mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code);
mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count);
mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count);
mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision);
mosqpp_EXPORT int DEPRECATED lib_init();
mosqpp_EXPORT int DEPRECATED lib_cleanup();
mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result);
mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len);
mosqpp_EXPORT int DEPRECATED subscribe_simple(
        struct mosquitto_message **messages,
        int msg_count,
        bool retained,
        const char *topic,
        int qos=0,
        const char *host="localhost",
        int port=1883,
        const char *client_id=NULL,
        int keepalive=60,
        bool clean_session=true,
        const char *username=NULL,
        const char *password=NULL,
        const struct libmosquitto_will *will=NULL,
        const struct libmosquitto_tls *tls=NULL);
mosqpp_EXPORT int DEPRECATED subscribe_callback(
        int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
        void *userdata,
        const char *topic,
        int qos=0,
        bool retained=true,
        const char *host="localhost",
        int port=1883,
        const char *client_id=NULL,
        int keepalive=60,
        bool clean_session=true,
        const char *username=NULL,
        const char *password=NULL,
        const struct libmosquitto_will *will=NULL,
        const struct libmosquitto_tls *tls=NULL);
/*
 * Class: mosquittopp
 *
 * A mosquitto client class. This is a C++ wrapper class for the mosquitto C
 * library. Please see mosquitto.h for details of the functions.
 */
class mosqpp_EXPORT DEPRECATED mosquittopp {
    private:
        struct mosquitto *m_mosq;
    public:
        DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true);
        virtual ~mosquittopp();
        int DEPRECATED reinitialise(const char *id, bool clean_session);
        int DEPRECATED socket();
        int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
        int DEPRECATED will_clear();
        int DEPRECATED username_pw_set(const char *username, const char *password=NULL);
        int DEPRECATED connect(const char *host, int port=1883, int keepalive=60);
        int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60);
        int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address);
        int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address);
        int DEPRECATED reconnect();
        int DEPRECATED reconnect_async();
        int DEPRECATED disconnect();
        int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
        int DEPRECATED subscribe(int *mid, const char *sub, int qos=0);
        int DEPRECATED unsubscribe(int *mid, const char *sub);
        void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
        int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages);
        void DEPRECATED message_retry_set(unsigned int message_retry);
        void DEPRECATED user_data_set(void *userdata);
        int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
        int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
        int DEPRECATED tls_insecure_set(bool value);
        int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
        int DEPRECATED opts_set(enum mosq_opt_t option, void *value);
        int DEPRECATED loop(int timeout=-1, int max_packets=1);
        int DEPRECATED loop_misc();
        int DEPRECATED loop_read(int max_packets=1);
        int DEPRECATED loop_write(int max_packets=1);
        int DEPRECATED loop_forever(int timeout=-1, int max_packets=1);
        int DEPRECATED loop_start();
        int DEPRECATED loop_stop(bool force=false);
        bool DEPRECATED want_write();
        int DEPRECATED threaded_set(bool threaded=true);
        int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
        // names in the functions commented to prevent unused parameter warning
        virtual void on_connect(int /*rc*/) {return;}
        virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;}
        virtual void on_disconnect(int /*rc*/) {return;}
        virtual void on_publish(int /*mid*/) {return;}
        virtual void on_message(const struct mosquitto_message * /*message*/) {return;}
        virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
        virtual void on_unsubscribe(int /*mid*/) {return;}
        virtual void on_log(int /*level*/, const char * /*str*/) {return;}
        virtual void on_error() {return;}
};
}
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/cpp/mosquittopp.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/dummypthread.h
New file
@@ -0,0 +1,13 @@
#ifndef DUMMYPTHREAD_H
#define DUMMYPTHREAD_H
#define pthread_create(A, B, C, D)
#define pthread_join(A, B)
#define pthread_cancel(A)
#define pthread_mutex_init(A, B)
#define pthread_mutex_destroy(A)
#define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A)
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_auth.c
New file
@@ -0,0 +1,49 @@
/*
Copyright (c) 2018 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 "config.h"
#include <stdio.h>
#include <string.h>
#include "logging_mosq.h"
#include "mosquitto_internal.h"
#include "mqtt_protocol.h"
#include "packet_mosq.h"
#include "property_mosq.h"
int handle__auth(struct mosquitto *mosq)
{
    int rc = 0;
    uint8_t reason_code;
    mosquitto_property *properties = NULL;
    if(!mosq) return MOSQ_ERR_INVAL;
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received AUTH", mosq->id);
    if(mosq->protocol != mosq_p_mqtt5){
        return MOSQ_ERR_PROTOCOL;
    }
    if(packet__read_byte(&mosq->in_packet, &reason_code)) return 1;
    rc = property__read_all(CMD_AUTH, &mosq->in_packet, &properties);
    if(rc) return rc;
    mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_auth.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_connack.c
New file
@@ -0,0 +1,110 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "read_handle.h"
int handle__connack(struct mosquitto *mosq)
{
    uint8_t connect_flags;
    uint8_t reason_code;
    int rc;
    mosquitto_property *properties = NULL;
    char *clientid = NULL;
    assert(mosq);
    rc = packet__read_byte(&mosq->in_packet, &connect_flags);
    if(rc) return rc;
    rc = packet__read_byte(&mosq->in_packet, &reason_code);
    if(rc) return rc;
    if(mosq->protocol == mosq_p_mqtt5){
        rc = property__read_all(CMD_CONNACK, &mosq->in_packet, &properties);
        if(rc) return rc;
    }
    mosquitto_property_read_string(properties, MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, &clientid, false);
    if(clientid){
        if(mosq->id){
            /* We've been sent a client identifier but already have one. This
             * shouldn't happen. */
            free(clientid);
            mosquitto_property_free_all(&properties);
            return MOSQ_ERR_PROTOCOL;
        }else{
            mosq->id = clientid;
            clientid = NULL;
        }
    }
    mosquitto_property_read_byte(properties, MQTT_PROP_MAXIMUM_QOS, &mosq->maximum_qos, false);
    mosquitto_property_read_int16(properties, MQTT_PROP_RECEIVE_MAXIMUM, &mosq->msgs_out.inflight_maximum, false);
    mosquitto_property_read_int16(properties, MQTT_PROP_SERVER_KEEP_ALIVE, &mosq->keepalive, false);
    mosquitto_property_read_int32(properties, MQTT_PROP_MAXIMUM_PACKET_SIZE, &mosq->maximum_packet_size, false);
    mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum;
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK (%d)", mosq->id, reason_code);
    pthread_mutex_lock(&mosq->callback_mutex);
    if(mosq->on_connect){
        mosq->in_callback = true;
        mosq->on_connect(mosq, mosq->userdata, reason_code);
        mosq->in_callback = false;
    }
    if(mosq->on_connect_with_flags){
        mosq->in_callback = true;
        mosq->on_connect_with_flags(mosq, mosq->userdata, reason_code, connect_flags);
        mosq->in_callback = false;
    }
    if(mosq->on_connect_v5){
        mosq->in_callback = true;
        mosq->on_connect_v5(mosq, mosq->userdata, reason_code, connect_flags, properties);
        mosq->in_callback = false;
    }
    pthread_mutex_unlock(&mosq->callback_mutex);
    mosquitto_property_free_all(&properties);
    switch(reason_code){
        case 0:
            pthread_mutex_lock(&mosq->state_mutex);
            if(mosq->state != mosq_cs_disconnecting){
                mosq->state = mosq_cs_connected;
            }
            pthread_mutex_unlock(&mosq->state_mutex);
            message__retry_check(mosq);
            return MOSQ_ERR_SUCCESS;
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            return MOSQ_ERR_CONN_REFUSED;
        default:
            return MOSQ_ERR_PROTOCOL;
    }
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_connack.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_disconnect.c
New file
@@ -0,0 +1,62 @@
/*
Copyright (c) 2009-2018 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 "config.h"
#include <stdio.h>
#include <string.h>
#include "logging_mosq.h"
#include "mqtt_protocol.h"
#include "memory_mosq.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__disconnect(struct mosquitto *mosq)
{
    int rc;
    uint8_t reason_code;
    mosquitto_property *properties = NULL;
    if(!mosq){
        return MOSQ_ERR_INVAL;
    }
    if(mosq->protocol != mosq_p_mqtt5){
        return MOSQ_ERR_PROTOCOL;
    }
    rc = packet__read_byte(&mosq->in_packet, &reason_code);
    if(rc) return rc;
    if(mosq->in_packet.remaining_length > 2){
        rc = property__read_all(CMD_DISCONNECT, &mosq->in_packet, &properties);
        if(rc) return rc;
        mosquitto_property_free_all(&properties);
    }
    log__printf(mosq, MOSQ_LOG_DEBUG, "Received DISCONNECT (%d)", reason_code);
    do_client_disconnect(mosq, reason_code, properties);
    mosquitto_property_free_all(&properties);
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_disconnect.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_ping.c
New file
@@ -0,0 +1,70 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__pingreq(struct mosquitto *mosq)
{
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", mosq->id);
#else
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGREQ", mosq->id);
#endif
    return send__pingresp(mosq);
}
int handle__pingresp(struct mosquitto *mosq)
{
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
    mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", mosq->id);
#else
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", mosq->id);
#endif
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_ping.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubackcomp.c
New file
@@ -0,0 +1,118 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
#ifdef WITH_BROKER
int handle__pubackcomp(struct mosquitto_db *db, struct mosquitto *mosq, const char *type)
#else
int handle__pubackcomp(struct mosquitto *mosq, const char *type)
#endif
{
    uint8_t reason_code = 0;
    uint16_t mid;
    int rc;
    mosquitto_property *properties = NULL;
    int qos;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    util__increment_send_quota(mosq);
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
    rc = packet__read_uint16(&mosq->in_packet, &mid);
    if(rc) return rc;
    qos = type[3] == 'A'?1:2; /* pubAck or pubComp */
    if(mid == 0) return MOSQ_ERR_PROTOCOL;
    if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
        rc = packet__read_byte(&mosq->in_packet, &reason_code);
        if(rc) return rc;
        if(mosq->in_packet.remaining_length > 3){
            rc = property__read_all(CMD_PUBACK, &mosq->in_packet, &properties);
            if(rc) return rc;
        }
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received %s from %s (Mid: %d, RC:%d)", type, mosq->id, mid, reason_code);
    /* Immediately free, we don't do anything with Reason String or User Property at the moment */
    mosquitto_property_free_all(&properties);
    rc = db__message_delete_outgoing(db, mosq, mid, mosq_ms_wait_for_pubcomp, qos);
    if(rc == MOSQ_ERR_NOT_FOUND){
        log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received %s from %s for an unknown packet identifier %d.", type, mosq->id, mid);
        return MOSQ_ERR_SUCCESS;
    }else{
        return rc;
    }
#else
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d, RC:%d)", mosq->id, type, mid, reason_code);
    rc = message__delete(mosq, mid, mosq_md_out, qos);
    if(rc){
        return rc;
    }else{
        /* Only inform the client the message has been sent once. */
        pthread_mutex_lock(&mosq->callback_mutex);
        if(mosq->on_publish){
            mosq->in_callback = true;
            mosq->on_publish(mosq, mosq->userdata, mid);
            mosq->in_callback = false;
        }
        if(mosq->on_publish_v5){
            mosq->in_callback = true;
            mosq->on_publish_v5(mosq, mosq->userdata, mid, reason_code, properties);
            mosq->in_callback = false;
        }
        pthread_mutex_unlock(&mosq->callback_mutex);
        mosquitto_property_free_all(&properties);
    }
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    message__release_to_inflight(mosq, mosq_md_out);
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
    return MOSQ_ERR_SUCCESS;
#endif
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubackcomp.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_publish.c
New file
@@ -0,0 +1,167 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <string.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "messages_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "send_mosq.h"
#include "time_mosq.h"
#include "util_mosq.h"
int handle__publish(struct mosquitto *mosq)
{
    uint8_t header;
    struct mosquitto_message_all *message;
    int rc = 0;
    uint16_t mid;
    int slen;
    mosquitto_property *properties = NULL;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
    message = mosquitto__calloc(1, sizeof(struct mosquitto_message_all));
    if(!message) return MOSQ_ERR_NOMEM;
    header = mosq->in_packet.command;
    message->dup = (header & 0x08)>>3;
    message->msg.qos = (header & 0x06)>>1;
    message->msg.retain = (header & 0x01);
    rc = packet__read_string(&mosq->in_packet, &message->msg.topic, &slen);
    if(rc){
        message__cleanup(&message);
        return rc;
    }
    if(!slen){
        message__cleanup(&message);
        return MOSQ_ERR_PROTOCOL;
    }
    if(message->msg.qos > 0){
        if(mosq->protocol == mosq_p_mqtt5){
            if(mosq->msgs_in.inflight_quota == 0){
                message__cleanup(&message);
                /* FIXME - should send a DISCONNECT here */
                return MOSQ_ERR_PROTOCOL;
            }
        }
        rc = packet__read_uint16(&mosq->in_packet, &mid);
        if(rc){
            message__cleanup(&message);
            return rc;
        }
        if(mid == 0){
            message__cleanup(&message);
            return MOSQ_ERR_PROTOCOL;
        }
        message->msg.mid = (int)mid;
    }
    if(mosq->protocol == mosq_p_mqtt5){
        rc = property__read_all(CMD_PUBLISH, &mosq->in_packet, &properties);
        if(rc) return rc;
    }
    message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos;
    if(message->msg.payloadlen){
        message->msg.payload = mosquitto__calloc(message->msg.payloadlen+1, sizeof(uint8_t));
        if(!message->msg.payload){
            message__cleanup(&message);
            mosquitto_property_free_all(&properties);
            return MOSQ_ERR_NOMEM;
        }
        rc = packet__read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen);
        if(rc){
            message__cleanup(&message);
            mosquitto_property_free_all(&properties);
            return rc;
        }
    }
    log__printf(mosq, MOSQ_LOG_DEBUG,
            "Client %s received PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))",
            mosq->id, message->dup, message->msg.qos, message->msg.retain,
            message->msg.mid, message->msg.topic,
            (long)message->msg.payloadlen);
    message->timestamp = mosquitto_time();
    switch(message->msg.qos){
        case 0:
            pthread_mutex_lock(&mosq->callback_mutex);
            if(mosq->on_message){
                mosq->in_callback = true;
                mosq->on_message(mosq, mosq->userdata, &message->msg);
                mosq->in_callback = false;
            }
            if(mosq->on_message_v5){
                mosq->in_callback = true;
                mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
                mosq->in_callback = false;
            }
            pthread_mutex_unlock(&mosq->callback_mutex);
            message__cleanup(&message);
            mosquitto_property_free_all(&properties);
            return MOSQ_ERR_SUCCESS;
        case 1:
            util__decrement_receive_quota(mosq);
            rc = send__puback(mosq, message->msg.mid, 0);
            pthread_mutex_lock(&mosq->callback_mutex);
            if(mosq->on_message){
                mosq->in_callback = true;
                mosq->on_message(mosq, mosq->userdata, &message->msg);
                mosq->in_callback = false;
            }
            if(mosq->on_message_v5){
                mosq->in_callback = true;
                mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
                mosq->in_callback = false;
            }
            pthread_mutex_unlock(&mosq->callback_mutex);
            message__cleanup(&message);
            mosquitto_property_free_all(&properties);
            return rc;
        case 2:
            util__decrement_receive_quota(mosq);
            rc = send__pubrec(mosq, message->msg.mid, 0);
            pthread_mutex_lock(&mosq->msgs_in.mutex);
            message->state = mosq_ms_wait_for_pubrel;
            message__queue(mosq, message, mosq_md_in);
            pthread_mutex_unlock(&mosq->msgs_in.mutex);
            mosquitto_property_free_all(&properties);
            return rc;
        default:
            message__cleanup(&message);
            mosquitto_property_free_all(&properties);
            return MOSQ_ERR_PROTOCOL;
    }
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_publish.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrec.c
New file
@@ -0,0 +1,110 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__pubrec(struct mosquitto_db *db, struct mosquitto *mosq)
{
    uint8_t reason_code = 0;
    uint16_t mid;
    int rc;
    mosquitto_property *properties = NULL;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
    rc = packet__read_uint16(&mosq->in_packet, &mid);
    if(rc) return rc;
    if(mid == 0) return MOSQ_ERR_PROTOCOL;
    if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
        rc = packet__read_byte(&mosq->in_packet, &reason_code);
        if(rc) return rc;
        if(mosq->in_packet.remaining_length > 3){
            rc = property__read_all(CMD_PUBREC, &mosq->in_packet, &properties);
            if(rc) return rc;
            /* Immediately free, we don't do anything with Reason String or User Property at the moment */
            mosquitto_property_free_all(&properties);
        }
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid);
    if(reason_code < 0x80){
        rc = db__message_update_outgoing(mosq, mid, mosq_ms_wait_for_pubcomp, 2);
    }else{
        return db__message_delete_outgoing(db, mosq, mid, mosq_ms_wait_for_pubrec, 2);
    }
#else
    UNUSED(db);
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid);
    if(reason_code < 0x80 || mosq->protocol != mosq_p_mqtt5){
        rc = message__out_update(mosq, mid, mosq_ms_wait_for_pubcomp, 2);
    }else{
        if(!message__delete(mosq, mid, mosq_md_out, 2)){
            /* Only inform the client the message has been sent once. */
            pthread_mutex_lock(&mosq->callback_mutex);
            if(mosq->on_publish_v5){
                mosq->in_callback = true;
                mosq->on_publish_v5(mosq, mosq->userdata, mid, reason_code, properties);
                mosq->in_callback = false;
            }
            pthread_mutex_unlock(&mosq->callback_mutex);
        }
        util__increment_send_quota(mosq);
        pthread_mutex_lock(&mosq->msgs_out.mutex);
        message__release_to_inflight(mosq, mosq_md_out);
        pthread_mutex_unlock(&mosq->msgs_out.mutex);
        return MOSQ_ERR_SUCCESS;
    }
#endif
    if(rc == MOSQ_ERR_NOT_FOUND){
        log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received PUBREC from %s for an unknown packet identifier %d.", mosq->id, mid);
    }else if(rc != MOSQ_ERR_SUCCESS){
        return rc;
    }
    rc = send__pubrel(mosq, mid);
    if(rc) return rc;
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrec.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrel.c
New file
@@ -0,0 +1,126 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
{
    uint8_t reason_code;
    uint16_t mid;
#ifndef WITH_BROKER
    struct mosquitto_message_all *message = NULL;
#endif
    int rc;
    mosquitto_property *properties = NULL;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
    if(mosq->protocol != mosq_p_mqtt31){
        if((mosq->in_packet.command&0x0F) != 0x02){
            return MOSQ_ERR_PROTOCOL;
        }
    }
    rc = packet__read_uint16(&mosq->in_packet, &mid);
    if(rc) return rc;
    if(mid == 0) return MOSQ_ERR_PROTOCOL;
    if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
        rc = packet__read_byte(&mosq->in_packet, &reason_code);
        if(rc) return rc;
        if(mosq->in_packet.remaining_length > 3){
            rc = property__read_all(CMD_PUBREL, &mosq->in_packet, &properties);
            if(rc) return rc;
        }
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREL from %s (Mid: %d)", mosq->id, mid);
    /* Immediately free, we don't do anything with Reason String or User Property at the moment */
    mosquitto_property_free_all(&properties);
    rc = db__message_release_incoming(db, mosq, mid);
    if(rc == MOSQ_ERR_PROTOCOL){
        return rc;
    }else if(rc != MOSQ_ERR_SUCCESS){
        /* Message not found. Still send a PUBCOMP anyway because this could be
         * due to a repeated PUBREL after a client has reconnected. */
    }
    rc = send__pubcomp(mosq, mid);
    if(rc) return rc;
#else
    UNUSED(db);
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid);
    rc = send__pubcomp(mosq, mid);
    if(rc){
        message__remove(mosq, mid, mosq_md_in, &message, 2);
        return rc;
    }
    rc = message__remove(mosq, mid, mosq_md_in, &message, 2);
    if(rc){
        return rc;
    }else{
        /* Only pass the message on if we have removed it from the queue - this
         * prevents multiple callbacks for the same message. */
        pthread_mutex_lock(&mosq->callback_mutex);
        if(mosq->on_message){
            mosq->in_callback = true;
            mosq->on_message(mosq, mosq->userdata, &message->msg);
            mosq->in_callback = false;
        }
        if(mosq->on_message_v5){
            mosq->in_callback = true;
            mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
            mosq->in_callback = false;
        }
        pthread_mutex_unlock(&mosq->callback_mutex);
        mosquitto_property_free_all(&properties);
        message__cleanup(&message);
    }
#endif
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_pubrel.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_suback.c
New file
@@ -0,0 +1,98 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "packet_mosq.h"
#include "property_mosq.h"
int handle__suback(struct mosquitto *mosq)
{
    uint16_t mid;
    uint8_t qos;
    int *granted_qos;
    int qos_count;
    int i = 0;
    int rc;
    mosquitto_property *properties = NULL;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", mosq->id);
#else
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received SUBACK", mosq->id);
#endif
    rc = packet__read_uint16(&mosq->in_packet, &mid);
    if(rc) return rc;
    if(mid == 0) return MOSQ_ERR_PROTOCOL;
    if(mosq->protocol == mosq_p_mqtt5){
        rc = property__read_all(CMD_SUBACK, &mosq->in_packet, &properties);
        if(rc) return rc;
    }
    qos_count = mosq->in_packet.remaining_length - mosq->in_packet.pos;
    granted_qos = mosquitto__malloc(qos_count*sizeof(int));
    if(!granted_qos) return MOSQ_ERR_NOMEM;
    while(mosq->in_packet.pos < mosq->in_packet.remaining_length){
        rc = packet__read_byte(&mosq->in_packet, &qos);
        if(rc){
            mosquitto__free(granted_qos);
            return rc;
        }
        granted_qos[i] = (int)qos;
        i++;
    }
#ifdef WITH_BROKER
    /* Immediately free, we don't do anything with Reason String or User Property at the moment */
    mosquitto_property_free_all(&properties);
#else
    pthread_mutex_lock(&mosq->callback_mutex);
    if(mosq->on_subscribe){
        mosq->in_callback = true;
        mosq->on_subscribe(mosq, mosq->userdata, mid, qos_count, granted_qos);
        mosq->in_callback = false;
    }
    if(mosq->on_subscribe_v5){
        mosq->in_callback = true;
        mosq->on_subscribe_v5(mosq, mosq->userdata, mid, qos_count, granted_qos, properties);
        mosq->in_callback = false;
    }
    pthread_mutex_unlock(&mosq->callback_mutex);
    mosquitto_property_free_all(&properties);
#endif
    mosquitto__free(granted_qos);
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_suback.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_unsuback.c
New file
@@ -0,0 +1,87 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif
#include "mosquitto.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__unsuback(struct mosquitto *mosq)
{
    uint16_t mid;
    int rc;
    mosquitto_property *properties = NULL;
    assert(mosq);
    if(mosq->state != mosq_cs_connected){
        return MOSQ_ERR_PROTOCOL;
    }
#ifdef WITH_BROKER
    log__printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", mosq->id);
#else
    log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received UNSUBACK", mosq->id);
#endif
    rc = packet__read_uint16(&mosq->in_packet, &mid);
    if(rc) return rc;
    if(mid == 0) return MOSQ_ERR_PROTOCOL;
    if(mosq->protocol == mosq_p_mqtt5){
        rc = property__read_all(CMD_UNSUBACK, &mosq->in_packet, &properties);
        if(rc) return rc;
    }
#ifdef WITH_BROKER
    /* Immediately free, we don't do anything with Reason String or User Property at the moment */
    mosquitto_property_free_all(&properties);
#else
    pthread_mutex_lock(&mosq->callback_mutex);
    if(mosq->on_unsubscribe){
        mosq->in_callback = true;
        mosq->on_unsubscribe(mosq, mosq->userdata, mid);
        mosq->in_callback = false;
    }
    if(mosq->on_unsubscribe_v5){
        mosq->in_callback = true;
        mosq->on_unsubscribe_v5(mosq, mosq->userdata, mid, properties);
        mosq->in_callback = false;
    }
    pthread_mutex_unlock(&mosq->callback_mutex);
    mosquitto_property_free_all(&properties);
#endif
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/handle_unsuback.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/helpers.c
New file
@@ -0,0 +1,227 @@
/*
Copyright (c) 2016-2019 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 "config.h"
#include <errno.h>
#include <stdbool.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
struct userdata__callback {
    const char *topic;
    int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *);
    void *userdata;
    int qos;
    int rc;
};
struct userdata__simple {
    struct mosquitto_message *messages;
    int max_msg_count;
    int message_count;
    bool want_retained;
};
static void on_connect(struct mosquitto *mosq, void *obj, int rc)
{
    struct userdata__callback *userdata = obj;
    UNUSED(rc);
    mosquitto_subscribe(mosq, NULL, userdata->topic, userdata->qos);
}
static void on_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    int rc;
    struct userdata__callback *userdata = obj;
    rc = userdata->callback(mosq, userdata->userdata, message);
    if(rc){
        mosquitto_disconnect(mosq);
    }
}
static int on_message_simple(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    struct userdata__simple *userdata = obj;
    int rc;
    if(userdata->max_msg_count == 0){
        return 0;
    }
    /* Don't process stale retained messages if 'want_retained' was false */
    if(!userdata->want_retained && message->retain){
        return 0;
    }
    userdata->max_msg_count--;
    rc = mosquitto_message_copy(&userdata->messages[userdata->message_count], message);
    if(rc){
        return rc;
    }
    userdata->message_count++;
    if(userdata->max_msg_count == 0){
        mosquitto_disconnect(mosq);
    }
    return 0;
}
libmosq_EXPORT int mosquitto_subscribe_simple(
        struct mosquitto_message **messages,
        int msg_count,
        bool want_retained,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls)
{
    struct userdata__simple userdata;
    int rc;
    int i;
    if(!topic || msg_count < 1 || !messages){
        return MOSQ_ERR_INVAL;
    }
    *messages = NULL;
    userdata.messages = calloc(sizeof(struct mosquitto_message), msg_count);
    if(!userdata.messages){
        return MOSQ_ERR_NOMEM;
    }
    userdata.message_count = 0;
    userdata.max_msg_count = msg_count;
    userdata.want_retained = want_retained;
    rc = mosquitto_subscribe_callback(
            on_message_simple, &userdata,
            topic, qos,
            host, port,
            client_id, keepalive, clean_session,
            username, password,
            will, tls);
    if(!rc && userdata.max_msg_count == 0){
        *messages = userdata.messages;
        return MOSQ_ERR_SUCCESS;
    }else{
        for(i=0; i<msg_count; i++){
            mosquitto_message_free_contents(&userdata.messages[i]);
        }
        free(userdata.messages);
        userdata.messages = NULL;
        return rc;
    }
}
libmosq_EXPORT int mosquitto_subscribe_callback(
        int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
        void *userdata,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls)
{
    struct mosquitto *mosq;
    struct userdata__callback cb_userdata;
    int rc;
    if(!callback || !topic){
        return MOSQ_ERR_INVAL;
    }
    cb_userdata.topic = topic;
    cb_userdata.qos = qos;
    cb_userdata.rc = 0;
    cb_userdata.userdata = userdata;
    cb_userdata.callback = callback;
    mosq = mosquitto_new(client_id, clean_session, &cb_userdata);
    if(!mosq){
        return MOSQ_ERR_NOMEM;
    }
    if(will){
        rc = mosquitto_will_set(mosq, will->topic, will->payloadlen, will->payload, will->qos, will->retain);
        if(rc){
            mosquitto_destroy(mosq);
            return rc;
        }
    }
    if(username){
        rc = mosquitto_username_pw_set(mosq, username, password);
        if(rc){
            mosquitto_destroy(mosq);
            return rc;
        }
    }
    if(tls){
        rc = mosquitto_tls_set(mosq, tls->cafile, tls->capath, tls->certfile, tls->keyfile, tls->pw_callback);
        if(rc){
            mosquitto_destroy(mosq);
            return rc;
        }
        rc = mosquitto_tls_opts_set(mosq, tls->cert_reqs, tls->tls_version, tls->ciphers);
        if(rc){
            mosquitto_destroy(mosq);
            return rc;
        }
    }
    mosquitto_connect_callback_set(mosq, on_connect);
    mosquitto_message_callback_set(mosq, on_message_callback);
    rc = mosquitto_connect(mosq, host, port, keepalive);
    if(rc){
        mosquitto_destroy(mosq);
        return rc;
    }
    rc = mosquitto_loop_forever(mosq, -1, 1);
    mosquitto_destroy(mosq);
    if(cb_userdata.rc){
        rc = cb_userdata.rc;
    }
    //if(!rc && cb_userdata.max_msg_count == 0){
        //return MOSQ_ERR_SUCCESS;
    //}else{
        //return rc;
    //}
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/helpers.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/libmosquitto.so.1
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/linker.version
New file
@@ -0,0 +1,134 @@
/* Linker version script - currently used here primarily to control which
 * symbols are exported.
 */
MOSQ_1.0 {
    global:
        mosquitto_lib_version;
        mosquitto_lib_init;
        mosquitto_lib_cleanup;
        mosquitto_new;
        mosquitto_destroy;
        mosquitto_reinitialise;
        mosquitto_will_set;
        mosquitto_will_clear;
        mosquitto_username_pw_set;
        mosquitto_connect;
        mosquitto_connect_async;
        mosquitto_reconnect;
        mosquitto_disconnect;
        mosquitto_publish;
        mosquitto_subscribe;
        mosquitto_unsubscribe;
        mosquitto_message_copy;
        mosquitto_message_free;
        mosquitto_loop;
        mosquitto_socket;
        mosquitto_loop_start;
        mosquitto_loop_stop;
        mosquitto_loop_read;
        mosquitto_loop_write;
        mosquitto_loop_misc;
        mosquitto_connect_callback_set;
        mosquitto_disconnect_callback_set;
        mosquitto_publish_callback_set;
        mosquitto_message_callback_set;
        mosquitto_subscribe_callback_set;
        mosquitto_unsubscribe_callback_set;
        mosquitto_log_callback_set;
        mosquitto_message_retry_set;
        mosquitto_want_write;
        mosquitto_user_data_set;
        mosquitto_strerror;
        mosquitto_connack_string;
        mosquitto_tls_set;
        mosquitto_tls_opts_set;
        mosquitto_tls_psk_set;
        mosquitto_sub_topic_tokenise;
        mosquitto_sub_topic_tokens_free;
        mosquitto_topic_matches_sub;
    local: *;
};
MOSQ_1.1 {
    global:
        mosquitto_loop_forever;
} MOSQ_1.0;
MOSQ_1.2 {
    global:
        mosquitto_connect_bind;
        mosquitto_connect_bind_async;
        mosquitto_max_inflight_messages_set;
        mosquitto_reconnect_delay_set;
        mosquitto_reconnect_async;
        mosquitto_tls_insecure_set;
} MOSQ_1.1;
MOSQ_1.3 {
    global:
        mosquitto_connect_srv;
} MOSQ_1.2;
MOSQ_1.4 {
    global:
        mosquitto_threaded_set;
        mosquitto_opts_set;
        mosquitto_pub_topic_check;
        mosquitto_sub_topic_check;
        mosquitto_socks5_set;
} MOSQ_1.3;
MOSQ_1.5 {
    global:
        mosquitto_subscribe_simple;
        mosquitto_subscribe_callback;
        mosquitto_message_free_contents;
        mosquitto_validate_utf8;
        mosquitto_userdata;
        mosquitto_pub_topic_check2;
        mosquitto_sub_topic_check2;
        mosquitto_topic_matches_sub2;
        mosquitto_connect_with_flags_callback_set;
} MOSQ_1.4;
MOSQ_1.6 {
    global:
        mosquitto_connect_bind_v5;
        mosquitto_connect_v5_callback_set;
        mosquitto_disconnect_v5;
        mosquitto_disconnect_v5_callback_set;
        mosquitto_int_option;
        mosquitto_message_v5_callback_set;
        mosquitto_property_add_binary;
        mosquitto_property_add_byte;
        mosquitto_property_add_int16;
        mosquitto_property_add_int32;
        mosquitto_property_add_string;
        mosquitto_property_add_string_pair;
        mosquitto_property_add_varint;
        mosquitto_property_check_all;
        mosquitto_property_check_command;
        mosquitto_property_free_all;
        mosquitto_property_read_binary;
        mosquitto_property_read_byte;
        mosquitto_property_read_int16;
        mosquitto_property_read_int32;
        mosquitto_property_read_string;
        mosquitto_property_read_string_pair;
        mosquitto_property_read_varint;
        mosquitto_publish_v5;
        mosquitto_publish_v5_callback_set;
        mosquitto_reason_string;
        mosquitto_string_option;
        mosquitto_string_to_command;
        mosquitto_string_to_property_info;
        mosquitto_subscribe_multiple;
        mosquitto_subscribe_v5;
        mosquitto_subscribe_v5_callback_set;
        mosquitto_unsubscribe_multiple;
        mosquitto_unsubscribe_v5;
        mosquitto_unsubscribe_v5_callback_set;
        mosquitto_void_option;
        mosquitto_will_set_v5;
} MOSQ_1.5;
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.c
New file
@@ -0,0 +1,59 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "mosquitto_internal.h"
#include "mosquitto.h"
#include "memory_mosq.h"
int log__printf(struct mosquitto *mosq, int priority, const char *fmt, ...)
{
    va_list va;
    char *s;
    int len;
    assert(mosq);
    assert(fmt);
    pthread_mutex_lock(&mosq->log_callback_mutex);
    if(mosq->on_log){
        len = strlen(fmt) + 500;
        s = mosquitto__malloc(len*sizeof(char));
        if(!s){
            pthread_mutex_unlock(&mosq->log_callback_mutex);
            return MOSQ_ERR_NOMEM;
        }
        va_start(va, fmt);
        vsnprintf(s, len, fmt, va);
        va_end(va);
        s[len-1] = '\0'; /* Ensure string is null terminated. */
        mosq->on_log(mosq, mosq->userdata, priority, s);
        mosquitto__free(s);
    }
    pthread_mutex_unlock(&mosq->log_callback_mutex);
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.h
New file
@@ -0,0 +1,23 @@
/*
Copyright (c) 2009-2019 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.
*/
#ifndef LOGGING_MOSQ_H
#define LOGGING_MOSQ_H
#include "mosquitto.h"
int log__printf(struct mosquitto *mosq, int priority, const char *fmt, ...);
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/logging_mosq.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/loop.c
New file
@@ -0,0 +1,390 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include <errno.h>
#ifndef WIN32
#include <sys/select.h>
#include <time.h>
#endif
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "socks_mosq.h"
#include "tls_mosq.h"
#include "util_mosq.h"
#if !defined(WIN32) && !defined(__SYMBIAN32__)
#define HAVE_PSELECT
#endif
int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
{
#ifdef HAVE_PSELECT
    struct timespec local_timeout;
#else
    struct timeval local_timeout;
#endif
    fd_set readfds, writefds;
    int fdcount;
    int rc;
    char pairbuf;
    int maxfd = 0;
    time_t now;
    if(!mosq || max_packets < 1) return MOSQ_ERR_INVAL;
#ifndef WIN32
    if(mosq->sock >= FD_SETSIZE || mosq->sockpairR >= FD_SETSIZE){
        return MOSQ_ERR_INVAL;
    }
#endif
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    if(mosq->sock != INVALID_SOCKET){
        maxfd = mosq->sock;
        FD_SET(mosq->sock, &readfds);
        pthread_mutex_lock(&mosq->current_out_packet_mutex);
        pthread_mutex_lock(&mosq->out_packet_mutex);
        if(mosq->out_packet || mosq->current_out_packet){
            FD_SET(mosq->sock, &writefds);
        }
#ifdef WITH_TLS
        if(mosq->ssl){
            if(mosq->want_write){
                FD_SET(mosq->sock, &writefds);
            }else if(mosq->want_connect){
                /* Remove possible FD_SET from above, we don't want to check
                 * for writing if we are still connecting, unless want_write is
                 * definitely set. The presence of outgoing packets does not
                 * matter yet. */
                FD_CLR(mosq->sock, &writefds);
            }
        }
#endif
        pthread_mutex_unlock(&mosq->out_packet_mutex);
        pthread_mutex_unlock(&mosq->current_out_packet_mutex);
    }else{
#ifdef WITH_SRV
        if(mosq->achan){
            pthread_mutex_lock(&mosq->state_mutex);
            if(mosq->state == mosq_cs_connect_srv){
                rc = ares_fds(mosq->achan, &readfds, &writefds);
                if(rc > maxfd){
                    maxfd = rc;
                }
            }else{
                pthread_mutex_unlock(&mosq->state_mutex);
                return MOSQ_ERR_NO_CONN;
            }
            pthread_mutex_unlock(&mosq->state_mutex);
        }
#else
        return MOSQ_ERR_NO_CONN;
#endif
    }
    if(mosq->sockpairR != INVALID_SOCKET){
        /* sockpairR is used to break out of select() before the timeout, on a
         * call to publish() etc. */
        FD_SET(mosq->sockpairR, &readfds);
        if(mosq->sockpairR > maxfd){
            maxfd = mosq->sockpairR;
        }
    }
    if(timeout < 0){
        timeout = 1000;
    }
    now = mosquitto_time();
    if(mosq->next_msg_out && now + timeout/1000 > mosq->next_msg_out){
        timeout = (mosq->next_msg_out - now)*1000;
    }
    if(timeout < 0){
        /* There has been a delay somewhere which means we should have already
         * sent a message. */
        timeout = 0;
    }
    local_timeout.tv_sec = timeout/1000;
#ifdef HAVE_PSELECT
    local_timeout.tv_nsec = (timeout-local_timeout.tv_sec*1000)*1e6;
#else
    local_timeout.tv_usec = (timeout-local_timeout.tv_sec*1000)*1000;
#endif
#ifdef HAVE_PSELECT
    fdcount = pselect(maxfd+1, &readfds, &writefds, NULL, &local_timeout, NULL);
#else
    fdcount = select(maxfd+1, &readfds, &writefds, NULL, &local_timeout);
#endif
    if(fdcount == -1){
#ifdef WIN32
        errno = WSAGetLastError();
#endif
        if(errno == EINTR){
            return MOSQ_ERR_SUCCESS;
        }else{
            return MOSQ_ERR_ERRNO;
        }
    }else{
        if(mosq->sock != INVALID_SOCKET){
            if(FD_ISSET(mosq->sock, &readfds)){
                rc = mosquitto_loop_read(mosq, max_packets);
                if(rc || mosq->sock == INVALID_SOCKET){
                    return rc;
                }
            }
            if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){
#ifndef WIN32
                if(read(mosq->sockpairR, &pairbuf, 1) == 0){
                }
#else
                recv(mosq->sockpairR, &pairbuf, 1, 0);
#endif
                /* Fake write possible, to stimulate output write even though
                 * we didn't ask for it, because at that point the publish or
                 * other command wasn't present. */
                if(mosq->sock != INVALID_SOCKET)
                    FD_SET(mosq->sock, &writefds);
            }
            if(mosq->sock != INVALID_SOCKET && FD_ISSET(mosq->sock, &writefds)){
#ifdef WITH_TLS
                if(mosq->want_connect){
                    rc = net__socket_connect_tls(mosq);
                    if(rc) return rc;
                }else
#endif
                {
                    rc = mosquitto_loop_write(mosq, max_packets);
                    if(rc || mosq->sock == INVALID_SOCKET){
                        return rc;
                    }
                }
            }
        }
#ifdef WITH_SRV
        if(mosq->achan){
            ares_process(mosq->achan, &readfds, &writefds);
        }
#endif
    }
    return mosquitto_loop_misc(mosq);
}
int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
{
    int run = 1;
    int rc;
    unsigned int reconnects = 0;
    unsigned long reconnect_delay;
#ifndef WIN32
    struct timespec req, rem;
#endif
    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->state == mosq_cs_connect_async){
        mosquitto_reconnect(mosq);
    }
    while(run){
        do{
            rc = mosquitto_loop(mosq, timeout, max_packets);
            if (reconnects !=0 && rc == MOSQ_ERR_SUCCESS){
                reconnects = 0;
            }
        }while(run && rc == MOSQ_ERR_SUCCESS);
        /* Quit after fatal errors. */
        switch(rc){
            case MOSQ_ERR_NOMEM:
            case MOSQ_ERR_PROTOCOL:
            case MOSQ_ERR_INVAL:
            case MOSQ_ERR_NOT_FOUND:
            case MOSQ_ERR_TLS:
            case MOSQ_ERR_PAYLOAD_SIZE:
            case MOSQ_ERR_NOT_SUPPORTED:
            case MOSQ_ERR_AUTH:
            case MOSQ_ERR_ACL_DENIED:
            case MOSQ_ERR_UNKNOWN:
            case MOSQ_ERR_EAI:
            case MOSQ_ERR_PROXY:
                return rc;
            case MOSQ_ERR_ERRNO:
                break;
        }
        if(errno == EPROTO){
            return rc;
        }
        do{
            rc = MOSQ_ERR_SUCCESS;
            pthread_mutex_lock(&mosq->state_mutex);
            if(mosq->state == mosq_cs_disconnecting){
                run = 0;
                pthread_mutex_unlock(&mosq->state_mutex);
            }else{
                pthread_mutex_unlock(&mosq->state_mutex);
                if(mosq->reconnect_delay_max > mosq->reconnect_delay){
                    if(mosq->reconnect_exponential_backoff){
                        reconnect_delay = mosq->reconnect_delay*(reconnects+1)*(reconnects+1);
                    }else{
                        reconnect_delay = mosq->reconnect_delay*(reconnects+1);
                    }
                }else{
                    reconnect_delay = mosq->reconnect_delay;
                }
                if(reconnect_delay > mosq->reconnect_delay_max){
                    reconnect_delay = mosq->reconnect_delay_max;
                }else{
                    reconnects++;
                }
#ifdef WIN32
                Sleep(reconnect_delay*1000);
#else
                req.tv_sec = reconnect_delay;
                req.tv_nsec = 0;
                while(nanosleep(&req, &rem) == -1 && errno == EINTR){
                    req = rem;
                }
#endif
                pthread_mutex_lock(&mosq->state_mutex);
                if(mosq->state == mosq_cs_disconnecting){
                    run = 0;
                    pthread_mutex_unlock(&mosq->state_mutex);
                }else{
                    pthread_mutex_unlock(&mosq->state_mutex);
                    rc = mosquitto_reconnect(mosq);
                }
            }
        }while(run && rc != MOSQ_ERR_SUCCESS);
    }
    return rc;
}
int mosquitto_loop_misc(struct mosquitto *mosq)
{
    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
    return mosquitto__check_keepalive(mosq);
}
static int mosquitto__loop_rc_handle(struct mosquitto *mosq, int rc)
{
    if(rc){
        net__socket_close(mosq);
        pthread_mutex_lock(&mosq->state_mutex);
        if(mosq->state == mosq_cs_disconnecting){
            rc = MOSQ_ERR_SUCCESS;
        }
        pthread_mutex_unlock(&mosq->state_mutex);
        pthread_mutex_lock(&mosq->callback_mutex);
        if(mosq->on_disconnect){
            mosq->in_callback = true;
            mosq->on_disconnect(mosq, mosq->userdata, rc);
            mosq->in_callback = false;
        }
        if(mosq->on_disconnect_v5){
            mosq->in_callback = true;
            mosq->on_disconnect_v5(mosq, mosq->userdata, rc, NULL);
            mosq->in_callback = false;
        }
        pthread_mutex_unlock(&mosq->callback_mutex);
        return rc;
    }
    return rc;
}
int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
{
    int rc;
    int i;
    if(max_packets < 1) return MOSQ_ERR_INVAL;
#ifdef WITH_TLS
    if(mosq->want_connect){
        return net__socket_connect_tls(mosq);
    }
#endif
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    max_packets = mosq->msgs_out.queue_len;
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
    pthread_mutex_lock(&mosq->msgs_in.mutex);
    max_packets += mosq->msgs_in.queue_len;
    pthread_mutex_unlock(&mosq->msgs_in.mutex);
    if(max_packets < 1) max_packets = 1;
    /* Queue len here tells us how many messages are awaiting processing and
     * have QoS > 0. We should try to deal with that many in this loop in order
     * to keep up. */
    for(i=0; i<max_packets || SSL_DATA_PENDING(mosq); i++){
#ifdef WITH_SOCKS
        if(mosq->socks5_host){
            rc = socks5__read(mosq);
        }else
#endif
        {
            rc = packet__read(mosq);
        }
        if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
            return mosquitto__loop_rc_handle(mosq, rc);
        }
    }
    return rc;
}
int mosquitto_loop_write(struct mosquitto *mosq, int max_packets)
{
    int rc;
    int i;
    if(max_packets < 1) return MOSQ_ERR_INVAL;
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    max_packets = mosq->msgs_out.queue_len;
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
    pthread_mutex_lock(&mosq->msgs_in.mutex);
    max_packets += mosq->msgs_in.queue_len;
    pthread_mutex_unlock(&mosq->msgs_in.mutex);
    if(max_packets < 1) max_packets = 1;
    /* Queue len here tells us how many messages are awaiting processing and
     * have QoS > 0. We should try to deal with that many in this loop in order
     * to keep up. */
    for(i=0; i<max_packets; i++){
        rc = packet__write(mosq);
        if(rc || errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
            return mosquitto__loop_rc_handle(mosq, rc);
        }
    }
    return rc;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/loop.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.c
New file
@@ -0,0 +1,160 @@
/*
Copyright (c) 2009-2019 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 "config.h"
#include <stdlib.h>
#include <string.h>
#include "memory_mosq.h"
#ifdef REAL_WITH_MEMORY_TRACKING
#  if defined(__APPLE__)
#    include <malloc/malloc.h>
#    define malloc_usable_size malloc_size
#  elif defined(__FreeBSD__)
#    include <malloc_np.h>
#  else
#    include <malloc.h>
#  endif
#endif
#ifdef REAL_WITH_MEMORY_TRACKING
static unsigned long memcount = 0;
static unsigned long max_memcount = 0;
#endif
#ifdef WITH_BROKER
static size_t mem_limit = 0;
void memory__set_limit(size_t lim)
{
    mem_limit = lim;
}
#endif
void *mosquitto__calloc(size_t nmemb, size_t size)
{
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem_limit && memcount + size > mem_limit){
        return NULL;
    }
#endif
    void *mem = calloc(nmemb, size);
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem){
        memcount += malloc_usable_size(mem);
        if(memcount > max_memcount){
            max_memcount = memcount;
        }
    }
#endif
    return mem;
}
void mosquitto__free(void *mem)
{
#ifdef REAL_WITH_MEMORY_TRACKING
    if(!mem){
        return;
    }
    memcount -= malloc_usable_size(mem);
#endif
    free(mem);
}
void *mosquitto__malloc(size_t size)
{
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem_limit && memcount + size > mem_limit){
        return NULL;
    }
#endif
    void *mem = malloc(size);
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem){
        memcount += malloc_usable_size(mem);
        if(memcount > max_memcount){
            max_memcount = memcount;
        }
    }
#endif
    return mem;
}
#ifdef REAL_WITH_MEMORY_TRACKING
unsigned long mosquitto__memory_used(void)
{
    return memcount;
}
unsigned long mosquitto__max_memory_used(void)
{
    return max_memcount;
}
#endif
void *mosquitto__realloc(void *ptr, size_t size)
{
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem_limit && memcount + size > mem_limit){
        return NULL;
    }
#endif
    void *mem;
#ifdef REAL_WITH_MEMORY_TRACKING
    if(ptr){
        memcount -= malloc_usable_size(ptr);
    }
#endif
    mem = realloc(ptr, size);
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem){
        memcount += malloc_usable_size(mem);
        if(memcount > max_memcount){
            max_memcount = memcount;
        }
    }
#endif
    return mem;
}
char *mosquitto__strdup(const char *s)
{
#ifdef REAL_WITH_MEMORY_TRACKING
    if(mem_limit && memcount + strlen(s) > mem_limit){
        return NULL;
    }
#endif
    char *str = strdup(s);
#ifdef REAL_WITH_MEMORY_TRACKING
    if(str){
        memcount += malloc_usable_size(str);
        if(memcount > max_memcount){
            max_memcount = memcount;
        }
    }
#endif
    return str;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.h
New file
@@ -0,0 +1,41 @@
/*
Copyright (c) 2010-2019 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.
*/
#ifndef MEMORY_MOSQ_H
#define MEMORY_MOSQ_H
#include <stdio.h>
#include <sys/types.h>
#if defined(WITH_MEMORY_TRACKING) && defined(WITH_BROKER) && defined(__GLIBC__)
#define REAL_WITH_MEMORY_TRACKING
#endif
void *mosquitto__calloc(size_t nmemb, size_t size);
void mosquitto__free(void *mem);
void *mosquitto__malloc(size_t size);
#ifdef REAL_WITH_MEMORY_TRACKING
unsigned long mosquitto__memory_used(void);
unsigned long mosquitto__max_memory_used(void);
#endif
void *mosquitto__realloc(void *ptr, size_t size);
char *mosquitto__strdup(const char *s);
#ifdef WITH_BROKER
void memory__set_limit(size_t lim);
#endif
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/memory_mosq.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.c
New file
@@ -0,0 +1,348 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <utlist.h>
#include "mosquitto_internal.h"
#include "mosquitto.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "send_mosq.h"
#include "time_mosq.h"
#include "util_mosq.h"
void message__cleanup(struct mosquitto_message_all **message)
{
    struct mosquitto_message_all *msg;
    if(!message || !*message) return;
    msg = *message;
    mosquitto__free(msg->msg.topic);
    mosquitto__free(msg->msg.payload);
    mosquitto__free(msg);
}
void message__cleanup_all(struct mosquitto *mosq)
{
    struct mosquitto_message_all *tail, *tmp;
    assert(mosq);
    DL_FOREACH_SAFE(mosq->msgs_in.inflight, tail, tmp){
        DL_DELETE(mosq->msgs_in.inflight, tail);
        message__cleanup(&tail);
    }
    DL_FOREACH_SAFE(mosq->msgs_out.inflight, tail, tmp){
        DL_DELETE(mosq->msgs_out.inflight, tail);
        message__cleanup(&tail);
    }
}
int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src)
{
    if(!dst || !src) return MOSQ_ERR_INVAL;
    dst->mid = src->mid;
    dst->topic = mosquitto__strdup(src->topic);
    if(!dst->topic) return MOSQ_ERR_NOMEM;
    dst->qos = src->qos;
    dst->retain = src->retain;
    if(src->payloadlen){
        dst->payload = mosquitto__calloc(src->payloadlen+1, sizeof(uint8_t));
        if(!dst->payload){
            mosquitto__free(dst->topic);
            return MOSQ_ERR_NOMEM;
        }
        memcpy(dst->payload, src->payload, src->payloadlen);
        dst->payloadlen = src->payloadlen;
    }else{
        dst->payloadlen = 0;
        dst->payload = NULL;
    }
    return MOSQ_ERR_SUCCESS;
}
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, int qos)
{
    struct mosquitto_message_all *message;
    int rc;
    assert(mosq);
    rc = message__remove(mosq, mid, dir, &message, qos);
    if(rc == MOSQ_ERR_SUCCESS){
        message__cleanup(&message);
    }
    return rc;
}
void mosquitto_message_free(struct mosquitto_message **message)
{
    struct mosquitto_message *msg;
    if(!message || !*message) return;
    msg = *message;
    mosquitto__free(msg->topic);
    mosquitto__free(msg->payload);
    mosquitto__free(msg);
}
void mosquitto_message_free_contents(struct mosquitto_message *message)
{
    if(!message) return;
    mosquitto__free(message->topic);
    mosquitto__free(message->payload);
}
int message__queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir)
{
    /* mosq->*_message_mutex should be locked before entering this function */
    assert(mosq);
    assert(message);
    assert(message->msg.qos != 0);
    if(dir == mosq_md_out){
        DL_APPEND(mosq->msgs_out.inflight, message);
        mosq->msgs_out.queue_len++;
    }else{
        DL_APPEND(mosq->msgs_in.inflight, message);
        mosq->msgs_in.queue_len++;
    }
    return message__release_to_inflight(mosq, dir);
}
void message__reconnect_reset(struct mosquitto *mosq)
{
    struct mosquitto_message_all *message, *tmp;
    assert(mosq);
    pthread_mutex_lock(&mosq->msgs_in.mutex);
    mosq->msgs_in.inflight_quota = mosq->msgs_in.inflight_maximum;
    mosq->msgs_in.queue_len = 0;
    DL_FOREACH_SAFE(mosq->msgs_in.inflight, message, tmp){
        mosq->msgs_in.queue_len++;
        message->timestamp = 0;
        if(message->msg.qos != 2){
            DL_DELETE(mosq->msgs_in.inflight, message);
            message__cleanup(&message);
        }else{
            /* Message state can be preserved here because it should match
            * whatever the client has got. */
            util__decrement_receive_quota(mosq);
        }
    }
    pthread_mutex_unlock(&mosq->msgs_in.mutex);
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum;
    mosq->msgs_out.queue_len = 0;
    DL_FOREACH_SAFE(mosq->msgs_out.inflight, message, tmp){
        mosq->msgs_out.queue_len++;
        message->timestamp = 0;
        if(mosq->msgs_out.inflight_quota != 0){
            util__decrement_send_quota(mosq);
            if(message->msg.qos == 1){
                message->state = mosq_ms_publish_qos1;
            }else if(message->msg.qos == 2){
                if(message->state == mosq_ms_wait_for_pubrec){
                    message->state = mosq_ms_publish_qos2;
                }else if(message->state == mosq_ms_wait_for_pubcomp){
                    message->state = mosq_ms_resend_pubrel;
                }
                /* Should be able to preserve state. */
            }
        }else{
            message->state = mosq_ms_invalid;
        }
    }
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
}
int message__release_to_inflight(struct mosquitto *mosq, enum mosquitto_msg_direction dir)
{
    /* mosq->*_message_mutex should be locked before entering this function */
    struct mosquitto_message_all *cur, *tmp;
    int rc = MOSQ_ERR_SUCCESS;
    if(dir == mosq_md_out){
        DL_FOREACH_SAFE(mosq->msgs_out.inflight, cur, tmp){
            if(mosq->msgs_out.inflight_quota > 0){
                if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){
                    if(cur->msg.qos == 1){
                        cur->state = mosq_ms_wait_for_puback;
                    }else if(cur->msg.qos == 2){
                        cur->state = mosq_ms_wait_for_pubrec;
                    }
                    rc = send__publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup, NULL, NULL, 0);
                    if(rc){
                        return rc;
                    }
                    util__decrement_send_quota(mosq);
                }
            }else{
                return MOSQ_ERR_SUCCESS;
            }
        }
    }
    return rc;
}
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message, int qos)
{
    struct mosquitto_message_all *cur, *tmp;
    bool found = false;
    assert(mosq);
    assert(message);
    if(dir == mosq_md_out){
        pthread_mutex_lock(&mosq->msgs_out.mutex);
        DL_FOREACH_SAFE(mosq->msgs_out.inflight, cur, tmp){
            if(found == false && cur->msg.mid == mid){
                if(cur->msg.qos != qos){
                    pthread_mutex_unlock(&mosq->msgs_out.mutex);
                    return MOSQ_ERR_PROTOCOL;
                }
                DL_DELETE(mosq->msgs_out.inflight, cur);
                *message = cur;
                mosq->msgs_out.queue_len--;
                found = true;
                break;
            }
        }
        pthread_mutex_unlock(&mosq->msgs_out.mutex);
        if(found){
            return MOSQ_ERR_SUCCESS;
        }else{
            return MOSQ_ERR_NOT_FOUND;
        }
    }else{
        pthread_mutex_lock(&mosq->msgs_in.mutex);
        DL_FOREACH_SAFE(mosq->msgs_in.inflight, cur, tmp){
            if(cur->msg.mid == mid){
                if(cur->msg.qos != qos){
                    pthread_mutex_unlock(&mosq->msgs_in.mutex);
                    return MOSQ_ERR_PROTOCOL;
                }
                DL_DELETE(mosq->msgs_in.inflight, cur);
                *message = cur;
                mosq->msgs_in.queue_len--;
                found = true;
                break;
            }
        }
        pthread_mutex_unlock(&mosq->msgs_in.mutex);
        if(found){
            return MOSQ_ERR_SUCCESS;
        }else{
            return MOSQ_ERR_NOT_FOUND;
        }
    }
}
void message__retry_check(struct mosquitto *mosq)
{
    struct mosquitto_message_all *msg;
    time_t now = mosquitto_time();
    assert(mosq);
#ifdef WITH_THREADING
    pthread_mutex_lock(&mosq->msgs_out.mutex);
#endif
    DL_FOREACH(mosq->msgs_out.inflight, msg){
        switch(msg->state){
            case mosq_ms_publish_qos1:
            case mosq_ms_publish_qos2:
                msg->timestamp = now;
                msg->dup = true;
                send__publish(mosq, msg->msg.mid, msg->msg.topic, msg->msg.payloadlen, msg->msg.payload, msg->msg.qos, msg->msg.retain, msg->dup, NULL, NULL, 0);
                break;
            case mosq_ms_wait_for_pubrel:
                msg->timestamp = now;
                msg->dup = true;
                send__pubrec(mosq, msg->msg.mid, 0);
                break;
            case mosq_ms_resend_pubrel:
            case mosq_ms_wait_for_pubcomp:
                msg->timestamp = now;
                msg->dup = true;
                send__pubrel(mosq, msg->msg.mid);
                break;
            default:
                break;
        }
    }
#ifdef WITH_THREADING
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
#endif
}
void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry)
{
    UNUSED(mosq);
    UNUSED(message_retry);
}
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state, int qos)
{
    struct mosquitto_message_all *message, *tmp;
    assert(mosq);
    pthread_mutex_lock(&mosq->msgs_out.mutex);
    DL_FOREACH_SAFE(mosq->msgs_out.inflight, message, tmp){
        if(message->msg.mid == mid){
            if(message->msg.qos != qos){
                pthread_mutex_unlock(&mosq->msgs_out.mutex);
                return MOSQ_ERR_PROTOCOL;
            }
            message->state = state;
            message->timestamp = mosquitto_time();
            pthread_mutex_unlock(&mosq->msgs_out.mutex);
            return MOSQ_ERR_SUCCESS;
        }
    }
    pthread_mutex_unlock(&mosq->msgs_out.mutex);
    return MOSQ_ERR_NOT_FOUND;
}
int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages)
{
    if(!mosq) return MOSQ_ERR_INVAL;
    mosq->send_maximum = max_inflight_messages;
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.h
New file
@@ -0,0 +1,32 @@
/*
Copyright (c) 2010-2019 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.
*/
#ifndef MESSAGES_MOSQ_H
#define MESSAGES_MOSQ_H
#include "mosquitto_internal.h"
#include "mosquitto.h"
void message__cleanup_all(struct mosquitto *mosq);
void message__cleanup(struct mosquitto_message_all **message);
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, int qos);
int message__queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir);
void message__reconnect_reset(struct mosquitto *mosq);
int message__release_to_inflight(struct mosquitto *mosq, enum mosquitto_msg_direction dir);
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message, int qos);
void message__retry_check(struct mosquitto *mosq);
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state, int qos);
#endif
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/messages_mosq.o
Binary files differ
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.c
New file
@@ -0,0 +1,612 @@
/*
Copyright (c) 2010-2019 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 "config.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "will_mosq.h"
void mosquitto__destroy(struct mosquitto *mosq);
int mosquitto_lib_version(int *major, int *minor, int *revision)
{
    if(major) *major = LIBMOSQUITTO_MAJOR;
    if(minor) *minor = LIBMOSQUITTO_MINOR;
    if(revision) *revision = LIBMOSQUITTO_REVISION;
    return LIBMOSQUITTO_VERSION_NUMBER;
}
int mosquitto_lib_init(void)
{
#ifdef WIN32
    srand(GetTickCount64());
#elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
    struct timespec tp;
    clock_gettime(CLOCK_MONOTONIC, &tp);
    srand(tp.tv_nsec);
#elif defined(__APPLE__)
    uint64_t ticks;
    ticks = mach_absolute_time();
    srand((unsigned int)ticks);
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    srand(tv.tv_sec*1000 + tv.tv_usec/1000);
#endif
    return net__init();
}
int mosquitto_lib_cleanup(void)
{
    net__cleanup();
    return MOSQ_ERR_SUCCESS;
}
struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata)
{
    struct mosquitto *mosq = NULL;
    int rc;
    if(clean_start == false && id == NULL){
        errno = EINVAL;
        return NULL;
    }
#ifndef WIN32
    signal(SIGPIPE, SIG_IGN);
#endif
    mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto));
    if(mosq){
        mosq->sock = INVALID_SOCKET;
        mosq->sockpairR = INVALID_SOCKET;
        mosq->sockpairW = INVALID_SOCKET;
#ifdef WITH_THREADING
        mosq->thread_id = pthread_self();
#endif
        rc = mosquitto_reinitialise(mosq, id, clean_start, userdata);
        if(rc){
            mosquitto_destroy(mosq);
            if(rc == MOSQ_ERR_INVAL){
                errno = EINVAL;
            }else if(rc == MOSQ_ERR_NOMEM){
                errno = ENOMEM;
            }
            return NULL;
        }
    }else{
        errno = ENOMEM;
    }
    return mosq;
}
int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_start, void *userdata)
{
    if(!mosq) return MOSQ_ERR_INVAL;
    if(clean_start == false && id == NULL){
        return MOSQ_ERR_INVAL;
    }
    mosquitto__destroy(mosq);
    memset(mosq, 0, sizeof(struct mosquitto));
    if(userdata){
        mosq->userdata = userdata;
    }else{
        mosq->userdata = mosq;
    }
    mosq->protocol = mosq_p_mqtt311;
    mosq->sock = INVALID_SOCKET;
    mosq->sockpairR = INVALID_SOCKET;
    mosq->sockpairW = INVALID_SOCKET;
    mosq->keepalive = 60;
    mosq->clean_start = clean_start;
    if(id){
        if(STREMPTY(id)){
            return MOSQ_ERR_INVAL;
        }
        if(mosquitto_validate_utf8(id, strlen(id))){
            return MOSQ_ERR_MALFORMED_UTF8;
        }
        mosq->id = mosquitto__strdup(id);
    }
    mosq->in_packet.payload = NULL;
    packet__cleanup(&mosq->in_packet);
    mosq->out_packet = NULL;
    mosq->current_out_packet = NULL;
    mosq->last_msg_in = mosquitto_time();
    mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
    mosq->ping_t = 0;
    mosq->last_mid = 0;
    mosq->state = mosq_cs_new;
    mosq->maximum_qos = 2;
    mosq->msgs_in.inflight_maximum = 20;
    mosq->msgs_out.inflight_maximum = 20;
    mosq->msgs_in.inflight_quota = 20;
    mosq->msgs_out.inflight_quota = 20;
    mosq->will = NULL;
    mosq->on_connect = NULL;
    mosq->on_publish = NULL;
    mosq->on_message = NULL;
    mosq->on_subscribe = NULL;
    mosq->on_unsubscribe = NULL;
    mosq->host = NULL;
    mosq->port = 1883;
    mosq->in_callback = false;
    mosq->reconnect_delay = 1;
    mosq->reconnect_delay_max = 1;
    mosq->reconnect_exponential_backoff = false;
    mosq->threaded = mosq_ts_none;
#ifdef WITH_TLS
    mosq->ssl = NULL;
    mosq->ssl_ctx = NULL;
    mosq->tls_cert_reqs = SSL_VERIFY_PEER;
    mosq->tls_insecure = false;
    mosq->want_write = false;
    mosq->tls_ocsp_required = false;
#endif
#ifdef WITH_THREADING
    pthread_mutex_init(&mosq->callback_mutex, NULL);
    pthread_mutex_init(&mosq->log_callback_mutex, NULL);
    pthread_mutex_init(&mosq->state_mutex, NULL);
    pthread_mutex_init(&mosq->out_packet_mutex, NULL);
    pthread_mutex_init(&mosq->current_out_packet_mutex, NULL);
    pthread_mutex_init(&mosq->msgtime_mutex, NULL);
    pthread_mutex_init(&mosq->msgs_in.mutex, NULL);
    pthread_mutex_init(&mosq->msgs_out.mutex, NULL);
    pthread_mutex_init(&mosq->mid_mutex, NULL);
    mosq->thread_id = pthread_self();
#endif
    return MOSQ_ERR_SUCCESS;
}
void mosquitto__destroy(struct mosquitto *mosq)
{
    struct mosquitto__packet *packet;
    if(!mosq) return;
#ifdef WITH_THREADING
#  ifdef HAVE_PTHREAD_CANCEL
    if(mosq->threaded == mosq_ts_self && !pthread_equal(mosq->thread_id, pthread_self())){
        pthread_cancel(mosq->thread_id);
        pthread_join(mosq->thread_id, NULL);
        mosq->threaded = mosq_ts_none;
    }
#  endif
    if(mosq->id){
        /* If mosq->id is not NULL then the client has already been initialised
         * and so the mutexes need destroying. If mosq->id is NULL, the mutexes
         * haven't been initialised. */
        pthread_mutex_destroy(&mosq->callback_mutex);
        pthread_mutex_destroy(&mosq->log_callback_mutex);
        pthread_mutex_destroy(&mosq->state_mutex);
        pthread_mutex_destroy(&mosq->out_packet_mutex);
        pthread_mutex_destroy(&mosq->current_out_packet_mutex);
        pthread_mutex_destroy(&mosq->msgtime_mutex);
        pthread_mutex_destroy(&mosq->msgs_in.mutex);
        pthread_mutex_destroy(&mosq->msgs_out.mutex);
        pthread_mutex_destroy(&mosq->mid_mutex);
    }
#endif
    if(mosq->sock != INVALID_SOCKET){
        net__socket_close(mosq);
    }
    message__cleanup_all(mosq);
    will__clear(mosq);
#ifdef WITH_TLS
    if(mosq->ssl){
        SSL_free(mosq->ssl);
    }
    if(mosq->ssl_ctx){
        SSL_CTX_free(mosq->ssl_ctx);
    }
    mosquitto__free(mosq->tls_cafile);
    mosquitto__free(mosq->tls_capath);
    mosquitto__free(mosq->tls_certfile);
    mosquitto__free(mosq->tls_keyfile);
    if(mosq->tls_pw_callback) mosq->tls_pw_callback = NULL;
    mosquitto__free(mosq->tls_version);
    mosquitto__free(mosq->tls_ciphers);
    mosquitto__free(mosq->tls_psk);
    mosquitto__free(mosq->tls_psk_identity);
    mosquitto__free(mosq->tls_alpn);
#endif
    mosquitto__free(mosq->address);
    mosq->address = NULL;
    mosquitto__free(mosq->id);
    mosq->id = NULL;
    mosquitto__free(mosq->username);
    mosq->username = NULL;
    mosquitto__free(mosq->password);
    mosq->password = NULL;
    mosquitto__free(mosq->host);
    mosq->host = NULL;
    mosquitto__free(mosq->bind_address);
    mosq->bind_address = NULL;
    /* Out packet cleanup */
    if(mosq->out_packet && !mosq->current_out_packet){
        mosq->current_out_packet = mosq->out_packet;
        mosq->out_packet = mosq->out_packet->next;
    }
    while(mosq->current_out_packet){
        packet = mosq->current_out_packet;
        /* Free data and reset values */
        mosq->current_out_packet = mosq->out_packet;
        if(mosq->out_packet){
            mosq->out_packet = mosq->out_packet->next;
        }
        packet__cleanup(packet);
        mosquitto__free(packet);
    }
    packet__cleanup(&mosq->in_packet);
    if(mosq->sockpairR != INVALID_SOCKET){
        COMPAT_CLOSE(mosq->sockpairR);
        mosq->sockpairR = INVALID_SOCKET;
    }
    if(mosq->sockpairW != INVALID_SOCKET){
        COMPAT_CLOSE(mosq->sockpairW);
        mosq->sockpairW = INVALID_SOCKET;
    }
}
void mosquitto_destroy(struct mosquitto *mosq)
{
    if(!mosq) return;
    mosquitto__destroy(mosq);
    mosquitto__free(mosq);
}
int mosquitto_socket(struct mosquitto *mosq)
{
    if(!mosq) return INVALID_SOCKET;
    return mosq->sock;
}
bool mosquitto_want_write(struct mosquitto *mosq)
{
    bool result = false;
    if(mosq->out_packet || mosq->current_out_packet){
        result = true;
    }
#ifdef WITH_TLS
    if(mosq->ssl){
        if (mosq->want_write) {
            result = true;
        }else if(mosq->want_connect){
            result = false;
        }
    }
#endif
    return result;
}
const char *mosquitto_strerror(int mosq_errno)
{
    switch(mosq_errno){
        case MOSQ_ERR_AUTH_CONTINUE:
            return "Continue with authentication.";
        case MOSQ_ERR_NO_SUBSCRIBERS:
            return "No subscribers.";
        case MOSQ_ERR_SUB_EXISTS:
            return "Subscription already exists.";
        case MOSQ_ERR_CONN_PENDING:
            return "Connection pending.";
        case MOSQ_ERR_SUCCESS:
            return "No error.";
        case MOSQ_ERR_NOMEM:
            return "Out of memory.";
        case MOSQ_ERR_PROTOCOL:
            return "A network protocol error occurred when communicating with the broker.";
        case MOSQ_ERR_INVAL:
            return "Invalid function arguments provided.";
        case MOSQ_ERR_NO_CONN:
            return "The client is not currently connected.";
        case MOSQ_ERR_CONN_REFUSED:
            return "The connection was refused.";
        case MOSQ_ERR_NOT_FOUND:
            return "Message not found (internal error).";
        case MOSQ_ERR_CONN_LOST:
            return "The connection was lost.";
        case MOSQ_ERR_TLS:
            return "A TLS error occurred.";
        case MOSQ_ERR_PAYLOAD_SIZE:
            return "Payload too large.";
        case MOSQ_ERR_NOT_SUPPORTED:
            return "This feature is not supported.";
        case MOSQ_ERR_AUTH:
            return "Authorisation failed.";
        case MOSQ_ERR_ACL_DENIED:
            return "Access denied by ACL.";
        case MOSQ_ERR_UNKNOWN:
            return "Unknown error.";
        case MOSQ_ERR_ERRNO:
            return strerror(errno);
        case MOSQ_ERR_EAI:
            return "Lookup error.";
        case MOSQ_ERR_PROXY:
            return "Proxy error.";
        case MOSQ_ERR_MALFORMED_UTF8:
            return "Malformed UTF-8";
        case MOSQ_ERR_DUPLICATE_PROPERTY:
            return "Duplicate property in property list";
        case MOSQ_ERR_TLS_HANDSHAKE:
            return "TLS handshake failed.";
        case MOSQ_ERR_QOS_NOT_SUPPORTED:
            return "Requested QoS not supported on server.";
        case MOSQ_ERR_OVERSIZE_PACKET:
            return "Packet larger than supported by the server.";
        case MOSQ_ERR_OCSP:
            return "OCSP error.";
        default:
            return "Unknown error.";
    }
}
const char *mosquitto_connack_string(int connack_code)
{
    switch(connack_code){
        case 0:
            return "Connection Accepted.";
        case 1:
            return "Connection Refused: unacceptable protocol version.";
        case 2:
            return "Connection Refused: identifier rejected.";
        case 3:
            return "Connection Refused: broker unavailable.";
        case 4:
            return "Connection Refused: bad user name or password.";
        case 5:
            return "Connection Refused: not authorised.";
        default:
            return "Connection Refused: unknown reason.";
    }
}
const char *mosquitto_reason_string(int reason_code)
{
    switch(reason_code){
        case MQTT_RC_SUCCESS:
            return "Success";
        case MQTT_RC_GRANTED_QOS1:
            return "Granted QoS 1";
        case MQTT_RC_GRANTED_QOS2:
            return "Granted QoS 2";
        case MQTT_RC_DISCONNECT_WITH_WILL_MSG:
            return "Disconnect with Will Message";
        case MQTT_RC_NO_MATCHING_SUBSCRIBERS:
            return "No matching subscribers";
        case MQTT_RC_NO_SUBSCRIPTION_EXISTED:
            return "No subscription existed";
        case MQTT_RC_CONTINUE_AUTHENTICATION:
            return "Continue authentication";
        case MQTT_RC_REAUTHENTICATE:
            return "Re-authenticate";
        case MQTT_RC_UNSPECIFIED:
            return "Unspecified error";
        case MQTT_RC_MALFORMED_PACKET:
            return "Malformed Packet";
        case MQTT_RC_PROTOCOL_ERROR:
            return "Protocol Error";
        case MQTT_RC_IMPLEMENTATION_SPECIFIC:
            return "Implementation specific error";
        case MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION:
            return "Unsupported Protocol Version";
        case MQTT_RC_CLIENTID_NOT_VALID:
            return "Client Identifier not valid";
        case MQTT_RC_BAD_USERNAME_OR_PASSWORD:
            return "Bad User Name or Password";
        case MQTT_RC_NOT_AUTHORIZED:
            return "Not authorized";
        case MQTT_RC_SERVER_UNAVAILABLE:
            return "Server unavailable";
        case MQTT_RC_SERVER_BUSY:
            return "Server busy";
        case MQTT_RC_BANNED:
            return "Banned";
        case MQTT_RC_SERVER_SHUTTING_DOWN:
            return "Server shutting down";
        case MQTT_RC_BAD_AUTHENTICATION_METHOD:
            return "Bad authentication method";
        case MQTT_RC_KEEP_ALIVE_TIMEOUT:
            return "Keep Alive timeout";
        case MQTT_RC_SESSION_TAKEN_OVER:
            return "Session taken over";
        case MQTT_RC_TOPIC_FILTER_INVALID:
            return "Topic Filter invalid";
        case MQTT_RC_TOPIC_NAME_INVALID:
            return "Topic Name invalid";
        case MQTT_RC_PACKET_ID_IN_USE:
            return "Packet Identifier in use";
        case MQTT_RC_PACKET_ID_NOT_FOUND:
            return "Packet Identifier not found";
        case MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED:
            return "Receive Maximum exceeded";
        case MQTT_RC_TOPIC_ALIAS_INVALID:
            return "Topic Alias invalid";
        case MQTT_RC_PACKET_TOO_LARGE:
            return "Packet too large";
        case MQTT_RC_MESSAGE_RATE_TOO_HIGH:
            return "Message rate too high";
        case MQTT_RC_QUOTA_EXCEEDED:
            return "Quota exceeded";
        case MQTT_RC_ADMINISTRATIVE_ACTION:
            return "Administrative action";
        case MQTT_RC_PAYLOAD_FORMAT_INVALID:
            return "Payload format invalid";
        case MQTT_RC_RETAIN_NOT_SUPPORTED:
            return "Retain not supported";
        case MQTT_RC_QOS_NOT_SUPPORTED:
            return "QoS not supported";
        case MQTT_RC_USE_ANOTHER_SERVER:
            return "Use another server";
        case MQTT_RC_SERVER_MOVED:
            return "Server moved";
        case MQTT_RC_SHARED_SUBS_NOT_SUPPORTED:
            return "Shared Subscriptions not supported";
        case MQTT_RC_CONNECTION_RATE_EXCEEDED:
            return "Connection rate exceeded";
        case MQTT_RC_MAXIMUM_CONNECT_TIME:
            return "Maximum connect time";
        case MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED:
            return "Subscription identifiers not supported";
        case MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED:
            return "Wildcard Subscriptions not supported";
        default:
            return "Unknown reason";
    }
}
int mosquitto_string_to_command(const char *str, int *cmd)
{
    if(!strcasecmp(str, "connect")){
        *cmd = CMD_CONNECT;
    }else if(!strcasecmp(str, "connack")){
        *cmd = CMD_CONNACK;
    }else if(!strcasecmp(str, "publish")){
        *cmd = CMD_PUBLISH;
    }else if(!strcasecmp(str, "puback")){
        *cmd = CMD_PUBACK;
    }else if(!strcasecmp(str, "pubrec")){
        *cmd = CMD_PUBREC;
    }else if(!strcasecmp(str, "pubrel")){
        *cmd = CMD_PUBREL;
    }else if(!strcasecmp(str, "pubcomp")){
        *cmd = CMD_PUBCOMP;
    }else if(!strcasecmp(str, "subscribe")){
        *cmd = CMD_SUBSCRIBE;
    }else if(!strcasecmp(str, "unsubscribe")){
        *cmd = CMD_UNSUBSCRIBE;
    }else if(!strcasecmp(str, "disconnect")){
        *cmd = CMD_DISCONNECT;
    }else if(!strcasecmp(str, "auth")){
        *cmd = CMD_AUTH;
    }else if(!strcasecmp(str, "will")){
        *cmd = CMD_WILL;
    }else{
        return MOSQ_ERR_INVAL;
    }
    return MOSQ_ERR_SUCCESS;
}
int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count)
{
    int len;
    int hier_count = 1;
    int start, stop;
    int hier;
    int tlen;
    int i, j;
    if(!subtopic || !topics || !count) return MOSQ_ERR_INVAL;
    len = strlen(subtopic);
    for(i=0; i<len; i++){
        if(subtopic[i] == '/'){
            if(i > len-1){
                /* Separator at end of line */
            }else{
                hier_count++;
            }
        }
    }
    (*topics) = mosquitto__calloc(hier_count, sizeof(char *));
    if(!(*topics)) return MOSQ_ERR_NOMEM;
    start = 0;
    stop = 0;
    hier = 0;
    for(i=0; i<len+1; i++){
        if(subtopic[i] == '/' || subtopic[i] == '\0'){
            stop = i;
            if(start != stop){
                tlen = stop-start + 1;
                (*topics)[hier] = mosquitto__calloc(tlen, sizeof(char));
                if(!(*topics)[hier]){
                    for(j=0; j<hier; j++){
                        mosquitto__free((*topics)[j]);
                    }
                    mosquitto__free((*topics));
                    return MOSQ_ERR_NOMEM;
                }
                for(j=start; j<stop; j++){
                    (*topics)[hier][j-start] = subtopic[j];
                }
            }
            start = i+1;
            hier++;
        }
    }
    *count = hier_count;
    return MOSQ_ERR_SUCCESS;
}
int mosquitto_sub_topic_tokens_free(char ***topics, int count)
{
    int i;
    if(!topics || !(*topics) || count<1) return MOSQ_ERR_INVAL;
    for(i=0; i<count; i++){
        mosquitto__free((*topics)[i]);
    }
    mosquitto__free(*topics);
    return MOSQ_ERR_SUCCESS;
}
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.h
New file
@@ -0,0 +1,2993 @@
/*
Copyright (c) 2010-2019 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.
*/
#ifndef MOSQUITTO_H
#define MOSQUITTO_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC)
#    ifdef libmosquitto_EXPORTS
#        define libmosq_EXPORT  __declspec(dllexport)
#    else
#        define libmosq_EXPORT  __declspec(dllimport)
#    endif
#else
#    define libmosq_EXPORT
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
#    ifndef __cplusplus
#        define bool char
#        define true 1
#        define false 0
#    endif
#else
#    ifndef __cplusplus
#        include <stdbool.h>
#    endif
#endif
#include <stddef.h>
#include <stdint.h>
#define LIBMOSQUITTO_MAJOR 1
#define LIBMOSQUITTO_MINOR 6
#define LIBMOSQUITTO_REVISION 3
/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */
#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)
/* Log types */
#define MOSQ_LOG_NONE            0
#define MOSQ_LOG_INFO            (1<<0)
#define MOSQ_LOG_NOTICE            (1<<1)
#define MOSQ_LOG_WARNING        (1<<2)
#define MOSQ_LOG_ERR            (1<<3)
#define MOSQ_LOG_DEBUG            (1<<4)
#define MOSQ_LOG_SUBSCRIBE        (1<<5)
#define MOSQ_LOG_UNSUBSCRIBE    (1<<6)
#define MOSQ_LOG_WEBSOCKETS        (1<<7)
#define MOSQ_LOG_INTERNAL        0x80000000
#define MOSQ_LOG_ALL            0x7FFFFFFF
/* Error values */
enum mosq_err_t {
    MOSQ_ERR_AUTH_CONTINUE = -4,
    MOSQ_ERR_NO_SUBSCRIBERS = -3,
    MOSQ_ERR_SUB_EXISTS = -2,
    MOSQ_ERR_CONN_PENDING = -1,
    MOSQ_ERR_SUCCESS = 0,
    MOSQ_ERR_NOMEM = 1,
    MOSQ_ERR_PROTOCOL = 2,
    MOSQ_ERR_INVAL = 3,
    MOSQ_ERR_NO_CONN = 4,
    MOSQ_ERR_CONN_REFUSED = 5,
    MOSQ_ERR_NOT_FOUND = 6,
    MOSQ_ERR_CONN_LOST = 7,
    MOSQ_ERR_TLS = 8,
    MOSQ_ERR_PAYLOAD_SIZE = 9,
    MOSQ_ERR_NOT_SUPPORTED = 10,
    MOSQ_ERR_AUTH = 11,
    MOSQ_ERR_ACL_DENIED = 12,
    MOSQ_ERR_UNKNOWN = 13,
    MOSQ_ERR_ERRNO = 14,
    MOSQ_ERR_EAI = 15,
    MOSQ_ERR_PROXY = 16,
    MOSQ_ERR_PLUGIN_DEFER = 17,
    MOSQ_ERR_MALFORMED_UTF8 = 18,
    MOSQ_ERR_KEEPALIVE = 19,
    MOSQ_ERR_LOOKUP = 20,
    MOSQ_ERR_MALFORMED_PACKET = 21,
    MOSQ_ERR_DUPLICATE_PROPERTY = 22,
    MOSQ_ERR_TLS_HANDSHAKE = 23,
    MOSQ_ERR_QOS_NOT_SUPPORTED = 24,
    MOSQ_ERR_OVERSIZE_PACKET = 25,
    MOSQ_ERR_OCSP = 26,
};
/* Option values */
enum mosq_opt_t {
    MOSQ_OPT_PROTOCOL_VERSION = 1,
    MOSQ_OPT_SSL_CTX = 2,
    MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3,
    MOSQ_OPT_RECEIVE_MAXIMUM = 4,
    MOSQ_OPT_SEND_MAXIMUM = 5,
    MOSQ_OPT_TLS_KEYFORM = 6,
    MOSQ_OPT_TLS_ENGINE = 7,
    MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8,
    MOSQ_OPT_TLS_OCSP_REQUIRED = 9,
    MOSQ_OPT_TLS_ALPN = 10,
};
/* MQTT specification restricts client ids to a maximum of 23 characters */
#define MOSQ_MQTT_ID_MAX_LENGTH 23
#define MQTT_PROTOCOL_V31 3
#define MQTT_PROTOCOL_V311 4
#define MQTT_PROTOCOL_V5 5
struct mosquitto_message{
    int mid;
    char *topic;
    void *payload;
    int payloadlen;
    int qos;
    bool retain;
};
struct mosquitto;
typedef struct mqtt5__property mosquitto_property;
/*
 * Topic: Threads
 *    libmosquitto provides thread safe operation, with the exception of
 *    <mosquitto_lib_init> which is not thread safe.
 *
 *    If your application uses threads you must use <mosquitto_threaded_set> to
 *    tell the library this is the case, otherwise it makes some optimisations
 *    for the single threaded case that may result in unexpected behaviour for
 *    the multi threaded case.
 */
/***************************************************
 * Important note
 *
 * The following functions that deal with network operations will return
 * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has
 * taken place. An attempt will be made to write the network data, but if the
 * socket is not available for writing at that time then the packet will not be
 * sent. To ensure the packet is sent, call mosquitto_loop() (which must also
 * be called to process incoming network data).
 * This is especially important when disconnecting a client that has a will. If
 * the broker does not receive the DISCONNECT command, it will assume that the
 * client has disconnected unexpectedly and send the will.
 *
 * mosquitto_connect()
 * mosquitto_disconnect()
 * mosquitto_subscribe()
 * mosquitto_unsubscribe()
 * mosquitto_publish()
 ***************************************************/
/* ======================================================================
 *
 * Section: Library version, init, and cleanup
 *
 * ====================================================================== */
/*
 * Function: mosquitto_lib_version
 *
 * Can be used to obtain version information for the mosquitto library.
 * This allows the application to compare the library version against the
 * version it was compiled against by using the LIBMOSQUITTO_MAJOR,
 * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines.
 *
 * Parameters:
 *  major -    an integer pointer. If not NULL, the major version of the
 *             library will be returned in this variable.
 *  minor -    an integer pointer. If not NULL, the minor version of the
 *             library will be returned in this variable.
 *  revision - an integer pointer. If not NULL, the revision of the library will
 *             be returned in this variable.
 *
 * Returns:
 *    LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major,
 *        minor and revision values.
 * See Also:
 *     <mosquitto_lib_cleanup>, <mosquitto_lib_init>
 */
libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision);
/*
 * Function: mosquitto_lib_init
 *
 * Must be called before any other mosquitto functions.
 *
 * This function is *not* thread safe.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - always
 *
 * See Also:
 *     <mosquitto_lib_cleanup>, <mosquitto_lib_version>
 */
libmosq_EXPORT int mosquitto_lib_init(void);
/*
 * Function: mosquitto_lib_cleanup
 *
 * Call to free resources associated with the library.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - always
 *
 * See Also:
 *     <mosquitto_lib_init>, <mosquitto_lib_version>
 */
libmosq_EXPORT int mosquitto_lib_cleanup(void);
/* ======================================================================
 *
 * Section: Client creation, destruction, and reinitialisation
 *
 * ====================================================================== */
/*
 * Function: mosquitto_new
 *
 * Create a new mosquitto client instance.
 *
 * Parameters:
 *     id -            String to use as the client id. If NULL, a random client id
 *                     will be generated. If id is NULL, clean_session must be true.
 *     clean_session - set to true to instruct the broker to clean all messages
 *                  and subscriptions on disconnect, false to instruct it to
 *                  keep them. See the man page mqtt(7) for more details.
 *                  Note that a client will never discard its own outgoing
 *                  messages on disconnect. Calling <mosquitto_connect> or
 *                  <mosquitto_reconnect> will cause the messages to be resent.
 *                  Use <mosquitto_reinitialise> to reset a client to its
 *                  original state.
 *                  Must be set to true if the id parameter is NULL.
 *     obj -           A user pointer that will be passed as an argument to any
 *                  callbacks that are specified.
 *
 * Returns:
 *     Pointer to a struct mosquitto on success.
 *     NULL on failure. Interrogate errno to determine the cause for the failure:
 *      - ENOMEM on out of memory.
 *      - EINVAL on invalid input parameters.
 *
 * See Also:
 *     <mosquitto_reinitialise>, <mosquitto_destroy>, <mosquitto_user_data_set>
 */
libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
/*
 * Function: mosquitto_destroy
 *
 * Use to free memory associated with a mosquitto client instance.
 *
 * Parameters:
 *     mosq - a struct mosquitto pointer to free.
 *
 * See Also:
 *     <mosquitto_new>, <mosquitto_reinitialise>
 */
libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq);
/*
 * Function: mosquitto_reinitialise
 *
 * This function allows an existing mosquitto client to be reused. Call on a
 * mosquitto instance to close any open network connections, free memory
 * and reinitialise the client with the new parameters. The end result is the
 * same as the output of <mosquitto_new>.
 *
 * Parameters:
 *     mosq -          a valid mosquitto instance.
 *     id -            string to use as the client id. If NULL, a random client id
 *                     will be generated. If id is NULL, clean_session must be true.
 *     clean_session - set to true to instruct the broker to clean all messages
 *                  and subscriptions on disconnect, false to instruct it to
 *                  keep them. See the man page mqtt(7) for more details.
 *                  Must be set to true if the id parameter is NULL.
 *     obj -           A user pointer that will be passed as an argument to any
 *                  callbacks that are specified.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * See Also:
 *     <mosquitto_new>, <mosquitto_destroy>
 */
libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj);
/* ======================================================================
 *
 * Section: Will
 *
 * ====================================================================== */
/*
 * Function: mosquitto_will_set
 *
 * Configure will information for a mosquitto instance. By default, clients do
 * not have a will.  This must be called before calling <mosquitto_connect>.
 *
 * Parameters:
 *     mosq -       a valid mosquitto instance.
 *     topic -      the topic on which to publish the will.
 *     payloadlen - the size of the payload (bytes). Valid values are between 0 and
 *               268,435,455.
 *     payload -    pointer to the data to send. If payloadlen > 0 this must be a
 *               valid memory location.
 *     qos -        integer value 0, 1 or 2 indicating the Quality of Service to be
 *               used for the will.
 *     retain -     set to true to make the will a retained message.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS -      on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_PAYLOAD_SIZE -   if payloadlen is too large.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8.
 */
libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain);
/*
 * Function: mosquitto_will_set_v5
 *
 * Configure will information for a mosquitto instance, with attached
 * properties. By default, clients do not have a will.  This must be called
 * before calling <mosquitto_connect>.
 *
 * Parameters:
 *     mosq -       a valid mosquitto instance.
 *     topic -      the topic on which to publish the will.
 *     payloadlen - the size of the payload (bytes). Valid values are between 0 and
 *               268,435,455.
 *     payload -    pointer to the data to send. If payloadlen > 0 this must be a
 *               valid memory location.
 *     qos -        integer value 0, 1 or 2 indicating the Quality of Service to be
 *               used for the will.
 *     retain -     set to true to make the will a retained message.
 *     properties - list of MQTT 5 properties. Can be NULL. On success only, the
 *                  property list becomes the property of libmosquitto once this
 *                  function is called and will be freed by the library. The
 *                  property list must be freed by the application on error.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS -      on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_PAYLOAD_SIZE -   if payloadlen is too large.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8.
 *     MOSQ_ERR_NOT_SUPPORTED -  if properties is not NULL and the client is not
 *                               using MQTT v5
 *     MOSQ_ERR_PROTOCOL -       if a property is invalid for use with wills.
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 */
libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties);
/*
 * Function: mosquitto_will_clear
 *
 * Remove a previously configured will. This must be called before calling
 * <mosquitto_connect>.
 *
 * Parameters:
 *     mosq - a valid mosquitto instance.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 */
libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq);
/* ======================================================================
 *
 * Section: Username and password
 *
 * ====================================================================== */
/*
 * Function: mosquitto_username_pw_set
 *
 * Configure username and password for a mosquitton instance. This is only
 * supported by brokers that implement the MQTT spec v3.1. By default, no
 * username or password will be sent.
 * If username is NULL, the password argument is ignored.
 * This must be called before calling mosquitto_connect().
 *
 * This is must be called before calling <mosquitto_connect>.
 *
 * Parameters:
 *     mosq -     a valid mosquitto instance.
 *     username - the username to send as a string, or NULL to disable
 *             authentication.
 *     password - the password to send as a string. Set to NULL when username is
 *                valid in order to send just a username.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 */
libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password);
/* ======================================================================
 *
 * Section: Connecting, reconnecting, disconnecting
 *
 * ====================================================================== */
/*
 * Function: mosquitto_connect
 *
 * Connect to an MQTT broker.
 *
 * Parameters:
 *     mosq -      a valid mosquitto instance.
 *     host -      the hostname or ip address of the broker to connect to.
 *     port -      the network port to connect to. Usually 1883.
 *     keepalive - the number of seconds after which the broker should send a PING
 *              message to the client if no other messages have been exchanged
 *              in that time.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect_bind>, <mosquitto_connect_async>, <mosquitto_reconnect>, <mosquitto_disconnect>, <mosquitto_tls_set>
 */
libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
/*
 * Function: mosquitto_connect_bind
 *
 * Connect to an MQTT broker. This extends the functionality of
 * <mosquitto_connect> by adding the bind_address parameter. Use this function
 * if you need to restrict network communication over a particular interface.
 *
 * Parameters:
 *     mosq -         a valid mosquitto instance.
 *     host -         the hostname or ip address of the broker to connect to.
 *     port -         the network port to connect to. Usually 1883.
 *     keepalive -    the number of seconds after which the broker should send a PING
 *                 message to the client if no other messages have been exchanged
 *                 in that time.
 *  bind_address - the hostname or ip address of the local network interface to
 *                 bind to.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect>, <mosquitto_connect_async>, <mosquitto_connect_bind_async>
 */
libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address);
/*
 * Function: mosquitto_connect_bind_v5
 *
 * Connect to an MQTT broker. This extends the functionality of
 * <mosquitto_connect> by adding the bind_address parameter. Use this function
 * if you need to restrict network communication over a particular interface.
 *
 * Parameters:
 *     mosq -         a valid mosquitto instance.
 *     host -         the hostname or ip address of the broker to connect to.
 *     port -         the network port to connect to. Usually 1883.
 *     keepalive -    the number of seconds after which the broker should send a PING
 *                 message to the client if no other messages have been exchanged
 *                 in that time.
 *  bind_address - the hostname or ip address of the local network interface to
 *                 bind to.
 *  properties - the MQTT 5 properties for the connect (not for the Will).
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT.
 *
 * See Also:
 *     <mosquitto_connect>, <mosquitto_connect_async>, <mosquitto_connect_bind_async>
 */
libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties);
/*
 * Function: mosquitto_connect_async
 *
 * Connect to an MQTT broker. This is a non-blocking call. If you use
 * <mosquitto_connect_async> your client must use the threaded interface
 * <mosquitto_loop_start>. If you need to use <mosquitto_loop>, you must use
 * <mosquitto_connect> to connect the client.
 *
 * May be called before or after <mosquitto_loop_start>.
 *
 * Parameters:
 *     mosq -      a valid mosquitto instance.
 *     host -      the hostname or ip address of the broker to connect to.
 *     port -      the network port to connect to. Usually 1883.
 *     keepalive - the number of seconds after which the broker should send a PING
 *              message to the client if no other messages have been exchanged
 *              in that time.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect_bind_async>, <mosquitto_connect>, <mosquitto_reconnect>, <mosquitto_disconnect>, <mosquitto_tls_set>
 */
libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive);
/*
 * Function: mosquitto_connect_bind_async
 *
 * Connect to an MQTT broker. This is a non-blocking call. If you use
 * <mosquitto_connect_bind_async> your client must use the threaded interface
 * <mosquitto_loop_start>. If you need to use <mosquitto_loop>, you must use
 * <mosquitto_connect> to connect the client.
 *
 * This extends the functionality of <mosquitto_connect_async> by adding the
 * bind_address parameter. Use this function if you need to restrict network
 * communication over a particular interface.
 *
 * May be called before or after <mosquitto_loop_start>.
 *
 * Parameters:
 *     mosq -         a valid mosquitto instance.
 *     host -         the hostname or ip address of the broker to connect to.
 *     port -         the network port to connect to. Usually 1883.
 *     keepalive -    the number of seconds after which the broker should send a PING
 *                 message to the client if no other messages have been exchanged
 *                 in that time.
 *  bind_address - the hostname or ip address of the local network interface to
 *                 bind to.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect_async>, <mosquitto_connect>, <mosquitto_connect_bind>
 */
libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address);
/*
 * Function: mosquitto_connect_srv
 *
 * Connect to an MQTT broker. This is a non-blocking call. If you use
 * <mosquitto_connect_async> your client must use the threaded interface
 * <mosquitto_loop_start>. If you need to use <mosquitto_loop>, you must use
 * <mosquitto_connect> to connect the client.
 *
 * This extends the functionality of <mosquitto_connect_async> by adding the
 * bind_address parameter. Use this function if you need to restrict network
 * communication over a particular interface.
 *
 * May be called before or after <mosquitto_loop_start>.
 *
 * Parameters:
 *     mosq -         a valid mosquitto instance.
 *     host -         the hostname or ip address of the broker to connect to.
 *     keepalive -    the number of seconds after which the broker should send a PING
 *                 message to the client if no other messages have been exchanged
 *                 in that time.
 *  bind_address - the hostname or ip address of the local network interface to
 *                 bind to.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect_async>, <mosquitto_connect>, <mosquitto_connect_bind>
 */
libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address);
/*
 * Function: mosquitto_reconnect
 *
 * Reconnect to a broker.
 *
 * This function provides an easy way of reconnecting to a broker after a
 * connection has been lost. It uses the values that were provided in the
 * <mosquitto_connect> call. It must not be called before
 * <mosquitto_connect>.
 *
 * Parameters:
 *     mosq - a valid mosquitto instance.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect>, <mosquitto_disconnect>, <mosquitto_reconnect_async>
 */
libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq);
/*
 * Function: mosquitto_reconnect_async
 *
 * Reconnect to a broker. Non blocking version of <mosquitto_reconnect>.
 *
 * This function provides an easy way of reconnecting to a broker after a
 * connection has been lost. It uses the values that were provided in the
 * <mosquitto_connect> or <mosquitto_connect_async> calls. It must not be
 * called before <mosquitto_connect>.
 *
 * Parameters:
 *     mosq - a valid mosquitto instance.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_ERRNO -   if a system call returned an error. The variable errno
 *                     contains the error code, even on Windows.
 *                     Use strerror_r() where available or FormatMessage() on
 *                     Windows.
 *
 * See Also:
 *     <mosquitto_connect>, <mosquitto_disconnect>
 */
libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq);
/*
 * Function: mosquitto_disconnect
 *
 * Disconnect from the broker.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NO_CONN -  if the client isn't connected to a broker.
 */
libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq);
/*
 * Function: mosquitto_disconnect_v5
 *
 * Disconnect from the broker, with attached MQTT properties.
 *
 * Use <mosquitto_property_add_*> to create a list of properties, then attach
 * them to this publish. Properties need freeing with
 * <mosquitto_property_free_all>.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    reason_code - the disconnect reason code.
 *     properties - a valid mosquitto_property list, or NULL.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NO_CONN -  if the client isn't connected to a broker.
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT.
 */
libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties);
/* ======================================================================
 *
 * Section: Publishing, subscribing, unsubscribing
 *
 * ====================================================================== */
/*
 * Function: mosquitto_publish
 *
 * Publish a message on a given topic.
 *
 * Parameters:
 *     mosq -       a valid mosquitto instance.
 *     mid -        pointer to an int. If not NULL, the function will set this
 *               to the message id of this particular message. This can be then
 *               used with the publish callback to determine when the message
 *               has been sent.
 *               Note that although the MQTT protocol doesn't use message ids
 *               for messages with QoS=0, libmosquitto assigns them message ids
 *               so they can be tracked with this parameter.
 *  topic -      null terminated string of the topic to publish to.
 *     payloadlen - the size of the payload (bytes). Valid values are between 0 and
 *               268,435,455.
 *     payload -    pointer to the data to send. If payloadlen > 0 this must be a
 *               valid memory location.
 *     qos -        integer value 0, 1 or 2 indicating the Quality of Service to be
 *               used for the message.
 *     retain -     set to true to make the message retained.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *    MOSQ_ERR_PROTOCOL -       if there is a protocol error communicating with the
 *                            broker.
 *     MOSQ_ERR_PAYLOAD_SIZE -   if payloadlen is too large.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by
 *                                 the broker.
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 *
 * See Also:
 *    <mosquitto_max_inflight_messages_set>
 */
libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain);
/*
 * Function: mosquitto_publish_v5
 *
 * Publish a message on a given topic, with attached MQTT properties.
 *
 * Use <mosquitto_property_add_*> to create a list of properties, then attach
 * them to this publish. Properties need freeing with
 * <mosquitto_property_free_all>.
 *
 * Requires the mosquitto instance to be connected with MQTT 5.
 *
 * Parameters:
 *     mosq -       a valid mosquitto instance.
 *     mid -        pointer to an int. If not NULL, the function will set this
 *               to the message id of this particular message. This can be then
 *               used with the publish callback to determine when the message
 *               has been sent.
 *               Note that although the MQTT protocol doesn't use message ids
 *               for messages with QoS=0, libmosquitto assigns them message ids
 *               so they can be tracked with this parameter.
 *  topic -      null terminated string of the topic to publish to.
 *     payloadlen - the size of the payload (bytes). Valid values are between 0 and
 *               268,435,455.
 *     payload -    pointer to the data to send. If payloadlen > 0 this must be a
 *               valid memory location.
 *     qos -        integer value 0, 1 or 2 indicating the Quality of Service to be
 *               used for the message.
 *     retain -     set to true to make the message retained.
 *     properties - a valid mosquitto_property list, or NULL.
 *
 * Returns:
 *     MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *    MOSQ_ERR_PROTOCOL -       if there is a protocol error communicating with the
 *                            broker.
 *     MOSQ_ERR_PAYLOAD_SIZE -   if payloadlen is too large.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH.
 *    MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by
 *                                 the broker.
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_publish_v5(
        struct mosquitto *mosq,
        int *mid,
        const char *topic,
        int payloadlen,
        const void *payload,
        int qos,
        bool retain,
        const mosquitto_property *properties);
/*
 * Function: mosquitto_subscribe
 *
 * Subscribe to a topic.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the subscribe callback to determine when the message has been
 *           sent.
 *    sub -  the subscription pattern.
 *    qos -  the requested Quality of Service for this subscription.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);
/*
 * Function: mosquitto_subscribe_v5
 *
 * Subscribe to a topic, with attached MQTT properties.
 *
 * Use <mosquitto_property_add_*> to create a list of properties, then attach
 * them to this subscribe. Properties need freeing with
 * <mosquitto_property_free_all>.
 *
 * Requires the mosquitto instance to be connected with MQTT 5.
 *
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the subscribe callback to determine when the message has been
 *           sent.
 *    sub -  the subscription pattern.
 *    qos -  the requested Quality of Service for this subscription.
 *    options - options to apply to this subscription, OR'd together. Set to 0 to
 *              use the default options, otherwise choose from the list:
 *              MQTT_SUB_OPT_NO_LOCAL - with this option set, if this client
 *                            publishes to a topic to which it is subscribed, the
 *                            broker will not publish the message back to the
 *                            client.
 *              MQTT_SUB_OPT_RETAIN_AS_PUBLISHED - with this option set, messages
 *                            published for this subscription will keep the
 *                            retain flag as was set by the publishing client.
 *                            The default behaviour without this option set has
 *                            the retain flag indicating whether a message is
 *                            fresh/stale.
 *              MQTT_SUB_OPT_SEND_RETAIN_ALWAYS - with this option set,
 *                            pre-existing retained messages are sent as soon as
 *                            the subscription is made, even if the subscription
 *                            already exists. This is the default behaviour, so
 *                            it is not necessary to set this option.
 *              MQTT_SUB_OPT_SEND_RETAIN_NEW - with this option set, pre-existing
 *                            retained messages for this subscription will be
 *                            sent when the subscription is made, but only if the
 *                            subscription does not already exist.
 *              MQTT_SUB_OPT_SEND_RETAIN_NEVER - with this option set,
 *                            pre-existing retained messages will never be sent
 *                            for this subscription.
 *     properties - a valid mosquitto_property list, or NULL.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE.
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties);
/*
 * Function: mosquitto_subscribe_multiple
 *
 * Subscribe to multiple topics.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the subscribe callback to determine when the message has been
 *           sent.
 *  sub_count - the count of subscriptions to be made
 *    sub -  array of sub_count pointers, each pointing to a subscription string.
 *           The "char *const *const" datatype ensures that neither the array of
 *           pointers nor the strings that they point to are mutable. If you aren't
 *           familiar with this, just think of it as a safer "char **",
 *           equivalent to "const char *" for a simple string pointer.
 *    qos -  the requested Quality of Service for each subscription.
 *    options - options to apply to this subscription, OR'd together. Set to 0 to
 *           use the default options, otherwise choose from the list:
 *           MQTT_SUB_OPT_NO_LOCAL - with this option set, if this client
 *                         publishes to a topic to which it is subscribed, the
 *                         broker will not publish the message back to the
 *                         client.
 *           MQTT_SUB_OPT_RETAIN_AS_PUBLISHED - with this option set, messages
 *                         published for this subscription will keep the
 *                         retain flag as was set by the publishing client.
 *                         The default behaviour without this option set has
 *                         the retain flag indicating whether a message is
 *                         fresh/stale.
 *           MQTT_SUB_OPT_SEND_RETAIN_ALWAYS - with this option set,
 *                         pre-existing retained messages are sent as soon as
 *                         the subscription is made, even if the subscription
 *                         already exists. This is the default behaviour, so
 *                         it is not necessary to set this option.
 *           MQTT_SUB_OPT_SEND_RETAIN_NEW - with this option set, pre-existing
 *                         retained messages for this subscription will be
 *                         sent when the subscription is made, but only if the
 *                         subscription does not already exist.
 *           MQTT_SUB_OPT_SEND_RETAIN_NEVER - with this option set,
 *                         pre-existing retained messages will never be sent
 *                         for this subscription.
 *     properties - a valid mosquitto_property list, or NULL. Only used with MQTT
 *                  v5 clients.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties);
/*
 * Function: mosquitto_unsubscribe
 *
 * Unsubscribe from a topic.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the unsubscribe callback to determine when the message has been
 *           sent.
 *    sub -  the unsubscription pattern.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub);
/*
 * Function: mosquitto_unsubscribe_v5
 *
 * Unsubscribe from a topic, with attached MQTT properties.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the unsubscribe callback to determine when the message has been
 *           sent.
 *    sub -  the unsubscription pattern.
 *     properties - a valid mosquitto_property list, or NULL. Only used with MQTT
 *                  v5 clients.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE.
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties);
/*
 * Function: mosquitto_unsubscribe_multiple
 *
 * Unsubscribe from multiple topics.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *    mid -  a pointer to an int. If not NULL, the function will set this to
 *           the message id of this particular message. This can be then used
 *           with the subscribe callback to determine when the message has been
 *           sent.
 *  sub_count - the count of unsubscriptions to be made
 *    sub -  array of sub_count pointers, each pointing to an unsubscription string.
 *           The "char *const *const" datatype ensures that neither the array of
 *           pointers nor the strings that they point to are mutable. If you aren't
 *           familiar with this, just think of it as a safer "char **",
 *           equivalent to "const char *" for a simple string pointer.
 *     properties - a valid mosquitto_property list, or NULL. Only used with MQTT
 *                  v5 clients.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success.
 *     MOSQ_ERR_INVAL -          if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -        if the client isn't connected to a broker.
 *     MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8
 *    MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than
 *                               supported by the broker.
 */
libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties);
/* ======================================================================
 *
 * Section: Struct mosquitto_message helper functions
 *
 * ====================================================================== */
/*
 * Function: mosquitto_message_copy
 *
 * Copy the contents of a mosquitto message to another message.
 * Useful for preserving a message received in the on_message() callback.
 *
 * Parameters:
 *    dst - a pointer to a valid mosquitto_message struct to copy to.
 *    src - a pointer to a valid mosquitto_message struct to copy from.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * See Also:
 *     <mosquitto_message_free>
 */
libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src);
/*
 * Function: mosquitto_message_free
 *
 * Completely free a mosquitto_message struct.
 *
 * Parameters:
 *    message - pointer to a mosquitto_message pointer to free.
 *
 * See Also:
 *     <mosquitto_message_copy>, <mosquitto_message_free_contents>
 */
libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message);
/*
 * Function: mosquitto_message_free_contents
 *
 * Free a mosquitto_message struct contents, leaving the struct unaffected.
 *
 * Parameters:
 *    message - pointer to a mosquitto_message struct to free its contents.
 *
 * See Also:
 *     <mosquitto_message_copy>, <mosquitto_message_free>
 */
libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message);
/* ======================================================================
 *
 * Section: Network loop (managed by libmosquitto)
 *
 * ====================================================================== */
/*
 * Function: mosquitto_loop
 *
 * The main network loop for the client. You must call this frequently in order
 * to keep communications between the client and broker working. If incoming
 * data is present it will then be processed. Outgoing commands, from e.g.
 * <mosquitto_publish>, are normally sent immediately that their function is
 * called, but this is not always possible. <mosquitto_loop> will also attempt
 * to send any remaining outgoing messages, which also includes commands that
 * are part of the flow for messages with QoS>0.
 *
 * An alternative approach is to use <mosquitto_loop_start> to run the client
 * loop in its own thread.
 *
 * This calls select() to monitor the client network socket. If you want to
 * integrate mosquitto client operation with your own select() call, use
 * <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_write> and
 * <mosquitto_loop_misc>.
 *
 * Threads:
 *
 * Parameters:
 *    mosq -        a valid mosquitto instance.
 *    timeout -     Maximum number of milliseconds to wait for network activity
 *                  in the select() call before timing out. Set to 0 for instant
 *                  return.  Set negative to use the default of 1000ms.
 *    max_packets - this parameter is currently unused and should be set to 1 for
 *                  future compatibility.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -   on success.
 *     MOSQ_ERR_INVAL -     if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -     if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -   if the client isn't connected to a broker.
 *  MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
 *    MOSQ_ERR_PROTOCOL -  if there is a protocol error communicating with the
 *                       broker.
 *     MOSQ_ERR_ERRNO -     if a system call returned an error. The variable errno
 *                       contains the error code, even on Windows.
 *                       Use strerror_r() where available or FormatMessage() on
 *                       Windows.
 * See Also:
 *    <mosquitto_loop_forever>, <mosquitto_loop_start>, <mosquitto_loop_stop>
 */
libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets);
/*
 * Function: mosquitto_loop_forever
 *
 * This function call loop() for you in an infinite blocking loop. It is useful
 * for the case where you only want to run the MQTT client loop in your
 * program.
 *
 * It handles reconnecting in case server connection is lost. If you call
 * mosquitto_disconnect() in a callback it will return.
 *
 * Parameters:
 *  mosq - a valid mosquitto instance.
 *    timeout -     Maximum number of milliseconds to wait for network activity
 *                  in the select() call before timing out. Set to 0 for instant
 *                  return.  Set negative to use the default of 1000ms.
 *    max_packets - this parameter is currently unused and should be set to 1 for
 *                  future compatibility.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -   on success.
 *     MOSQ_ERR_INVAL -     if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -     if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -   if the client isn't connected to a broker.
 *  MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
 *    MOSQ_ERR_PROTOCOL -  if there is a protocol error communicating with the
 *                       broker.
 *     MOSQ_ERR_ERRNO -     if a system call returned an error. The variable errno
 *                       contains the error code, even on Windows.
 *                       Use strerror_r() where available or FormatMessage() on
 *                       Windows.
 *
 * See Also:
 *    <mosquitto_loop>, <mosquitto_loop_start>
 */
libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);
/*
 * Function: mosquitto_loop_start
 *
 * This is part of the threaded client interface. Call this once to start a new
 * thread to process network traffic. This provides an alternative to
 * repeatedly calling <mosquitto_loop> yourself.
 *
 * Parameters:
 *  mosq - a valid mosquitto instance.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -       on success.
 *     MOSQ_ERR_INVAL -         if the input parameters were invalid.
 *    MOSQ_ERR_NOT_SUPPORTED - if thread support is not available.
 *
 * See Also:
 *    <mosquitto_connect_async>, <mosquitto_loop>, <mosquitto_loop_forever>, <mosquitto_loop_stop>
 */
libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq);
/*
 * Function: mosquitto_loop_stop
 *
 * This is part of the threaded client interface. Call this once to stop the
 * network thread previously created with <mosquitto_loop_start>. This call
 * will block until the network thread finishes. For the network thread to end,
 * you must have previously called <mosquitto_disconnect> or have set the force
 * parameter to true.
 *
 * Parameters:
 *  mosq - a valid mosquitto instance.
 *    force - set to true to force thread cancellation. If false,
 *            <mosquitto_disconnect> must have already been called.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -       on success.
 *     MOSQ_ERR_INVAL -         if the input parameters were invalid.
 *    MOSQ_ERR_NOT_SUPPORTED - if thread support is not available.
 *
 * See Also:
 *    <mosquitto_loop>, <mosquitto_loop_start>
 */
libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force);
/* ======================================================================
 *
 * Section: Network loop (for use in other event loops)
 *
 * ====================================================================== */
/*
 * Function: mosquitto_loop_read
 *
 * Carry out network read operations.
 * This should only be used if you are not using mosquitto_loop() and are
 * monitoring the client network socket for activity yourself.
 *
 * Parameters:
 *    mosq -        a valid mosquitto instance.
 *    max_packets - this parameter is currently unused and should be set to 1 for
 *                  future compatibility.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -   on success.
 *     MOSQ_ERR_INVAL -     if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -     if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -   if the client isn't connected to a broker.
 *  MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
 *    MOSQ_ERR_PROTOCOL -  if there is a protocol error communicating with the
 *                       broker.
 *     MOSQ_ERR_ERRNO -     if a system call returned an error. The variable errno
 *                       contains the error code, even on Windows.
 *                       Use strerror_r() where available or FormatMessage() on
 *                       Windows.
 *
 * See Also:
 *    <mosquitto_socket>, <mosquitto_loop_write>, <mosquitto_loop_misc>
 */
libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets);
/*
 * Function: mosquitto_loop_write
 *
 * Carry out network write operations.
 * This should only be used if you are not using mosquitto_loop() and are
 * monitoring the client network socket for activity yourself.
 *
 * Parameters:
 *    mosq -        a valid mosquitto instance.
 *    max_packets - this parameter is currently unused and should be set to 1 for
 *                  future compatibility.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -   on success.
 *     MOSQ_ERR_INVAL -     if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -     if an out of memory condition occurred.
 *     MOSQ_ERR_NO_CONN -   if the client isn't connected to a broker.
 *  MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
 *    MOSQ_ERR_PROTOCOL -  if there is a protocol error communicating with the
 *                       broker.
 *     MOSQ_ERR_ERRNO -     if a system call returned an error. The variable errno
 *                       contains the error code, even on Windows.
 *                       Use strerror_r() where available or FormatMessage() on
 *                       Windows.
 *
 * See Also:
 *    <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_misc>, <mosquitto_want_write>
 */
libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets);
/*
 * Function: mosquitto_loop_misc
 *
 * Carry out miscellaneous operations required as part of the network loop.
 * This should only be used if you are not using mosquitto_loop() and are
 * monitoring the client network socket for activity yourself.
 *
 * This function deals with handling PINGs and checking whether messages need
 * to be retried, so should be called fairly frequently.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -   on success.
 *     MOSQ_ERR_INVAL -     if the input parameters were invalid.
 *     MOSQ_ERR_NO_CONN -   if the client isn't connected to a broker.
 *
 * See Also:
 *    <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_write>
 */
libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq);
/* ======================================================================
 *
 * Section: Network loop (helper functions)
 *
 * ====================================================================== */
/*
 * Function: mosquitto_socket
 *
 * Return the socket handle for a mosquitto instance. Useful if you want to
 * include a mosquitto client in your own select() calls.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *
 * Returns:
 *    The socket for the mosquitto client or -1 on failure.
 */
libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq);
/*
 * Function: mosquitto_want_write
 *
 * Returns true if there is data ready to be written on the socket.
 *
 * Parameters:
 *    mosq - a valid mosquitto instance.
 *
 * See Also:
 *    <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_write>
 */
libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq);
/*
 * Function: mosquitto_threaded_set
 *
 * Used to tell the library that your application is using threads, but not
 * using <mosquitto_loop_start>. The library operates slightly differently when
 * not in threaded mode in order to simplify its operation. If you are managing
 * your own threads and do not use this function you will experience crashes
 * due to race conditions.
 *
 * When using <mosquitto_loop_start>, this is set automatically.
 *
 * Parameters:
 *  mosq -     a valid mosquitto instance.
 *  threaded - true if your application is using threads, false otherwise.
 */
libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded);
/* ======================================================================
 *
 * Section: Client options
 *
 * ====================================================================== */
/*
 * Function: mosquitto_opts_set
 *
 * Used to set options for the client.
 *
 * This function is deprecated, the replacement <mosquitto_int_option> and
 * <mosquitto_void_option> functions should be used instead.
 *
 * Parameters:
 *    mosq -   a valid mosquitto instance.
 *    option - the option to set.
 *    value -  the option specific value.
 *
 * Options:
 *    MOSQ_OPT_PROTOCOL_VERSION
 *              Value must be an int, set to either MQTT_PROTOCOL_V31 or
 *              MQTT_PROTOCOL_V311. Must be set before the client connects.
 *              Defaults to MQTT_PROTOCOL_V31.
 *
 *    MOSQ_OPT_SSL_CTX
 *              Pass an openssl SSL_CTX to be used when creating TLS connections
 *              rather than libmosquitto creating its own.  This must be called
 *              before connecting to have any effect. If you use this option, the
 *              onus is on you to ensure that you are using secure settings.
 *              Setting to NULL means that libmosquitto will use its own SSL_CTX
 *              if TLS is to be used.
 *              This option is only available for openssl 1.1.0 and higher.
 *
 *    MOSQ_OPT_SSL_CTX_WITH_DEFAULTS
 *              Value must be an int set to 1 or 0. If set to 1, then the user
 *              specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the
 *              default options applied to it. This means that you only need to
 *              change the values that are relevant to you. If you use this
 *              option then you must configure the TLS options as normal, i.e.
 *              you should use <mosquitto_tls_set> to configure the cafile/capath
 *              as a minimum.
 *              This option is only available for openssl 1.1.0 and higher.
 */
libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value);
/*
 * Function: mosquitto_int_option
 *
 * Used to set integer options for the client.
 *
 * Parameters:
 *    mosq -   a valid mosquitto instance.
 *    option - the option to set.
 *    value -  the option specific value.
 *
 * Options:
 *    MOSQ_OPT_PROTOCOL_VERSION
 *              Value must be set to either MQTT_PROTOCOL_V31,
 *              MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the
 *              client connects.  Defaults to MQTT_PROTOCOL_V311.
 *
 *    MOSQ_OPT_RECEIVE_MAXIMUM
 *              Value can be set between 1 and 65535 inclusive, and represents
 *              the maximum number of incoming QoS 1 and QoS 2 messages that this
 *              client wants to process at once. Defaults to 20. This option is
 *              not valid for MQTT v3.1 or v3.1.1 clients.
 *              Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the
 *              proplist passed to mosquitto_connect_v5(), then that property
 *              will override this option. Using this option is the recommended
 *              method however.
 *
 *    MOSQ_OPT_SEND_MAXIMUM
 *              Value can be set between 1 and 65535 inclusive, and represents
 *              the maximum number of outgoing QoS 1 and QoS 2 messages that this
 *              client will attempt to have "in flight" at once. Defaults to 20.
 *              This option is not valid for MQTT v3.1 or v3.1.1 clients.
 *              Note that if the broker being connected to sends a
 *              MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than
 *              this option, then the broker provided value will be used.
 *
 *    MOSQ_OPT_SSL_CTX_WITH_DEFAULTS
 *              If value is set to a non zero value, then the user specified
 *              SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default
 *              options applied to it. This means that you only need to change
 *              the values that are relevant to you. If you use this option then
 *              you must configure the TLS options as normal, i.e.  you should
 *              use <mosquitto_tls_set> to configure the cafile/capath as a
 *              minimum.
 *              This option is only available for openssl 1.1.0 and higher.
 *    MOSQ_OPT_TLS_OCSP_REQUIRED
 *              Set whether OCSP checking on TLS connections is required. Set to
 *              1 to enable checking, or 0 (the default) for no checking.
 */
libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value);
/*
 * Function: mosquitto_void_option
 *
 * Used to set void* options for the client.
 *
 * Parameters:
 *    mosq -   a valid mosquitto instance.
 *    option - the option to set.
 *    value -  the option specific value.
 *
 * Options:
 *    MOSQ_OPT_SSL_CTX
 *              Pass an openssl SSL_CTX to be used when creating TLS connections
 *              rather than libmosquitto creating its own.  This must be called
 *              before connecting to have any effect. If you use this option, the
 *              onus is on you to ensure that you are using secure settings.
 *              Setting to NULL means that libmosquitto will use its own SSL_CTX
 *              if TLS is to be used.
 *              This option is only available for openssl 1.1.0 and higher.
 */
libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value);
/*
 * Function: mosquitto_reconnect_delay_set
 *
 * Control the behaviour of the client when it has unexpectedly disconnected in
 * <mosquitto_loop_forever> or after <mosquitto_loop_start>. The default
 * behaviour if this function is not used is to repeatedly attempt to reconnect
 * with a delay of 1 second until the connection succeeds.
 *
 * Use reconnect_delay parameter to change the delay between successive
 * reconnection attempts. You may also enable exponential backoff of the time
 * between reconnections by setting reconnect_exponential_backoff to true and
 * set an upper bound on the delay with reconnect_delay_max.
 *
 * Example 1:
 *    delay=2, delay_max=10, exponential_backoff=False
 *    Delays would be: 2, 4, 6, 8, 10, 10, ...
 *
 * Example 2:
 *    delay=3, delay_max=30, exponential_backoff=True
 *    Delays would be: 3, 6, 12, 24, 30, 30, ...
 *
 * Parameters:
 *  mosq -                          a valid mosquitto instance.
 *  reconnect_delay -               the number of seconds to wait between
 *                                  reconnects.
 *  reconnect_delay_max -           the maximum number of seconds to wait
 *                                  between reconnects.
 *  reconnect_exponential_backoff - use exponential backoff between
 *                                  reconnect attempts. Set to true to enable
 *                                  exponential backoff.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 */
libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
/*
 * Function: mosquitto_max_inflight_messages_set
 *
 * This function is deprected. Use the <mosquitto_int_option> function with the
 * MOSQ_OPT_SEND_MAXIMUM option instead.
 *
 * Set the number of QoS 1 and 2 messages that can be "in flight" at one time.
 * An in flight message is part way through its delivery flow. Attempts to send
 * further messages with <mosquitto_publish> will result in the messages being
 * queued until the number of in flight messages reduces.
 *
 * A higher number here results in greater message throughput, but if set
 * higher than the maximum in flight messages on the broker may lead to
 * delays in the messages being acknowledged.
 *
 * Set to 0 for no maximum.
 *
 * Parameters:
 *  mosq -                  a valid mosquitto instance.
 *  max_inflight_messages - the maximum number of inflight messages. Defaults
 *                          to 20.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 */
libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages);
/*
 * Function: mosquitto_message_retry_set
 *
 * This function now has no effect.
 */
libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry);
/*
 * Function: mosquitto_user_data_set
 *
 * When <mosquitto_new> is called, the pointer given as the "obj" parameter
 * will be passed to the callbacks as user data. The <mosquitto_user_data_set>
 * function allows this obj parameter to be updated at any time. This function
 * will not modify the memory pointed to by the current user data pointer. If
 * it is dynamically allocated memory you must free it yourself.
 *
 * Parameters:
 *  mosq - a valid mosquitto instance.
 *     obj -  A user pointer that will be passed as an argument to any callbacks
 *            that are specified.
 */
libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj);
/* Function: mosquitto_userdata
 *
 * Retrieve the "userdata" variable for a mosquitto client.
 *
 * Parameters:
 *     mosq - a valid mosquitto instance.
 *
 * Returns:
 *    A pointer to the userdata member variable.
 */
libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq);
/* ======================================================================
 *
 * Section: TLS support
 *
 * ====================================================================== */
/*
 * Function: mosquitto_tls_set
 *
 * Configure the client for certificate based SSL/TLS support. Must be called
 * before <mosquitto_connect>.
 *
 * Cannot be used in conjunction with <mosquitto_tls_psk_set>.
 *
 * Define the Certificate Authority certificates to be trusted (ie. the server
 * certificate must be signed with one of these certificates) using cafile.
 *
 * If the server you are connecting to requires clients to provide a
 * certificate, define certfile and keyfile with your client certificate and
 * private key. If your private key is encrypted, provide a password callback
 * function or you will have to enter the password at the command line.
 *
 * Parameters:
 *  mosq -        a valid mosquitto instance.
 *  cafile -      path to a file containing the PEM encoded trusted CA
 *                certificate files. Either cafile or capath must not be NULL.
 *  capath -      path to a directory containing the PEM encoded trusted CA
 *                certificate files. See mosquitto.conf for more details on
 *                configuring this directory. Either cafile or capath must not
 *                be NULL.
 *  certfile -    path to a file containing the PEM encoded certificate file
 *                for this client. If NULL, keyfile must also be NULL and no
 *                client certificate will be used.
 *  keyfile -     path to a file containing the PEM encoded private key for
 *                this client. If NULL, certfile must also be NULL and no
 *                client certificate will be used.
 *  pw_callback - if keyfile is encrypted, set pw_callback to allow your client
 *                to pass the correct password for decryption. If set to NULL,
 *                the password must be entered on the command line.
 *                Your callback must write the password into "buf", which is
 *                "size" bytes long. The return value must be the length of the
 *                password. "userdata" will be set to the calling mosquitto
 *                instance. The mosquitto userdata member variable can be
 *                retrieved using <mosquitto_userdata>.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * See Also:
 *    <mosquitto_tls_opts_set>, <mosquitto_tls_psk_set>,
 *    <mosquitto_tls_insecure_set>, <mosquitto_userdata>
 */
libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq,
        const char *cafile, const char *capath,
        const char *certfile, const char *keyfile,
        int (*pw_callback)(char *buf, int size, int rwflag, void *userdata));
/*
 * Function: mosquitto_tls_insecure_set
 *
 * Configure verification of the server hostname in the server certificate. If
 * value is set to true, it is impossible to guarantee that the host you are
 * connecting to is not impersonating your server. This can be useful in
 * initial server testing, but makes it possible for a malicious third party to
 * impersonate your server through DNS spoofing, for example.
 * Do not use this function in a real system. Setting value to true makes the
 * connection encryption pointless.
 * Must be called before <mosquitto_connect>.
 *
 * Parameters:
 *  mosq -  a valid mosquitto instance.
 *  value - if set to false, the default, certificate hostname checking is
 *          performed. If set to true, no hostname checking is performed and
 *          the connection is insecure.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *
 * See Also:
 *    <mosquitto_tls_set>
 */
libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value);
/*
 * Function: mosquitto_tls_opts_set
 *
 * Set advanced SSL/TLS options. Must be called before <mosquitto_connect>.
 *
 * Parameters:
 *  mosq -        a valid mosquitto instance.
 *    cert_reqs -   an integer defining the verification requirements the client
 *                  will impose on the server. This can be one of:
 *                  * SSL_VERIFY_NONE (0): the server will not be verified in any way.
 *                  * SSL_VERIFY_PEER (1): the server certificate will be verified
 *                    and the connection aborted if the verification fails.
 *                  The default and recommended value is SSL_VERIFY_PEER. Using
 *                  SSL_VERIFY_NONE provides no security.
 *    tls_version - the version of the SSL/TLS protocol to use as a string. If NULL,
 *                  the default value is used. The default value and the
 *                  available values depend on the version of openssl that the
 *                  library was compiled against. For openssl >= 1.0.1, the
 *                  available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2
 *                  as the default. For openssl < 1.0.1, only tlsv1 is available.
 *    ciphers -     a string describing the ciphers available for use. See the
 *                  "openssl ciphers" tool for more information. If NULL, the
 *                  default ciphers will be used.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * See Also:
 *    <mosquitto_tls_set>
 */
libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers);
/*
 * Function: mosquitto_tls_psk_set
 *
 * Configure the client for pre-shared-key based TLS support. Must be called
 * before <mosquitto_connect>.
 *
 * Cannot be used in conjunction with <mosquitto_tls_set>.
 *
 * Parameters:
 *  mosq -     a valid mosquitto instance.
 *  psk -      the pre-shared-key in hex format with no leading "0x".
 *  identity - the identity of this client. May be used as the username
 *             depending on the server settings.
 *    ciphers -  a string describing the PSK ciphers available for use. See the
 *               "openssl ciphers" tool for more information. If NULL, the
 *               default ciphers will be used.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 *
 * See Also:
 *    <mosquitto_tls_set>
 */
libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers);
/* ======================================================================
 *
 * Section: Callbacks
 *
 * ====================================================================== */
/*
 * Function: mosquitto_connect_callback_set
 *
 * Set the connect callback. This is called when the broker sends a CONNACK
 * message in response to a connection.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_connect - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, int rc)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj - the user data provided in <mosquitto_new>
 *  rc -  the return code of the connection response, one of:
 *
 * * 0 - success
 * * 1 - connection refused (unacceptable protocol version)
 * * 2 - connection refused (identifier rejected)
 * * 3 - connection refused (broker unavailable)
 * * 4-255 - reserved for future use
 */
libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int));
/*
 * Function: mosquitto_connect_with_flags_callback_set
 *
 * Set the connect callback. This is called when the broker sends a CONNACK
 * message in response to a connection.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_connect - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, int rc)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj - the user data provided in <mosquitto_new>
 *  rc -  the return code of the connection response, one of:
 *  flags - the connect flags.
 *
 * * 0 - success
 * * 1 - connection refused (unacceptable protocol version)
 * * 2 - connection refused (identifier rejected)
 * * 3 - connection refused (broker unavailable)
 * * 4-255 - reserved for future use
 */
libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int));
/*
 * Function: mosquitto_connect_v5_callback_set
 *
 * Set the connect callback. This is called when the broker sends a CONNACK
 * message in response to a connection.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_connect - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, int rc)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj - the user data provided in <mosquitto_new>
 *  rc -  the return code of the connection response, one of:
 * * 0 - success
 * * 1 - connection refused (unacceptable protocol version)
 * * 2 - connection refused (identifier rejected)
 * * 3 - connection refused (broker unavailable)
 * * 4-255 - reserved for future use
 *  flags - the connect flags.
 *  props - list of MQTT 5 properties, or NULL
 *
 */
libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props));
/*
 * Function: mosquitto_disconnect_callback_set
 *
 * Set the disconnect callback. This is called when the broker has received the
 * DISCONNECT command and has disconnected the client.
 *
 * Parameters:
 *  mosq -          a valid mosquitto instance.
 *  on_disconnect - a callback function in the following form:
 *                  void callback(struct mosquitto *mosq, void *obj)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  rc -   integer value indicating the reason for the disconnect. A value of 0
 *         means the client has called <mosquitto_disconnect>. Any other value
 *         indicates that the disconnect is unexpected.
 */
libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int));
/*
 * Function: mosquitto_disconnect_v5_callback_set
 *
 * Set the disconnect callback. This is called when the broker has received the
 * DISCONNECT command and has disconnected the client.
 *
 * Parameters:
 *  mosq -          a valid mosquitto instance.
 *  on_disconnect - a callback function in the following form:
 *                  void callback(struct mosquitto *mosq, void *obj)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  rc -   integer value indicating the reason for the disconnect. A value of 0
 *         means the client has called <mosquitto_disconnect>. Any other value
 *         indicates that the disconnect is unexpected.
 *  props - list of MQTT 5 properties, or NULL
 */
libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *));
/*
 * Function: mosquitto_publish_callback_set
 *
 * Set the publish callback. This is called when a message initiated with
 * <mosquitto_publish> has been sent to the broker successfully.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_publish - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, int mid)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  mid -  the message id of the sent message.
 */
libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int));
/*
 * Function: mosquitto_publish_v5_callback_set
 *
 * Set the publish callback. This is called when a message initiated with
 * <mosquitto_publish> has been sent to the broker. This callback will be
 * called both if the message is sent successfully, or if the broker responded
 * with an error, which will be reflected in the reason_code parameter.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_publish - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, int mid)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  mid -  the message id of the sent message.
 *  reason_code - the MQTT 5 reason code
 *  props - list of MQTT 5 properties, or NULL
 */
libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *));
/*
 * Function: mosquitto_message_callback_set
 *
 * Set the message callback. This is called when a message is received from the
 * broker.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_message - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
 *
 * Callback Parameters:
 *  mosq -    the mosquitto instance making the callback.
 *  obj -     the user data provided in <mosquitto_new>
 *  message - the message data. This variable and associated memory will be
 *            freed by the library after the callback completes. The client
 *            should make copies of any of the data it requires.
 *
 * See Also:
 *     <mosquitto_message_copy>
 */
libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
/*
 * Function: mosquitto_message_v5_callback_set
 *
 * Set the message callback. This is called when a message is received from the
 * broker.
 *
 * Parameters:
 *  mosq -       a valid mosquitto instance.
 *  on_message - a callback function in the following form:
 *               void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
 *
 * Callback Parameters:
 *  mosq -    the mosquitto instance making the callback.
 *  obj -     the user data provided in <mosquitto_new>
 *  message - the message data. This variable and associated memory will be
 *            freed by the library after the callback completes. The client
 *            should make copies of any of the data it requires.
 *  props - list of MQTT 5 properties, or NULL
 *
 * See Also:
 *     <mosquitto_message_copy>
 */
libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *));
/*
 * Function: mosquitto_subscribe_callback_set
 *
 * Set the subscribe callback. This is called when the broker responds to a
 * subscription request.
 *
 * Parameters:
 *  mosq -         a valid mosquitto instance.
 *  on_subscribe - a callback function in the following form:
 *                 void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
 *
 * Callback Parameters:
 *  mosq -        the mosquitto instance making the callback.
 *  obj -         the user data provided in <mosquitto_new>
 *  mid -         the message id of the subscribe message.
 *  qos_count -   the number of granted subscriptions (size of granted_qos).
 *  granted_qos - an array of integers indicating the granted QoS for each of
 *                the subscriptions.
 */
libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *));
/*
 * Function: mosquitto_subscribe_v5_callback_set
 *
 * Set the subscribe callback. This is called when the broker responds to a
 * subscription request.
 *
 * Parameters:
 *  mosq -         a valid mosquitto instance.
 *  on_subscribe - a callback function in the following form:
 *                 void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
 *
 * Callback Parameters:
 *  mosq -        the mosquitto instance making the callback.
 *  obj -         the user data provided in <mosquitto_new>
 *  mid -         the message id of the subscribe message.
 *  qos_count -   the number of granted subscriptions (size of granted_qos).
 *  granted_qos - an array of integers indicating the granted QoS for each of
 *                the subscriptions.
 *  props - list of MQTT 5 properties, or NULL
 */
libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *));
/*
 * Function: mosquitto_unsubscribe_callback_set
 *
 * Set the unsubscribe callback. This is called when the broker responds to a
 * unsubscription request.
 *
 * Parameters:
 *  mosq -           a valid mosquitto instance.
 *  on_unsubscribe - a callback function in the following form:
 *                   void callback(struct mosquitto *mosq, void *obj, int mid)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  mid -  the message id of the unsubscribe message.
 */
libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int));
/*
 * Function: mosquitto_unsubscribe_v5_callback_set
 *
 * Set the unsubscribe callback. This is called when the broker responds to a
 * unsubscription request.
 *
 * Parameters:
 *  mosq -           a valid mosquitto instance.
 *  on_unsubscribe - a callback function in the following form:
 *                   void callback(struct mosquitto *mosq, void *obj, int mid)
 *
 * Callback Parameters:
 *  mosq - the mosquitto instance making the callback.
 *  obj -  the user data provided in <mosquitto_new>
 *  mid -  the message id of the unsubscribe message.
 *  props - list of MQTT 5 properties, or NULL
 */
libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *));
/*
 * Function: mosquitto_log_callback_set
 *
 * Set the logging callback. This should be used if you want event logging
 * information from the client library.
 *
 *  mosq -   a valid mosquitto instance.
 *  on_log - a callback function in the following form:
 *           void callback(struct mosquitto *mosq, void *obj, int level, const char *str)
 *
 * Callback Parameters:
 *  mosq -  the mosquitto instance making the callback.
 *  obj -   the user data provided in <mosquitto_new>
 *  level - the log message level from the values:
 *            MOSQ_LOG_INFO
 *            MOSQ_LOG_NOTICE
 *            MOSQ_LOG_WARNING
 *            MOSQ_LOG_ERR
 *            MOSQ_LOG_DEBUG
 *    str -   the message string.
 */
libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *));
/*
 * Function: mosquitto_string_option
 *
 * Used to set const char* options for the client.
 *
 * Parameters:
 *    mosq -   a valid mosquitto instance.
 *    option - the option to set.
 *    value -  the option specific value.
 *
 * Options:
 *    MOSQ_OPT_TLS_ENGINE
 *              Configure the client for TLS Engine support. Pass a TLS Engine ID
 *              to be used when creating TLS connections.
 *              Must be set before <mosquitto_connect>.
 *    MOSQ_OPT_TLS_KEYFORM
 *            Configure the client to treat the keyfile differently depending
 *            on its type.  Must be set before <mosquitto_connect>.
 *              Set as either "pem" or "engine", to determine from where the
 *              private key for a TLS connection will be obtained. Defaults to
 *              "pem", a normal private key file.
 *    MOSQ_OPT_TLS_KPASS_SHA1
 *              Where the TLS Engine requires the use of a password to be
 *              accessed, this option allows a hex encoded SHA1 hash of the
 *              private key password to be passed to the engine directly.
 *              Must be set before <mosquitto_connect>.
 *    MOSQ_OPT_TLS_ALPN
 *              If the broker being connected to has multiple services available
 *              on a single TLS port, such as both MQTT and WebSockets, use this
 *              option to configure the ALPN option for the connection.
 */
libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value);
/*
 * Function: mosquitto_reconnect_delay_set
 *
 * Control the behaviour of the client when it has unexpectedly disconnected in
 * <mosquitto_loop_forever> or after <mosquitto_loop_start>. The default
 * behaviour if this function is not used is to repeatedly attempt to reconnect
 * with a delay of 1 second until the connection succeeds.
 *
 * Use reconnect_delay parameter to change the delay between successive
 * reconnection attempts. You may also enable exponential backoff of the time
 * between reconnections by setting reconnect_exponential_backoff to true and
 * set an upper bound on the delay with reconnect_delay_max.
 *
 * Example 1:
 *    delay=2, delay_max=10, exponential_backoff=False
 *    Delays would be: 2, 4, 6, 8, 10, 10, ...
 *
 * Example 2:
 *    delay=3, delay_max=30, exponential_backoff=True
 *    Delays would be: 3, 6, 12, 24, 30, 30, ...
 *
 * Parameters:
 *  mosq -                          a valid mosquitto instance.
 *  reconnect_delay -               the number of seconds to wait between
 *                                  reconnects.
 *  reconnect_delay_max -           the maximum number of seconds to wait
 *                                  between reconnects.
 *  reconnect_exponential_backoff - use exponential backoff between
 *                                  reconnect attempts. Set to true to enable
 *                                  exponential backoff.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success.
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 */
libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
/* =============================================================================
 *
 * Section: SOCKS5 proxy functions
 *
 * =============================================================================
 */
/*
 * Function: mosquitto_socks5_set
 *
 * Configure the client to use a SOCKS5 proxy when connecting. Must be called
 * before connecting. "None" and "username/password" authentication is
 * supported.
 *
 * Parameters:
 *   mosq - a valid mosquitto instance.
 *   host - the SOCKS5 proxy host to connect to.
 *   port - the SOCKS5 proxy port to use.
 *   username - if not NULL, use this username when authenticating with the proxy.
 *   password - if not NULL and username is not NULL, use this password when
 *              authenticating with the proxy.
 */
libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password);
/* =============================================================================
 *
 * Section: Utility functions
 *
 * =============================================================================
 */
/*
 * Function: mosquitto_strerror
 *
 * Call to obtain a const string description of a mosquitto error number.
 *
 * Parameters:
 *    mosq_errno - a mosquitto error number.
 *
 * Returns:
 *    A constant string describing the error.
 */
libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno);
/*
 * Function: mosquitto_connack_string
 *
 * Call to obtain a const string description of an MQTT connection result.
 *
 * Parameters:
 *    connack_code - an MQTT connection result.
 *
 * Returns:
 *    A constant string describing the result.
 */
libmosq_EXPORT const char *mosquitto_connack_string(int connack_code);
/*
 * Function: mosquitto_reason_string
 *
 * Call to obtain a const string description of an MQTT reason code.
 *
 * Parameters:
 *    reason_code - an MQTT reason code.
 *
 * Returns:
 *    A constant string describing the reason.
 */
libmosq_EXPORT const char *mosquitto_reason_string(int reason_code);
/* Function: mosquitto_string_to_command
 *
 * Take a string input representing an MQTT command and convert it to the
 * libmosquitto integer representation.
 *
 * Parameters:
 *   str - the string to parse.
 *   cmd - pointer to an int, for the result.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - on an invalid input.
 *
 * Example:
 *  mosquitto_string_to_command("CONNECT", &cmd);
 *  // cmd == CMD_CONNECT
 */
libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd);
/*
 * Function: mosquitto_sub_topic_tokenise
 *
 * Tokenise a topic or subscription string into an array of strings
 * representing the topic hierarchy.
 *
 * For example:
 *
 * subtopic: "a/deep/topic/hierarchy"
 *
 * Would result in:
 *
 * topics[0] = "a"
 * topics[1] = "deep"
 * topics[2] = "topic"
 * topics[3] = "hierarchy"
 *
 * and:
 *
 * subtopic: "/a/deep/topic/hierarchy/"
 *
 * Would result in:
 *
 * topics[0] = NULL
 * topics[1] = "a"
 * topics[2] = "deep"
 * topics[3] = "topic"
 * topics[4] = "hierarchy"
 *
 * Parameters:
 *    subtopic - the subscription/topic to tokenise
 *    topics -   a pointer to store the array of strings
 *    count -    an int pointer to store the number of items in the topics array.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS -        on success
 *     MOSQ_ERR_NOMEM -          if an out of memory condition occurred.
 *     MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8
 *
 * Example:
 *
 * > char **topics;
 * > int topic_count;
 * > int i;
 * >
 * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count);
 * >
 * > for(i=0; i<token_count; i++){
 * >     printf("%d: %s\n", i, topics[i]);
 * > }
 *
 * See Also:
 *    <mosquitto_sub_topic_tokens_free>
 */
libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count);
/*
 * Function: mosquitto_sub_topic_tokens_free
 *
 * Free memory that was allocated in <mosquitto_sub_topic_tokenise>.
 *
 * Parameters:
 *    topics - pointer to string array.
 *    count - count of items in string array.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *
 * See Also:
 *    <mosquitto_sub_topic_tokenise>
 */
libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count);
/*
 * Function: mosquitto_topic_matches_sub
 * Function: mosquitto_topic_matches_sub2
 *
 * Check whether a topic matches a subscription.
 *
 * For example:
 *
 * foo/bar would match the subscription foo/# or +/bar
 * non/matching would not match the subscription non/+/+
 *
 * Parameters:
 *    sub - subscription string to check topic against.
 *    sublen - length in bytes of sub string
 *    topic - topic to check.
 *    topiclen - length in bytes of topic string
 *    result - bool pointer to hold result. Will be set to true if the topic
 *             matches the subscription.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *     MOSQ_ERR_INVAL -   if the input parameters were invalid.
 *     MOSQ_ERR_NOMEM -   if an out of memory condition occurred.
 */
libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result);
libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result);
/*
 * Function: mosquitto_pub_topic_check
 *
 * Check whether a topic to be used for publishing is valid.
 *
 * This searches for + or # in a topic and checks its length.
 *
 * This check is already carried out in <mosquitto_publish> and
 * <mosquitto_will_set>, there is no need to call it directly before them. It
 * may be useful if you wish to check the validity of a topic in advance of
 * making a connection for example.
 *
 * Parameters:
 *   topic - the topic to check
 *   topiclen - length of the topic in bytes
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS -        for a valid topic
 *   MOSQ_ERR_INVAL -          if the topic contains a + or a #, or if it is too long.
 *      MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8
 *
 * See Also:
 *   <mosquitto_sub_topic_check>
 */
libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic);
libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen);
/*
 * Function: mosquitto_sub_topic_check
 *
 * Check whether a topic to be used for subscribing is valid.
 *
 * This searches for + or # in a topic and checks that they aren't in invalid
 * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its
 * length.
 *
 * This check is already carried out in <mosquitto_subscribe> and
 * <mosquitto_unsubscribe>, there is no need to call it directly before them.
 * It may be useful if you wish to check the validity of a topic in advance of
 * making a connection for example.
 *
 * Parameters:
 *   topic - the topic to check
 *   topiclen - the length in bytes of the topic
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS -        for a valid topic
 *   MOSQ_ERR_INVAL -          if the topic contains a + or a # that is in an
 *                             invalid position, or if it is too long.
 *      MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8
 *
 * See Also:
 *   <mosquitto_sub_topic_check>
 */
libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic);
libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen);
struct libmosquitto_will {
    char *topic;
    void *payload;
    int payloadlen;
    int qos;
    bool retain;
};
struct libmosquitto_auth {
    char *username;
    char *password;
};
struct libmosquitto_tls {
    char *cafile;
    char *capath;
    char *certfile;
    char *keyfile;
    char *ciphers;
    char *tls_version;
    int (*pw_callback)(char *buf, int size, int rwflag, void *userdata);
    int cert_reqs;
};
/*
 * Function: mosquitto_subscribe_simple
 *
 * Helper function to make subscribing to a topic and retrieving some messages
 * very straightforward.
 *
 * This connects to a broker, subscribes to a topic, waits for msg_count
 * messages to be received, then returns after disconnecting cleanly.
 *
 * Parameters:
 *   messages - pointer to a "struct mosquitto_message *". The received
 *              messages will be returned here. On error, this will be set to
 *              NULL.
 *   msg_count - the number of messages to retrieve.
 *   want_retained - if set to true, stale retained messages will be treated as
 *                   normal messages with regards to msg_count. If set to
 *                   false, they will be ignored.
 *   topic - the subscription topic to use (wildcards are allowed).
 *   qos - the qos to use for the subscription.
 *   host - the broker to connect to.
 *   port - the network port the broker is listening on.
 *   client_id - the client id to use, or NULL if a random client id should be
 *               generated.
 *   keepalive - the MQTT keepalive value.
 *   clean_session - the MQTT clean session flag.
 *   username - the username string, or NULL for no username authentication.
 *   password - the password string, or NULL for an empty password.
 *   will - a libmosquitto_will struct containing will information, or NULL for
 *          no will.
 *   tls - a libmosquitto_tls struct containing TLS related parameters, or NULL
 *         for no use of TLS.
 *
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS - on success
 *   >0 - on error.
 */
libmosq_EXPORT int mosquitto_subscribe_simple(
        struct mosquitto_message **messages,
        int msg_count,
        bool want_retained,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls);
/*
 * Function: mosquitto_subscribe_callback
 *
 * Helper function to make subscribing to a topic and processing some messages
 * very straightforward.
 *
 * This connects to a broker, subscribes to a topic, then passes received
 * messages to a user provided callback. If the callback returns a 1, it then
 * disconnects cleanly and returns.
 *
 * Parameters:
 *   callback - a callback function in the following form:
 *              int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
 *              Note that this is the same as the normal on_message callback,
 *              except that it returns an int.
 *   userdata - user provided pointer that will be passed to the callback.
 *   topic - the subscription topic to use (wildcards are allowed).
 *   qos - the qos to use for the subscription.
 *   host - the broker to connect to.
 *   port - the network port the broker is listening on.
 *   client_id - the client id to use, or NULL if a random client id should be
 *               generated.
 *   keepalive - the MQTT keepalive value.
 *   clean_session - the MQTT clean session flag.
 *   username - the username string, or NULL for no username authentication.
 *   password - the password string, or NULL for an empty password.
 *   will - a libmosquitto_will struct containing will information, or NULL for
 *          no will.
 *   tls - a libmosquitto_tls struct containing TLS related parameters, or NULL
 *         for no use of TLS.
 *
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS - on success
 *   >0 - on error.
 */
libmosq_EXPORT int mosquitto_subscribe_callback(
        int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *),
        void *userdata,
        const char *topic,
        int qos,
        const char *host,
        int port,
        const char *client_id,
        int keepalive,
        bool clean_session,
        const char *username,
        const char *password,
        const struct libmosquitto_will *will,
        const struct libmosquitto_tls *tls);
/*
 * Function: mosquitto_validate_utf8
 *
 * Helper function to validate whether a UTF-8 string is valid, according to
 * the UTF-8 spec and the MQTT additions.
 *
 * Parameters:
 *   str - a string to check
 *   len - the length of the string in bytes
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS -        on success
 *   MOSQ_ERR_INVAL -          if str is NULL or len<0 or len>65536
 *   MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8
 */
libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len);
/* =============================================================================
 *
 * Section: Properties
 *
 * =============================================================================
 */
/*
 * Function: mosquitto_property_add_byte
 *
 * Add a new byte property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - integer value for the new property
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1);
 */
libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value);
/*
 * Function: mosquitto_property_add_int16
 *
 * Add a new int16 property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM)
 *    value - integer value for the new property
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000);
 */
libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value);
/*
 * Function: mosquitto_property_add_int32
 *
 * Add a new int32 property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL)
 *    value - integer value for the new property
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400);
 */
libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value);
/*
 * Function: mosquitto_property_add_varint
 *
 * Add a new varint property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER)
 *    value - integer value for the new property
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1);
 */
libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value);
/*
 * Function: mosquitto_property_add_binary
 *
 * Add a new binary property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to the property data
 *    len - length of property data in bytes
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len);
 */
libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len);
/*
 * Function: mosquitto_property_add_string
 *
 * Add a new string property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE)
 *    value - string value for the new property, must be UTF-8 and zero terminated
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *    MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8.
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json");
 */
libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value);
/*
 * Function: mosquitto_property_add_string_pair
 *
 * Add a new string pair property to a property list.
 *
 * If *proplist == NULL, a new list will be created, otherwise the new property
 * will be appended to the list.
 *
 * Parameters:
 *    proplist - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY)
 *    name - string name for the new property, must be UTF-8 and zero terminated
 *    value - string value for the new property, must be UTF-8 and zero terminated
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL
 *    MOSQ_ERR_NOMEM - on out of memory
 *    MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8.
 *
 * Example:
 *    mosquitto_property *proplist = NULL;
 *    mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub");
 */
libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value);
/*
 * Function: mosquitto_property_read_byte
 *
 * Attempt to read a byte property matching an identifier, from a property list
 * or single property. This function can search for multiple entries of the
 * same identifier by using the returned value and skip_first. Note however
 * that it is forbidden for most properties to be duplicated.
 *
 * If the property is not found, *value will not be modified, so it is safe to
 * pass a variable with a default value to be potentially overwritten:
 *
 * uint16_t keepalive = 60; // default value
 * // Get value from property list, or keep default if not found.
 * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false);
 *
 * Parameters:
 *    proplist - mosquitto_property pointer, the list of properties or single property
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to store the value, or NULL if the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL.
 *
 * Example:
 *    // proplist is obtained from a callback
 *    mosquitto_property *prop;
 *    prop = mosquitto_property_read_byte(proplist, identifier, &value, false);
 *    while(prop){
 *        printf("value: %s\n", value);
 *        prop = mosquitto_property_read_byte(prop, identifier, &value);
 *    }
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte(
        const mosquitto_property *proplist,
        int identifier,
        uint8_t *value,
        bool skip_first);
/*
 * Function: mosquitto_property_read_int16
 *
 * Read an int16 property value from a property.
 *
 * Parameters:
 *    property - property to read
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to store the value, or NULL if the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16(
        const mosquitto_property *proplist,
        int identifier,
        uint16_t *value,
        bool skip_first);
/*
 * Function: mosquitto_property_read_int32
 *
 * Read an int32 property value from a property.
 *
 * Parameters:
 *    property - pointer to mosquitto_property pointer, the list of properties
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to store the value, or NULL if the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32(
        const mosquitto_property *proplist,
        int identifier,
        uint32_t *value,
        bool skip_first);
/*
 * Function: mosquitto_property_read_varint
 *
 * Read a varint property value from a property.
 *
 * Parameters:
 *    property - property to read
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to store the value, or NULL if the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint(
        const mosquitto_property *proplist,
        int identifier,
        uint32_t *value,
        bool skip_first);
/*
 * Function: mosquitto_property_read_binary
 *
 * Read a binary property value from a property.
 *
 * On success, value must be free()'d by the application.
 *
 * Parameters:
 *    property - property to read
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to store the value, or NULL if the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary(
        const mosquitto_property *proplist,
        int identifier,
        void **value,
        uint16_t *len,
        bool skip_first);
/*
 * Function: mosquitto_property_read_string
 *
 * Read a string property value from a property.
 *
 * On success, value must be free()'d by the application.
 *
 * Parameters:
 *    property - property to read
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    value - pointer to char*, for the property data to be stored in, or NULL if
 *            the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string(
        const mosquitto_property *proplist,
        int identifier,
        char **value,
        bool skip_first);
/*
 * Function: mosquitto_property_read_string_pair
 *
 * Read a string pair property value pair from a property.
 *
 * On success, name and value must be free()'d by the application.
 *
 * Parameters:
 *    property - property to read
 *    identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
 *    name - pointer to char* for the name property data to be stored in, or NULL
 *           if the name is not required.
 *    value - pointer to char*, for the property data to be stored in, or NULL if
 *            the value is not required.
 *    skip_first - boolean that indicates whether the first item in the list
 *                 should be ignored or not. Should usually be set to false.
 *
 * Returns:
 *    A valid property pointer if the property is found
 *    NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
 *
 * Example:
 *    See <mosquitto_property_read_byte>
 */
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(
        const mosquitto_property *proplist,
        int identifier,
        char **name,
        char **value,
        bool skip_first);
/*
 * Function: mosquitto_property_free_all
 *
 * Free all properties from a list of properties. Frees the list and sets *properties to NULL.
 *
 * Parameters:
 *   properties - list of properties to free
 *
 * Example:
 *   mosquitto_properties *properties = NULL;
 *   // Add properties
 *   mosquitto_property_free_all(&properties);
 */
libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties);
/*
 * Function: mosquitto_property_copy_all
 *
 * Parameters:
 *    dest : pointer for new property list
 *    src : property list
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on successful copy
 *    MOSQ_ERR_INVAL - if dest is NULL
 *    MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL)
 */
libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src);
/*
 * Function: mosquitto_property_check_command
 *
 * Check whether a property identifier is valid for the given command.
 *
 * Parameters:
 *   command - MQTT command (e.g. CMD_CONNECT)
 *   identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY)
 *
 * Returns:
 *   MOSQ_ERR_SUCCESS - if the identifier is valid for command
 *   MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command.
 */
libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier);
/*
 * Function: mosquitto_property_check_all
 *
 * Check whether a list of properties are valid for a particular command,
 * whether there are duplicates, and whether the values are valid where
 * possible.
 *
 * Note that this function is used internally in the library whenever
 * properties are passed to it, so in basic use this is not needed, but should
 * be helpful to check property lists *before* the point of using them.
 *
 * Parameters:
 *    command - MQTT command (e.g. CMD_CONNECT)
 *    properties - list of MQTT properties to check.
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - if all properties are valid
 *    MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden.
 *    MOSQ_ERR_PROTOCOL - if any property is invalid
 */
libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties);
/* Function: mosquitto_string_to_property_info
 *
 * Parse a property name string and convert to a property identifier and data type.
 * The property name is as defined in the MQTT specification, with - as a
 * separator, for example: payload-format-indicator.
 *
 * Parameters:
 *    propname - the string to parse
 *    identifier - pointer to an int to receive the property identifier
 *    type - pointer to an int to receive the property type
 *
 * Returns:
 *    MOSQ_ERR_SUCCESS - on success
 *    MOSQ_ERR_INVAL - if the string does not match a property
 *
 * Example:
 *    mosquitto_string_to_property_info("response-topic", &id, &type);
 *    // id == MQTT_PROP_RESPONSE_TOPIC
 *    // type == MQTT_PROP_TYPE_STRING
 */
libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type);
#ifdef __cplusplus
}
#endif
#endif
Diff truncated after the above file
proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mosquitto_internal.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/mqtt_protocol.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq_ocsp.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/net_mosq_ocsp.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/options.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/options.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_datatypes.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_datatypes.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/packet_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/property_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/read_handle.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_connect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_connect.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_disconnect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_disconnect.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_publish.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_publish.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_subscribe.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_subscribe.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_unsubscribe.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/send_unsubscribe.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/socks_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/srv_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/srv_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/thread_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/thread_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/time_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/tls_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/utf8_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/utf8_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_topic.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/util_topic.o proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.h proj1_mqttd/mosquitto/mosquitto-1.6.3/lib/will_mosq.o proj1_mqttd/mosquitto/mosquitto-1.6.3/libmosquitto.pc.in proj1_mqttd/mosquitto/mosquitto-1.6.3/libmosquittopp.pc.in proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto-14x14.png proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto-16x16.png proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/legacy/mosquitto.svg proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-logo-min.svg proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-logo-only.svg proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-text-below.svg proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto-text-side.svg proj1_mqttd/mosquitto/mosquitto-1.6.3/logo/mosquitto.ico proj1_mqttd/mosquitto/mosquitto-1.6.3/man/CMakeLists.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/man/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/man/html.xsl proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/libmosquitto.3.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/manpage.xsl proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto-tls.7.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.8.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto.conf.5.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_passwd.1.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_pub.1.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_rr.1.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mosquitto_sub.1.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7 proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7.meta proj1_mqttd/mosquitto/mosquitto-1.6.3/man/mqtt.7.xml proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_log_mysql.pl proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_parse.pl proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_read.pl proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/cc128_read.py proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/CurrentCostMQTT.py proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/CurrentCostMQTT.server proj1_mqttd/mosquitto/mosquitto-1.6.3/misc/currentcost/gnome-panel/currentcost.png proj1_mqttd/mosquitto/mosquitto-1.6.3/mosquitto.conf proj1_mqttd/mosquitto/mosquitto-1.6.3/notice.html proj1_mqttd/mosquitto/mosquitto-1.6.3/pskfile.example proj1_mqttd/mosquitto/mosquitto-1.6.3/pwfile.example proj1_mqttd/mosquitto/mosquitto-1.6.3/readme-windows.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/readme.md proj1_mqttd/mosquitto/mosquitto-1.6.3/security/mosquitto.apparmor proj1_mqttd/mosquitto/mosquitto-1.6.3/service/monit/mosquitto.monit proj1_mqttd/mosquitto/mosquitto-1.6.3/service/svscan/run proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/README proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/mosquitto.service.notify proj1_mqttd/mosquitto/mosquitto-1.6.3/service/systemd/mosquitto.service.simple proj1_mqttd/mosquitto/mosquitto-1.6.3/service/upstart/mosquitto.conf proj1_mqttd/mosquitto/mosquitto-1.6.3/src/CMakeLists.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/src/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/src/bridge.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/conf.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/conf_includedir.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/context.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/database.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/db_dump/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/src/db_dump/db_dump.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/deps/uthash.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/deps/utlist.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_auth.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_connack.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_connect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_disconnect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_publish.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_subscribe.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/handle_unsubscribe.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/lib_load.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/linker-macosx.syms proj1_mqttd/mosquitto/mosquitto-1.6.3/src/linker.syms proj1_mqttd/mosquitto/mosquitto-1.6.3/src/logging.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/loop.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_broker.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_broker_internal.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_passwd.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/mosquitto_plugin.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/net.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read_v234.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_read_v5.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_write.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/persist_write_v5.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/plugin.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/plugin_defer.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/property_broker.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/read_handle.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/security.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/security_default.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_auth.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_connack.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_suback.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/send_unsuback.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/service.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/session_expiry.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/signals.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/subs.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/sys_tree.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/sys_tree.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/uhpa.h proj1_mqttd/mosquitto/mosquitto-1.6.3/src/websockets.c proj1_mqttd/mosquitto/mosquitto-1.6.3/src/will_delay.c proj1_mqttd/mosquitto/mosquitto-1.6.3/tags proj1_mqttd/mosquitto/mosquitto-1.6.3/test/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-anon-denied.pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-anon-denied.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-bad-packet.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-disconnect-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-duplicate-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-duplicate.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-0-311.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-missing.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-id-utf8.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-protonum.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-invalid-reserved.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-success-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-invalid-utf8.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-flag.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-password-denied.pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-no-password-denied.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied-no-will.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied.pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-denied.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success-no-tls.pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success-no-tls.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success.pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-password-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/01-connect-uname-pwd-no-flag.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-shared-qos0-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subhier-crash.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-retain-as-publish.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-send-retain.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-subscription-id.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-topic-alias-unknown.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-topic-alias.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-bad-pubcomp.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-bad-pubrec.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry-retain.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry-will.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-message-expiry.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-nolocal.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-puback-1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-puback-2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-bad-pubcomp.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-pubrec-error-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-pubrec-error.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-receive-maximum-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subpub-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-dollar-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-invalid-utf8.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-persistence-flipflop.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-subscribe-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-invalid-no-topic.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-multiple-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-multiple.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/02-unsubscribe-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-pattern-matching-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-pattern-matching.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos1-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos2-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-disconnect-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos1-len-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos1-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos2-len-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-qos2-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos1-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos2-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-b2c-timeout-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-disconnect-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-qos2-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-c2b-timeout-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-dollar-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-dollar.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-invalid-utf8.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-no-subscribers-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-queued-bytes.conf proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-queued-bytes.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1-retain-disabled.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/03-publish-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source-persist-diff-port.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source-persist.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-check-source.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-clear.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-fresh.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0-repeated.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-qos1-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/04-retain-upgrade-outgoing-qos.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-clean-session-qos1-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-clean-session-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/05-session-expiry-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-disconnect-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-disconnect-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-late-connection-retain.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-late-connection.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-b2br-remapping.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos1-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos2-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-disconnect-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-br2b-remapping.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-fail-persist-resend-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-fail-persist-resend-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-no-local.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-per-listener-settings.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-reconnect-local-out-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/06-bridge-reconnect-local-out.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay-reconnect.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay-recover.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-delay.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-disconnect-with-will.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-invalid-utf8.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-no-flag.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null-topic.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-null.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-properties.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/07-will-reconnect-1273.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-bridge-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-bridge.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-crl.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-expired.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-revoked.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth-without.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-cert-auth.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-identity.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-auth-wrong-ca.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-auth.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-ssl-connect-no-identity.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-bridge.psk proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-bridge.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-pub.psk proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/08-tls-psk-pub.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-access-variants.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-change.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-acl-empty-file.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-auth-bad-method.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-change-username.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-multistep-reauth.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-multistep.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-single.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-single2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-extended-auth-unsupported.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-pub.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-sub-denied.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-acl-sub.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-context-params.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-defer-unpwd-fail.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-defer-unpwd-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-msg-params.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-unpwd-fail.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-unpwd-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-v2-unpwd-fail.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-plugin-auth-v2-unpwd-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/09-pwfile-parse-invalid.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/10-listener-mount-point-helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/10-listener-mount-point.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-message-expiry.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription-no-local.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-persistent-subscription.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-pub-props.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/11-subscription-id.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-assigned-client-identifier.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-broker.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-connect.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-maximum-packet-size-publish.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-response-topic-correlation-data.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-response-topic.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-server-keepalive.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-session-expiry-invalid.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-subpub-content-type.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-subpub-payload-format.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/12-prop-topic-alias-invalid.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/08-tls-psk-bridge.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/08-tls-psk-pub.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_acl.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_acl_sub_denied.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_context_params.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_multiple.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_single.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_extended_single2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_msg_params.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_pwd.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/auth_plugin_v2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/c/mosquitto_plugin_v2.h proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/mosq_test_helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/prop_subpub_helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/readme.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/broker/test.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-con-discon-success.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-keepalive-pingreq.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-no-clean-session.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-server-keepalive-pingreq.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-unpwd-set.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-will-set.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/01-will-unpwd-set.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-subscribe-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe-multiple-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe-v5.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/02-unsubscribe.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos2-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-b2c-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-disconnect.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-receive-maximum.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos1-timeout.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-disconnect.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-len.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-maximum-qos-0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-maximum-qos-1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-pubrec-error.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-receive-maximum-1.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-receive-maximum-2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2-timeout.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-c2b-qos2.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-qos0-no-payload.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-publish-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-request-response-correlation.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/03-request-response.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/04-retain-qos0.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-bad-cacert.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-cert-auth-enc.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-cert-auth.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-connect-no-auth.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/08-ssl-fake-cacert.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/09-util-topic-tokenise.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-oversize-packet.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-send-content-type.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/11-prop-send-payload-format.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-con-discon-success.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-keepalive-pingreq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-no-clean-session.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-server-keepalive-pingreq.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-unpwd-set.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-will-set.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/01-will-unpwd-set.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos0.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-subscribe-qos2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe-multiple-v5.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe-v5.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/02-unsubscribe.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos2-len.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-b2c-qos2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-disconnect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-len.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos1-receive-maximum.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-disconnect.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-len.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-pubrec-error.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-c2b-qos2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-qos0-no-payload.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-publish-qos0.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-2.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/03-request-response-correlation-1.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/04-retain-qos0.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-bad-cacert.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-cert-auth-enc.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-cert-auth.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-connect-no-auth.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/08-ssl-fake-cacert.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/09-util-topic-tokenise.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-oversize-packet.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-send-content-type.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/11-prop-send-payload-format.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/c/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-con-discon-success.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-keepalive-pingreq.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-no-clean-session.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-unpwd-set.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-will-set.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/01-will-unpwd-set.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos0.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos1.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-subscribe-qos2.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/02-unsubscribe.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-b2c-qos1.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-b2c-qos2.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-c2b-qos2.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-qos0-no-payload.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/03-publish-qos0.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/04-retain-qos0.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-bad-cacert.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-cert-auth.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-connect-no-auth.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/08-ssl-fake-cacert.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/09-util-topic-tokenise.cpp proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/cpp/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/mosq_test_helper.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/lib/test.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mosq_test.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_opts.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_props.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/mqtt5_rc.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_common.h proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_pub.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/old/msgsps_sub.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ptest.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/auth_plugin.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/pwfile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/random.conf proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/random_client.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/random/test.py proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/all-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-encrypted.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-encrypted.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-expired.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-revoked.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client-revoked.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/client.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/crl.pem proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/crlnumber proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/index.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/index.txt.attr proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/demoCA/serial proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/gen.sh proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/openssl.cnf proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/readme.txt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/crlnumber proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/index.txt.attr proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/rootCA/serial proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server-expired.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/server.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/crlnumber proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/index.txt.attr proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/signingCA/serial proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-alt-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-alt-ca.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-bad-root-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-bad-root-ca.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-ca.srl proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-fake-root-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-fake-root-ca.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-root-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-root-ca.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-signing-ca.crt proj1_mqttd/mosquitto/mosquitto-1.6.3/test/ssl/test-signing-ca.key proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/Makefile proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/datatype_read.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/datatype_write.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/corrupt-header-long.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/corrupt-header-short.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/empty.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/unsupported-version.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-bad-chunk.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg-bad-dbid.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg-truncated.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-cfg.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-client-message.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-client.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-message-store.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-retain.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v3-sub.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v4-cfg.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v4-message-store.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-bad-chunk.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-cfg-truncated.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-cfg.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client-message-props.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client-message.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-client.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-message-store-props.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-message-store.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-retain.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_read/v5-sub.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/empty.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/v4-full.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/files/persist_write/v5-message-store-no-ref.test-db proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_read_stubs.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_read_test.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_write_stubs.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/persist_write_test.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_add.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_read.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_user_read.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/property_write.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/publish_test.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/stubs.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/test.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/utf8.c proj1_mqttd/mosquitto/mosquitto-1.6.3/test/unit/util_topic_test.c