예제 #1
0
static void postmap_body(void *ptr, int unused_rec_type,
			         const char *keybuf,
			         ssize_t unused_len,
			         off_t unused_offset)
{
    POSTMAP_KEY_STATE *state = (POSTMAP_KEY_STATE *) ptr;
    DICT  **dicts = state->dicts;
    char  **maps = state->maps;
    int     map_count = state->map_count;
    int     dict_flags = state->dict_flags;
    const char *map_name;
    const char *value;
    int     n;

    for (n = 0; n < map_count; n++) {
	if (dicts[n] == 0)
	    dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
			dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
		    dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
	if ((value = dict_get(dicts[n], keybuf)) != 0) {
	    if (*value == 0) {
		msg_warn("table %s:%s: key %s: empty string result is not allowed",
			 dicts[n]->type, dicts[n]->name, keybuf);
		msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
			 dicts[n]->type, dicts[n]->name);
	    }
	    vstream_printf("%s	%s\n", keybuf, value);
	    state->found = 1;
	    break;
	}
	if (dicts[n]->error)
	    msg_fatal("table %s:%s: query error: %m",
		      dicts[n]->type, dicts[n]->name);
    }
}
예제 #2
0
static int postmap_deletes(VSTREAM *in, char **maps, const int map_count,
			           int dict_flags)
{
    int     found = 0;
    VSTRING *keybuf = vstring_alloc(100);
    DICT  **dicts;
    const char *map_name;
    int     n;
    int     open_flags;

    /*
     * Sanity check.
     */
    if (map_count <= 0)
	msg_panic("postmap_deletes: bad map count");

    /*
     * Open maps ahead of time.
     */
    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
    for (n = 0; n < map_count; n++) {
	map_name = split_at(maps[n], ':');
	if (map_name && strcmp(maps[n], DICT_TYPE_PROXY) == 0)
	    open_flags = O_RDWR | O_CREAT;	/* XXX */
	else
	    open_flags = O_RDWR;
	dicts[n] = (map_name != 0 ?
		    dict_open3(maps[n], map_name, open_flags, dict_flags) :
		  dict_open3(var_db_type, maps[n], open_flags, dict_flags));
    }

    /*
     * Perform all requests.
     */
    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
	for (n = 0; n < map_count; n++) {
	    found |= (dict_del(dicts[n], STR(keybuf)) == 0);
	    if (dicts[n]->error)
		msg_fatal("table %s:%s: delete error: %m",
			  dicts[n]->type, dicts[n]->name);
	}
    }

    /*
     * Cleanup.
     */
    for (n = 0; n < map_count; n++)
	if (dicts[n])
	    dict_close(dicts[n]);
    myfree((void *) dicts);
    vstring_free(keybuf);

    return (found);
}
예제 #3
0
static void postmap_seq(const char *map_type, const char *map_name,
			        int dict_flags)
{
    DICT   *dict;
    const char *key;
    const char *value;
    int     func;

    if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
	msg_fatal("can't sequence maps via the proxy service");
    dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
    for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
	if (dict_seq(dict, func, &key, &value) != 0)
	    break;
	if (*key == 0) {
	    msg_warn("table %s:%s: empty lookup key value is not allowed",
		     map_type, map_name);
	} else if (*value == 0) {
	    msg_warn("table %s:%s: key %s: empty string result is not allowed",
		     map_type, map_name, key);
	    msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
		     map_type, map_name);
	}
	vstream_printf("%s	%s\n", key, value);
    }
    if (dict->error)
	msg_fatal("table %s:%s: sequence error: %m", dict->type, dict->name);
    vstream_fflush(VSTREAM_OUT);
    dict_close(dict);
}
예제 #4
0
파일: dict_open.c 프로젝트: LMDB/postfix
DICT   *dict_open(const char *dict_spec, int open_flags, int dict_flags)
{
    char   *saved_dict_spec = mystrdup(dict_spec);
    char   *dict_name;
    DICT   *dict;

    if ((dict_name = split_at(saved_dict_spec, ':')) == 0)
	msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s\"",
		  dict_spec);

    dict = dict_open3(saved_dict_spec, dict_name, open_flags, dict_flags);
    myfree(saved_dict_spec);
    return (dict);
}
예제 #5
0
static int postmap_delete(const char *map_type, const char *map_name,
			          const char *key, int dict_flags)
{
    DICT   *dict;
    int     status;
    int     open_flags;

    if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
	open_flags = O_RDWR | O_CREAT;		/* XXX */
    else
	open_flags = O_RDWR;
    dict = dict_open3(map_type, map_name, open_flags, dict_flags);
    status = dict_del(dict, key);
    if (dict->error)
	msg_fatal("table %s:%s: delete error: %m", dict->type, dict->name);
    dict_close(dict);
    return (status == 0);
}
예제 #6
0
static int postmap_query(const char *map_type, const char *map_name,
			         const char *key, int dict_flags)
{
    DICT   *dict;
    const char *value;

    dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
    if ((value = dict_get(dict, key)) != 0) {
	if (*value == 0) {
	    msg_warn("table %s:%s: key %s: empty string result is not allowed",
		     map_type, map_name, key);
	    msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
		     map_type, map_name);
	}
	vstream_printf("%s\n", value);
    }
    if (dict->error)
	msg_fatal("table %s:%s: query error: %m", dict->type, dict->name);
    vstream_fflush(VSTREAM_OUT);
    dict_close(dict);
    return (value != 0);
}
예제 #7
0
static int postmap_queries(VSTREAM *in, char **maps, const int map_count,
			           const int postmap_flags,
			           const int dict_flags)
{
    int     found = 0;
    VSTRING *keybuf = vstring_alloc(100);
    DICT  **dicts;
    const char *map_name;
    const char *value;
    int     n;

    /*
     * Sanity check.
     */
    if (map_count <= 0)
	msg_panic("postmap_queries: bad map count");

    /*
     * Prepare to open maps lazily.
     */
    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
    for (n = 0; n < map_count; n++)
	dicts[n] = 0;

    /*
     * Perform all queries. Open maps on the fly, to avoid opening unecessary
     * maps.
     */
    if ((postmap_flags & POSTMAP_FLAG_HB_KEY) == 0) {
	while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
	    for (n = 0; n < map_count; n++) {
		if (dicts[n] == 0)
		    dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
		       dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
		    dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
		if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
		    if (*value == 0) {
			msg_warn("table %s:%s: key %s: empty string result is not allowed",
			       dicts[n]->type, dicts[n]->name, STR(keybuf));
			msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
				 dicts[n]->type, dicts[n]->name);
		    }
		    vstream_printf("%s	%s\n", STR(keybuf), value);
		    found = 1;
		    break;
		}
		if (dicts[n]->error)
		    msg_fatal("table %s:%s: query error: %m",
			      dicts[n]->type, dicts[n]->name);
	    }
	}
    } else {
	POSTMAP_KEY_STATE key_state;
	MIME_STATE *mime_state;
	int     mime_errs = 0;

	/*
	 * Bundle up the request and instantiate a MIME parsing engine.
	 */
	key_state.dicts = dicts;
	key_state.maps = maps;
	key_state.map_count = map_count;
	key_state.dict_flags = dict_flags;
	key_state.header_done = 0;
	key_state.found = 0;
	mime_state =
	    mime_state_alloc((postmap_flags & POSTMAP_FLAG_MIME_KEY) ?
			     0 : MIME_OPT_DISABLE_MIME,
			     (postmap_flags & POSTMAP_FLAG_HEADER_KEY) ?
			     postmap_header : (MIME_STATE_HEAD_OUT) 0,
			     (postmap_flags & POSTMAP_FLAG_FULL_KEY) ?
			     (MIME_STATE_ANY_END) 0 : postmap_head_end,
			     (postmap_flags & POSTMAP_FLAG_BODY_KEY) ?
			     postmap_body : (MIME_STATE_BODY_OUT) 0,
			     (MIME_STATE_ANY_END) 0,
			     (MIME_STATE_ERR_PRINT) 0,
			     (void *) &key_state);

	/*
	 * Process the input message.
	 */
	while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF
	       && key_state.header_done == 0 && mime_errs == 0)
	    mime_errs = mime_state_update(mime_state, REC_TYPE_NORM,
					  STR(keybuf), LEN(keybuf));

	/*
	 * Flush the MIME engine output buffer and tidy up loose ends.
	 */
	if (mime_errs == 0)
	    mime_errs = mime_state_update(mime_state, REC_TYPE_END, "", 0);
	if (mime_errs)
	    msg_fatal("message format error: %s",
		      mime_state_detail(mime_errs)->text);
	mime_state_free(mime_state);
	found = key_state.found;
    }
    if (found)
	vstream_fflush(VSTREAM_OUT);

    /*
     * Cleanup.
     */
    for (n = 0; n < map_count; n++)
	if (dicts[n])
	    dict_close(dicts[n]);
    myfree((void *) dicts);
    vstring_free(keybuf);

    return (found);
}
예제 #8
0
static int postalias_queries(VSTREAM *in, char **maps, const int map_count,
			             const int dict_flags)
{
    int     found = 0;
    VSTRING *keybuf = vstring_alloc(100);
    DICT  **dicts;
    const char *map_name;
    const char *value;
    int     n;

    /*
     * Sanity check.
     */
    if (map_count <= 0)
	msg_panic("postalias_queries: bad map count");

    /*
     * Prepare to open maps lazily.
     */
    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
    for (n = 0; n < map_count; n++)
	dicts[n] = 0;

    /*
     * Perform all queries. Open maps on the fly, to avoid opening unecessary
     * maps.
     */
    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
	for (n = 0; n < map_count; n++) {
	    if (dicts[n] == 0)
		dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
		       dict_open3(maps[n], map_name, O_RDONLY, dict_flags) :
		    dict_open3(var_db_type, maps[n], O_RDONLY, dict_flags));
	    if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
		if (*value == 0) {
		    msg_warn("table %s:%s: key %s: empty string result is not allowed",
			     dicts[n]->type, dicts[n]->name, STR(keybuf));
		    msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
			     dicts[n]->type, dicts[n]->name);
		}
		vstream_printf("%s:	%s\n", STR(keybuf), value);
		found = 1;
		break;
	    }
	    if (dicts[n]->error)
		msg_fatal("table %s:%s: query error: %m",
			  dicts[n]->type, dicts[n]->name);
	}
    }
    if (found)
	vstream_fflush(VSTREAM_OUT);

    /*
     * Cleanup.
     */
    for (n = 0; n < map_count; n++)
	if (dicts[n])
	    dict_close(dicts[n]);
    myfree((void *) dicts);
    vstring_free(keybuf);

    return (found);
}