int mosquitto_lib_cleanup(void) { _mosquitto_net_cleanup(); return MOSQ_ERR_SUCCESS; }
int main(int argc, char *argv[]) { int *listensock = NULL; int listensock_count = 0; int listensock_index = 0; struct mqtt3_config config; char buf[1024]; int i, j; FILE *pid; int listener_max; int rc; char err[256]; #ifdef WIN32 SYSTEMTIME st; #else struct timeval tv; #endif #if defined(WIN32) || defined(__CYGWIN__) if(argc == 2){ if(!strcmp(argv[1], "run")){ service_run(); return 0; }else if(!strcmp(argv[1], "install")){ service_install(); return 0; }else if(!strcmp(argv[1], "uninstall")){ service_uninstall(); return 0; } } #endif #ifdef WIN32 GetSystemTime(&st); srand(st.wSecond + st.wMilliseconds); #else gettimeofday(&tv, NULL); srand(tv.tv_sec + tv.tv_usec); #endif memset(&int_db, 0, sizeof(struct mosquitto_db)); _mosquitto_net_init(); mqtt3_config_init(&config); rc = mqtt3_config_parse_args(&config, argc, argv); if(rc != MOSQ_ERR_SUCCESS) return rc; int_db.config = &config; if(config.daemon){ #ifndef WIN32 switch(fork()){ case 0: break; case -1: strerror_r(errno, err, 256); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error in fork: %s", err); return 1; default: return MOSQ_ERR_SUCCESS; } #else _mosquitto_log_printf(NULL, MOSQ_LOG_WARNING, "Warning: Can't start in daemon mode in Windows."); #endif } if(config.daemon && config.pid_file){ pid = _mosquitto_fopen(config.pid_file, "wt"); if(pid){ fprintf(pid, "%d", getpid()); fclose(pid); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to write pid file."); return 1; } } rc = drop_privileges(&config); if(rc != MOSQ_ERR_SUCCESS) return rc; rc = mqtt3_db_open(&config, &int_db); if(rc != MOSQ_ERR_SUCCESS){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Couldn't open database."); return rc; } /* Initialise logging only after initialising the database in case we're * logging to topics */ mqtt3_log_init(config.log_type, config.log_dest); _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s (build date %s) starting", VERSION, TIMESTAMP); if(config.config_file){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Using default config."); } rc = mosquitto_security_module_init(&int_db); if(rc) return rc; rc = mosquitto_security_init(&int_db, false); if(rc) return rc; #ifdef WITH_SYS_TREE if(config.sys_interval > 0){ /* Set static $SYS messages */ snprintf(buf, 1024, "mosquitto version %s", VERSION); mqtt3_db_messages_easy_queue(&int_db, NULL, "$SYS/broker/version", 2, strlen(buf), buf, 1); snprintf(buf, 1024, "%s", TIMESTAMP); mqtt3_db_messages_easy_queue(&int_db, NULL, "$SYS/broker/timestamp", 2, strlen(buf), buf, 1); #ifdef CHANGESET snprintf(buf, 1024, "%s", CHANGESET); mqtt3_db_messages_easy_queue(&int_db, NULL, "$SYS/broker/changeset", 2, strlen(buf), buf, 1); #endif } #endif listener_max = -1; listensock_index = 0; for(i=0; i<config.listener_count; i++){ if(mqtt3_socket_listen(&config.listeners[i])){ _mosquitto_free(int_db.contexts); mqtt3_db_close(&int_db); if(config.pid_file){ remove(config.pid_file); } return 1; } listensock_count += config.listeners[i].sock_count; listensock = _mosquitto_realloc(listensock, sizeof(int)*listensock_count); if(!listensock){ _mosquitto_free(int_db.contexts); mqtt3_db_close(&int_db); if(config.pid_file){ remove(config.pid_file); } return 1; } for(j=0; j<config.listeners[i].sock_count; j++){ if(config.listeners[i].socks[j] == INVALID_SOCKET){ _mosquitto_free(int_db.contexts); mqtt3_db_close(&int_db); if(config.pid_file){ remove(config.pid_file); } return 1; } listensock[listensock_index] = config.listeners[i].socks[j]; if(listensock[listensock_index] > listener_max){ listener_max = listensock[listensock_index]; } listensock_index++; } } signal(SIGINT, handle_sigint); signal(SIGTERM, handle_sigint); #ifdef SIGHUP signal(SIGHUP, handle_sighup); #endif #ifndef WIN32 signal(SIGUSR1, handle_sigusr1); signal(SIGUSR2, handle_sigusr2); signal(SIGPIPE, SIG_IGN); #endif #ifdef WITH_BRIDGE for(i=0; i<config.bridge_count; i++){ if(mqtt3_bridge_new(&int_db, &(config.bridges[i]))){ _mosquitto_log_printf(NULL, MOSQ_LOG_WARNING, "Warning: Unable to connect to bridge %s.", config.bridges[i].name); } } #endif run = 1; rc = mosquitto_main_loop(&int_db, listensock, listensock_count, listener_max); _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s terminating", VERSION); mqtt3_log_close(); #ifdef WITH_PERSISTENCE if(config.persistence){ mqtt3_db_backup(&int_db, true, true); } #endif for(i=0; i<int_db.context_count; i++){ if(int_db.contexts[i]){ mqtt3_context_cleanup(&int_db, int_db.contexts[i], true); } } _mosquitto_free(int_db.contexts); int_db.contexts = NULL; mqtt3_db_close(&int_db); if(listensock){ for(i=0; i<listensock_count; i++){ if(listensock[i] != INVALID_SOCKET){ #ifndef WIN32 close(listensock[i]); #else closesocket(listensock[i]); #endif } } _mosquitto_free(listensock); } mosquitto_security_module_cleanup(&int_db); if(config.pid_file){ remove(config.pid_file); } _mosquitto_net_cleanup(); mqtt3_config_cleanup(int_db.config); return rc; }