/* Now just handle string hash table correctly */ GHashTable * cl_get_hashtable(struct ha_msg * msg, const char * name) { struct ha_msg * tmp_msg = NULL; GHashTable * htable = NULL; int i; if (msg==NULL || name==NULL) { stdmsg_log(LOG_ERR, "cl_get_hashtable: parameter error."); return NULL; } if ((tmp_msg = cl_get_struct(msg, name)) == NULL) { stdmsg_log(LOG_ERR, "cl_get_hashtable: get NULL field."); return NULL; } htable = g_hash_table_new_full(g_str_hash, g_str_equal, free_str_key, free_str_val); for (i = 0; i < tmp_msg->nfields; i++) { if( FT_STRING != tmp_msg->types[i] ) { stdmsg_log(LOG_ERR, "cl_get_hashtable: " "field data type error."); continue; } g_hash_table_insert(htable, g_strndup(tmp_msg->names[i], tmp_msg->nlens[i]), g_strndup(tmp_msg->values[i], tmp_msg->vlens[i])); stdmsg_log(LOG_DEBUG, "cl_get_hashtable: field[%d]: " "name=%s, value=%s", i, tmp_msg->names[i], (const char *)tmp_msg->values[i]); } stdmsg_log(LOG_DEBUG, "cl_get_hashtable: table's address=%p", htable); return htable; }
static void convert_ha_field(xmlNode * parent, void *msg_v, int lpc) { int type = 0; const char *name = NULL; const char *value = NULL; xmlNode *xml = NULL; HA_Message *msg = msg_v; int rc = BZ_OK; size_t orig_len = 0; unsigned int used = 0; char *uncompressed = NULL; char *compressed = NULL; int size = orig_len * 10; CRM_CHECK(parent != NULL, return); CRM_CHECK(msg != NULL, return); name = msg->names[lpc]; type = cl_get_type(msg, name); switch (type) { case FT_STRUCT: convert_ha_message(parent, msg->values[lpc], name); break; case FT_COMPRESS: case FT_UNCOMPRESS: convert_ha_message(parent, cl_get_struct(msg, name), name); break; case FT_STRING: value = msg->values[lpc]; CRM_CHECK(value != NULL, return); crm_trace("Converting %s/%d/%s", name, type, value[0] == '<' ? "xml" : "field"); if (value[0] != '<') { crm_xml_add(parent, name, value); break; } /* unpack xml string */ xml = string2xml(value); if (xml == NULL) { crm_err("Conversion of field '%s' failed", name); return; } add_node_nocopy(parent, NULL, xml); break; case FT_BINARY: value = cl_get_binary(msg, name, &orig_len); size = orig_len * 10 + 1; /* +1 because an exact 10x compression factor happens occasionally */ if (orig_len < 3 || value[0] != 'B' || value[1] != 'Z' || value[2] != 'h') { if (strstr(name, "uuid") == NULL) { crm_err("Skipping non-bzip binary field: %s", name); } return; } compressed = calloc(1, orig_len); memcpy(compressed, value, orig_len); crm_trace("Trying to decompress %d bytes", (int)orig_len); retry: uncompressed = realloc_safe(uncompressed, size); memset(uncompressed, 0, size); used = size - 1; /* always leave room for a trailing '\0' * BZ2_bzBuffToBuffDecompress won't say anything if * the uncompressed data is exactly 'size' bytes */ rc = BZ2_bzBuffToBuffDecompress(uncompressed, &used, compressed, orig_len, 1, 0); if (rc == BZ_OUTBUFF_FULL) { size = size * 2; /* don't try to allocate more memory than we have */ if (size > 0) { goto retry; } } if (rc != BZ_OK) { crm_err("Decompression of %s (%d bytes) into %d failed: %d", name, (int)orig_len, size, rc); } else if (used >= size) { CRM_ASSERT(used < size); } else { CRM_LOG_ASSERT(uncompressed[used] == 0); uncompressed[used] = 0; xml = string2xml(uncompressed); } if (xml != NULL) { add_node_copy(parent, xml); free_xml(xml); } free(uncompressed); free(compressed); break; } }