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; }
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; }
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; }
void * vtable_get(var_t *table, char *name) { var_t *v; if((v = vtable_lookup(table, name)) == NULL) { return NULL; } return v->v_data; }
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; }
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; }
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; }
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; }
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; }
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; }
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);