Exemple #1
0
GSList *
dime_parse_records(const char *data, size_t size)
{
	const char * const data0 = data;
	GSList *list = NULL;

	for (;;) {
		struct dime_record *record;
		size_t ret;
		
		record = dime_record_alloc();
		list = g_slist_prepend(list, record);
		
		ret = dime_parse_record_header(data, size, record);
		if (0 == ret) {
			goto error;
		}
		data += ret;
		size -= ret;

		if (data0 == data) {
			if (0 == (DIME_F_MB & record->flags)) {
				/* FIXME: Warning, no message begin flag */
				goto error;
			}
		}
		if (DIME_F_ME & record->flags) {
			break;
		}
	}

	return g_slist_reverse(list);

error:

	dime_list_free(&list);
	return NULL;
}
Exemple #2
0
bool
thex_download_finished(struct thex_download *ctx)
{
	GSList *records;
	bool success = FALSE;

	g_return_val_if_fail(ctx, FALSE);
	g_return_val_if_fail(!ctx->finished, FALSE);

	ctx->finished = TRUE;

	g_assert(ctx->pos <= ctx->data_size);
	ctx->data_size = ctx->pos;	/* Amount which is actually valid */

	if (NULL == ctx->data) {
		records = NULL;
		goto finish;			/* Did not receive anything */
	}

	records = dime_parse_records(ctx->data, ctx->data_size);
	if (records) {
		const struct dime_record *record;
		const char *data;
		char *hashtree_id;
		size_t size;
		
		record = dime_find_record(records, "text/xml", NULL);
		if (NULL == record) {
			if (GNET_PROPERTY(tigertree_debug)) {
				dump_hex(stderr, "THEX data", ctx->data, ctx->data_size);
			}
			goto finish;
		}

		data = dime_record_data(record);
		size = dime_record_data_length(record);
		hashtree_id = thex_download_handle_xml(ctx, data, size);
		if (NULL == hashtree_id) {
			if (GNET_PROPERTY(tigertree_debug)) {
				g_debug("TTH could not determine hashtree ID");
				dump_hex(stderr, "THEX data", ctx->data, ctx->data_size);
			}
			/* Bug workaround:
			 * Try without an ID. GnucDNA 1.1.1.4 sends truncated XML with
			 * a missing closing tag.
			 */
		}

		record = dime_find_record(records, THEX_TREE_TYPE, hashtree_id);
		if (NULL == record && NULL != hashtree_id) {
			/* Bug workaround:
			 * Ignore the ID and fetch the first record with a matching
			 * type. BearShare 5.2 prepends a bogus double-quote to the ID.
			 */
			record = dime_find_record(records, THEX_TREE_TYPE, NULL);
		}
		HFREE_NULL(hashtree_id);

		if (NULL == record) {
			if (GNET_PROPERTY(tigertree_debug)) {
				dump_hex(stderr, "THEX data", ctx->data, ctx->data_size);
			}
			goto finish;
		}

		data = dime_record_data(record);
		size = dime_record_data_length(record);

		if (!thex_download_handle_hashtree(ctx, data, size))
			goto finish;

	} else {
		if (GNET_PROPERTY(tigertree_debug)) {
			g_debug("TTH could not parse DIME records");
			dump_hex(stderr, "THEX data", ctx->data, ctx->data_size);
		}
		goto finish;
	}
	success = TRUE;

finish:
	dime_list_free(&records);
	HFREE_NULL(ctx->data);
	return success;
}