Use regex.[ch] from msysGit's /git
[cvsps/4msysgit.git] / cbtcommon / tcpsocket.c
blobb649f1cce27461b61e096910e4054723888e5231
1 /*
2 * Copyright 2001, 2002, 2003 David Mansfield and Cobite, Inc.
3 * See COPYING file for license information
4 */
6 #ifdef SOLARIS
7 #include <strings.h>
8 #else
9 #include <string.h>
10 #endif
12 #ifdef __MINGW32__
13 #include <winsock2.h>
14 #include <errno.h>
15 #undef WIN32
16 #elif defined(WIN32)
17 #include <winsock2.h>
18 #else /* not windows */
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <netdb.h>
24 #include <errno.h>
26 #ifdef SOLARIS
27 #include <netinet/tcp.h>
28 #endif
30 #endif /* if windows */
32 #include "tcpsocket.h"
33 #include "debug.h"
34 #include "rcsid.h"
35 #ifdef __MINGW32__
36 #elif defined(WIN32)
37 #include "win32fd.h"
38 #endif
40 RCSID("$Id: tcpsocket.c,v 1.6 1999/12/27 20:35:34 david Exp $");
42 int
43 tcp_create_socket(int reuse_addr)
45 int retval;
46 int yes = 1;
48 if ((retval = socket(AF_INET, SOCK_STREAM, 0)) < 0)
50 debug(DEBUG_TCP, "tcp: can't create socket");
51 return retval;
54 if (reuse_addr)
56 setsockopt( retval, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(int));
59 debug(DEBUG_TCP, "tcp: socket created");
60 #ifdef WIN32
61 return get_fd(retval, WIN32_SOCKET);
62 #else
63 return retval;
64 #endif
67 int
68 tcp_bind_and_listen(int sockfd, unsigned short tcp_port)
70 struct sockaddr_in addr;
72 memset((char *) &addr, 0, sizeof(struct sockaddr_in));
73 addr.sin_family = AF_INET;
74 addr.sin_addr.s_addr = htonl(INADDR_ANY);
75 addr.sin_port = htons(tcp_port);
77 #ifdef WIN32
78 sockfd = win32_file_table[sockfd].win32id;
79 #endif
81 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
83 debug(DEBUG_ERROR, "tcp: can't bind to socket");
84 return -1;
88 if (listen(sockfd, LISTEN_QUEUE_SIZE) < 0)
90 debug(DEBUG_ERROR, "tcp: can't listen on socket");
91 return -1;
94 debug(DEBUG_TCP, "tcp: socket bound and listening");
96 return 0;
99 int
100 tcp_accept_connection(int sockfd)
102 struct sockaddr_in remaddr;
103 int addrlen;
104 int retval;
106 #ifdef WIN32
107 sockfd = win32_file_table[sockfd].win32id;
108 #endif
110 addrlen = sizeof(struct sockaddr_in);
112 #ifdef WIN32
113 if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) == INVALID_SOCKET)
115 debug(DEBUG_APPERROR, "tcp: error accepting connection");
116 return -1;
118 #else
119 if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
121 if (errno != EINTR )
122 debug(DEBUG_ERROR, "tcp: error accepting connection");
124 return -1;
126 #endif
128 debug(DEBUG_TCP, "tcp: got connection (fd=%d)", retval);
130 return retval;
133 unsigned int
134 tcp_get_client_ip(int fd)
136 struct sockaddr_in remaddr;
137 int addrlen;
138 int retval;
139 unsigned int saddr;
141 #ifdef WIN32
142 fd = win32_file_table[fd].win32id;
143 #endif
145 addrlen = sizeof(struct sockaddr_in);
147 if ((retval = getpeername(fd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
149 debug(DEBUG_ERROR, "tcp: error getting remote's ip address");
150 return 0;
153 saddr = ntohl(remaddr.sin_addr.s_addr);
155 return saddr;
159 tcp_connect(int sockfd, const char *rem_addr, unsigned short port)
161 struct sockaddr_in addr;
162 int addrlen;
163 long ipno;
165 #ifdef WIN32
166 sockfd = win32_file_table[sockfd].win32id;
167 #endif
169 if ( convert_address(&ipno , rem_addr) < 0 )
171 return -1;
174 addrlen = sizeof(struct sockaddr_in);
176 memset((char *) &addr, 0, sizeof(struct sockaddr_in));
177 addr.sin_family = AF_INET;
178 addr.sin_addr.s_addr = ipno;
179 addr.sin_port = htons(port);
181 if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0)
183 debug(DEBUG_ERROR, "connect error");
184 return -1;
187 debug(DEBUG_STATUS, "tcp: connection established on port %d", port);
188 return 0;
192 convert_address(long *dest, const char *addr_str)
194 #ifdef LINUX
195 struct in_addr ip;
196 #endif
197 int retval = 0;
198 char errstr[256];
200 /* first try converting "numbers and dots" notation */
201 #ifdef LINUX
202 if ( inet_aton(addr_str, &ip) )
204 memcpy(dest, &ip.s_addr, sizeof(ip.s_addr));
206 #else
207 if ( (*dest = inet_addr(addr_str)) != -1)
209 /* nothing */
211 #endif
212 else /* if it fails, do a gethostbyname() */
214 struct hostent *host;
215 if ((host = gethostbyname(addr_str)) == NULL)
217 switch(h_errno)
219 case HOST_NOT_FOUND:
220 strcpy(errstr, "HOST_NOT_FOUND");
221 break;
223 case NO_ADDRESS:
224 strcpy(errstr, "NO_ADDRESS");
225 break;
227 case NO_RECOVERY:
228 strcpy(errstr, "NO_RECOVERY");
229 break;
231 case TRY_AGAIN:
232 strcpy(errstr, "TRY_AGAIN");
233 break;
236 debug(DEBUG_ERROR, "gethostbyname failed for %s: ", addr_str, errstr);
238 retval = -1;
241 memcpy(dest, host->h_addr_list[0], sizeof(unsigned long));
245 return retval;
248 int tcp_get_local_address(int sockfd, unsigned int *ip, unsigned short *port)
250 struct sockaddr_in addr;
251 int addrlen = sizeof(struct sockaddr_in);
253 if(getsockname(sockfd, (struct sockaddr *)&addr, &addrlen) < 0)
255 debug(DEBUG_SYSERROR, "getsockname failed" );
256 return -1;
259 *ip = ntohl( addr.sin_addr.s_addr );
260 *port = ntohs( addr.sin_port );
262 return 0;