int smtpd_token(char *cp, SMTPD_TOKEN **argvp) { static SMTPD_TOKEN *smtp_argv; static MVECT mvect; int n; if (smtp_argv == 0) smtp_argv = (SMTPD_TOKEN *) mvect_alloc(&mvect, sizeof(*smtp_argv), 1, smtpd_token_init, (MVECT_FN) 0); for (n = 0; /* void */ ; n++) { smtp_argv = (SMTPD_TOKEN *) mvect_realloc(&mvect, n + 1); if ((cp = smtp_next_token(cp, smtp_argv + n)) == 0) break; } *argvp = smtp_argv; return (n); }
int pop3d_token(char *cp, POP3D_TOKEN **argvp) { static POP3D_TOKEN *pop3_argv; static MVECT mvect; int n; if (pop3_argv == 0) pop3_argv = (POP3D_TOKEN *) mvect_alloc(&mvect, sizeof(*pop3_argv), 1, pop3d_token_init, (MVECT_FN) 0); for (n = 0; /* void */ ; n++) { pop3_argv = (POP3D_TOKEN *) mvect_realloc(&mvect, n + 1); if ((cp = pop3_next_token(cp, pop3_argv + n)) == 0) break; } *argvp = pop3_argv; return (n); }
void dict_open_dlinfo(const char *path) { char *myname="dict_open_dlinfo"; VSTREAM *conf_fp=vstream_fopen(path,O_RDONLY,0); VSTRING *buf = vstring_alloc(100); char *cp; ARGV *argv; MVECT vector; int nelm=0; int linenum=0; dict_dlinfo=(DLINFO*)mvect_alloc(&vector,sizeof(DLINFO),3,NULL,NULL); if (!conf_fp) { msg_warn("%s: cannot open %s. No dynamic maps will be allowed.", myname, path); } else { while (vstring_get_nonl(buf,conf_fp) != VSTREAM_EOF) { cp = vstring_str(buf); linenum++; if (*cp == '#' || *cp == '\0') continue; argv = argv_split(cp, " \t"); if (argv->argc != 3 && argv->argc != 4) { msg_fatal("%s: Expected \"pattern .so-name open-function [mkmap-function]\" at line %d", myname, linenum); } if (STREQ(argv->argv[0],"*")) { msg_warn("%s: wildcard dynamic map entry no longer supported.", myname); continue; } if (argv->argv[1][0] != '/') { msg_fatal("%s: .so name must begin with a \"/\" at line %d", myname, linenum); } if (nelm >= vector.nelm) { dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+3); } dict_dlinfo[nelm].pattern = mystrdup(argv->argv[0]); dict_dlinfo[nelm].soname = mystrdup(argv->argv[1]); dict_dlinfo[nelm].openfunc = mystrdup(argv->argv[2]); if (argv->argc==4) dict_dlinfo[nelm].mkmapfunc = mystrdup(argv->argv[3]); else dict_dlinfo[nelm].mkmapfunc = NULL; nelm++; argv_free(argv); } } if (nelm >= vector.nelm) { dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+1); } dict_dlinfo[nelm].pattern = NULL; dict_dlinfo[nelm].soname = NULL; dict_dlinfo[nelm].openfunc = NULL; dict_dlinfo[nelm].mkmapfunc = NULL; if (conf_fp) vstream_fclose(conf_fp); vstring_free(buf); }
DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags) { const char myname[] = "dict_cidr_open"; DICT_CIDR *dict_cidr; VSTREAM *map_fp = 0; struct stat st; VSTRING *line_buffer = 0; VSTRING *why = 0; DICT_CIDR_ENTRY *rule; DICT_CIDR_ENTRY *last_rule = 0; int last_line = 0; int lineno; int nesting = 0; DICT_CIDR_ENTRY **rule_stack = 0; MVECT mvect; /* * Let the optimizer worry about eliminating redundant code. */ #define DICT_CIDR_OPEN_RETURN(d) do { \ DICT *__d = (d); \ if (map_fp != 0 && vstream_fclose(map_fp)) \ msg_fatal("cidr map %s: read error: %m", mapname); \ if (line_buffer != 0) \ vstring_free(line_buffer); \ if (why != 0) \ vstring_free(why); \ return (__d); \ } while (0) /* * Sanity checks. */ if (open_flags != O_RDONLY) DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags, "%s:%s map requires O_RDONLY access mode", DICT_TYPE_CIDR, mapname)); /* * Open the configuration file. */ if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0) DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags, "open %s: %m", mapname)); if (fstat(vstream_fileno(map_fp), &st) < 0) msg_fatal("fstat %s: %m", mapname); line_buffer = vstring_alloc(100); why = vstring_alloc(100); /* * XXX Eliminate unnecessary queries by setting a flag that says "this * map matches network addresses only". */ dict_cidr = (DICT_CIDR *) dict_alloc(DICT_TYPE_CIDR, mapname, sizeof(*dict_cidr)); dict_cidr->dict.lookup = dict_cidr_lookup; dict_cidr->dict.close = dict_cidr_close; dict_cidr->dict.flags = dict_flags | DICT_FLAG_PATTERN; dict_cidr->head = 0; dict_cidr->dict.owner.uid = st.st_uid; dict_cidr->dict.owner.status = (st.st_uid != 0); while (readllines(line_buffer, map_fp, &last_line, &lineno)) { rule = dict_cidr_parse_rule(vstring_str(line_buffer), lineno, nesting, why); if (rule == 0) { msg_warn("cidr map %s, line %d: %s: skipping this rule", mapname, lineno, vstring_str(why)); continue; } if (rule->cidr_info.op == CIDR_MATCH_OP_IF) { if (rule_stack == 0) rule_stack = (DICT_CIDR_ENTRY **) mvect_alloc(&mvect, sizeof(*rule_stack), nesting + 1, (MVECT_FN) 0, (MVECT_FN) 0); else rule_stack = (DICT_CIDR_ENTRY **) mvect_realloc(&mvect, nesting + 1); rule_stack[nesting] = rule; nesting++; } else if (rule->cidr_info.op == CIDR_MATCH_OP_ENDIF) { DICT_CIDR_ENTRY *if_rule; if (nesting-- <= 0) /* Already handled in dict_cidr_parse_rule(). */ msg_panic("%s: ENDIF without IF", myname); if_rule = rule_stack[nesting]; if (if_rule->cidr_info.op != CIDR_MATCH_OP_IF) msg_panic("%s: unexpected rule stack element type %d", myname, if_rule->cidr_info.op); if_rule->cidr_info.block_end = &(rule->cidr_info); } if (last_rule == 0) dict_cidr->head = rule; else last_rule->cidr_info.next = &(rule->cidr_info); last_rule = rule; } while (nesting-- > 0) msg_warn("cidr map %s, line %d: IF has no matching ENDIF", mapname, rule_stack[nesting]->lineno); if (rule_stack) (void) mvect_free(&mvect); DICT_CIDR_OPEN_RETURN(DICT_DEBUG (&dict_cidr->dict)); }