exp_t * exp_list(exp_t *list, exp_t *exp) { ll_t *ll; if (list->ex_type != EX_LIST) { ll = ll_create(); if (ll == NULL) { log_die(EX_SOFTWARE, "exp_list: ll_create failed"); } if (LL_INSERT(ll, list) == -1) { log_die(EX_SOFTWARE, "exp_list: LL_INSERT failed"); } list = exp_create(EX_LIST, ll); } else { ll = list->ex_data; } if (LL_INSERT(ll, exp) == -1) { log_die(EX_SOFTWARE, "exp_list: LL_INSERT failed"); } return list; }
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; }
int vlist_append(var_t *list, var_t *item) { ll_t *ll = list->v_data; if((LL_INSERT(ll, item)) == -1) { log_warning("vlist_append: LL_INSERT failed"); return -1; } return 0; }
exp_t * exp_create(exp_type_t type, void *data) { exp_t *exp; exp = (exp_t *) malloc(sizeof (exp_t)); if (exp == NULL) { log_sys_die(EX_OSERR, "exp_create: malloc"); } exp->ex_type = type; exp->ex_data = data; if (LL_INSERT(exp_garbage, exp) == -1) { log_die(EX_OSERR, "exp_create: LL_INSERT failed"); } return exp; }
msgmod_t * msgmod_create(msgmod_mod_t mod, msgmod_target_t target, ...) { msgmod_t *mm; va_list ap; exp_t *exp; mm = (msgmod_t *) malloc(sizeof (msgmod_t)); if (mm == NULL) { log_sys_die(EX_OSERR, "msgmod_create: malloc"); } mm->mm_callback = msgmod_get_callback(mod, target); if (mm->mm_callback == NULL) { acl_parser_error("syntax error (msgmod callback)"); // Not reached. return NULL; } mm->mm_args = ll_create(); if (mm->mm_args == NULL) { log_die(EX_SOFTWARE, "msgmod_create: ll_create failed"); } va_start(ap, target); while ((exp = va_arg(ap, exp_t *))) { if (LL_INSERT(mm->mm_args, exp) == -1) { log_die(EX_SOFTWARE, "msgmod_create: LL_INSERT failed"); } } return mm; }
static var_t * exp_eval_function(exp_t *exp, var_t *mailspec) { exp_function_t *ef = exp->ex_data; acl_function_t *af; var_t *args = NULL; ll_t *single = NULL; var_t *v = NULL; af = acl_function_lookup(ef->ef_name); if (af == NULL) { log_error("exp_eval_function: unknown function \"%s\"", ef->ef_name); goto error; } /* * Function has arguments */ if (ef->ef_args) { args = exp_eval(ef->ef_args, mailspec); if (args == NULL) { log_error("exp_eval_function: exp_eval failed"); goto error; } /* * Convert single argument into list. */ if (args->v_type != VT_LIST) { single = ll_create(); if (single == NULL) { log_error("exp_eval_function: ll_create failed"); goto error; } if (LL_INSERT(single, args) == -1) { log_error("exp_eval_function: LL_INSERT failed"); goto error; } } } else { /* * Function has no arguments -> empty list */ single = ll_create(); if (single == NULL) { log_error("exp_eval_function: ll_create failed"); goto error; } } if (af->af_type == AF_SIMPLE) { v = exp_eval_function_simple(ef->ef_name, af, single ? single : args->v_data); } else { v = exp_eval_function_complex(ef->ef_name, af, single ? single : args->v_data); } if (v == NULL) { log_error("exp_eval_function: function \"%s\" failed", ef->ef_name); goto error; } error: if (single) { ll_delete(single, NULL); } if (args) { exp_free(args); } return v; }
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; }
void module_load(char *file) { module_t *mod; VAR_INT_T *load; char key[256]; if (util_stripped_filename(key, sizeof key, file)) { log_die(EX_SOFTWARE, "module_load: util_stripped_filename failed"); } load = (VAR_INT_T *) cf_get_value(VT_INT, "modules", key, NULL); if (load != NULL) { if (!*load) { log_debug("module_glob: %s disabled in config", file); return; } } log_debug("module_glob: load %s", file); mod = (module_t *) malloc(sizeof (module_t)); if (mod == NULL) { log_sys_die(EX_SOFTWARE, "module_load: malloc"); } mod->mod_path = strdup(file); mod->mod_name = strrchr(mod->mod_path, '/') + 1; /* * Open module */ mod->mod_handle = dlopen(file, RTLD_LAZY); if (mod->mod_handle == NULL) { log_sys_die(EX_SOFTWARE, "module_load: dlopen: %s", dlerror()); } /* * Load Symbols */ mod->mod_init = module_symbol_load(mod->mod_handle, file, "init", 1); mod->mod_fini = module_symbol_load(mod->mod_handle, file, "fini", 0); /* * Initialize module */ if (mod->mod_init()) { log_die(EX_SOFTWARE, "module_load: %s: init failed", mod->mod_name); } if (LL_INSERT(module_list, mod) == -1) { log_die(EX_SOFTWARE, "module_load: LL_INSERT failed"); } return; }