Mercurial > masqmail
comparison src/libident/id_open.c @ 0:08114f7dcc23 0.2.21
this is masqmail-0.2.21 from oliver kurth
author | meillo@marmaro.de |
---|---|
date | Fri, 26 Sep 2008 17:05:23 +0200 |
parents | |
children | 26e34ae9a3e3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:08114f7dcc23 |
---|---|
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 /* | |
42 ident_t *id_open __P3(struct in_addr *, laddr, | |
43 struct in_addr *, faddr, | |
44 struct timeval *, timeout) | |
45 */ | |
46 | |
47 ident_t *id_open __P(( __STRUCT_IN_ADDR_P laddr, | |
48 __STRUCT_IN_ADDR_P faddr, | |
49 __STRUCT_TIMEVAL_P timeout)) | |
50 { | |
51 ident_t *id; | |
52 int res, tmperrno; | |
53 struct sockaddr_in sin_laddr, sin_faddr; | |
54 fd_set rs, ws, es; | |
55 #ifndef OLD_SETSOCKOPT | |
56 int on = 1; | |
57 struct linger linger; | |
58 #endif | |
59 | |
60 if ((id = (ident_t *) malloc(sizeof(*id))) == 0) | |
61 return 0; | |
62 | |
63 if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
64 { | |
65 free(id); | |
66 return 0; | |
67 } | |
68 | |
69 if (timeout) | |
70 { | |
71 if ((res = fcntl(id->fd, F_GETFL, 0)) < 0) | |
72 goto ERROR; | |
73 | |
74 #ifndef VMS | |
75 if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0) | |
76 goto ERROR; | |
77 #endif | |
78 } | |
79 | |
80 /* We silently ignore errors if we can't change LINGER */ | |
81 #ifdef OLD_SETSOCKOPT | |
82 /* Old style setsockopt() */ | |
83 (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER); | |
84 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR); | |
85 #else | |
86 /* New style setsockopt() */ | |
87 linger.l_onoff = 0; | |
88 linger.l_linger = 0; | |
89 | |
90 (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); | |
91 (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); | |
92 #endif | |
93 | |
94 id->buf[0] = '\0'; | |
95 | |
96 bzero((char *)&sin_laddr, sizeof(sin_laddr)); | |
97 sin_laddr.sin_family = AF_INET; | |
98 sin_laddr.sin_addr = *laddr; | |
99 sin_laddr.sin_port = 0; | |
100 | |
101 if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) | |
102 { | |
103 #ifdef DEBUG | |
104 perror("libident: bind"); | |
105 #endif | |
106 goto ERROR; | |
107 } | |
108 | |
109 bzero((char *)&sin_faddr, sizeof(sin_faddr)); | |
110 sin_faddr.sin_family = AF_INET; | |
111 sin_faddr.sin_addr = *faddr; | |
112 sin_faddr.sin_port = htons(IDPORT); | |
113 | |
114 errno = 0; | |
115 res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr)); | |
116 if (res < 0 && errno != EINPROGRESS) | |
117 { | |
118 #ifdef DEBUG | |
119 perror("libident: connect"); | |
120 #endif | |
121 goto ERROR; | |
122 } | |
123 | |
124 if (timeout) | |
125 { | |
126 FD_ZERO(&rs); | |
127 FD_ZERO(&ws); | |
128 FD_ZERO(&es); | |
129 | |
130 FD_SET(id->fd, &rs); | |
131 FD_SET(id->fd, &ws); | |
132 FD_SET(id->fd, &es); | |
133 | |
134 #ifdef __hpux | |
135 if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0) | |
136 #else | |
137 if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0) | |
138 #endif | |
139 { | |
140 #ifdef DEBUG | |
141 perror("libident: select"); | |
142 #endif | |
143 goto ERROR; | |
144 } | |
145 | |
146 if (res == 0) | |
147 { | |
148 errno = ETIMEDOUT; | |
149 goto ERROR; | |
150 } | |
151 | |
152 if (FD_ISSET(id->fd, &es)) | |
153 goto ERROR; | |
154 | |
155 if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws)) | |
156 goto ERROR; | |
157 } | |
158 | |
159 return id; | |
160 | |
161 ERROR: | |
162 tmperrno = errno; /* Save, so close() won't erase it */ | |
163 close(id->fd); | |
164 free(id); | |
165 errno = tmperrno; | |
166 return 0; | |
167 } |