masqmail
view src/libident/id_open.c @ 246:4cff8638dd9b
SMTP client: tries EHLO now always first
Changed the behavior of the SMTP client. Now always an EHLO greeting
is sent, no matter what kind of greeting text the server had sent. If
the EHLO failed, an HELO greeting is tried as fall back. This is the
behavior RFC 2821 requires (section 3.2).
This change will fix setups that were not possible to sent to a
server because that requires AUTH but hadn't said ``ESMTP'' in its
greeting message.
See also: Debian bug #349211
Thanks to Steffen (inne)
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Thu, 28 Oct 2010 16:40:02 -0300 |
parents | 08114f7dcc23 |
children |
line source
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 */
8 #ifdef NeXT3
9 # include <libc.h>
10 #endif
12 #include <stdio.h>
13 #include <errno.h>
14 #include <fcntl.h>
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
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>
31 #define IN_LIBIDENT_SRC
32 #include "ident.h"
34 #include <arpa/inet.h>
36 #ifdef _AIX
37 # include <sys/select.h>
38 #endif
41 /*
42 ident_t *id_open __P3(struct in_addr *, laddr, struct in_addr *, faddr, struct timeval *, timeout)
43 */
45 ident_t*
46 id_open __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P faddr, __STRUCT_TIMEVAL_P timeout))
47 {
48 ident_t *id;
49 int res, tmperrno;
50 struct sockaddr_in sin_laddr, sin_faddr;
51 fd_set rs, ws, es;
52 #ifndef OLD_SETSOCKOPT
53 int on = 1;
54 struct linger linger;
55 #endif
57 if ((id = (ident_t *) malloc(sizeof(*id))) == 0)
58 return 0;
60 if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
61 free(id);
62 return 0;
63 }
65 if (timeout) {
66 if ((res = fcntl(id->fd, F_GETFL, 0)) < 0)
67 goto ERROR;
69 #ifndef VMS
70 if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0)
71 goto ERROR;
72 #endif
73 }
75 /* We silently ignore errors if we can't change LINGER */
76 #ifdef OLD_SETSOCKOPT
77 /* Old style setsockopt() */
78 (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER);
79 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR);
80 #else
81 /* New style setsockopt() */
82 linger.l_onoff = 0;
83 linger.l_linger = 0;
85 (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
86 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on));
87 #endif
89 id->buf[0] = '\0';
91 bzero((char *) &sin_laddr, sizeof(sin_laddr));
92 sin_laddr.sin_family = AF_INET;
93 sin_laddr.sin_addr = *laddr;
94 sin_laddr.sin_port = 0;
96 if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) {
97 #ifdef DEBUG
98 perror("libident: bind");
99 #endif
100 goto ERROR;
101 }
103 bzero((char *) &sin_faddr, sizeof(sin_faddr));
104 sin_faddr.sin_family = AF_INET;
105 sin_faddr.sin_addr = *faddr;
106 sin_faddr.sin_port = htons(IDPORT);
108 errno = 0;
109 res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr));
110 if (res < 0 && errno != EINPROGRESS) {
111 #ifdef DEBUG
112 perror("libident: connect");
113 #endif
114 goto ERROR;
115 }
117 if (timeout) {
118 FD_ZERO(&rs);
119 FD_ZERO(&ws);
120 FD_ZERO(&es);
122 FD_SET(id->fd, &rs);
123 FD_SET(id->fd, &ws);
124 FD_SET(id->fd, &es);
126 #ifdef __hpux
127 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0)
128 #else
129 if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0)
130 #endif
131 {
132 #ifdef DEBUG
133 perror("libident: select");
134 #endif
135 goto ERROR;
136 }
138 if (res == 0) {
139 errno = ETIMEDOUT;
140 goto ERROR;
141 }
143 if (FD_ISSET(id->fd, &es))
144 goto ERROR;
146 if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws))
147 goto ERROR;
148 }
150 return id;
152 ERROR:
153 tmperrno = errno; /* Save, so close() won't erase it */
154 close(id->fd);
155 free(id);
156 errno = tmperrno;
157 return 0;
158 }