Exemplo n.º 1
0
MAPS   *maps_create(const char *title, const char *map_names, int dict_flags)
{
    const char *myname = "maps_create";
    char   *temp;
    char   *bufp;
    static char sep[] = CHARS_COMMA_SP;
    static char parens[] = CHARS_BRACE;
    MAPS   *maps;
    char   *map_type_name;
    VSTRING *map_type_name_flags;
    DICT   *dict;

    /*
     * Initialize.
     */
    maps = (MAPS *) mymalloc(sizeof(*maps));
    maps->title = mystrdup(title);
    maps->argv = argv_alloc(2);
    maps->error = 0;

    /*
     * For each specified type:name pair, either register a new dictionary,
     * or increment the reference count of an existing one.
     */
    if (*map_names) {
	bufp = temp = mystrdup(map_names);
	map_type_name_flags = vstring_alloc(10);

#define OPEN_FLAGS	O_RDONLY

	while ((map_type_name = mystrtokq(&bufp, sep, parens)) != 0) {
	    vstring_sprintf(map_type_name_flags, "%s(%o,%s)",
			    map_type_name, OPEN_FLAGS,
			    dict_flags_str(dict_flags));
	    if ((dict = dict_handle(vstring_str(map_type_name_flags))) == 0)
		dict = dict_open(map_type_name, OPEN_FLAGS, dict_flags);
	    if ((dict->flags & dict_flags) != dict_flags)
		msg_panic("%s: map %s has flags 0%o, want flags 0%o",
			  myname, map_type_name, dict->flags, dict_flags);
	    dict_register(vstring_str(map_type_name_flags), dict);
	    argv_add(maps->argv, vstring_str(map_type_name_flags), ARGV_END);
	}
	myfree(temp);
	vstring_free(map_type_name_flags);
    }
    return (maps);
}
Exemplo n.º 2
0
static ARGV *match_list_parse(ARGV *list, char *string, int init_match)
{
    const char *myname = "match_list_parse";
    VSTRING *buf = vstring_alloc(10);
    VSTREAM *fp;
    const char *delim = " ,\t\r\n";
    char   *bp = string;
    char   *start;
    char   *item;
    char   *map_type_name_flags;
    int     match;

#define OPEN_FLAGS	O_RDONLY
#define DICT_FLAGS	(DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX)
#define STR(x)		vstring_str(x)

    /*
     * /filename contents are expanded in-line. To support !/filename we
     * prepend the negation operator to each item from the file.
     */
    while ((start = mystrtokq(&bp, delim, "{}")) != 0) {
	if (*start == '#') {
	    msg_warn("%s: comment at end of line is not supported: %s %s",
		     myname, start, bp);
	    break;
	}
	for (match = init_match, item = start; *item == '!'; item++)
	    match = !match;
	if (*item == 0)
	    msg_fatal("%s: no pattern after '!'", myname);
	if (*item == '/') {			/* /file/name */
	    if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) {
		vstring_sprintf(buf, "%s:%s", DICT_TYPE_NOFILE, item);
		/* XXX Should increment existing map refcount. */
		if (dict_handle(STR(buf)) == 0)
		    dict_register(STR(buf),
				  dict_surrogate(DICT_TYPE_NOFILE, item,
						 OPEN_FLAGS, DICT_FLAGS,
						 "open file %s: %m", item));
		argv_add(list, STR(buf), (char *) 0);
	    } else {
		while (vstring_fgets(buf, fp))
		    if (vstring_str(buf)[0] != '#')
			list = match_list_parse(list, vstring_str(buf), match);
		if (vstream_fclose(fp))
		    msg_fatal("%s: read file %s: %m", myname, item);
	    }
	} else if (MATCH_DICTIONARY(item)) {	/* type:table */
	    vstring_sprintf(buf, "%s%s(%o,%s)", match ? "" : "!",
			    item, OPEN_FLAGS, dict_flags_str(DICT_FLAGS));
	    map_type_name_flags = STR(buf) + (match == 0);
	    /* XXX Should increment existing map refcount. */
	    if (dict_handle(map_type_name_flags) == 0)
		dict_register(map_type_name_flags,
			      dict_open(item, OPEN_FLAGS, DICT_FLAGS));
	    argv_add(list, STR(buf), (char *) 0);
	} else {				/* other pattern */
	    argv_add(list, match ? item :
		     STR(vstring_sprintf(buf, "!%s", item)), (char *) 0);
	}
    }
    vstring_free(buf);
    return (list);
}
Exemplo n.º 3
0
MILTERS *milter_new(const char *names,
		            int conn_timeout,
		            int cmd_timeout,
		            int msg_timeout,
		            const char *protocol,
		            const char *def_action,
		            MILTER_MACROS *macros)
{
    MILTERS *milters;
    MILTER *head = 0;
    MILTER *tail = 0;
    char   *name;
    MILTER *milter;
    const char *sep = ", \t\r\n";
    const char *parens = "{}";
    int     my_conn_timeout;
    int     my_cmd_timeout;
    int     my_msg_timeout;
    const char *my_protocol;
    const char *my_def_action;

    /*
     * Initialize.
     */
    link_override_table_to_variable(time_table, my_conn_timeout);
    link_override_table_to_variable(time_table, my_cmd_timeout);
    link_override_table_to_variable(time_table, my_msg_timeout);
    link_override_table_to_variable(str_table, my_protocol);
    link_override_table_to_variable(str_table, my_def_action);

    /*
     * Parse the milter list.
     */
    milters = (MILTERS *) mymalloc(sizeof(*milters));
    if (names != 0 && *names != 0) {
	char   *saved_names = mystrdup(names);
	char   *cp = saved_names;
	char   *op;
	char   *err;

	/*
	 * Instantiate Milters, allowing for per-Milter overrides.
	 */
	while ((name = mystrtokq(&cp, sep, parens)) != 0) {
	    my_conn_timeout = conn_timeout;
	    my_cmd_timeout = cmd_timeout;
	    my_msg_timeout = msg_timeout;
	    my_protocol = protocol;
	    my_def_action = def_action;
	    if (name[0] == '{') {		/* } */
		op = name;
		if ((err = extpar(&op, parens, EXTPAR_FLAG_NONE)) != 0)
		    msg_fatal("milter service syntax error: %s", err);
		if ((name = mystrtok(&op, sep)) == 0)
		    msg_fatal("empty milter definition: \"%s\"", names);
		attr_override(op, sep, parens,
			      ATTR_OVER_STR_TABLE, str_table,
			      ATTR_OVER_TIME_TABLE, time_table,
			      0);
	    }
	    milter = milter8_create(name, my_conn_timeout, my_cmd_timeout,
				    my_msg_timeout, my_protocol,
				    my_def_action, milters);
	    if (head == 0) {
		head = milter;
	    } else {
		tail->next = milter;
	    }
	    tail = milter;
	}
	myfree(saved_names);
    }
    milters->milter_list = head;
    milters->mac_lookup = 0;
    milters->mac_context = 0;
    milters->macros = macros;
    milters->add_header = 0;
    milters->upd_header = milters->ins_header = 0;
    milters->del_header = 0;
    milters->add_rcpt = milters->del_rcpt = 0;
    milters->repl_body = 0;
    milters->chg_context = 0;
    return (milters);
}
Exemplo n.º 4
0
static void pcf_register_dbms_helper(char *str_value,
         const char *(flag_parameter) (const char *, int, PCF_MASTER_ENT *),
				             PCF_MASTER_ENT *local_scope)
{
    const PCF_DBMS_INFO *dp;
    char   *db_type;
    char   *prefix;
    static VSTRING *candidate = 0;
    const char **cpp;
    char   *err;

    /*
     * Naive parsing. We don't really know if this substring specifies a
     * database or some other text.
     */
    while ((db_type = mystrtokq(&str_value, " ,\t\r\n", "{}")) != 0) {

	/*
	 * Skip over "proxy:" maptypes, to emulate the proxymap(8) server's
	 * behavior when opening a local database configuration file.
	 */
	while ((prefix = split_at(db_type, ':')) != 0
	       && strcmp(db_type, DICT_TYPE_PROXY) == 0)
	    db_type = prefix;

	/*
	 * Look for database:prefix where the prefix is not a pathname and
	 * the database is a known type. Synthesize candidate parameter names
	 * from the user-defined prefix and from the database-defined suffix
	 * list, and see if those parameters have a "name=value" entry in the
	 * local or global namespace.
	 */
	if (prefix != 0 && *prefix != '/' && *prefix != '.') {
	    if (*prefix == '{') {		/* } */
		if ((err = extpar(&prefix, "{}", EXTPAR_FLAG_NONE)) != 0) {
		    /* XXX Encapsulate this in pcf_warn() function. */
		    if (local_scope)
			msg_warn("%s:%s: %s",
				 MASTER_CONF_FILE, local_scope->name_space,
				 err);
		    else
			msg_warn("%s: %s", MAIN_CONF_FILE, err);
		    myfree(err);
		}
		pcf_register_dbms_helper(prefix, flag_parameter,
					 local_scope);
	    } else {
		for (dp = pcf_dbms_info; dp->db_type != 0; dp++) {
		    if (strcmp(db_type, dp->db_type) == 0) {
			for (cpp = dp->db_suffixes; *cpp; cpp++) {
			    vstring_sprintf(candidate ? candidate :
					    (candidate = vstring_alloc(30)),
					    "%s_%s", prefix, *cpp);
			    flag_parameter(STR(candidate),
				  PCF_PARAM_FLAG_DBMS | PCF_PARAM_FLAG_USER,
					   local_scope);
			}
			break;
		    }
		}
	    }
	}
    }
}