コード例 #1
0
ファイル: vlist.c プロジェクト: badzong/mopher
int
vlist_dereference(var_t *list, ...)
{
	va_list ap;
	var_t *v;
	void **p;
	ll_t *ll;
	ll_entry_t *pos;

	va_start(ap, list);

	ll = list->v_data;
	pos = LL_START(ll);

	while ((v = ll_next(ll, &pos)))
	{
		p = va_arg(ap, void **);

		/*
		 * Skip NULL Pointers.
		 */
		if (p == NULL) {
			continue;
		}

		*p = v->v_data;
	}

	va_end(ap);

	return 0;
}
コード例 #2
0
ファイル: vlist.c プロジェクト: badzong/mopher
var_t *
vlist_record_from_table(var_t *scheme, var_t *table)
{
	var_t *record = NULL, *vs, *vt;
	ll_t *ll;
	ll_entry_t *pos;
	void *data;
	var_type_t type;
	char *name;

	record = vlist_create(scheme->v_name, VF_KEEPNAME);
	if (record == NULL)
	{
		log_warning("vlist_record: vlist_create failed");
		return NULL;
	}

	ll = scheme->v_data;
	pos = LL_START(ll);

	while ((vs = ll_next(ll, &pos)))
	{
		name = vs->v_name;
		vt = vtable_lookup(table, name);

		if (vt == NULL && vs->v_flags & VF_KEY)
		{
			log_error("vlist_record_from_table: \"%s\" is missing "
				"in vtable and declared as key", name);
			goto error;
		}


		data = vt == NULL ? NULL : vt->v_data;
		type = vt == NULL ? VT_NULL : vt->v_type;

		if (vlist_append_new(record, type, name, data,
			VF_COPY | vs->v_flags) == -1)
		{
			log_warning("vlist_record_from_table: vlist_append_new"
				" failed");
			goto error;
		}
	}

	return record;

error:
	if(record)
	{
		var_delete(record);
	}
	return NULL;
}
コード例 #3
0
ファイル: cf.c プロジェクト: badzong/mopher
int
cf_load_list(ll_t *list, char *key, var_type_t type)
{
	var_t *v, *item;
	ll_entry_t *pos;

	v = vtable_lookup(cf_config, key);
	if (v == NULL)
	{
		log_error("cf_load_list: %s not found", key);
		return -1;
	}

	// Scalar
	if (v->v_type == type)
	{
		if (LL_INSERT(list, v->v_data) == -1)
		{
			log_error("cf_load_list: LL_INSERT failed");
			return -1;
		}
		return 0;
	}

	// Unexpected type
	if (v->v_type != VT_LIST)
	{
		log_error("config error: unexpected value for %s", key);
		return -1;
	}

	pos = LL_START((ll_t *) v->v_data);
	while ((item = ll_next(v->v_data, &pos)))
	{
		if (item->v_type != type)
		{
			log_error("config error: unexpected value in %s", key);
			return -1;
		}

		if (LL_INSERT(list, item->v_data) == -1)
		{
			log_error("cf_load_list: LL_INSERT failed");
			return -1;
		}
	}

	return 0;
}
コード例 #4
0
ファイル: vlist.c プロジェクト: badzong/mopher
var_t *
vlist_record(var_t *scheme, ...)
{
	va_list ap;
	var_t *record = NULL, *v;
	int flags;
	void *data;
	ll_t *ll;
	ll_entry_t *pos;

	va_start(ap, scheme);

	record = vlist_create(scheme->v_name, VF_KEEPNAME);
	if (record == NULL)
	{
		log_warning("vlist_record: vlist_create failed");
		return NULL;
	}

	ll = scheme->v_data;
	pos = LL_START(ll);

	while ((v = ll_next(ll, &pos)))
	{
		flags = v->v_flags;
		flags |= VF_KEEPDATA | VF_KEEPNAME;
		flags &= ~(VF_COPYNAME | VF_COPYDATA);

		data = va_arg(ap, void *);

		if (vlist_append_new(record, v->v_type, v->v_name, data, flags)
		    == -1)
		{
			log_warning("vlist_record: vlist_append_new failed");

			var_delete(record);
			return NULL;
		}
	}

	va_end(ap);

	return record;
}
コード例 #5
0
var_t *
exp_eval_in(var_t *needle, var_t *haystack)
{
	var_t *v;
	ll_t *list;
	ll_entry_t *pos;
	int cmp;

	if (needle == NULL || haystack == NULL)
	{
		return EXP_EMPTY;
	}

	if (needle->v_data == NULL || haystack->v_data == NULL)
	{
		log_debug("exp_eval_in: empty value");
		return EXP_EMPTY;
	}

	if (haystack->v_type != VT_LIST)
	{
		log_error("exp_eval_in: in operator only works on lists");
		return NULL;
	}

	list = haystack->v_data;
	pos = LL_START(list);
	while ((v = ll_next(list, &pos)))
	{
		if (var_compare(&cmp, needle, v))
		{
			log_error("exp_eval_in: var_compare failed");
		}

		if (cmp == 0)
		{
			return EXP_TRUE;
		}
	}

	return EXP_FALSE;
}
コード例 #6
0
ファイル: vlist.c プロジェクト: badzong/mopher
var_t *
vlist_record_lookup(var_t *record, char *key)
{
	ll_t *list = record->v_data;
	ll_entry_t *pos;
	var_t *item;

	/*
	 * Bad search: but records usually only have less than 10 values.
	 */
	pos = LL_START(list);
	while ((item = ll_next(list, &pos)))
	{
		if (strcmp(item->v_name, key) == 0)
		{
			return item;
		}
	}

	return NULL;
}
コード例 #7
0
static var_t *
exp_eval_list(exp_t *exp, var_t *mailspec)
{
	ll_t *exp_list = exp->ex_data;
	ll_entry_t *pos;
	exp_t *exp_item;
	var_t *var_item, *var_list = NULL;

	var_list = vlist_create(NULL, VF_EXP_FREE);
	if (var_list == NULL)
	{
		log_sys_error("exp_eval_list: malloc");
		goto error;
	}

	pos = LL_START(exp_list);
	while ((exp_item = ll_next(exp_list, &pos)))
	{
		var_item = exp_eval(exp_item, mailspec);

		if (vlist_append(var_list, var_item))
		{
			log_sys_error("exp_eval_list: malloc");
			goto error;
		}
	}

	return var_list;


error:

	if (var_list)
	{
		var_delete(var_list);
	}

	return NULL;
}
コード例 #8
0
ファイル: vlist.c プロジェクト: badzong/mopher
int
vlist_record_keys_missing(var_t *record, var_t *table)
{
	ll_t *list = record->v_data;
	ll_entry_t *pos;
	var_t *item;

	pos = LL_START(list);
	while ((item = ll_next(list, &pos)))
	{
		if ((item->v_flags & VF_KEY) == 0)
		{
			continue;
		}

		if (vtable_lookup(table, item->v_name) == NULL)
		{
			return -1;
		}
	}

	return 0;
}
コード例 #9
0
static var_t *
exp_eval_function_simple(char *name, acl_function_t *af, ll_t *args)
{
	ll_t garbage;
	ll_entry_t *pos;
	void **argv = NULL;
	var_t *v = NULL;
	int argc;
	int size;
	int i;
	var_t *arg;

	/*
	 * Initialize garbage
	 */
	ll_init(&garbage);

	/*
	 * Check argc
	 */
	argc = args->ll_size;
	if (argc != af->af_argc)
	{
		log_error("exp_eval_function_simple: function \"%s\" requires "
		    "%d arguments", name, af->af_argc);
		return NULL;
	}

	size = (argc + 1) * sizeof (void *);

	argv = (void **) malloc(size);
	if (argv == NULL)
	{
		log_sys_error("exp_eval_function_simple: malloc");
		return NULL;
	}

	memset(argv, 0, size);

	/*
	 * Prepare argv
	 */
	pos = LL_START(args);
	for (i = 0; (arg = ll_next(args, &pos)); ++i)
	{
		if (af->af_types[i] == arg->v_type)
		{
			argv[i] = arg->v_data;
			continue;
		}

		/*
		 * Type casting required. Don't care about the remains of arg
		 * (freed with args!).
		 */
		arg = var_cast_copy(af->af_types[i], arg);
		if (arg == NULL)
		{
			log_error("exp_eval_function_simple: var_cast_copy "
			    "failed");

			goto error;
		}

		/*
		 * Need to free copy later
		 */
		if (LL_INSERT(&garbage, arg) == -1)
		{
			log_error("exp_eval_function_simlpe: LL_INSERT "
			    "failed");

			var_delete(arg);
			goto error;
		}

		argv[i] = arg->v_data;
	}

	v = af->af_callback.fc_simple(argc, argv);


error:
	ll_clear(&garbage, (ll_delete_t) var_delete);

	if (argv)
	{
		free(argv);
	}

	return v;
}
コード例 #10
0
ファイル: hitlist.c プロジェクト: badzong/mopher
static var_t *
hitlist_record(hitlist_t *hl, var_t *attrs, int load_data)
{
	ll_entry_t *pos;
	var_t *key;
	char *keystr;
	var_t *v;
	var_t *schema = NULL;
	VAR_INT_T zero = 0;
	char *name;

	name = hl->hl_table? hl->hl_table: hl->hl_name;

	schema = vlist_create(name, VF_KEEPNAME);
	if (schema == NULL)
	{
		log_error("hitlist_schema: vlist_create failed");
		goto error;
	}

	pos = LL_START(hl->hl_keys);
	while ((key = ll_next(hl->hl_keys, &pos)))
	{
		// Impossible
		if (key->v_data == NULL)
		{
			log_error("hitlist_schema: key is NULL");
			goto error;
		}

		// Bad configured
		if (key->v_type != VT_STRING)
		{
			log_error("hitlist_scheme: bad configuration %s:"
				" hitlist keys must be strings.", hl->hl_name);
			goto error;
		}

		keystr = key->v_data;

		// Variables
		if (keystr[0] == '$')
		{
			v = acl_variable_get(attrs, keystr);
		}

		// Regular symbol
		else
		{
			v = acl_symbol_get(attrs, keystr);
		}

		if (v == NULL)
		{
			log_error("hitlist_scheme: %s: lookup %s failed",
				hl->hl_name, keystr);
			goto error;
		}

		if (load_data && v->v_data == NULL)
		{
			log_error("hitlist_scheme: %s: key %s is NULL",
				hl->hl_name, keystr);
			goto error;
		}

		if (vlist_append_new(schema, v->v_type, keystr,
			load_data? v->v_data: NULL, VF_COPY | VF_KEY))
		{
			log_error("hitlist_schema: %s: vlist_append_new"
				" failed", hl->hl_name);
			goto error;
		}
	}

	// Add value
	if (vlist_append_new(schema, VT_INT, hl->hl_value_field,
	    load_data? &zero: NULL, VF_COPY))
	{
		log_error("hitlist_schema: %s: vlist_append_new failed for %s",
			hl->hl_name, hl->hl_value_field);
		goto error;
	}

	if (vlist_append_new(schema, VT_INT, hl->hl_expire_field,
	    load_data? &zero: NULL, VF_COPY))
	{
		log_error("hitlist_schema: %s: vlist_append_new failed for %s",
			hl->hl_name, hl->hl_expire_field);
		goto error;
	}

	return schema;

error:
	if (schema != NULL)
	{
		var_delete(schema);
	}

	return NULL;
}
コード例 #11
0
ファイル: msgmod.c プロジェクト: badzong/mopher
acl_action_type_t
msgmod(milter_stage_t stage, char *stagename, var_t *mailspec, void *data,
	int depth)
{
	msgmod_t *mm = data;
	void *ctx;
	acl_action_type_t action = ACL_ERROR;
	var_t **args = NULL;
	int argc;
	int size;
	var_t *v, *copy;
	int i;
	exp_t *exp;
	ll_t *ll;
	ll_entry_t *pos;

	/*
	 * Get milter ctx pointer
	 */
	ctx = vtable_get(mailspec, "milter_ctx");
	if (ctx == NULL)
	{
		log_error("msgmod: ctx not set");
		goto error;
	}

	/*
	 * Evaluate arguments
	 */
	argc = mm->mm_args->ll_size;
	size = (argc + 1) * sizeof (var_t *);

	args = (var_t **) malloc(size);
	if (args == NULL)
	{
		log_sys_error("msgmod: malloc");
		goto error;
	}

	memset(args, 0, size);

	ll = mm->mm_args;
	pos = LL_START(ll);

	for (i = 0; i < argc; ++i)
	{
		exp = ll_next(ll, &pos);
		if (exp == NULL)
		{
			log_die(EX_SOFTWARE, "msgmod: empty argument");
		}

		v = exp_eval(exp, mailspec);
		if (v == NULL)
		{
			log_error("msgmod: exp_eval failed");
			goto error;
		}

		// Cast all aruments to VT_STRING
		if (v->v_type != VT_STRING)
		{
			copy = var_cast_copy(VT_STRING, v);
			if (copy == NULL)
			{
				log_error("msgmod: var_cast_copy failed");
				goto error;
			}

			exp_free(v);

			/*
			 * args are freed using exp_free. Set VF_EXP_FREE to
			 * free copy.
			 */
			copy->v_flags |= VF_EXP_FREE;
			
			v = copy;
		}
		
		args[i] = v;
	}

	if (mm->mm_callback(ctx, argc, args))
	{
		log_error("msgmod: mm_callback failed");
		goto error;
	}

	action = ACL_NONE;

error:

	/*
	 * Free args
	 */
	for (i = 0; args[i]; ++i)
	{
		exp_free(args[i]);
	}

	if (args)
	{
		free(args);
	}

	return action;
}