static int server_exec_cmd(int sock, char *cmd) { int argc = 0; char *argv[MAXARGS]; char *save, *p, *nil; server_function_t *sf; int r; log_debug("server_exec_cmd: %s", cmd); for (nil = cmd; (p = strtok_r(nil, " ", &save)) && argc < MAXARGS; nil = NULL, ++argc) { argv[argc] = p; } if (argc == MAXARGS) { server_reply(sock, "Too many arguments"); log_error("server_exec_cmd: Too many arguments"); return -1; } sf = sht_lookup(&server_function_table, argv[0]); if (sf == NULL) { sf = sht_lookup(&server_function_table, "help"); if (sf == NULL) { log_die(EX_SOFTWARE, "server_exec_cmd: help not found. This is impossible hence fatal."); } } r = sf->sf_callback(sock, argc, argv); switch (r) { case 0: server_reply(sock, "CLOSE"); break; case -1: log_error("server_exec_cmd: %s failed", argv[0]); server_reply(sock, "ERROR"); break; default: server_ok(sock); break; } return r; }
exp_t * exp_symbol(char *symbol) { exp_t *exp; /* * Check definitions */ exp = sht_lookup(exp_defs, symbol); if (exp) { free(symbol); return exp; } /* * Check symbols */ if (acl_symbol_lookup(symbol) == NULL) { acl_parser_error("unknown symbol \"%s\"", symbol); } return exp_create(EX_SYMBOL, symbol); }
void watchdog(var_t *table, char *stage) { watchdog_t *wd; char *id; if (pthread_mutex_lock(&watchdog_mutex)) { log_sys_error("watchdog: pthread_mutex_lock"); return; } watchdog_init(); // In init id is not set. No problem. id = vtable_get(table, "id"); if (id == NULL) { goto exit; } // Record does not exist wd = sht_lookup(&watchdog_table, id); if (wd == NULL) { wd = watchdog_create(id, stage); if (wd == NULL) { log_error("watchdog: watchdog_create failed"); goto exit; } if (sht_insert(&watchdog_table, id, wd)) { log_error("watchdog: sht_insert failed"); goto exit; } } else { wd->wd_stage = stage; wd->wd_instage = time(NULL); } exit: if (pthread_mutex_unlock(&watchdog_mutex)) { log_sys_error("watchdog: pthread_mutex_unlock"); } return; }
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; }