Пример #1
0
/*
 * request builder.
 * call if
 *  - line is connected,
 *  - socket is connected.
 *  - SSL is connected.
 *  - HTTP header is sent.
 */
static int
rspull_request(transaction *tr, char *buf, int len, int *wrote)
{
	arms_context_t *res = arms_get_context();
	rspull_context_t *ctx = tr->tr_ctx.arg;
	int total, size;

	libarms_log(ARMS_LOG_IRS_ACCESS_START, NULL);

	/* reset arg if retried */
	ctx->pa_index = 0;

	total = size = arms_write_begin_message(tr, buf, len);
	buf += size;
	len -= size;
	
	size = snprintf(buf, len,
			"<protocol-version>%d.%d</protocol-version>",
			ARMS_PROTOCOL_VERSION_MAJOR,
			ARMS_PROTOCOL_VERSION_MINOR);
	buf += size;
	len -= size;
	total += size;

	size = snprintf(buf, len, "<trigger>%s</trigger>", res->trigger);
	buf += size;
	len -= size;
	total += size;

	if (res->version[0] != '\0') {
		size = snprintf(buf, len,
		    "<firmware-info>%s</firmware-info>",
		    arms_escape(res->version));
		buf += size;
		len -= size;
		total += size;
	}

	total += arms_write_end_message(tr, buf, len);

	tr->tr_ctx.read_done = 0;

	*wrote = total;
	return TR_WRITE_DONE;
}
Пример #2
0
/*
 * rv: wrote bytes excludes NUL.
 *
 * pm_string: "hoge"(sync),
 *		"hoge-start"(async from RS),
 *
 * <arms-message>
 * <arms-request type="hoge"or"hoge-start"or"hoge-done">
 * <hoge-request>or<hoge-start-request>or<hoge-done-request>
 */
int
arms_write_begin_message(transaction *tr, char *buf, int len)
{
	tr_ctx_t *tr_ctx = &tr->tr_ctx;
	arms_context_t *res = arms_get_context();

	switch (arms_req_or_res(tr)) {
	case REQ:
		return snprintf(buf, len,
				"<arms-message>"
				"<arms-request type=\"%s%s\">"
				"%s"
				"<distribution-id>%s</distribution-id>"
				"%s"
				"<description>%s</description>"
				"<%s%s>",
				tr_ctx->pm->pm_string,
				arms_msg_way_str(tr),
				arms_get_transaction_result(tr),
				arms_distid_str(tr),
				arms_get_transaction_id(tr_ctx),
				arms_escape(res->description),
				tr_ctx->pm->pm_string, arms_msg_type_str(tr));
	case RES:
		return snprintf(buf, len,
				"<arms-message>"
				"<arms-response type=\"%s%s\">"
				"%s"
				"<result-code>%d</result-code>"
				"<description>%s</description>"
				"<%s%s>",
				tr_ctx->pm->pm_string,
				arms_msg_way_str(tr),
				arms_get_transaction_id(tr_ctx),
				tr_ctx->result,
				arms_get_result_str(tr_ctx->result),
				tr_ctx->pm->pm_string, arms_msg_type_str(tr));
	default:
		/*bug?*/
		return 0;
	}
}
Пример #3
0
/*
 * Generate md-command-response mesage.
 */
static int
md_command_response(transaction *tr, char *buf, int len, int *wrote)
{
	tr_ctx_t *tr_ctx = &tr->tr_ctx;
	struct md_command_args *arg = tr_ctx->arg;
	arms_context_t *res = arms_get_context();
	int size, total, rv;

	switch (arg->state) {
	case BEGIN:
		libarms_log(ARMS_LOG_DEBUG, "Generate response to RS");
		arg->result[0] = '\0';
		rv = res->callbacks.command_cb(
			arg->mod_id,
			ARMS_PUSH_MD_COMMAND,
			arg->request, arg->req_len,
			arg->result, sizeof(arg->result) - 1,
			&arg->next,
			res->udata);
		arg->encoding = ARMS_DATA_TEXT;
		if (ARMS_RESULT_IS_ERROR(rv)) {
			tr_ctx->result = 102;/*exec error*/
			arg->state = ERROR_RESULT;
		} else {
			arg->state = FIRST_RESULT;
		}
		if (ARMS_RESULT_IS_BYTES(rv)) {
			if (ARMS_RV_DATA_MASK(rv) < sizeof(arg->result)) {
				arg->encoding = ARMS_DATA_BINARY;
				arg->resultlen = ARMS_RV_DATA_MASK(rv);
			} else {
				/* too big bytes.  no md-result */
				tr_ctx->result = 102;/*exec error*/
				arg->state = ERROR_RESULT;
				snprintf(arg->result, sizeof(arg->result),
					 "data length too big (%d bytes)",
					 ARMS_RV_DATA_MASK(rv));
			}
		}
		size = arms_write_begin_message(tr, buf, len);
		buf += size;
		len -= size;
		if (arg->encoding == ARMS_DATA_BINARY) {
			size += snprintf(buf, len,
				 "<md-result id=\"%d\" encoding=\"base64\">",
					 arg->mod_id);
		} else {
			size += snprintf(buf, len,
				 "<md-result id=\"%d\">", arg->mod_id);
		}
		*wrote = size;
		return TR_WANT_WRITE;
	case ERROR_RESULT:
		*wrote = strlcpy(buf, arms_escape(arg->result), len);
		arg->state = DONE;
		return TR_WANT_WRITE;
	case FIRST_RESULT:
		if (arg->encoding == ARMS_DATA_BINARY) {
			int blen;

			blen = ROUND_BASE64_BINARY(arg->resultlen);
			arg->resultlen -= blen;
			*wrote = arms_base64_encode(buf, len,
						    arg->result,
						    blen);
			memcpy(arg->result,
			       arg->result + blen, arg->resultlen);
		} else {
			*wrote = strlcpy(buf, arms_escape(arg->result), len);
			arg->resultlen = 0;
		}
		if ((arg->next & ARMS_FRAG_FINISHED) != 0)
			arg->state = DONE;
		else
			arg->state = NEXT_RESULT;
		return TR_WANT_WRITE;
	case NEXT_RESULT:
		arg->result[arg->resultlen] = '\0';
		arg->next = 0;
		rv = res->callbacks.command_cb(
			arg->mod_id,
			ARMS_PUSH_MD_COMMAND,
			NULL, 0,
			arg->result + arg->resultlen,
			sizeof(arg->result) - 1 - arg->resultlen,
			&arg->next,
			res->udata);
		if (ARMS_RESULT_IS_BYTES(rv) &&
		    ARMS_RV_DATA_MASK(rv) < sizeof(arg->result)) {
			int blen;

			/* binary */
			arg->resultlen += ARMS_RV_DATA_MASK(rv);
			blen = ROUND_BASE64_BINARY(arg->resultlen);
			arg->resultlen -= blen;
			*wrote = arms_base64_encode(buf, len,
						    arg->result,
						    blen);
			memcpy(arg->result,
			       arg->result + blen, arg->resultlen);
		} else {
			/* text */
			*wrote = strlcpy(buf, arms_escape(arg->result), len);
			arg->resultlen = 0;
		}
		if ((arg->next & ARMS_FRAG_FINISHED) != 0)
			arg->state = DONE;
		else
			arg->state = NEXT_RESULT;
		return TR_WANT_WRITE;
	case DONE:
		if (arg->resultlen > 0) {
			total = size = arms_base64_encode(buf, len,
					  arg->result, arg->resultlen);
			buf += size;
			len -= size;
		} else {
			total = 0;
		}

		size = snprintf(buf, len, "</md-result>");
		buf += size;
		len -= size;
		total += size;

		total += arms_write_end_message(tr, buf, len);
		*wrote = total;
		arg->state = END;
		return TR_WRITE_DONE;
	case END:
		return TR_WRITE_DONE;
	default:
		break;
	}
	return TR_FATAL_ERROR;
}