예제 #1
0
파일: worker.c 프로젝트: formorer/nagios
int send_kvvec(int sd, struct kvvec *kvv)
{
	int ret;
	struct kvvec_buf *kvvb;

	/*
	 * key=value, separated by nul bytes and two nul's
	 * delimit one message from another. We need to cut
	 * one from MSG_DELIM_LEN here though, since nul is
	 * added unconditionally after each value as well
	 * and we'd otherwise run into an off-by-one when
	 * parsing the messages back into sensible order.
	 */
	kvvb = kvvec2buf(kvv, KV_SEP, PAIR_SEP, MSG_DELIM_LEN_SEND);
	if (!kvvb) {
		/*
		 * XXX: do *something* sensible here to let the
		 * master know we failed, although the most likely
		 * reason is OOM, in which case the OOM-slayer will
		 * probably kill us sooner or later.
		 */
		return 0;
	}

	/* use bufsize here, as it gets us the nul string delimiter */
	ret = write(sd, kvvb->buf, kvvb->bufsize);
	free(kvvb->buf);
	free(kvvb);
	return ret;
}
예제 #2
0
파일: workers.c 프로젝트: caidui/nagios4-cn
/*
 * Handles adding the command and macros to the kvvec,
 * as well as shipping the command off to a designated
 * worker
 */
static int wproc_run_job(struct wproc_job *job, nagios_macros *mac)
{
	static struct kvvec kvv = KVVEC_INITIALIZER;
	struct kvvec_buf *kvvb;
	struct kvvec *env_kvvp = NULL;
	struct kvvec_buf *env_kvvb = NULL;
	struct wproc_worker *wp;
	int ret, result = OK;

	if (!job || !job->wp)
		return ERROR;

	wp = job->wp;

	if (!kvvec_init(&kvv, 4))	/* job_id, type, command and timeout */
		return ERROR;

	kvvec_addkv(&kvv, "job_id", (char *)mkstr("%d", job->id));
	kvvec_addkv(&kvv, "type", (char *)mkstr("%d", job->type));
	kvvec_addkv(&kvv, "command", job->command);
	kvvec_addkv(&kvv, "timeout", (char *)mkstr("%u", job->timeout));

	/* Add the macro environment variables */
	if(mac) {
		env_kvvp = macros_to_kvv(mac);
		if(NULL != env_kvvp) {
			env_kvvb = kvvec2buf(env_kvvp, '=', '\n', 0);
			if(NULL == env_kvvb) {
				kvvec_destroy(env_kvvp, KVVEC_FREE_KEYS);
			}
			else {
				kvvec_addkv_wlen(&kvv, "env", strlen("env"), env_kvvb->buf,
						env_kvvb->buflen);
			}
		}
	}
	kvvb = build_kvvec_buf(&kvv);
	ret = write(wp->sd, kvvb->buf, kvvb->bufsize);
	if (ret != (int)kvvb->bufsize) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: '%s' seems to be choked. ret = %d; bufsize = %lu: errno = %d (%s)\n",
			  wp->name, ret, kvvb->bufsize, errno, strerror(errno));
		destroy_job(job);
		result = ERROR;
	} else {
		wp->jobs_running++;
		wp->jobs_started++;
		loadctl.jobs_running++;
	}
	if(NULL != env_kvvp) kvvec_destroy(env_kvvp, KVVEC_FREE_KEYS);
	if(NULL != env_kvvb) {
		free(env_kvvb->buf);
		free(env_kvvb);
	}
	free(kvvb->buf);
	free(kvvb);

	return result;
}
예제 #3
0
파일: worker.c 프로젝트: ageric/nagios
struct kvvec_buf *build_kvvec_buf(struct kvvec *kvv)
{
	struct kvvec_buf *kvvb;

	/*
	 * key=value, separated by PAIR_SEP and messages
	 * delimited by MSG_DELIM
	 */
	kvvb = kvvec2buf(kvv, KV_SEP, PAIR_SEP, MSG_DELIM_LEN);
	if (!kvvb) {
		return NULL;
	}
	memcpy(kvvb->buf + (kvvb->bufsize - MSG_DELIM_LEN), MSG_DELIM, MSG_DELIM_LEN);

	return kvvb;
}
예제 #4
0
int main(int argc, char **argv)
{
	int i, j;
	struct kvvec *kvv, *kvv2, *kvv3;
	struct kvvec_buf *kvvb, *kvvb2;
	struct kvvec k = KVVEC_INITIALIZER;

	t_set_colors(0);

	t_start("key/value vector tests");
	kvv = kvvec_create(1);
	kvv2 = kvvec_create(1);
	kvv3 = kvvec_create(1);
	add_vars(kvv, test_data, 1239819);
	add_vars(kvv, (const char **)argv + 1, argc - 1);

	kvvec_sort(kvv);
	kvvec_foreach(kvv, NULL, walker);

	/* kvvec2buf -> buf2kvvec -> kvvec2buf -> buf2kvvec conversion */
	kvvb = kvvec2buf(kvv, KVSEP, PAIRSEP, OVERALLOC);
	kvv3 = buf2kvvec(kvvb->buf, kvvb->buflen, KVSEP, PAIRSEP, KVVEC_COPY);
	kvvb2 = kvvec2buf(kvv3, KVSEP, PAIRSEP, OVERALLOC);

	buf2kvvec_prealloc(kvv2, kvvb->buf, kvvb->buflen, KVSEP, PAIRSEP, KVVEC_ASSIGN);
	kvvec_foreach(kvv2, kvv, walker);

	kvvb = kvvec2buf(kvv, KVSEP, PAIRSEP, OVERALLOC);

	test(kvv->kv_pairs == kvv2->kv_pairs, "pairs should be identical");

	for (i = 0; i < kvv->kv_pairs; i++) {
		struct key_value *kv1, *kv2;
		kv1 = &kvv->kv[i];
		if (i >= kvv2->kv_pairs) {
			t_fail("missing var %d in kvv2", i);
			printf("[%s=%s] (%d+%d)\n", kv1->key, kv1->value, kv1->key_len, kv1->value_len);
			continue;
		}
		kv2 = &kvv2->kv[i];
		if (!test(!kv_compare(kv1, kv2), "kv pair %d must match", i)) {
			printf("%d failed: [%s=%s] (%d+%d) != [%s=%s (%d+%d)]\n",
				   i,
				   kv1->key, kv1->value, kv1->key_len, kv1->value_len,
				   kv2->key, kv2->value, kv2->key_len, kv2->value_len);
		}
	}

	test(kvvb2->buflen == kvvb->buflen, "buflens must match");
	test(kvvb2->bufsize == kvvb->bufsize, "bufsizes must match");

	if (kvvb2->buflen == kvvb->buflen && kvvb2->bufsize == kvvb->bufsize &&
		!memcmp(kvvb2->buf, kvvb->buf, kvvb->bufsize))
	{
		t_pass("kvvec -> buf -> kvvec conversion works flawlessly");
	} else {
		t_fail("kvvec -> buf -> kvvec conversion failed :'(");
	}

	free(kvvb->buf);
	free(kvvb);
	free(kvvb2->buf);
	free(kvvb2);
	kvvec_destroy(kvv, 1);
	kvvec_destroy(kvv3, KVVEC_FREE_ALL);

	for (j = 0; pair_term_missing[j]; j++) {
		buf2kvvec_prealloc(&k, strdup(pair_term_missing[j]), strlen(pair_term_missing[j]), '=', ';', KVVEC_COPY);
		for (i = 0; i < k.kv_pairs; i++) {
			struct key_value *kv = &k.kv[i];
			test(kv->key_len == kv->value_len, "%d.%d; key_len=%d; value_len=%d (%s = %s)",
				 j, i, kv->key_len, kv->value_len, kv->key, kv->value);
			test(kv->value_len == strlen(kv->value),
				 "%d.%d; kv->value_len(%d) == strlen(%s)(%d)",
				 j, i, kv->value_len, kv->value, (int)strlen(kv->value));
		}
	}

	t_end();
	return 0;
}