ARGV *dict_mapnames() { HTABLE_INFO **ht_info; HTABLE_INFO **ht; DICT_OPEN_INFO *dp; ARGV *mapnames; #ifndef NO_DYNAMIC_MAPS DLINFO *dlp; #endif if (dict_open_hash == 0) dict_open_init(); mapnames = argv_alloc(dict_open_hash->used + 1); for (ht_info = ht = htable_list(dict_open_hash); *ht; ht++) { dp = (DICT_OPEN_INFO *) ht[0]->value; argv_add(mapnames, dp->type, ARGV_END); } #ifndef NO_DYNAMIC_MAPS if (!dict_dlinfo) msg_fatal("dlinfo==NULL"); for (dlp=dict_dlinfo; dlp->pattern; dlp++) { argv_add(mapnames, dlp->pattern, ARGV_END); } #endif qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]), dict_sort_alpha_cpp); myfree((char *) ht_info); argv_terminate(mapnames); return mapnames; }
const char *dict_changed_name(void) { const char *myname = "dict_changed_name"; struct stat st; HTABLE_INFO **ht_info_list; HTABLE_INFO **ht; HTABLE_INFO *h; const char *status; DICT *dict; ht_info_list = htable_list(dict_table); for (status = 0, ht = ht_info_list; status == 0 && (h = *ht) != 0; ht++) { dict = ((DICT_NODE *) h->value)->dict; if (dict->stat_fd < 0) /* not file-based */ continue; if (dict->mtime == 0) /* not bloody likely */ msg_warn("%s: table %s: null time stamp", myname, h->key); if (fstat(dict->stat_fd, &st) < 0) msg_fatal("%s: fstat: %m", myname); if (st.st_mtime != dict->mtime || st.st_nlink == 0) status = h->key; } myfree((char *) ht_info_list); return (status); }
static void show_parameters(int mode, char **names) { HTABLE_INFO **list; HTABLE_INFO **ht; char **namep; char *value; /* * Show all parameters. */ if (*names == 0) { list = htable_list(param_table); qsort((char *) list, param_table->used, sizeof(*list), comp_names); for (ht = list; *ht; ht++) print_parameter(mode, ht[0]->value); myfree((char *) list); return; } /* * Show named parameters. */ for (namep = names; *namep; namep++) { if ((value = htable_find(param_table, *namep)) == 0) { msg_warn("%s: unknown parameter", *namep); } else { print_parameter(mode, value); } } }
int forward_finish(DELIVER_REQUEST *request, DELIVER_ATTR attr, int cancel) { HTABLE_INFO **dt_list; HTABLE_INFO **dt; HTABLE_INFO **sn_list; HTABLE_INFO **sn; HTABLE *table_snd; char *delivered; char *sender; FORWARD_INFO *info; int status = cancel; /* * Sanity checks. */ if (forward_dt == 0) msg_panic("forward_finish: missing forward_init call"); /* * Walk over all delivered-to header addresses and over each envelope * sender address. */ for (dt = dt_list = htable_list(forward_dt); *dt; dt++) { delivered = dt[0]->key; table_snd = (HTABLE *) dt[0]->value; for (sn = sn_list = htable_list(table_snd); *sn; sn++) { sender = sn[0]->key; info = (FORWARD_INFO *) sn[0]->value; if (status == 0) status |= forward_send(info, request, attr, delivered); if (msg_verbose) msg_info("forward_finish: delivered %s sender %s status %d", delivered, sender, status); (void) vstream_fclose(info->cleanup); myfree(info->queue_id); myfree((void *) info); } myfree((void *) sn_list); htable_free(table_snd, (void (*) (void *)) 0); } myfree((void *) dt_list); htable_free(forward_dt, (void (*) (void *)) 0); forward_dt = 0; return (status); }
void dict_walk(DICT_WALK_ACTION action, char *ptr) { HTABLE_INFO **ht_info_list; HTABLE_INFO **ht; HTABLE_INFO *h; ht_info_list = htable_list(dict_table); for (ht = ht_info_list; (h = *ht) != 0; ht++) action(h->key, (DICT *) h->value, ptr); myfree((char *) ht_info_list); }
static historyp make_variable_history(void) { alist al; historyp hp; hpair *pair; al = htable_list(var_table); hp = new_history(FALSE); for (pair = alist_first(al); pair != NULL; pair = alist_next(al)) alist_append(hp->completions, zstrdup(pair->key)); alist_delete(al); return hp; }
ARGV *dict_mapnames() { HTABLE_INFO **ht_info; HTABLE_INFO **ht; DICT_OPEN_INFO *dp; ARGV *mapnames; if (dict_open_hash == 0) dict_open_init(); mapnames = argv_alloc(dict_open_hash->used + 1); for (ht_info = ht = htable_list(dict_open_hash); *ht; ht++) { dp = (DICT_OPEN_INFO *) ht[0]->value; argv_add(mapnames, dp->type, ARGV_END); } qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]), dict_sort_alpha_cpp); myfree((char *) ht_info); argv_terminate(mapnames); return mapnames; }
void psc_dnsbl_init(void) { const char *myname = "psc_dnsbl_init"; ARGV *dnsbl_site = argv_split(var_psc_dnsbl_sites, CHARS_COMMA_SP); char **cpp; /* * Sanity check. */ if (dnsbl_site_cache != 0) msg_panic("%s: called more than once", myname); /* * pre-compute the DNSBLOG socket name. */ psc_dnsbl_service = concatenate(MAIL_CLASS_PRIVATE, "/", var_dnsblog_service, (char *) 0); /* * Prepare for quick iteration when sending out queries to all DNSBL * servers, and for quick lookup when a reply arrives from a specific * DNSBL server. */ dnsbl_site_cache = htable_create(13); for (cpp = dnsbl_site->argv; *cpp; cpp++) psc_dnsbl_add_site(*cpp); argv_free(dnsbl_site); dnsbl_site_list = htable_list(dnsbl_site_cache); /* * The per-client blocklist score. */ dnsbl_score_cache = htable_create(13); /* * Space for ad-hoc DNSBLOG server request/reply parameters. */ reply_client = vstring_alloc(100); reply_dnsbl = vstring_alloc(100); reply_addr = vstring_alloc(100); }
static int dict_thash_sequence(DICT *dict, int function, const char **key, const char **value) { const char *myname = "dict_thash_sequence"; DICT_THASH *dict_thash = (DICT_THASH *) dict; /* * Determine and execute the seek function. */ switch (function) { case DICT_SEQ_FUN_FIRST: if (dict_thash->info == 0) dict_thash->info = htable_list(dict_thash->table); dict_thash->cursor = dict_thash->info; break; case DICT_SEQ_FUN_NEXT: if (dict_thash->cursor[0]) dict_thash->cursor += 1; break; default: msg_panic("%s: invalid function: %d", myname, function); } /* * Return the entry under the cursor. */ if (dict_thash->cursor[0]) { *key = dict_thash->cursor[0]->key; *value = dict_thash->cursor[0]->value; DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_SUCCESS); } else { *key = 0; *value = 0; DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_FAIL); } }
void edit_parameters(int mode, int argc, char **argv) { char *path; EDIT_FILE *ep; VSTREAM *src; VSTREAM *dst; VSTRING *buf = vstring_alloc(100); VSTRING *key = vstring_alloc(10); char *cp; char *edit_key; char *edit_val; HTABLE *table; struct cvalue { char *value; int found; }; struct cvalue *cvalue; HTABLE_INFO **ht_info; HTABLE_INFO **ht; int interesting; const char *err; /* * Store command-line parameters for quick lookup. */ table = htable_create(argc); while ((cp = *argv++) != 0) { if (strchr(cp, '\n') != 0) msg_fatal("-e or -# accepts no multi-line input"); while (ISSPACE(*cp)) cp++; if (*cp == '#') msg_fatal("-e or -# accepts no comment input"); if (mode & EDIT_MAIN) { if ((err = split_nameval(cp, &edit_key, &edit_val)) != 0) msg_fatal("%s: \"%s\"", err, cp); } else if (mode & COMMENT_OUT) { if (*cp == 0) msg_fatal("-# requires non-blank parameter names"); if (strchr(cp, '=') != 0) msg_fatal("-# requires parameter names only"); edit_key = mystrdup(cp); trimblanks(edit_key, 0); edit_val = 0; } else { msg_panic("edit_parameters: unknown mode %d", mode); } cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue)); cvalue->value = edit_val; cvalue->found = 0; htable_enter(table, edit_key, (char *) cvalue); } /* * Open a temp file for the result. This uses a deterministic name so we * don't leave behind thrash with random names. */ set_config_dir(); path = concatenate(var_config_dir, "/", MAIN_CONF_FILE, (char *) 0); if ((ep = edit_file_open(path, O_CREAT | O_WRONLY, 0644)) == 0) msg_fatal("open %s%s: %m", path, EDIT_FILE_SUFFIX); dst = ep->tmp_fp; /* * Open the original file for input. */ if ((src = vstream_fopen(path, O_RDONLY, 0)) == 0) { /* OK to delete, since we control the temp file name exclusively. */ (void) unlink(ep->tmp_path); msg_fatal("open %s for reading: %m", path); } /* * Copy original file to temp file, while replacing parameters on the * fly. Issue warnings for names found multiple times. */ #define STR(x) vstring_str(x) interesting = 0; while (vstring_get(buf, src) != VSTREAM_EOF) { for (cp = STR(buf); ISSPACE(*cp) /* including newline */ ; cp++) /* void */ ; /* Copy comment, all-whitespace, or empty line. */ if (*cp == '#' || *cp == 0) { vstream_fputs(STR(buf), dst); } /* Copy, skip or replace continued text. */ else if (cp > STR(buf)) { if (interesting == 0) vstream_fputs(STR(buf), dst); else if (mode & COMMENT_OUT) vstream_fprintf(dst, "#%s", STR(buf)); } /* Copy or replace start of logical line. */ else { vstring_strncpy(key, cp, strcspn(cp, " \t\r\n=")); cvalue = (struct cvalue *) htable_find(table, STR(key)); if ((interesting = !!cvalue) != 0) { if (cvalue->found++ == 1) msg_warn("%s: multiple entries for \"%s\"", path, STR(key)); if (mode & EDIT_MAIN) vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value); else if (mode & COMMENT_OUT) vstream_fprintf(dst, "#%s", cp); else msg_panic("edit_parameters: unknown mode %d", mode); } else { vstream_fputs(STR(buf), dst); } } } /* * Generate new entries for parameters that were not found. */ if (mode & EDIT_MAIN) { for (ht_info = ht = htable_list(table); *ht; ht++) { cvalue = (struct cvalue *) ht[0]->value; if (cvalue->found == 0) vstream_fprintf(dst, "%s = %s\n", ht[0]->key, cvalue->value); } myfree((char *) ht_info); } /* * When all is well, rename the temp file to the original one. */ if (vstream_fclose(src)) msg_fatal("read %s: %m", path); if (edit_file_close(ep) != 0) msg_fatal("close %s%s: %m", path, EDIT_FILE_SUFFIX); /* * Cleanup. */ myfree(path); vstring_free(buf); vstring_free(key); htable_free(table, myfree); }