Esempio n. 1
0
/*
 * Copy argument
 */
static int
md_command_cparg(AXP *axp, uint32_t pm_type, int tag,
		 const char *buf, size_t len, tr_ctx_t *tr_ctx)
{
	struct md_command_args *arg = tr_ctx->arg;
	uint32_t mod_id;

	if (arg->already_running) {
		tr_ctx->result = 302;
		return 0;
	}

	switch (tag) {
		case ARMS_TAG_START_CPARG:
			break;
		case ARMS_TAG_END_CPARG:
			if (arg->mod_count < 1) {
				tr_ctx->result = 203;/*Parameter Problem*/
			}
			break;
		case ARMS_TAG_MDCOMMAND:
			if (tr_ctx->read_done)
				break;
			arg->mod_count++;
			if (arg->mod_count > 1) {
				tr_ctx->result = 422;/*Multiple Request*/
				return -1;
			}
			mod_id = get_module_id(axp, tag);
			arg->mod_id = mod_id;
			if (sizeof(arg->request) < len) {
				tr_ctx->result = 402;/*SA Failure*/
				return -1;
			}
			if (arms_get_encoding(axp, tag) == ARMS_DATA_BINARY) {
				/* decode base64 */
				len = arms_base64_decode_stream(&arg->base64,
							 arg->request,
							 sizeof(arg->request),
							 buf, len);
			} else {
				memcpy(arg->request, buf, len);
			}
			arg->req_len = len;
			break;
		default:
			break;
	}

	return 0;
}
Esempio n. 2
0
/*
 * Copy argument
 */
static int
configure_cparg(AXP *axp, uint32_t pm_type, int tag,
		const char *buf, size_t len, tr_ctx_t *tr_ctx)
{
	struct configure_args *arg = tr_ctx->arg;
	arms_context_t *res = arms_get_context();
	uint32_t mod_id;
	const char *mod_ver = NULL;
	const char *mod_loc = NULL;
	arms_config_cb_t config_cb;
	int flag, err;
	static int module_added = 0;

	if (tr_ctx->result == 302)
		return 0;

	if (arg->already_running) {
		tr_ctx->result = 302;
		return 0;
	}

	config_cb = res->callbacks.config_cb;

	switch (tag) {
	case ARMS_TAG_START_CPARG:
		module_added = 1;
		arg->first = 1;
		break;
	case ARMS_TAG_END_CPARG:
		/* call sync_module if <md-config> is not included. */
		if (module_added) {
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->result = 411;/*Commit failure*/
				return -1;
			}
			module_added = 0;
		}
		break;
	case ARMS_TAG_MODULE:
		mod_id = get_module_id(axp, tag);
		mod_ver = get_module_ver(axp, tag);
		/* add module id to 'new' */
		err = add_module(mod_id, mod_ver, buf);
		if (err < 0) {
			tr_ctx->result = 411;/*Commit failure*/
			return -1;
		}
		break;
	case ARMS_TAG_MDCONF:
		if (module_added) {
			/*
			 * move module id from 'new' to 'current'
			 */
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->result = 411;/*Commit failure*/
				return -1;
			}
			module_added = 0;
		}
		mod_id = get_module_id(axp, tag);
		if (!arms_module_is_exist(mod_id)) {
			/*
			 * <md-config> found, but <module> not found.
			 */
			tr_ctx->result = 415;/*System Error*/
			return -1;
		}
		mod_ver = lookup_module_ver(mod_id);
		mod_loc = lookup_module_location(mod_id);
		if (mod_loc == NULL)
			mod_loc = "";
		if (config_cb == NULL)
			break;
		if (arms_get_encoding(axp, tag) == ARMS_DATA_BINARY) {
			/* decode base64 */
			len = arms_base64_decode_stream(&arg->base64,
			    arg->request, sizeof(arg->request) - 1,
			    buf, len);
			arg->request[len] = '\0';
			buf = arg->request;
		}
		/*
		 * buf, len is prepared.
		 * if res->fragment == 0 and AXP_PARSE_CONTENT,
		 * buffered part of config.
		 */
		if (res->fragment == 0) {
			arg->catbuf = REALLOC(arg->catbuf, arg->catlen + len);
			if (arg->catbuf == NULL) {
				/*Resource Exhausted*/
				tr_ctx->result = 413;
				return -1;
			}
			memcpy(arg->catbuf + arg->catlen, buf, len);
			arg->catlen += len;
			if (tr_ctx->parse_state == AXP_PARSE_CONTENT) {
				/* wait for next data */
				return 0;
			}
			/* AXP_PARSE_END */
			buf = arg->catbuf;
			len = arg->catlen;
		}
		/* set fragment flag */
		flag = 0;
		if (arg->first) {
			flag |= ARMS_FRAG_FIRST;
			arg->first = 0;
		}
		/* continued' config */
		if (tr_ctx->parse_state == AXP_PARSE_CONTENT) {
			flag |= ARMS_FRAG_CONTINUE;
		}

		/* callback it */
		do {
			int slen;
			/* call config callback */
			if (res->fragment != 0 && len > res->fragment) {
				slen = res->fragment;
			} else {
				slen = len;
				/* if last fragment */
				if (tr_ctx->parse_state == AXP_PARSE_END) {
					flag |= ARMS_FRAG_FINISHED;
					/* prepare for next md-config */
					arg->first = 1;
				}
			}
			err = (*config_cb) (mod_id, mod_ver,
					    mod_loc,
					    ARMS_PUSH_STORE_CONFIG,
					    buf, slen, flag,
					    res->udata);
			if (err) {
				arg->errs++;
				tr_ctx->result = 410;
				return -1;
			}
			buf += slen;
			len -= slen;
			flag &= ~ARMS_FRAG_FIRST;
			flag |= ARMS_FRAG_CONTINUE;
		} while(len > 0);
		if (arg->catbuf != NULL) {
			/* reset for next module id */
			FREE(arg->catbuf);
			arg->catbuf = NULL;
			arg->catlen = 0;
		}
		break;
	default:
		break;
	}

	return 0;
}
Esempio n. 3
0
/* AXP Extention handler */
static int
store_tag(AXP *axp, int when, int type, int tag,
		const char *buf, size_t len, void *u)
{
	/*
	 * note: max size of encoded text via expat is 64kirobyte.
	 * decoded binary size is 3/4 of encoded text.
	 * + 2: module bytes
	 */
	static char decbuf[AXP_BUFSIZE * 3 / 4 + 2 + 1];

	tr_ctx_t *tr_ctx = u;
	rspull_context_t *ctx = tr_ctx->arg;
	arms_context_t *res = arms_get_context();
	uint32_t mod_id = 0;
	const char *mod_ver = NULL;
	const char *mod_loc = NULL;
	static int module_added = 0;
	arms_config_cb_t func;
	int flag, err = 0;

	/* Emergency stop requested */
	if (tr_ctx->read_done) {
		return 0;
	}

	if ((func = res->callbacks.config_cb) == NULL) {
		return -1;
	}

	switch (tag) {
	case ARMS_TAG_MODULE:
		if (when != AXP_PARSE_END)
			return 0;
		/* chained to new module storage */
		mod_id = get_module_id(axp, ARMS_TAG_MODULE);
		mod_ver = get_module_ver(axp, ARMS_TAG_MODULE);
		err = add_module(mod_id, mod_ver, (const char *)buf);
		if (err < 0) {
			tr_ctx->res_result = 415;/*System Error*/
			tr_ctx->read_done = 1;
			err = 0; /* not parser err */
			break;
		}
		module_added = 1;
		break;
	case ARMS_TAG_MDCONF:
		if (module_added) {
			/* module db: new -> current */
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				break;
			}
			module_added = 0;
		}
		if (when == AXP_PARSE_START) {
			ctx->data.first_fragment = 1;
			return 0;
		}

		/* chained to md-config storage */
		mod_id = get_module_id(axp, ARMS_TAG_MDCONF);
		if (!arms_module_is_exist(mod_id)) {
			/*
			 * <md-config> found, but <module> not found.
			 */
			tr_ctx->res_result = 415;/*System Error*/
			tr_ctx->read_done = 1;
			break;
		}
		mod_ver = lookup_module_ver(mod_id);
		mod_loc = lookup_module_location(mod_id);

		if (arms_get_encoding(axp, tag) == ARMS_DATA_BINARY) {
			int newlen;
			newlen = arms_base64_decode_stream(&ctx->base64,
			    decbuf, sizeof(decbuf) - 1, buf, len);
			if (newlen < 0) {
				libarms_log(ARMS_LOG_EBASE64_DECODE,
					    "base64 decode error "
					    "srclen %d, dstlen %d",
					    len, sizeof(decbuf) - 1);
				tr_ctx->res_result = 402;/*SA Failure*/
				tr_ctx->read_done = 1;
				break;
			}
			len = newlen;
			decbuf[len] = '\0';
			buf = decbuf;
		}
		/*
		 * buf, len is prepared.
		 * if res->fragment == 0 and AXP_PARSE_CONTENT,
		 * buffered part of config.
		 */
		if (res->fragment == 0) {
			ctx->catbuf = REALLOC(ctx->catbuf, ctx->catlen + len);
			if (ctx->catbuf == NULL) {
				/*Resource Exhausted*/
				tr_ctx->result = 413;
				return -1;
			}
			memcpy(ctx->catbuf + ctx->catlen, buf, len);
			ctx->catlen += len;
			if (when == AXP_PARSE_CONTENT) {
				/* wait for next data */
				return 0;
			}
			/* AXP_PARSE_END */
			buf = ctx->catbuf;
			len = ctx->catlen;
		}
		/* CONTENT or END */
		flag = 0;
		if (ctx->data.first_fragment == 1) {
			flag |= ARMS_FRAG_FIRST;
			ctx->data.first_fragment = 0;
		}
		/* continued' config */
		if (when == AXP_PARSE_CONTENT) {
			flag |= ARMS_FRAG_CONTINUE;
		}
		/* callback it */
		do {
			int slen;
			/* call config callback */
			if (res->fragment != 0 && len > res->fragment) {
				slen = res->fragment;
			} else {
				slen = len;
				/* if last fragment */
				if (when == AXP_PARSE_END)
					flag |= ARMS_FRAG_FINISHED;
			}
			err = (*func)(mod_id,
				      mod_ver,		/* version */
				      mod_loc,		/* infostring */
				      ARMS_PULL_STORE_CONFIG,
				      buf, slen, flag, res->udata);
			if (err < 0) {
				res->trigger = "invalid config";
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				err = 0; /* not parser err */
				break;
			}
			buf += slen;
			len -= slen;
			flag &= ~ARMS_FRAG_FIRST;
			flag |= ARMS_FRAG_CONTINUE;
		} while(len > 0);
		if (ctx->catbuf != NULL) {
			/* reset for next module id */
			FREE(ctx->catbuf);
			ctx->catbuf = NULL;
			ctx->catlen = 0;
		}
		break;
	case ARMS_TAG_PUSH_ADDRESS:
		if (when != AXP_PARSE_END)
			return 0;
		if (ctx->pa_index < MAX_RS_INFO) {
			res->rs_push_address[ctx->pa_index++] = STRDUP(buf);
		}
		break;
	case ARMS_TAG_PULL_SERVER_URL:
		if (when != AXP_PARSE_END)
			return 0;
		if (ctx->pu_index < MAX_RS_INFO) {
			res->rs_pull_url[ctx->pu_index++] = STRDUP(buf);
		}
		break;
	case ARMS_TAG_MSG:
		if (when != AXP_PARSE_END)
			return 0;

		if (module_added) {
			/* care no <md-config> case. */
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				break;
			}
			module_added = 0;
		}
		if (acmi_get_num_server(res->acmi, ACMI_CONFIG_CONFSOL) == ctx->pu_index) {
			res->rs_pull_1st = acmi_get_current_server(res->acmi,
								   ACMI_CONFIG_CONFSOL);
		} else {
			res->rs_pull_1st = -1;
		}
		tr_ctx->read_done = 1;
		break;
	default:
		break;
	}

	return err;
}