summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src/global/virtual8_maps.c
blob: fb05dc7d0d8e0bd6f05b31c926f191a0f121e792 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*++
/* NAME
/*	virtual8_maps 3
/* SUMMARY
/*	virtual delivery agent map lookups
/* SYNOPSIS
/*	#include <virtual8_maps.h>
/*
/*	MAPS	*virtual8_maps_create(title, map_names, flags)
/*	const char *title;
/*	const char *map_names;
/*	int	flags;
/*
/*	const char *virtual8_maps_find(maps, recipient)
/*	MAPS	*maps;
/*	const char *recipient;
/*
/*	MAPS	*virtual8_maps_free(maps)
/*	MAPS	*maps;
/* DESCRIPTION
/*	This module does user lookups for the virtual delivery
/*	agent. The code is made available as a library module so that
/*	other programs can perform compatible queries.
/*
/*	Lookups are case sensitive.
/*
/*	virtual8_maps_create() takes list of type:name pairs and opens the
/*	named dictionaries.
/*	The result is a handle that must be specified along with all
/*	other virtual8_maps_xxx() operations.
/*	See dict_open(3) for a description of flags.
/*
/*	virtual8_maps_find() searches the specified list of dictionaries
/*	in the specified order for the named key. The result is in
/*	memory that is overwritten upon each call.
/*
/*	virtual8_maps_free() releases storage claimed by virtual8_maps_create()
/*	and conveniently returns a null pointer.
/*
/*	Arguments:
/* .IP title
/*	String used for diagnostics. Typically one specifies the
/*	type of information stored in the lookup tables.
/* .IP map_names
/*	Null-terminated string with type:name dictionary specifications,
/*	separated by whitespace or commas.
/* .IP maps
/*	A result from maps_create().
/* .IP key
/*	Null-terminated string with a lookup key. Table lookup is case
/*	sensitive.
/* DIAGNOSTICS
/*	The dict_errno variable is non-zero in case of problems.
/* BUGS
/*	This code is a temporary solution that implements a hard-coded
/*	lookup strategy. In a future version of Postfix, the lookup
/*	strategy should become configurable.
/* SEE ALSO
/*	virtual(8) virtual mailbox delivery agent
/*	maps(3) multi-dictionary search
/*	dict_open(3) low-level dictionary interface
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include <sys_defs.h>
#include <string.h>

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>

/* Global library. */

#include <maps.h>
#include <mail_params.h>
#include <strip_addr.h>
#include <virtual8_maps.h>

/* Application-specific. */

/* virtual8_maps_find - lookup for virtual delivery agent */

const char *virtual8_maps_find(MAPS *maps, const char *recipient)
{
    const char *ratsign;
    const char *result;
    char   *bare = 0;

    /*
     * Look up the address minus the optional extension. This is done first,
     * to avoid hammering the database with extended address lookups, and to
     * have straightforward semantics (extensions are always ignored).
     */
    if (*var_rcpt_delim
     && (bare = strip_addr(recipient, (char **) 0, *var_rcpt_delim)) != 0) {
	result = maps_find(maps, bare, DICT_FLAG_FIXED);
	myfree(bare);
	if (result != 0 || dict_errno != 0)
	    return (result);
    }

    /*
     * Look up the full address. Allow regexp table searches.
     */
    if (bare == 0) {
	result = maps_find(maps, recipient, DICT_FLAG_NONE);
	if (result != 0 || dict_errno != 0)
	    return (result);
    }

    /*
     * Look up the @domain catch-all.
     */
    if ((ratsign = strrchr(recipient, '@')) == 0)
	return (0);
    return (maps_find(maps, ratsign, DICT_FLAG_FIXED));
}

#ifdef TEST

#include <vstream.h>
#include <vstring.h>
#include <vstring_vstream.h>

#define STR(x)	vstring_str(x)

int     main(int argc, char **argv)
{
    VSTRING *buffer;
    MAPS   *maps;
    const char *result;

    if (argc != 2)
	msg_fatal("usage: %s mapname", argv[0]);

    var_rcpt_delim = "+";
    var_double_bounce_sender = DEF_DOUBLE_BOUNCE;

    maps = virtual8_maps_create("testmap", argv[1], DICT_FLAG_LOCK);
    buffer = vstring_alloc(1);

    while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
	result = virtual8_maps_find(maps, STR(buffer));
	vstream_printf("%s -> %s\n", STR(buffer), result ? result : "(none)");
	vstream_fflush(VSTREAM_OUT);
    }
    virtual8_maps_free(maps);
    vstring_free(buffer);
    return (0);
}

#endif