kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'feature/mdns-value-len' into 'master'
mdns: allow explicit txt value length See merge request espressif/esp-idf!13981pull/6904/head
commit
3452c5f194
|
@ -79,6 +79,7 @@ typedef struct mdns_result_s {
|
|||
uint16_t port; /*!< service port */
|
||||
// TXT
|
||||
mdns_txt_item_t * txt; /*!< txt record */
|
||||
uint8_t *txt_value_len; /*!< array of txt value len of each record */
|
||||
size_t txt_count; /*!< number of txt items */
|
||||
// A and AAAA
|
||||
mdns_ip_addr_t * addr; /*!< linked list of IP addresses found */
|
||||
|
@ -173,6 +174,8 @@ esp_err_t mdns_instance_name_set(const char * instance_name);
|
|||
/**
|
||||
* @brief Add service to mDNS server
|
||||
*
|
||||
* @note The value length of txt items will be automatically decided by strlen
|
||||
*
|
||||
* @param instance_name instance name to set. If NULL,
|
||||
* global instance name or hostname will be used
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
|
@ -189,10 +192,11 @@ esp_err_t mdns_instance_name_set(const char * instance_name);
|
|||
*/
|
||||
esp_err_t mdns_service_add(const char * instance_name, const char * service_type, const char * proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add service to mDNS server with a delegated hostname
|
||||
*
|
||||
* @note The value length of txt items will be automatically decided by strlen
|
||||
*
|
||||
* @param instance_name instance name to set. If NULL,
|
||||
* global instance name or hostname will be used
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
|
@ -321,6 +325,8 @@ esp_err_t mdns_service_port_set_for_host(const char * service_type, const char *
|
|||
/**
|
||||
* @brief Replace all TXT items for service
|
||||
*
|
||||
* @note The value length of txt items will be automatically decided by strlen
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
|
||||
|
@ -337,6 +343,8 @@ esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, md
|
|||
/**
|
||||
* @brief Replace all TXT items for service with hostname
|
||||
*
|
||||
* @note The value length of txt items will be automatically decided by strlen
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param hostname service hostname. If NULL, local hostname will be used.
|
||||
|
@ -355,6 +363,8 @@ esp_err_t mdns_service_txt_set_for_host(const char * service_type, const char *
|
|||
/**
|
||||
* @brief Set/Add TXT item for service TXT record
|
||||
*
|
||||
* @note The value length will be automatically decided by strlen
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param key the key that you want to add/update
|
||||
|
@ -368,10 +378,29 @@ esp_err_t mdns_service_txt_set_for_host(const char * service_type, const char *
|
|||
*/
|
||||
esp_err_t mdns_service_txt_item_set(const char * service_type, const char * proto, const char * key, const char * value);
|
||||
|
||||
/**
|
||||
* @brief Set/Add TXT item for service TXT record
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param key the key that you want to add/update
|
||||
* @param value the new value of the key
|
||||
* @param value_len the length of the value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_ERR_NOT_FOUND Service not found
|
||||
* - ESP_ERR_NO_MEM memory error
|
||||
*/
|
||||
esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service_type, const char *proto,
|
||||
const char *key, const char *value, uint8_t value_len);
|
||||
|
||||
/**
|
||||
* @brief Set/Add TXT item for service TXT record with hostname
|
||||
*
|
||||
* @note The value length will be automatically decided by strlen
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param hostname service hostname. If NULL, local hostname will be used.
|
||||
|
@ -387,6 +416,26 @@ esp_err_t mdns_service_txt_item_set(const char * service_type, const char * prot
|
|||
esp_err_t mdns_service_txt_item_set_for_host(const char * service_type, const char * proto, const char * hostname,
|
||||
const char * key, const char * value);
|
||||
|
||||
/**
|
||||
* @brief Set/Add TXT item for service TXT record with hostname and txt value length
|
||||
*
|
||||
* @param service_type service type (_http, _ftp, etc)
|
||||
* @param proto service protocol (_tcp, _udp)
|
||||
* @param hostname service hostname. If NULL, local hostname will be used.
|
||||
* @param key the key that you want to add/update
|
||||
* @param value the new value of the key
|
||||
* @param value_len the length of the value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_ERR_NOT_FOUND Service not found
|
||||
* - ESP_ERR_NO_MEM memory error
|
||||
*/
|
||||
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *service_type, const char *proto,
|
||||
const char *hostname, const char *key,
|
||||
const char *value, uint8_t value_len);
|
||||
|
||||
/**
|
||||
* @brief Remove TXT item for service TXT record
|
||||
*
|
||||
|
|
|
@ -43,7 +43,7 @@ static void _mdns_search_finish_done(void);
|
|||
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * search, mdns_name_t * name, uint16_t type, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, esp_ip_addr_t * ip, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, uint8_t *txt_value_len, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static bool _mdns_append_host_list_in_services(mdns_out_answer_t ** destination, mdns_srv_item_t * services[], size_t services_len, bool flush, bool bye);
|
||||
static bool _mdns_append_host_list(mdns_out_answer_t ** destination, bool flush, bool bye);
|
||||
|
@ -418,6 +418,17 @@ static inline uint8_t _mdns_append_type(uint8_t * packet, uint16_t * index, uint
|
|||
return 10;
|
||||
}
|
||||
|
||||
static inline uint8_t _mdns_append_string_with_len(uint8_t * packet, uint16_t * index, const char * string, uint8_t len)
|
||||
{
|
||||
if ((*index + len + 1) >= MDNS_MAX_PACKET_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
_mdns_append_u8(packet, index, len);
|
||||
memcpy(packet + *index, string, len);
|
||||
*index += len;
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief appends single string to a packet, incrementing the index
|
||||
*
|
||||
|
@ -656,10 +667,12 @@ static uint16_t _mdns_append_txt_record(uint8_t * packet, uint16_t * index, mdns
|
|||
char * tmp;
|
||||
mdns_txt_linked_item_t * txt = service->txt;
|
||||
while (txt) {
|
||||
tmp = (char *)malloc(2 + strlen(txt->key) + strlen(txt->value));
|
||||
uint8_t txt_data_len = strlen(txt->key) + txt->value_len + 1;
|
||||
tmp = (char *)malloc(txt_data_len);
|
||||
if (tmp) {
|
||||
sprintf(tmp, "%s=%s", txt->key, txt->value);
|
||||
uint8_t l = _mdns_append_string(packet, index, tmp);
|
||||
int offset = sprintf(tmp, "%s=", txt->key);
|
||||
memcpy(tmp + offset, txt->value, txt->value_len);
|
||||
uint8_t l = _mdns_append_string_with_len(packet, index, tmp, txt_data_len);
|
||||
free(tmp);
|
||||
if (!l) {
|
||||
return 0;
|
||||
|
@ -2072,6 +2085,7 @@ static mdns_txt_linked_item_t * _mdns_allocate_txt(size_t num_items, mdns_txt_it
|
|||
free(new_item);
|
||||
break;
|
||||
}
|
||||
new_item->value_len = strlen(new_item->value);
|
||||
new_item->next = new_txt;
|
||||
new_txt = new_item;
|
||||
}
|
||||
|
@ -2842,7 +2856,8 @@ static int _mdns_txt_item_name_get_len(const uint8_t * data, size_t len)
|
|||
/**
|
||||
* @brief Create TXT result array from parsed TXT data
|
||||
*/
|
||||
static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_item_t ** out_txt, size_t * out_count)
|
||||
static void _mdns_result_txt_create(const uint8_t *data, size_t len, mdns_txt_item_t **out_txt, uint8_t **out_value_len,
|
||||
size_t *out_count)
|
||||
{
|
||||
*out_txt = NULL;
|
||||
*out_count = 0;
|
||||
|
@ -2862,7 +2877,14 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
|
|||
HOOK_MALLOC_FAILED;
|
||||
return;
|
||||
}
|
||||
uint8_t * txt_value_len = (uint8_t *)malloc(num_items);
|
||||
if (!txt_value_len) {
|
||||
free(txt);
|
||||
HOOK_MALLOC_FAILED;
|
||||
return;
|
||||
}
|
||||
memset(txt, 0, sizeof(mdns_txt_item_t) * num_items);
|
||||
memset(txt_value_len, 0, num_items);
|
||||
size_t txt_num = 0;
|
||||
|
||||
while (i < len) {
|
||||
|
@ -2886,29 +2908,33 @@ static void _mdns_result_txt_create(const uint8_t * data, size_t len, mdns_txt_i
|
|||
goto handle_error;//error
|
||||
}
|
||||
|
||||
mdns_txt_item_t * t = &txt[txt_num++];
|
||||
mdns_txt_item_t * t = &txt[txt_num];
|
||||
uint8_t * value_len = &txt_value_len[txt_num];
|
||||
txt_num++;
|
||||
|
||||
memcpy(key, data + i, name_len);
|
||||
key[name_len] = 0;
|
||||
i += name_len + 1;
|
||||
t->key = key;
|
||||
|
||||
int value_len = partLen - name_len - 1;
|
||||
if (value_len > 0) {
|
||||
char * value = (char *)malloc(value_len + 1);
|
||||
int new_value_len = partLen - name_len - 1;
|
||||
if (new_value_len > 0) {
|
||||
char * value = (char *)malloc(new_value_len + 1);
|
||||
if (!value) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto handle_error;//error
|
||||
}
|
||||
memcpy(value, data + i, value_len);
|
||||
value[value_len] = 0;
|
||||
i += value_len;
|
||||
memcpy(value, data + i, new_value_len);
|
||||
value[new_value_len] = 0;
|
||||
*value_len = new_value_len;
|
||||
i += new_value_len;
|
||||
t->value = value;
|
||||
}
|
||||
}
|
||||
|
||||
*out_txt = txt;
|
||||
*out_count = txt_num;
|
||||
*out_value_len = txt_value_len;
|
||||
return;
|
||||
|
||||
handle_error :
|
||||
|
@ -2917,6 +2943,7 @@ handle_error :
|
|||
free((char *)t->key);
|
||||
free((char *)t->value);
|
||||
}
|
||||
free(txt_value_len);
|
||||
free(txt);
|
||||
}
|
||||
|
||||
|
@ -3246,6 +3273,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
|
|||
} else if (type == MDNS_TYPE_TXT) {
|
||||
if (search_result) {
|
||||
mdns_txt_item_t * txt = NULL;
|
||||
uint8_t *txt_value_len = NULL;
|
||||
size_t txt_count = 0;
|
||||
|
||||
mdns_result_t * result = NULL;
|
||||
|
@ -3266,16 +3294,17 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
|
|||
}
|
||||
}
|
||||
if (!result->txt) {
|
||||
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
|
||||
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_value_len, &txt_count);
|
||||
if (txt_count) {
|
||||
result->txt = txt;
|
||||
result->txt_count = txt_count;
|
||||
result->txt_value_len = txt_value_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_count);
|
||||
_mdns_result_txt_create(data_ptr, data_len, &txt, &txt_value_len, &txt_count);
|
||||
if (txt_count) {
|
||||
_mdns_search_result_add_txt(search_result, txt, txt_count, packet->tcpip_if, packet->ip_protocol);
|
||||
_mdns_search_result_add_txt(search_result, txt, txt_value_len, txt_count, packet->tcpip_if, packet->ip_protocol);
|
||||
}
|
||||
}
|
||||
} else if (ours) {
|
||||
|
@ -3824,7 +3853,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char
|
|||
/**
|
||||
* @brief Called from parser to add TXT data to search result
|
||||
*/
|
||||
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, uint8_t *txt_value_len, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||
{
|
||||
mdns_result_t * r = search->result;
|
||||
while (r) {
|
||||
|
@ -3833,6 +3862,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
|
|||
goto free_txt;
|
||||
}
|
||||
r->txt = txt;
|
||||
r->txt_value_len = txt_value_len;
|
||||
r->txt_count = txt_count;
|
||||
return;
|
||||
}
|
||||
|
@ -3847,6 +3877,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_it
|
|||
|
||||
memset(r, 0 , sizeof(mdns_result_t));
|
||||
r->txt = txt;
|
||||
r->txt_value_len = txt_value_len;
|
||||
r->txt_count = txt_count;
|
||||
r->tcpip_if = tcpip_if;
|
||||
r->ip_protocol = ip_protocol;
|
||||
|
@ -4225,6 +4256,7 @@ static void _mdns_execute_action(mdns_action_t * action)
|
|||
free((char *)txt->value);
|
||||
free(key);
|
||||
txt->value = value;
|
||||
txt->value_len = action->data.srv_txt_set.value_len;
|
||||
break;
|
||||
}
|
||||
txt = txt->next;
|
||||
|
@ -4238,6 +4270,7 @@ static void _mdns_execute_action(mdns_action_t * action)
|
|||
}
|
||||
txt->key = key;
|
||||
txt->value = value;
|
||||
txt->value_len = action->data.srv_txt_set.value_len;
|
||||
txt->next = service->txt;
|
||||
service->txt = txt;
|
||||
}
|
||||
|
@ -4860,8 +4893,8 @@ esp_err_t mdns_instance_name_set(const char * instance)
|
|||
* MDNS SERVICES
|
||||
* */
|
||||
|
||||
esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto,
|
||||
const char * hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items)
|
||||
esp_err_t mdns_service_add_for_host(const char * instance, const char * service, const char * proto, const char * hostname,
|
||||
uint16_t port, mdns_txt_item_t txt[], size_t num_items)
|
||||
{
|
||||
if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(hostname) ||
|
||||
!port) {
|
||||
|
@ -5013,17 +5046,19 @@ esp_err_t mdns_service_txt_set(const char * service, const char * proto, mdns_tx
|
|||
return mdns_service_txt_set_for_host(service, proto, _mdns_server->hostname, txt, num_items);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char * proto, const char * hostname,
|
||||
const char * key, const char * value)
|
||||
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *service, const char *proto,
|
||||
const char *hostname, const char *key,
|
||||
const char *value, uint8_t value_len)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(key) || !value) {
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) ||
|
||||
_str_null_or_empty(key) || !value) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
mdns_srv_item_t *s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
|
||||
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
|
||||
if (!action) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
return ESP_ERR_NO_MEM;
|
||||
|
@ -5036,12 +5071,14 @@ esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char *
|
|||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
action->data.srv_txt_set.value = strdup(value);
|
||||
action->data.srv_txt_set.value = (char *)malloc(value_len);
|
||||
if (!action->data.srv_txt_set.value) {
|
||||
free(action->data.srv_txt_set.key);
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memcpy(action->data.srv_txt_set.value, value, value_len);
|
||||
action->data.srv_txt_set.value_len = value_len;
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
|
||||
free(action->data.srv_txt_set.key);
|
||||
free(action->data.srv_txt_set.value);
|
||||
|
@ -5051,12 +5088,31 @@ esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char *
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_set(const char * service, const char * proto, const char * key, const char * value)
|
||||
esp_err_t mdns_service_txt_item_set_for_host(const char *service, const char *proto, const char *hostname,
|
||||
const char *key, const char *value)
|
||||
{
|
||||
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, hostname, key, value,
|
||||
strlen(value));
|
||||
}
|
||||
|
||||
|
||||
esp_err_t mdns_service_txt_item_set(const char *service, const char *proto, const char *key, const char *value)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return mdns_service_txt_item_set_for_host(service, proto, _mdns_server->hostname, key, value);
|
||||
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, _mdns_server->hostname, key,
|
||||
value, strlen(value));
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service, const char *proto, const char *key,
|
||||
const char *value, uint8_t value_len)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return mdns_service_txt_item_set_for_host_with_explicit_value_len(service, proto, _mdns_server->hostname, key,
|
||||
value, value_len);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_remove_for_host(const char * service, const char * proto, const char * hostname,
|
||||
|
@ -5215,6 +5271,7 @@ void mdns_query_results_free(mdns_result_t * results)
|
|||
free((char *)(r->txt[i].value));
|
||||
}
|
||||
free(r->txt);
|
||||
free(r->txt_value_len);
|
||||
|
||||
while (r->addr) {
|
||||
a = r->addr;
|
||||
|
|
|
@ -277,7 +277,8 @@ typedef struct {
|
|||
|
||||
typedef struct mdns_txt_linked_item_s {
|
||||
const char * key; /*!< item key name */
|
||||
const char * value; /*!< item value string */
|
||||
char * value; /*!< item value string */
|
||||
uint8_t value_len; /*!< item value length */
|
||||
struct mdns_txt_linked_item_s * next; /*!< next result, or NULL for the last result in the list */
|
||||
} mdns_txt_linked_item_t;
|
||||
|
||||
|
@ -426,6 +427,7 @@ typedef struct {
|
|||
mdns_srv_item_t * service;
|
||||
char * key;
|
||||
char * value;
|
||||
uint8_t value_len;
|
||||
} srv_txt_set;
|
||||
struct {
|
||||
mdns_srv_item_t * service;
|
||||
|
|
|
@ -75,7 +75,7 @@ static void initialise_mdns(void)
|
|||
//add another TXT item
|
||||
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") );
|
||||
//change TXT item value
|
||||
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "u", "admin") );
|
||||
ESP_ERROR_CHECK( mdns_service_txt_item_set_with_explicit_value_len("_http", "_tcp", "u", "admin", strlen("admin")) );
|
||||
free(hostname);
|
||||
}
|
||||
|
||||
|
@ -98,9 +98,10 @@ static void mdns_print_results(mdns_result_t * results){
|
|||
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
|
||||
}
|
||||
if(r->txt_count){
|
||||
printf(" TXT : [%u] ", r->txt_count);
|
||||
printf(" TXT : [%zu] ", r->txt_count);
|
||||
for(t=0; t<r->txt_count; t++){
|
||||
printf("%s=%s; ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL");
|
||||
printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL",
|
||||
r->txt_value_len[t]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue