int mqtt3_log_init(struct mqtt3_config *config) { int rc = 0; log_priorities = config->log_type; log_destinations = config->log_dest; if(log_destinations & MQTT3_LOG_SYSLOG){ #ifndef WIN32 openlog("mosquitto", LOG_PID|LOG_CONS, config->log_facility); #else syslog_h = OpenEventLog(NULL, "mosquitto"); #endif } if(log_destinations & MQTT3_LOG_FILE){ if(drop_privileges(config, true)){ return 1; } config->log_fptr = _mosquitto_fopen(config->log_file, "at"); if(!config->log_fptr){ log_destinations = MQTT3_LOG_STDERR; log_priorities = MOSQ_LOG_ERR; _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); return MOSQ_ERR_INVAL; } restore_privileges(); } return rc; }
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)) { #ifdef WITH_TLS FILE *fptr; if(!mosq || (!cafile && !capath) || (certfile && !keyfile) || (!certfile && keyfile)) return MOSQ_ERR_INVAL; if(cafile){ fptr = _mosquitto_fopen(cafile, "rt"); if(fptr){ fclose(fptr); }else{ return MOSQ_ERR_INVAL; } mosq->tls_cafile = _mosquitto_strdup(cafile); if(!mosq->tls_cafile){ return MOSQ_ERR_NOMEM; } }else if(mosq->tls_cafile){ _mosquitto_free(mosq->tls_cafile); mosq->tls_cafile = NULL; } if(capath){ mosq->tls_capath = _mosquitto_strdup(capath); if(!mosq->tls_capath){ return MOSQ_ERR_NOMEM; } }else if(mosq->tls_capath){ _mosquitto_free(mosq->tls_capath); mosq->tls_capath = NULL; } if(certfile){ fptr = _mosquitto_fopen(certfile, "rt"); if(fptr){ fclose(fptr); }else{ if(mosq->tls_cafile){ _mosquitto_free(mosq->tls_cafile); mosq->tls_cafile = NULL; } if(mosq->tls_capath){ _mosquitto_free(mosq->tls_capath); mosq->tls_capath = NULL; } return MOSQ_ERR_INVAL; } mosq->tls_certfile = _mosquitto_strdup(certfile); if(!mosq->tls_certfile){ return MOSQ_ERR_NOMEM; } }else{ if(mosq->tls_certfile) _mosquitto_free(mosq->tls_certfile); mosq->tls_certfile = NULL; } if(keyfile){ fptr = _mosquitto_fopen(keyfile, "rt"); if(fptr){ fclose(fptr); }else{ if(mosq->tls_cafile){ _mosquitto_free(mosq->tls_cafile); mosq->tls_cafile = NULL; } if(mosq->tls_capath){ _mosquitto_free(mosq->tls_capath); mosq->tls_capath = NULL; } if(mosq->tls_certfile){ _mosquitto_free(mosq->tls_certfile); mosq->tls_certfile = NULL; } return MOSQ_ERR_INVAL; } mosq->tls_keyfile = _mosquitto_strdup(keyfile); if(!mosq->tls_keyfile){ return MOSQ_ERR_NOMEM; } }else{ if(mosq->tls_keyfile) _mosquitto_free(mosq->tls_keyfile); mosq->tls_keyfile = NULL; } mosq->tls_pw_callback = pw_callback; return MOSQ_ERR_SUCCESS; #else return MOSQ_ERR_NOT_SUPPORTED; #endif }
void my_message_file_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { struct mosq_config *cfg; int i; bool res; if(process_messages == false) return; assert(obj); cfg = (struct mosq_config *)obj; if(cfg->retained_only && !message->retain && process_messages){ process_messages = false; mosquitto_disconnect(mosq); 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; } } cfg->fmask_topic = message->topic; FILE *fptr = NULL; _fmask(cfg->fmask, cfg); char *path, *prog; path = dirname(strdup(cfg->ffmask)); prog = basename(strdup(cfg->ffmask)); mkpath(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); /* reasonable method to distinguish between directory * and a writable node (by default is off) */ if(cfg->nodesuffix) { char *sf = cfg->nsuffix; /* limit 16 bytes. */ sf = stpcpy(sf, cfg->nodesuffix); if(cfg->nsuffix) { char *to = cfg->ffmask; to = stpcpy(to, path); to = stpcpy(to, "/"); if(prog) { to = stpcpy(to, prog); } to = stpcpy(to, "."); to = stpcpy(to, cfg->nsuffix); } } if(cfg->overwrite) { fptr = _mosquitto_fopen(cfg->ffmask, "w"); } else { fptr = _mosquitto_fopen(cfg->ffmask, "a"); } if(!fptr){ fprintf(stderr, "Error: cannot open outfile, using stdout - %s\n", cfg->ffmask); // need to do normal stdout //mosquitto_message_callback_set(mosq, "my_message_callback"); } else{ if(cfg->verbose){ if(message->payloadlen){ fprintf(fptr, "%s ", message->topic); fwrite(message->payload, 1, message->payloadlen, fptr); if(cfg->eol){ fprintf(fptr, "\n"); } }else{ if(cfg->eol){ fprintf(fptr, "%s (null)\n", message->topic); } } }else{ if(message->payloadlen){ fwrite(message->payload, 1, message->payloadlen, fptr); if(cfg->eol){ fprintf(fptr, "\n"); } } } fclose(fptr); } if(cfg->msg_count>0){ msg_count++; if(cfg->msg_count == msg_count){ process_messages = false; mosquitto_disconnect(mosq); } } }
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; }