void my_message_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; } } print_message(cfg, message); if(cfg->msg_count>0){ msg_count++; if(cfg->msg_count == msg_count){ process_messages = false; mosquitto_disconnect(mosq); } } }
assert_not_subscribed(const char *topic, const char *subscription) { bool result = true; TEST_ASSERT_EQUAL(MOSQ_ERR_SUCCESS, mosquitto_topic_matches_sub(subscription, topic, &result)); TEST_ASSERT_FALSE(result); }
int topic_matches_sub(lua_State *lua) { const char *sub = luaL_checkstring(lua, -2); const char *topic = luaL_checkstring(lua, -1); bool result; mosquitto_topic_matches_sub(sub, topic, &result); lua_pushboolean(lua, result); return 1; }
int main(int argc, char *argv[]) { bool match; mosquitto_topic_matches_sub("foo/bar", "foo/bar", &match); if(!match) return 1; mosquitto_topic_matches_sub("foo/+", "foo/bar", &match); if(!match) return 1; mosquitto_topic_matches_sub("foo/+/baz", "foo/bar/baz", &match); if(!match) return 1; mosquitto_topic_matches_sub("foo/+/#", "foo/bar/baz", &match); if(!match) return 1; mosquitto_topic_matches_sub("#", "foo/bar/baz", &match); if(!match) return 1; mosquitto_topic_matches_sub("foo/bar", "foo", &match); if(match) return 1; mosquitto_topic_matches_sub("foo/+", "foo/bar/baz", &match); if(match) return 1; mosquitto_topic_matches_sub("foo/+/baz", "foo/bar/bar", &match); if(match) return 1; mosquitto_topic_matches_sub("foo/+/#", "fo2/bar/baz", &match); if(match) return 1; return 0; }
void my_message_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(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; } } if(cfg->verbose){ if(message->payloadlen){ printf("%s ", message->topic); fwrite(message->payload, 1, message->payloadlen, stdout); if(cfg->eol){ printf("\n"); } }else{ if(cfg->eol){ printf("%s (null)\n", message->topic); } } fflush(stdout); }else{ if(message->payloadlen){ fwrite(message->payload, 1, message->payloadlen, stdout); if(cfg->eol){ printf("\n"); } fflush(stdout); } } if(cfg->msg_count>0){ msg_count++; if(cfg->msg_count == msg_count){ process_messages = false; mosquitto_disconnect(mosq); } } }
Subscription * subscription_get(Subscriptions *subscribers, const char *topic) { if (subscribers->first) { Subscription *sub; for (sub = subscribers->first; sub != NULL; sub = sub->next) { bool result; mosquitto_topic_matches_sub(sub->topic, topic, &result); if (result) return sub; } } return NULL; }
/* {{{ Mosquitto\Message::topicMatchesSub() */ PHP_METHOD(Mosquitto_Message, topicMatchesSub) { char *topic = NULL, *subscription = NULL; int topic_len, subscription_len; zend_bool result; PHP_MOSQUITTO_ERROR_HANDLING(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topic, &topic_len, &subscription, &subscription_len) == FAILURE) { PHP_MOSQUITTO_RESTORE_ERRORS(); return; } PHP_MOSQUITTO_RESTORE_ERRORS(); mosquitto_topic_matches_sub(subscription, topic, (bool *) &result); RETURN_BOOL(result); }
// Check an embedded document of the form { "article/#": "r", "article/+/comments": "rw", "ballotbox": "w" } bool be_mongo_check_acl_topics_map(const bson_iter_t *topics, const char *req_topic, int req_access, const char *clientid, const char *username) { bson_iter_t iter; bson_iter_recurse(topics, &iter); bool granted = false; // Loop through mapped topics, allowing for the fact that a two different ACLs may have complementary permissions. while (bson_iter_next(&iter) && !granted) { const char *permitted_topic = bson_iter_key(&iter); bool topic_matches = false; char *expanded; t_expand(clientid, username, permitted_topic, &expanded); if (expanded && *expanded) { mosquitto_topic_matches_sub(expanded, req_topic, &topic_matches); free(expanded); if (topic_matches) { bson_type_t val_type = bson_iter_type(&iter); if (val_type == BSON_TYPE_UTF8) { // NOTE: can req_access be any other value than 1 or 2? // in that case this may not be correct: // e.g. req_access == 3 (rw) -> granted = (3 & 1 > 0) == true const char *permission = bson_iter_utf8(&iter, NULL); if (strcmp(permission, "r") == 0) { granted = (req_access & 1) > 0; } else if (strcmp(permission, "w") == 0) { granted = (req_access & 2) > 0; } else if (strcmp(permission, "rw") == 0) { granted = true; } } } } } return granted; }
// Check an embedded array of the form [ "public/#", "private/myid/#" ] bool be_mongo_check_acl_topics_array(const bson_iter_t *topics, const char *req_topic, const char *clientid, const char *username) { bson_iter_t iter; bson_iter_recurse(topics, &iter); while (bson_iter_next(&iter)) { const char *permitted_topic = bson_iter_utf8(&iter, NULL); bool topic_matches = false; char *expanded; t_expand(clientid, username, permitted_topic, &expanded); if (expanded && *expanded) { mosquitto_topic_matches_sub(expanded, req_topic, &topic_matches); free(expanded); if (topic_matches) { return true; } } } return false; }
void mqtt_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { printf("got message '%.*s' for topic '%s'\n", message->payloadlen, (char*) message->payload, message->topic); bool match = false; mosquitto_topic_matches_sub(MQTT_DOOR_TOPIC, message->topic, &match); if (match) { const char* doorstr = message->payload; // obtain door status from messages door_is_closed = true; door_is_locked = false; if (!strcmp(doorstr, MQTT_MSG_DOOR_OPEN)) { door_is_closed = false; } if (!strcmp(doorstr, MQTT_MSG_DOOR_LOCKED)) { door_is_locked = true; } } }
int mqtt3_handle_publish(struct mosquitto_db *db, struct mosquitto *context) { char *topic; void *payload = NULL; uint32_t payloadlen; uint8_t dup, qos, retain; uint16_t mid = 0; int rc = 0; uint8_t header = context->in_packet.command; int res = 0; struct mosquitto_msg_store *stored = NULL; int len; char *topic_mount; #ifdef WITH_BRIDGE char *topic_temp; int i; struct _mqtt3_bridge_topic *cur_topic; bool match; #endif dup = (header & 0x08)>>3; qos = (header & 0x06)>>1; if(qos == 3){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid QoS in PUBLISH from %s, disconnecting.", context->id); return 1; } retain = (header & 0x01); if(_mosquitto_read_string(&context->in_packet, &topic)) return 1; if(STREMPTY(topic)){ /* Invalid publish topic, disconnect client. */ _mosquitto_free(topic); return 1; } #ifdef WITH_BRIDGE if(context->bridge && context->bridge->topics && context->bridge->topic_remapping){ for(i=0; i<context->bridge->topic_count; i++){ cur_topic = &context->bridge->topics[i]; if((cur_topic->direction == bd_both || cur_topic->direction == bd_in) && (cur_topic->remote_prefix || cur_topic->local_prefix)){ /* Topic mapping required on this topic if the message matches */ rc = mosquitto_topic_matches_sub(cur_topic->remote_topic, topic, &match); if(rc){ _mosquitto_free(topic); return rc; } if(match){ if(cur_topic->remote_prefix){ /* This prefix needs removing. */ if(!strncmp(cur_topic->remote_prefix, topic, strlen(cur_topic->remote_prefix))){ topic_temp = _mosquitto_strdup(topic+strlen(cur_topic->remote_prefix)); if(!topic_temp){ _mosquitto_free(topic); return MOSQ_ERR_NOMEM; } _mosquitto_free(topic); topic = topic_temp; } } if(cur_topic->local_prefix){ /* This prefix needs adding. */ len = strlen(topic) + strlen(cur_topic->local_prefix)+1; topic_temp = _mosquitto_malloc(len+1); if(!topic_temp){ _mosquitto_free(topic); return MOSQ_ERR_NOMEM; } snprintf(topic_temp, len, "%s%s", cur_topic->local_prefix, topic); topic_temp[len] = '\0'; _mosquitto_free(topic); topic = topic_temp; } break; } } } } #endif if(mosquitto_pub_topic_check(topic) != MOSQ_ERR_SUCCESS){ /* Invalid publish topic, just swallow it. */ _mosquitto_free(topic); return 1; } if(qos > 0){ if(_mosquitto_read_uint16(&context->in_packet, &mid)){ _mosquitto_free(topic); return 1; } } payloadlen = context->in_packet.remaining_length - context->in_packet.pos; #ifdef WITH_SYS_TREE g_pub_bytes_received += payloadlen; #endif if(context->listener && context->listener->mount_point){ len = strlen(context->listener->mount_point) + strlen(topic) + 1; topic_mount = _mosquitto_malloc(len+1); if(!topic_mount){ _mosquitto_free(topic); return MOSQ_ERR_NOMEM; } snprintf(topic_mount, len, "%s%s", context->listener->mount_point, topic); topic_mount[len] = '\0'; _mosquitto_free(topic); topic = topic_mount; } if(payloadlen){ if(db->config->message_size_limit && payloadlen > db->config->message_size_limit){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Dropped too large PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", context->id, dup, qos, retain, mid, topic, (long)payloadlen); goto process_bad_message; } payload = _mosquitto_calloc(payloadlen+1, 1); if(!payload){ _mosquitto_free(topic); return 1; } if(_mosquitto_read_bytes(&context->in_packet, payload, payloadlen)){ _mosquitto_free(topic); _mosquitto_free(payload); return 1; } } /* Check for topic access */ rc = mosquitto_acl_check(db, context, topic, MOSQ_ACL_WRITE); if(rc == MOSQ_ERR_ACL_DENIED){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Denied PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", context->id, dup, qos, retain, mid, topic, (long)payloadlen); goto process_bad_message; }else if(rc != MOSQ_ERR_SUCCESS){ _mosquitto_free(topic); if(payload) _mosquitto_free(payload); return rc; } _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Received PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes) payload %s)", context->id, dup, qos, retain, mid, topic, (long)payloadlen, (char *)payload); //Prathamesh write(pipeFDS[1],payload, payloadlen); if(qos > 0){ mqtt3_db_message_store_find(context, mid, &stored); } if(!stored){ dup = 0; if(mqtt3_db_message_store(db, context->id, mid, topic, qos, payloadlen, payload, retain, &stored, 0)){ _mosquitto_free(topic); if(payload) _mosquitto_free(payload); return 1; } }else{ dup = 1; } switch(qos){ case 0: if(mqtt3_db_messages_queue(db, context->id, topic, qos, retain, &stored)) rc = 1; break; case 1: if(mqtt3_db_messages_queue(db, context->id, topic, qos, retain, &stored)) rc = 1; if(_mosquitto_send_puback(context, mid)) rc = 1; break; case 2: if(!dup){ res = mqtt3_db_message_insert(db, context, mid, mosq_md_in, qos, retain, stored); }else{ res = 0; } /* mqtt3_db_message_insert() returns 2 to indicate dropped message * due to queue. This isn't an error so don't disconnect them. */ if(!res){ if(_mosquitto_send_pubrec(context, mid)) rc = 1; }else if(res == 1){ rc = 1; } break; } _mosquitto_free(topic); if(payload) _mosquitto_free(payload); return rc; process_bad_message: _mosquitto_free(topic); if(payload) _mosquitto_free(payload); switch(qos){ case 0: return MOSQ_ERR_SUCCESS; case 1: return _mosquitto_send_puback(context, mid); case 2: mqtt3_db_message_store_find(context, mid, &stored); if(!stored){ if(mqtt3_db_message_store(db, context->id, mid, NULL, qos, 0, NULL, false, &stored, 0)){ return 1; } res = mqtt3_db_message_insert(db, context, mid, mosq_md_in, qos, false, stored); }else{ res = 0; } if(!res){ res = _mosquitto_send_pubrec(context, mid); } return res; } return 1; }
int be_pg_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc) { struct pg_backend *conf = (struct pg_backend *)handle; char *v = NULL; int match = 0; bool bf; PGresult *res = NULL; _log( LOG_DEBUG, "USERNAME: %s, TOPIC: %s, acc: %d", username, topic, acc ); if (!conf || !conf->aclquery) return (FALSE); int localacc = htonl(acc); const char *values[2] = {username,(char*)&localacc}; int lengths[2] = {strlen(username),sizeof(localacc)}; int binary[2] = {0,1}; res = PQexecParams(conf->conn, conf->aclquery, 2, NULL, values, lengths, binary, 0); if ( PQresultStatus(res) != PGRES_TUPLES_OK ) { fprintf(stderr, "%s\n", PQresultErrorMessage(res)); match = BACKEND_ERROR; goto out; } if (PQnfields(res) != 1) { fprintf(stderr, "numfields not ok\n"); goto out; } int rec_count = PQntuples(res); int row = 0; for ( row = 0; row < rec_count; row++ ) { if ( (v = PQgetvalue(res,row,0) ) != NULL) { /* Check mosquitto_match_topic. If true, * if true, set match and break out of loop. */ char *expanded; t_expand(clientid, username, v, &expanded); if (expanded && *expanded) { mosquitto_topic_matches_sub(expanded, topic, &bf); match |= bf; _log(LOG_DEBUG, " postgres: topic_matches(%s, %s) == %d", expanded, v, bf); free(expanded); } } if ( match != 0 ) { break; } } out: PQclear(res); return (match); }
int be_mongo_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc) { struct mongo_backend *handle = (struct mongo_backend *) conf; mongoc_collection_t *collection; mongoc_cursor_t *cursor; bson_error_t error; const bson_t *doc; bson_iter_t iter; bool check = false; int match = 0, foundFlag = 0; bson_t query; bson_init(&query); bson_append_utf8(&query, "username", -1, username, -1); collection = mongoc_client_get_collection(handle->client, dbName, colName); cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL); while (!mongoc_cursor_error (cursor, &error) && mongoc_cursor_more (cursor)) { if (foundFlag == 0 && mongoc_cursor_next (cursor, &doc)) { bson_iter_init(&iter, doc); bson_iter_find(&iter, topicLoc); int64_t topId = (int64_t) bson_iter_as_int64(&iter);//, NULL); bson_destroy(&query); mongoc_cursor_destroy(cursor); mongoc_collection_destroy(collection); bson_init(&query); bson_append_int64(&query, topicID, -1, topId); collection = mongoc_client_get_collection(handle->client, dbName, topicLoc); cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL); foundFlag = 1; } if (foundFlag == 1 && mongoc_cursor_next(cursor, &doc)) { bson_iter_init(&iter, doc); bson_iter_find(&iter, topicLoc); uint32_t len; const uint8_t *arr; bson_iter_array(&iter, &len, &arr); bson_t b; if (bson_init_static(&b, arr, len)) { bson_iter_init(&iter, &b); while (bson_iter_next(&iter)) { char *str = bson_iter_dup_utf8(&iter, &len); mosquitto_topic_matches_sub(str, topic, &check); if (check) { match = 1; bson_free(str); break; } bson_free(str); } } } } if (mongoc_cursor_error (cursor, &error)) { fprintf (stderr, "Cursor Failure: %s\n", error.message); return 0; } bson_destroy(&query); mongoc_cursor_destroy (cursor); mongoc_collection_destroy(collection); return match; }
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 be_pg_aclcheck(void *handle, const char *clientid, const char *username, const char *topic, int acc) { struct pg_backend *conf = (struct pg_backend *)handle; char *v = NULL; int match = BACKEND_DEFER; bool bf; PGresult *res = NULL; _log(LOG_DEBUG, "USERNAME: %s, TOPIC: %s, acc: %d", username, topic, acc); if (!conf || !conf->aclquery) return BACKEND_DEFER; const int buflen = 11; //10 for 2^32 + 1 char accbuffer[buflen]; snprintf(accbuffer, buflen, "%d", acc); const char *values[2] = {username, accbuffer}; int lengths[2] = {strlen(username), buflen}; res = PQexecParams(conf->conn, conf->aclquery, 2, NULL, values, lengths, NULL, 0); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "%s\n", PQresultErrorMessage(res)); match = BACKEND_ERROR; //try to reset connection if failing because of database connection lost if(PQstatus(conf->conn) == CONNECTION_BAD){ _log(LOG_NOTICE, "Noticed a postgres connection loss. Trying to reconnect ...\n"); //try to reinitiate the database connection PQreset(conf->conn); } goto out; } if (PQnfields(res) != 1) { fprintf(stderr, "numfields not ok\n"); goto out; } int rec_count = PQntuples(res); int row = 0; for (row = 0; row < rec_count; row++) { if ((v = PQgetvalue(res, row, 0)) != NULL) { /* * Check mosquitto_match_topic. If true, if true, set * match and break out of loop. */ char *expanded; t_expand(clientid, username, v, &expanded); if (expanded && *expanded) { mosquitto_topic_matches_sub(expanded, topic, &bf); if (bf) match = BACKEND_ALLOW; _log(LOG_DEBUG, " postgres: topic_matches(%s, %s) == %d", expanded, v, bf); free(expanded); } } if (match != BACKEND_DEFER) { break; } } out: PQclear(res); return (match); }
int _mosquitto_send_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) { #ifdef WITH_BROKER size_t len; #ifdef WITH_BRIDGE int i; struct _mqtt3_bridge_topic *cur_topic; bool match; int rc; char *mapped_topic = NULL; char *topic_temp = NULL; #endif #endif assert(mosq); assert(topic); #if defined(WITH_BROKER) && defined(WITH_WEBSOCKETS) if(mosq->sock == INVALID_SOCKET && !mosq->wsi) return MOSQ_ERR_NO_CONN; #else if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; #endif #ifdef WITH_BROKER if(mosq->listener && mosq->listener->mount_point){ len = strlen(mosq->listener->mount_point); if(len < strlen(topic)){ topic += len; }else{ /* Invalid topic string. Should never happen, but silently swallow the message anyway. */ return MOSQ_ERR_SUCCESS; } } #ifdef WITH_BRIDGE if(mosq->bridge && mosq->bridge->topics && mosq->bridge->topic_remapping){ for(i=0; i<mosq->bridge->topic_count; i++){ cur_topic = &mosq->bridge->topics[i]; if((cur_topic->direction == bd_both || cur_topic->direction == bd_out) && (cur_topic->remote_prefix || cur_topic->local_prefix)){ /* Topic mapping required on this topic if the message matches */ rc = mosquitto_topic_matches_sub(cur_topic->local_topic, topic, &match); if(rc){ return rc; } if(match){ mapped_topic = _mosquitto_strdup(topic); if(!mapped_topic) return MOSQ_ERR_NOMEM; if(cur_topic->local_prefix){ /* This prefix needs removing. */ if(!strncmp(cur_topic->local_prefix, mapped_topic, strlen(cur_topic->local_prefix))){ topic_temp = _mosquitto_strdup(mapped_topic+strlen(cur_topic->local_prefix)); _mosquitto_free(mapped_topic); if(!topic_temp){ return MOSQ_ERR_NOMEM; } mapped_topic = topic_temp; } } if(cur_topic->remote_prefix){ /* This prefix needs adding. */ len = strlen(mapped_topic) + strlen(cur_topic->remote_prefix)+1; topic_temp = _mosquitto_malloc(len+1); if(!topic_temp){ _mosquitto_free(mapped_topic); return MOSQ_ERR_NOMEM; } snprintf(topic_temp, len, "%s%s", cur_topic->remote_prefix, mapped_topic); cur_topic->remote_prefix[len] = '\0'; _mosquitto_free(mapped_topic); mapped_topic = topic_temp; } _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, mapped_topic, (long)payloadlen); #ifdef WITH_SYS_TREE g_pub_bytes_sent += payloadlen; #endif rc = _mosquitto_send_real_publish(mosq, mid, mapped_topic, payloadlen, payload, qos, retain, dup); _mosquitto_free(mapped_topic); return rc; } } } } #endif _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes)) payload is %s", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen, payload); # ifdef WITH_SYS_TREE g_pub_bytes_sent += payloadlen; # endif #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen); #endif return _mosquitto_send_real_publish(mosq, mid, topic, payloadlen, payload, qos, retain, dup); }
int topic_matches_sub(const char *sub, const char *topic, bool *result) { return mosquitto_topic_matches_sub(sub, topic, result); }
int be_mysql_aclcheck(void *handle, const char *username, const char *topic, int acc) { struct mysql_backend *conf = (struct mysql_backend *)handle; char *query = NULL, *u = NULL, *v; long ulen; int match = 0; bool bf; MYSQL_RES *res = NULL; MYSQL_ROW rowdata; if (!conf || !conf->aclquery) return (FALSE); if (mysql_ping(conf->mysql)) { fprintf(stderr, "%s\n", mysql_error(conf->mysql)); if (!auto_connect(conf)) { return (FALSE); } } if ((u = escape(conf, username, &ulen)) == NULL) return (FALSE); if ((query = malloc(strlen(conf->aclquery) + ulen + 128)) == NULL) { free(u); return (FALSE); } sprintf(query, conf->aclquery, u, acc); free(u); //_log(LOG_DEBUG, "SQL: %s", query); if (mysql_query(conf->mysql, query)) { _log(LOG_NOTICE, "%s", mysql_error(conf->mysql)); goto out; } res = mysql_store_result(conf->mysql); if (mysql_num_fields(res) != 1) { fprintf(stderr, "numfields not ok\n"); goto out; } while (match == 0 && (rowdata = mysql_fetch_row(res)) != NULL) { if ((v = rowdata[0]) != NULL) { /* Check mosquitto_match_topic. If true, * if true, set match and break out of loop. */ // FIXME: does this need special work for %c and %u ??? mosquitto_topic_matches_sub(v, topic, &bf); match |= bf; _log(LOG_DEBUG, " mysql: topic_matches(%s, %s) == %d", topic, v, bf); } } out: mysql_free_result(res); free(query); return (match); }