Mercurial > dropbear
comparison dbutil.c @ 26:0969767bca0d
snapshot of stuff
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 26 Jul 2004 02:44:20 +0000 |
parents | f76c9389e9e0 |
children | b4874d772210 |
comparison
equal
deleted
inserted
replaced
25:e4b6e2d569b2 | 26:0969767bca0d |
---|---|
111 fprintf(stderr, "\n"); | 111 fprintf(stderr, "\n"); |
112 va_end(param); | 112 va_end(param); |
113 } | 113 } |
114 #endif /* DEBUG_TRACE */ | 114 #endif /* DEBUG_TRACE */ |
115 | 115 |
116 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will | |
117 * return immediately if nonblocking is set */ | |
118 int connect_remote(const char* remotehost, const char* remoteport, | |
119 int nonblocking, char ** errstring) { | |
120 | |
121 struct addrinfo *res0 = NULL, *res = NULL, hints; | |
122 int sock; | |
123 int err; | |
124 | |
125 TRACE(("enter connect_remote")); | |
126 | |
127 if (errstring != NULL) { | |
128 *errstring = NULL; | |
129 } | |
130 | |
131 memset(&hints, 0, sizeof(hints)); | |
132 hints.ai_socktype = SOCK_STREAM; | |
133 hints.ai_family = PF_UNSPEC; | |
134 | |
135 err = getaddrinfo(remotehost, remoteport, &hints, &res0); | |
136 if (err) { | |
137 if (errstring != NULL && *errstring == NULL) { | |
138 int len; | |
139 len = 20 + strlen(gai_strerror(err)); | |
140 *errstring = (char*)m_malloc(len); | |
141 snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); | |
142 } | |
143 TRACE(("Error resolving: %s", gai_strerror(err))); | |
144 return -1; | |
145 } | |
146 | |
147 sock = -1; | |
148 err = EADDRNOTAVAIL; | |
149 for (res = res0; res; res = res->ai_next) { | |
150 | |
151 sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
152 if (sock < 0) { | |
153 err = errno; | |
154 continue; | |
155 } | |
156 | |
157 if (nonblocking) { | |
158 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { | |
159 close(sock); | |
160 sock = -1; | |
161 if (errstring != NULL && *errstring == NULL) { | |
162 *errstring = m_strdup("Failed non-blocking"); | |
163 } | |
164 TRACE(("Failed non-blocking: %s", strerror(errno))); | |
165 continue; | |
166 } | |
167 } | |
168 | |
169 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { | |
170 if (errno == EINPROGRESS) { | |
171 TRACE(("Connect in progress")); | |
172 break; | |
173 } else { | |
174 err = errno; | |
175 close(sock); | |
176 sock = -1; | |
177 continue; | |
178 } | |
179 } | |
180 | |
181 break; /* Success */ | |
182 } | |
183 | |
184 if (sock < 0) { | |
185 /* Failed */ | |
186 if (errstring != NULL && *errstring == NULL) { | |
187 int len; | |
188 len = 20 + strlen(strerror(err)); | |
189 *errstring = (char*)m_malloc(len); | |
190 snprintf(*errstring, len, "Error connecting: %s", strerror(err)); | |
191 } | |
192 TRACE(("Error connecting: %s", strerror(err))); | |
193 } else { | |
194 /* Success */ | |
195 /* (err is used as a dummy var here) */ | |
196 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err)); | |
197 } | |
198 | |
199 freeaddrinfo(res0); | |
200 | |
201 TRACE(("leave connect_remote: sock %d", sock)); | |
202 return sock; | |
203 } | |
204 | |
116 /* Return a string representation of the socket address passed. The return | 205 /* Return a string representation of the socket address passed. The return |
117 * value is allocated with malloc() */ | 206 * value is allocated with malloc() */ |
118 unsigned char * getaddrstring(struct sockaddr * addr) { | 207 unsigned char * getaddrstring(struct sockaddr * addr) { |
119 | 208 |
120 char *retstring; | 209 char *retstring; |
302 return; | 391 return; |
303 while (len--) { | 392 while (len--) { |
304 *p++ = 0x66; | 393 *p++ = 0x66; |
305 } | 394 } |
306 } | 395 } |
396 |