4 * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #include <glib/gi18n-lib.h>
31 #include <sys/timeb.h>
36 #include "libc_internal.h"
38 #include <glib/gstdio.h>
42 # define S_ISDIR(m) (((m)&S_IFDIR)==S_IFDIR)
45 static char errbuf
[1024];
48 static int wpurple_is_socket( int fd
) {
50 int optlen
= sizeof(int);
52 if( (getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (void*)&optval
, &optlen
)) == SOCKET_ERROR
) {
53 int error
= WSAGetLastError();
54 if( error
== WSAENOTSOCK
)
57 purple_debug(PURPLE_DEBUG_WARNING
, "wpurple", "wpurple_is_socket: getsockopt returned error: %d\n", error
);
65 int wpurple_socket (int namespace, int style
, int protocol
) {
68 ret
= socket( namespace, style
, protocol
);
70 if (ret
== (int)INVALID_SOCKET
) {
71 errno
= WSAGetLastError();
77 int wpurple_connect(int socket
, struct sockaddr
*addr
, u_long length
) {
80 ret
= connect( socket
, addr
, length
);
82 if( ret
== SOCKET_ERROR
) {
83 errno
= WSAGetLastError();
84 if( errno
== WSAEWOULDBLOCK
)
85 errno
= WSAEINPROGRESS
;
91 int wpurple_getsockopt(int socket
, int level
, int optname
, void *optval
, socklen_t
*optlenptr
) {
92 if(getsockopt(socket
, level
, optname
, optval
, optlenptr
) == SOCKET_ERROR
) {
93 errno
= WSAGetLastError();
99 int wpurple_setsockopt(int socket
, int level
, int optname
, const void *optval
, socklen_t optlen
) {
100 if(setsockopt(socket
, level
, optname
, optval
, optlen
) == SOCKET_ERROR
) {
101 errno
= WSAGetLastError();
107 int wpurple_getsockname(int socket
, struct sockaddr
*addr
, socklen_t
*lenptr
) {
108 if(getsockname(socket
, addr
, lenptr
) == SOCKET_ERROR
) {
109 errno
= WSAGetLastError();
115 int wpurple_bind(int socket
, struct sockaddr
*addr
, socklen_t length
) {
116 if(bind(socket
, addr
, length
) == SOCKET_ERROR
) {
117 errno
= WSAGetLastError();
123 int wpurple_listen(int socket
, unsigned int n
) {
124 if(listen(socket
, n
) == SOCKET_ERROR
) {
125 errno
= WSAGetLastError();
131 int wpurple_sendto(int socket
, const void *buf
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
) {
133 if ((ret
= sendto(socket
, buf
, len
, flags
, to
, tolen
)
135 errno
= WSAGetLastError();
136 if(errno
== WSAEWOULDBLOCK
|| errno
== WSAEINPROGRESS
)
144 /* This is not a full implementation of fcntl. Update as needed.. */
145 int wpurple_fcntl(int socket
, int command
, ...) {
157 va_start(args
, command
);
158 val
= va_arg(args
, int);
165 ret
= ioctlsocket(socket
, FIONBIO
, &imode
);
171 ret
= ioctlsocket(socket
, FIONBIO
, &imode
);
178 if( ret
== SOCKET_ERROR
) {
179 errno
= WSAGetLastError();
185 purple_debug(PURPLE_DEBUG_WARNING
, "wpurple", "wpurple_fcntl: Unsupported command\n");
191 int wpurple_ioctl(int fd
, int command
, void* val
) {
195 if (ioctlsocket(fd
, FIONBIO
, (unsigned long *)val
) == SOCKET_ERROR
) {
196 errno
= WSAGetLastError();
203 INTERFACE_INFO InterfaceList
[20];
204 unsigned long nBytesReturned
;
205 if (WSAIoctl(fd
, SIO_GET_INTERFACE_LIST
,
206 0, 0, &InterfaceList
,
207 sizeof(InterfaceList
), &nBytesReturned
,
208 0, 0) == SOCKET_ERROR
) {
209 errno
= WSAGetLastError();
213 struct ifconf
*ifc
= val
;
214 char *tmp
= ifc
->ifc_buf
;
216 nBytesReturned
/ sizeof(INTERFACE_INFO
);
217 for (i
= 0; i
< nNumInterfaces
; i
++) {
218 INTERFACE_INFO ii
= InterfaceList
[i
];
219 struct ifreq
*ifr
= (struct ifreq
*) tmp
;
220 struct sockaddr_in
*sa
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
222 sa
->sin_family
= ii
.iiAddress
.AddressIn
.sin_family
;
223 sa
->sin_port
= ii
.iiAddress
.AddressIn
.sin_port
;
224 sa
->sin_addr
.s_addr
= ii
.iiAddress
.AddressIn
.sin_addr
.s_addr
;
225 tmp
+= sizeof(struct ifreq
);
227 /* Make sure that we can fit in the original buffer */
228 if (tmp
>= (ifc
->ifc_buf
+ ifc
->ifc_len
+ sizeof(struct ifreq
))) {
232 /* Replace the length with the actually used length */
233 ifc
->ifc_len
= ifc
->ifc_len
- (ifc
->ifc_buf
- tmp
);
244 int wpurple_inet_aton(const char *name
, struct in_addr
*addr
) {
245 if((addr
->s_addr
= inet_addr(name
)) == INADDR_NONE
)
251 /* Thanks to GNU wget for this inet_ntop() implementation */
253 wpurple_inet_ntop (int af
, const void *src
, char *dst
, socklen_t cnt
)
255 /* struct sockaddr can't accomodate struct sockaddr_in6. */
257 struct sockaddr_in6 sin6
;
258 struct sockaddr_in sin
;
263 ZeroMemory(&sa
, sizeof(sa
));
267 sa
.sin
.sin_family
= AF_INET
;
268 sa
.sin
.sin_addr
= *(struct in_addr
*) src
;
269 srcsize
= sizeof (sa
.sin
);
272 sa
.sin6
.sin6_family
= AF_INET6
;
273 sa
.sin6
.sin6_addr
= *(struct in6_addr
*) src
;
274 srcsize
= sizeof (sa
.sin6
);
280 if (WSAAddressToString ((struct sockaddr
*) &sa
, srcsize
, NULL
, dst
, &dstlen
) != 0)
282 errno
= WSAGetLastError();
285 return (const char *) dst
;
289 wpurple_inet_pton(int af
, const char *src
, void *dst
)
291 /* struct sockaddr can't accomodate struct sockaddr_in6. */
293 struct sockaddr_in6 sin6
;
294 struct sockaddr_in sin
;
301 sa
.sin
.sin_family
= AF_INET
;
302 srcsize
= sizeof (sa
.sin
);
305 sa
.sin6
.sin6_family
= AF_INET6
;
306 srcsize
= sizeof (sa
.sin6
);
309 errno
= WSAEPFNOSUPPORT
;
313 if (WSAStringToAddress((LPTSTR
)src
, af
, NULL
, (struct sockaddr
*) &sa
, &srcsize
) != 0)
315 errno
= WSAGetLastError();
322 memcpy(dst
, &sa
.sin
.sin_addr
, sizeof(sa
.sin
.sin_addr
));
325 memcpy(dst
, &sa
.sin6
.sin6_addr
, sizeof(sa
.sin6
.sin6_addr
));
334 struct hostent
* wpurple_gethostbyname(const char *name
) {
337 if((hp
= gethostbyname(name
)) == NULL
) {
338 errno
= WSAGetLastError();
345 char* wpurple_strerror(int errornum
) {
346 if (errornum
> WSABASEERR
) {
348 case WSAECONNABORTED
: /* 10053 */
349 g_snprintf(errbuf
, sizeof(errbuf
), "%s", _("Connection interrupted by other software on your computer."));
351 case WSAECONNRESET
: /* 10054 */
352 g_snprintf(errbuf
, sizeof(errbuf
), "%s", _("Remote host closed connection."));
354 case WSAETIMEDOUT
: /* 10060 */
355 g_snprintf(errbuf
, sizeof(errbuf
), "%s", _("Connection timed out."));
357 case WSAECONNREFUSED
: /* 10061 */
358 g_snprintf(errbuf
, sizeof(errbuf
), "%s", _("Connection refused."));
360 case WSAEADDRINUSE
: /* 10048 */
361 g_snprintf(errbuf
, sizeof(errbuf
), "%s", _("Address already in use."));
364 g_snprintf(errbuf
, sizeof(errbuf
), "Windows socket error #%d", errornum
);
367 const char *tmp
= g_strerror(errornum
);
368 g_snprintf(errbuf
, sizeof(errbuf
), "%s", tmp
);
376 * We need to figure out whether fd is a file or socket handle.
378 int wpurple_read(int fd
, void *buf
, unsigned int size
) {
383 g_return_val_if_reached(-1);
386 if(wpurple_is_socket(fd
)) {
387 if((ret
= recv(fd
, buf
, size
, 0)) == SOCKET_ERROR
) {
388 errno
= WSAGetLastError();
389 if(errno
== WSAEWOULDBLOCK
|| errno
== WSAEINPROGRESS
)
394 /* success reading socket */
398 /* fd is not a socket handle.. pass it off to read */
399 return _read(fd
, buf
, size
);
403 int wpurple_send(int fd
, const void *buf
, unsigned int size
, int flags
) {
406 ret
= send(fd
, buf
, size
, flags
);
408 if (ret
== SOCKET_ERROR
) {
409 errno
= WSAGetLastError();
410 if(errno
== WSAEWOULDBLOCK
|| errno
== WSAEINPROGRESS
)
417 int wpurple_write(int fd
, const void *buf
, unsigned int size
) {
421 g_return_val_if_reached(-1);
424 if(wpurple_is_socket(fd
))
425 return wpurple_send(fd
, buf
, size
, 0);
427 return _write(fd
, buf
, size
);
430 int wpurple_recv(int fd
, void *buf
, size_t len
, int flags
) {
433 if((ret
= recv(fd
, buf
, len
, flags
)) == SOCKET_ERROR
) {
434 errno
= WSAGetLastError();
435 if(errno
== WSAEWOULDBLOCK
|| errno
== WSAEINPROGRESS
)
443 int wpurple_close(int fd
) {
448 g_return_val_if_reached(-1);
451 if( wpurple_is_socket(fd
) ) {
452 if( (ret
= closesocket(fd
)) == SOCKET_ERROR
) {
453 errno
= WSAGetLastError();
463 int wpurple_gethostname(char *name
, size_t size
) {
464 if(gethostname(name
, size
) == SOCKET_ERROR
) {
465 errno
= WSAGetLastError();
473 int wpurple_gettimeofday(struct timeval
*p
, struct timezone
*z
) {
475 struct _timeb timebuffer
;
479 z
->tz_minuteswest
= _timezone
/60;
480 z
->tz_dsttime
= _daylight
;
485 p
->tv_sec
= timebuffer
.time
; /* seconds since 1-1-1970 */
486 p
->tv_usec
= timebuffer
.millitm
*1000; /* microseconds */
494 struct tm
* wpurple_localtime_r (const time_t *time
, struct tm
*resultp
) {
499 tmptm
= localtime(time
);
501 return memcpy(resultp
, tmptm
, sizeof(struct tm
));