Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / smtp / smtp_unalias.c
blob9e9eec91092bf6b95fb34d742a3cbeb0fac22796
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* smtp_unalias 3
6 /* SUMMARY
7 /* replace host/domain alias by official name
8 /* SYNOPSIS
9 /* #include "smtp.h"
11 /* const char *smtp_unalias_name(name)
12 /* const char *name;
14 /* VSTRING *smtp_unalias_addr(result, addr)
15 /* VSTRING *result;
16 /* const char *addr;
17 /* DESCRIPTION
18 /* smtp_unalias_name() looks up A or MX records for the specified
19 /* name and returns the official name provided in the reply. When
20 /* no A or MX record is found, the result is a copy of the input.
21 /* In order to improve performance, smtp_unalias_name() remembers
22 /* results in a private cache, so a name is looked up only once.
24 /* smtp_unalias_addr() returns the input address, which is in
25 /* RFC 821 quoted form, after replacing the domain part by the
26 /* official name as found by smtp_unalias_name(). When the input
27 /* contains no domain part, the result is a copy of the input.
28 /* LICENSE
29 /* .ad
30 /* .fi
31 /* The Secure Mailer license must be distributed with this software.
32 /* AUTHOR(S)
33 /* Wietse Venema
34 /* IBM T.J. Watson Research
35 /* P.O. Box 704
36 /* Yorktown Heights, NY 10598, USA
37 /*--*/
39 /* System library. */
41 #include <sys_defs.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <stdlib.h>
46 #include <netdb.h>
47 #include <string.h>
49 /* Utility library. */
51 #include <htable.h>
52 #include <vstring.h>
53 #include <msg.h>
55 /* DNS library. */
57 #include <dns.h>
59 /* Application-specific. */
61 #include "smtp.h"
63 static int smtp_unalias_flags;
65 /* smtp_unalias_name - look up the official host or domain name. */
67 const char *smtp_unalias_name(const char *name)
69 static HTABLE *cache;
70 VSTRING *fqdn;
71 char *result;
73 if (*name == '[')
74 return (name);
77 * Initialize the cache on the fly. The smtp client is designed to exit
78 * after servicing a limited number of requests, so there is no need to
79 * prevent the cache from growing too large, or to expire old entries.
81 if (cache == 0)
82 cache = htable_create(10);
85 * Look up the fqdn. If none is found use the query name instead, so that
86 * we won't lose time looking up the same bad name again.
88 if ((result = htable_find(cache, name)) == 0) {
89 fqdn = vstring_alloc(10);
90 if (dns_lookup_l(name, smtp_unalias_flags, (DNS_RR **) 0, fqdn,
91 (VSTRING *) 0, DNS_REQ_FLAG_NONE, T_MX, T_A,
92 #ifdef HAS_IPV6
93 T_AAAA,
94 #endif
95 0) != DNS_OK)
96 vstring_strcpy(fqdn, name);
97 htable_enter(cache, name, result = vstring_export(fqdn));
99 return (result);
102 /* smtp_unalias_addr - rewrite aliases in domain part of address */
104 VSTRING *smtp_unalias_addr(VSTRING *result, const char *addr)
106 char *at;
107 const char *fqdn;
109 if ((at = strrchr(addr, '@')) == 0 || at[1] == 0) {
110 vstring_strcpy(result, addr);
111 } else {
112 fqdn = smtp_unalias_name(at + 1);
113 vstring_strncpy(result, addr, at - addr + 1);
114 vstring_strcat(result, fqdn);
116 return (result);
119 #ifdef TEST
122 * Test program - read address from stdin, print result on stdout.
125 #include <vstring_vstream.h>
127 int main(int unused_argc, char **unused_argv)
129 VSTRING *addr = vstring_alloc(10);
130 VSTRING *result = vstring_alloc(10);
132 smtp_unalias_flags |= RES_DEBUG;
134 while (vstring_fgets_nonl(addr, VSTREAM_IN)) {
135 smtp_unalias_addr(result, vstring_str(addr));
136 vstream_printf("%s -> %s\n", vstring_str(addr), vstring_str(result));
137 vstream_fflush(VSTREAM_OUT);
139 vstring_free(addr);
140 vstring_free(result);
141 return (0);
144 #endif