/* * 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; }
/* * 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; } }
/* * 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; }