Mercurial > masqmail
annotate src/libident/id_open.c @ 222:8cddc65765bd
added support for STARTTLS wrappers
added the route config option `instant_helo' which
causes masqmail, as SMTP client, not to wait for the
server's 220 greeting. Instead if says EHLO right at
once. You'll need this for STARTTLS wrappers that
usually eat the greeting line.
author | meillo@marmaro.de |
---|---|
date | Fri, 23 Jul 2010 10:57:53 +0200 |
parents | 26e34ae9a3e3 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 ** id_open.c Establish/initiate a connection to an IDENT server | |
3 ** | |
4 ** Author: Peter Eriksson <pen@lysator.liu.se> | |
5 ** Fixes: Pär Emanuelsson <pell@lysator.liu.se> | |
6 */ | |
7 | |
8 #ifdef NeXT3 | |
9 # include <libc.h> | |
10 #endif | |
11 | |
12 #include <stdio.h> | |
13 #include <errno.h> | |
14 #include <fcntl.h> | |
15 | |
16 #ifdef HAVE_ANSIHEADERS | |
17 # include <stdlib.h> | |
18 # include <string.h> | |
19 # include <unistd.h> | |
20 # if !defined(__sgi) && !defined(VMS) | |
21 # define bzero(p,l) memset(p, 0, l) | |
22 # endif | |
23 #endif | |
24 | |
25 #include <sys/types.h> | |
26 #include <sys/socket.h> | |
27 #include <sys/wait.h> | |
28 #include <sys/time.h> | |
29 #include <sys/file.h> | |
30 | |
31 #define IN_LIBIDENT_SRC | |
32 #include "ident.h" | |
33 | |
34 #include <arpa/inet.h> | |
35 | |
36 #ifdef _AIX | |
37 # include <sys/select.h> | |
38 #endif | |
39 | |
40 | |
41 /* | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
42 ident_t *id_open __P3(struct in_addr *, laddr, struct in_addr *, faddr, struct timeval *, timeout) |
0 | 43 */ |
44 | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
45 ident_t* |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
46 id_open __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P faddr, __STRUCT_TIMEVAL_P timeout)) |
0 | 47 { |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
48 ident_t *id; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
49 int res, tmperrno; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
50 struct sockaddr_in sin_laddr, sin_faddr; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
51 fd_set rs, ws, es; |
0 | 52 #ifndef OLD_SETSOCKOPT |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
53 int on = 1; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
54 struct linger linger; |
0 | 55 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
56 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
57 if ((id = (ident_t *) malloc(sizeof(*id))) == 0) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
58 return 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
59 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
60 if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
61 free(id); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
62 return 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
63 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
64 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
65 if (timeout) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
66 if ((res = fcntl(id->fd, F_GETFL, 0)) < 0) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
67 goto ERROR; |
0 | 68 |
69 #ifndef VMS | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
70 if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
71 goto ERROR; |
0 | 72 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
73 } |
0 | 74 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
75 /* We silently ignore errors if we can't change LINGER */ |
0 | 76 #ifdef OLD_SETSOCKOPT |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
77 /* Old style setsockopt() */ |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
78 (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
79 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR); |
0 | 80 #else |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
81 /* New style setsockopt() */ |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
82 linger.l_onoff = 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
83 linger.l_linger = 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
84 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
85 (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
86 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); |
0 | 87 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
88 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
89 id->buf[0] = '\0'; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
90 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
91 bzero((char *) &sin_laddr, sizeof(sin_laddr)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
92 sin_laddr.sin_family = AF_INET; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
93 sin_laddr.sin_addr = *laddr; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
94 sin_laddr.sin_port = 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
95 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
96 if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) { |
0 | 97 #ifdef DEBUG |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
98 perror("libident: bind"); |
0 | 99 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
100 goto ERROR; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
101 } |
0 | 102 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
103 bzero((char *) &sin_faddr, sizeof(sin_faddr)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
104 sin_faddr.sin_family = AF_INET; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
105 sin_faddr.sin_addr = *faddr; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
106 sin_faddr.sin_port = htons(IDPORT); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
107 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
108 errno = 0; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
109 res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr)); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
110 if (res < 0 && errno != EINPROGRESS) { |
0 | 111 #ifdef DEBUG |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
112 perror("libident: connect"); |
0 | 113 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
114 goto ERROR; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
115 } |
0 | 116 |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
117 if (timeout) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
118 FD_ZERO(&rs); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
119 FD_ZERO(&ws); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
120 FD_ZERO(&es); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
121 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
122 FD_SET(id->fd, &rs); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
123 FD_SET(id->fd, &ws); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
124 FD_SET(id->fd, &es); |
0 | 125 |
126 #ifdef __hpux | |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
127 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0) |
0 | 128 #else |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
129 if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0) |
0 | 130 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
131 { |
0 | 132 #ifdef DEBUG |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
133 perror("libident: select"); |
0 | 134 #endif |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
135 goto ERROR; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
136 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
137 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
138 if (res == 0) { |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
139 errno = ETIMEDOUT; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
140 goto ERROR; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
141 } |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
142 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
143 if (FD_ISSET(id->fd, &es)) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
144 goto ERROR; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
145 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
146 if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws)) |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
147 goto ERROR; |
0 | 148 } |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
149 |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
150 return id; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
151 |
0 | 152 ERROR: |
10
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
153 tmperrno = errno; /* Save, so close() won't erase it */ |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
154 close(id->fd); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
155 free(id); |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
156 errno = tmperrno; |
26e34ae9a3e3
changed indention and line wrapping to a more consistent style
meillo@marmaro.de
parents:
0
diff
changeset
|
157 return 0; |
0 | 158 } |