示例#1
0
文件: cf.c 项目: badzong/mopher
static void
cf_load_symbols(void)
{
	cf_symbol_t *symbol;
	var_t *v;

	for(symbol = cf_symbols; symbol->cs_name; ++symbol) {

		v = vtable_lookup(cf_config, symbol->cs_name);
		if(v == NULL) {
			continue;
		}

		switch(v->v_type) {
		case VT_INT:
			*(VAR_INT_T *) symbol->cs_ptr =
				*(VAR_INT_T *) v->v_data;
			 break;

		case VT_FLOAT:
			*(VAR_FLOAT_T *) symbol->cs_ptr =
				*(VAR_FLOAT_T *) v->v_data;
			 break;

		case VT_STRING:
			*((char **) symbol->cs_ptr) = (char *) v->v_data;
			break;

		default:
			log_die(EX_CONFIG, "cf_symbols_load: bad type");
		}
	}

	return;
}
示例#2
0
文件: cf.c 项目: badzong/mopher
void
cf_set_keylist(var_t *table, ll_t *keys, var_t *v)
{
	char *key;
	var_t *sub;

	if (table == NULL) {
		table = cf_config;
	}

	/*
	 * Last key queued belongs to var_t *v itself.
	 */
	key = LL_DEQUEUE(keys);
	if(keys->ll_size == 0) {

		/*
		 * keys is created in cf_yacc.y and no longer needed.
		 */
		ll_delete(keys, NULL);

		if(v->v_name == NULL) {
			v->v_name = key;
		}

		if(vtable_set(table, v) == -1) {
			log_die(EX_CONFIG, "cf_set: vtable_set failed");
		}

		return;
	}

	if((sub = vtable_lookup(table, key))) {
		cf_set_keylist(sub, keys, v);

		/*
		 * key is strdupd in cf_yacc.y and no longer needed.
		 */
		free(key);

		return;
	}

	if ((sub = vtable_create(key, 0)) == NULL) {
		log_die(EX_CONFIG, "cf_setr: vtable_create failed");
	}

	if(vtable_set(table, sub) == -1) {
		log_die(EX_CONFIG, "cf_set: vtable_set failed");
	}

	cf_set_keylist(sub, keys, v);

	return;
}
示例#3
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;
}
示例#4
0
文件: vtable.c 项目: badzong/mopher
void *
vtable_get(var_t *table, char *name)
{
	var_t *v;

	if((v = vtable_lookup(table, name)) == NULL)
	{
		return NULL;
	}

	return v->v_data;
}
示例#5
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;
}
示例#6
0
static var_t *
exp_isset(var_t *mailspec, exp_t *exp)
{
	if (exp->ex_type != EX_SYMBOL)
	{
		log_error("exp_isset: bad type");
		return NULL;
	}

	if (vtable_lookup(mailspec, exp->ex_data))
	{
		return EXP_TRUE;
	}

	return EXP_FALSE;
}
示例#7
0
文件: vtable.c 项目: badzong/mopher
void
vtable_remove(var_t *table, char *name)
{
	ht_t *ht = table->v_data;
	var_t *v;

	v = vtable_lookup(table, name);
	if (v == NULL)
	{
		log_debug("vtable_remove: \"%s\" not found", name);
		return;
	}

	ht_remove(ht, v);

	return;
}
示例#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
文件: vtable.c 项目: badzong/mopher
var_t *
vtable_getva(var_type_t type, var_t *table, va_list ap)
{
	char *key;
	var_t *v = table;

	for(;;) {
		key = va_arg(ap, char *);

		if (key == NULL)
		{
			break;
		}

		if (v->v_type != VT_TABLE)
		{
			log_info("vtable_getva: \"%s\" not a table", key);
			return NULL;
		}

		v = vtable_lookup(v, key);
		if (v == NULL)
		{
			log_debug("vtable_getva: no data for \"%s\"", key);
			return NULL;
		}
	}

	if (v->v_type != type)
	{
		log_warning("vtable_getva: type mismatch for \"%s\"", key);
		return NULL;
	}

	return v;
}
示例#10
0
文件: hitlist.c 项目: badzong/mopher
static int
hitlist_lookup(milter_stage_t stage, char *name, var_t *attrs)
{
	hitlist_t *hl;
	var_t *lookup = NULL;
	var_t *record = NULL;
	VAR_INT_T *value;
	VAR_INT_T *expire;
	var_t *addition;
	int success = -1;

	// Used for SQL_SAFE_UPDATE
	VAR_INT_T value_diff = 0;
	VAR_INT_T expire_diff = 0;
	int update_record = 0;

	hl = sht_lookup(hitlists, name);
	if (hl == NULL)
	{
		log_error("Unknown hitlist: %s", name);
		goto exit;
	}

	// If the DB is not open yet, there's a race on hl->hl_connected.
	if (pthread_mutex_lock(&hl->hl_mutex))
	{
		log_sys_error("hitlist_db_open: pthread_mutex_lock");
		goto exit;
	}

	// Open Database
	if (!hl->hl_connected)
	{
		if (hitlist_db_open(hl, attrs))
		{
			log_error("hitlist_lookup: hitlist_db_open failed");
			goto exit;
		}
	}

	// Create lookup record
	lookup = hitlist_record(hl, attrs, 1);
	if (lookup == NULL)
	{
		// Happens if a key is not set or NULL
		log_error("hitlist_lookup: hitlist_record failed");
		vtable_set_null(attrs, name, VF_COPYNAME);

		// Failing would lead to acl termination
		success = 0;
		goto exit;
	}

	if (dbt_db_get(&hl->hl_dbt, lookup, &record))
	{
		log_error("hitlist_lookup: dbt_db_get failed");
		goto exit;
	}

	if (record == NULL)
	{
		// Add new record
		if (hl->hl_create)
		{
			log_debug("hitlist_lookup: %s add record", name);
			record = lookup;
			lookup = NULL;
		}
		// No record found, set symbol to null
		else
		{
			vtable_set_null(attrs, name, VF_COPYNAME);
			log_debug("hitlist_lookup: %s no record", name);
			success = 0;
			goto exit;
		}
	}
	else
	{
		update_record = 1;
		log_debug("hitlist_lookup: %s record found", name);
	}

	value = vlist_record_get(record, hl->hl_value_field);
	expire = vlist_record_get(record, hl->hl_expire_field);
	if (value == NULL || expire == NULL)
	{
		log_error("hitlist_lookup: vlist_record_get failed");
		goto exit;
	}

	// Count
       	if (hl->hl_count)
       	{
		++(*value);
		value_diff = 1;
       	}

	// Sum
        else if (hl->hl_sum)
        {
		addition = vtable_lookup(attrs, hl->hl_sum);
		if (addition == NULL)
		{
			log_error("hitlist: sum field %s is undefined", hl->hl_sum);
			goto exit;
		}

		if (addition->v_type != VT_INT)
		{
			log_error("hitlist: sum field %s must be integer", hl->hl_sum);
			goto exit;
		}

		*value += *(VAR_INT_T *) addition->v_data;
		value_diff = *(VAR_INT_T *) addition->v_data;
        }

        if (hl->hl_update)
        {

		// Record never expires
		if (hl->hl_timeout == 0)
		{
			*expire = INT_MAX;
			expire_diff = 0;
		}
		// Record is extended every time a match is found
		else if (hl->hl_extend)
		{
			*expire = time(NULL) + hl->hl_timeout;
			expire_diff = hl->hl_timeout;
		}
		// Record expires after a fixed timeout
		else if (hl->hl_timeout && *expire == 0)
		{
			*expire = time(NULL) + hl->hl_timeout;
			expire_diff = hl->hl_timeout;
		}

		// SQL_SAFE_UPDATE
		if(update_record && hl->hl_dbt.dbt_driver->dd_use_sql)
		{
			if (hitlist_sql_safe_update(hl, record, hl->hl_value_field, value_diff,
				hl->hl_expire_field, expire_diff))
			{
				log_error("hitlist_lookup: hitlist_sql_safe_update failed");
				goto exit;
			}
		}
		else
		{
			if (dbt_db_set(&hl->hl_dbt, record))
			{
				log_error("hitlist_lookup: dbt_db_set failed");
				goto exit;
			}
		}
        }

	// Add symbol
	if (vtable_set_new(attrs, VT_INT, name, value, VF_COPY))
	{
		log_error("hitlist_lookup: vtable_set_new failed");

		goto exit;
	}

	success = 0;

exit:
	if (lookup != NULL)
	{
		var_delete(lookup);
	}

	if (record != NULL)
	{
		var_delete(record);
	}

	if (pthread_mutex_unlock(&hl->hl_mutex))
	{
		log_sys_error("hitlist_db_open: pthread_mutex_unlock");
	}

	return success;
}
示例#11
0
文件: vtable.c 项目: badzong/mopher
			log_warning("vtable_setv: vtable_set_new failed");
			return -1;
		}
	}

	return 0;
}


int
vtable_rename(var_t *table, char *old, char *new)
{
	var_t *record;
	ht_t *ht = table->v_data;

	record = vtable_lookup(table, old);
	if (record == NULL)
	{
		log_debug("vtable_rename: \"%s\" not in table", old);
		return -1;
	}

	if (vtable_set_new(table, record->v_type, new, record->v_data,
	    VF_COPY))
	{
		log_error("vtable_rename: vtable_set_new failed");
		return -1;
	}

	ht_remove(ht, record);