Exemple #1
0
int
arms_dump_state(arms_context_t *res, char *state, size_t size)
{
	struct arms_dumped_state *newstate;
	MD5_CTX md5ctx;
	int i;

	/* check size */
	if (size < arms_size_of_state())
		return ARMS_ESIZE;

	newstate = CALLOC(1, sizeof(struct arms_dumped_state));
	if (newstate == NULL)
		return ARMS_EFATAL;

	/* create new state array */
	memset(newstate, 0, sizeof(*newstate));
	newstate->state_version = ARMS_STATE_VERSION;
	DUMP(rs_endpoint);
	DUMP(rs_preshared_key);
	/* acmi (RS list) */
	for (i = 0; i < 5; i++) {
		char *cert;

		acmi_get_url_idx(res->acmi, ACMI_CONFIG_CONFSOL,
				 newstate->rsinfo[i].url,
				 URL_MAX_LEN + 1, i);
		cert = acmi_get_cert_idx(res->acmi, ACMI_CONFIG_CONFSOL, i);
		if ((cert != NULL) && (strlen(cert) < sizeof(newstate->rsinfo[i].cert)) ) {
			strncpy(newstate->rsinfo[i].cert, cert, sizeof(newstate->rsinfo[i].cert));
		}
	}
	newstate->current_server = acmi_get_current_server(res->acmi,
						ACMI_CONFIG_CONFSOL);
	newstate->retry_max = acmi_get_rmax(res->acmi,
						 ACMI_CONFIG_CONFSOL);
	newstate->retry_int = acmi_get_rint(res->acmi,
						 ACMI_CONFIG_CONFSOL);
	newstate->lltimeout = acmi_get_lltimeout(res->acmi,
						 ACMI_CONFIG_CONFSOL);
	newstate->result = res->result;

	newstate->num_line = 
		acmi_get_lines(res->acmi, ACMI_CONFIG_CONFSOL,
			       newstate->line_defs);
	newstate->last_line = res->last_line;
#if 0
	/* compare with previus state array */
	if (!memcmp(&newstate, state, sizeof(*newstate)))
		return ARMS_ENOCHANGE;
#endif
	MD5_Init(&md5ctx);
	MD5_Update(&md5ctx, newstate,
		  sizeof(*newstate) - sizeof(newstate->digest));
	MD5_Final(newstate->digest, &md5ctx);

	/* copy new array to specified address */
	memcpy(state, newstate, sizeof(*newstate));
	FREE(newstate);

	return 0;
}
Exemple #2
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;
}