1
0
mirror of https://github.com/irssi/irssi.git synced 2024-06-23 06:35:36 +00:00

Use GIOChannel instead of sockets directly. Helps porting to win32 :)

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@962 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2000-12-04 22:57:18 +00:00 committed by cras
parent e81fdd7307
commit 1c9f45b4a4
16 changed files with 224 additions and 203 deletions

View File

@ -53,11 +53,11 @@
#define G_INPUT_READ (1 << 0)
#define G_INPUT_WRITE (1 << 1)
typedef void (*GInputFunction) (void *data, int source, int condition);
typedef void (*GInputFunction) (void *data, GIOChannel *source, int condition);
int g_input_add(int source, int condition,
int g_input_add(GIOChannel *source, int condition,
GInputFunction function, void *data);
int g_input_add_full(int source, int priority, int condition,
int g_input_add_full(GIOChannel *source, int priority, int condition,
GInputFunction function, void *data);
#define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)

View File

@ -52,20 +52,17 @@ static int irssi_io_invoke(GIOChannel *source, GIOCondition condition,
if (condition & G_IO_OUT)
icond |= G_INPUT_WRITE;
if (rec->condition & icond) {
rec->function(rec->data, g_io_channel_unix_get_fd(source),
icond);
}
if (rec->condition & icond)
rec->function(rec->data, source, icond);
return TRUE;
}
int g_input_add_full(int source, int priority, int condition,
int g_input_add_full(GIOChannel *source, int priority, int condition,
GInputFunction function, void *data)
{
IRSSI_INPUT_REC *rec;
unsigned int result;
GIOChannel *channel;
GIOCondition cond;
rec = g_new(IRSSI_INPUT_REC, 1);
@ -79,15 +76,13 @@ int g_input_add_full(int source, int priority, int condition,
if (condition & G_INPUT_WRITE)
cond |= G_IO_OUT;
channel = g_io_channel_unix_new (source);
result = g_io_add_watch_full(channel, priority, cond,
result = g_io_add_watch_full(source, priority, cond,
irssi_io_invoke, rec, g_free);
g_io_channel_unref(channel);
return result;
}
int g_input_add(int source, int condition,
int g_input_add(GIOChannel *source, int condition,
GInputFunction function, void *data)
{
return g_input_add_full(source, G_PRIORITY_DEFAULT, condition,

View File

@ -29,7 +29,7 @@
typedef struct {
time_t created;
int handle;
GIOChannel *handle;
int tag;
} NET_DISCONNECT_REC;
@ -85,7 +85,7 @@ static int sig_timeout_disconnect(void)
/* Try to let the other side close the connection, if it still isn't
disconnected after certain amount of time, close it ourself */
void net_disconnect_later(int handle)
void net_disconnect_later(GIOChannel *handle)
{
NET_DISCONNECT_REC *rec;
@ -114,7 +114,7 @@ void net_disconnect_deinit(void)
#ifndef WIN32
NET_DISCONNECT_REC *rec;
time_t now, max;
int first;
int first, fd;
struct timeval tv;
fd_set set;
@ -131,12 +131,13 @@ void net_disconnect_deinit(void)
continue;
}
fd = g_io_channel_unix_get_fd(rec->handle);
FD_ZERO(&set);
FD_SET(rec->handle, &set);
FD_SET(fd, &set);
tv.tv_sec = first ? 0 : max-now;
tv.tv_usec = first ? 100000 : 0;
if (select(rec->handle+1, &set, NULL, NULL, &tv) > 0 &&
FD_ISSET(rec->handle, &set)) {
if (select(fd+1, &set, NULL, NULL, &tv) > 0 &&
FD_ISSET(fd, &set)) {
/* data coming .. check if we can close the handle */
sig_disconnect(rec);
} else if (first) {

View File

@ -29,15 +29,49 @@ typedef struct {
NET_CALLBACK func;
void *data;
int pipes[2];
GIOChannel *pipes[2];
int port;
IPADDR *my_ip;
int tag;
} SIMPLE_THREAD_REC;
#define is_fatal_error(err) \
(err != 0 && err != G_IO_ERROR_AGAIN && errno != EINTR)
static int g_io_channel_write_block(GIOChannel *channel, void *data, int len)
{
int err, ret, sent;
sent = 0;
do {
err = g_io_channel_write(channel, (char *) data + sent,
len-sent, &ret);
sent += ret;
} while (ret < len && !is_fatal_error(err));
return err != 0 ? -1 : 0;
}
static int g_io_channel_read_block(GIOChannel *channel, void *data, int len)
{
time_t maxwait;
int err, ret, received;
maxwait = time(NULL)+2;
received = 0;
do {
err = g_io_channel_read(channel, (char *) data + received,
len-received, &ret);
received += ret;
} while (received < len && time(NULL) < maxwait &&
(ret != 0 || !is_fatal_error(err)));
return received < len ? -1 : 0;
}
/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is
written to pipe when found PID of the resolver child is returned */
int net_gethostbyname_nonblock(const char *addr, int pipe)
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
{
RESOLVED_IP_REC rec;
const char *errorstr;
@ -72,9 +106,9 @@ int net_gethostbyname_nonblock(const char *addr, int pipe)
rec.errlen = strlen(errorstr)+1;
}
write(pipe, &rec, sizeof(rec));
g_io_channel_write_block(pipe, &rec, sizeof(rec));
if (rec.error != 0)
write(pipe, errorstr, rec.errlen);
g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
#ifndef WIN32
if (pid == 0)
@ -86,45 +120,24 @@ int net_gethostbyname_nonblock(const char *addr, int pipe)
}
/* get the resolved IP address */
int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec)
int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
{
time_t maxwait;
int len, ret;
rec->error = -1;
rec->errorstr = NULL;
/* get ip+error - try for max. 1-2 seconds */
#ifndef WIN32
fcntl(pipe, F_SETFL, O_NONBLOCK);
fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
#endif
maxwait = time(NULL)+2;
len = 0;
do {
ret = read(pipe, (char *) rec+len, sizeof(*rec)-len);
if (ret == -1) return -1;
len += ret;
} while (len < sizeof(*rec) && time(NULL) < maxwait);
if (len < sizeof(*rec))
return -1; /* timeout */
if (g_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1)
return -1;
if (rec->error) {
/* read error string */
rec->errorstr = g_malloc(rec->errlen+1);
len = 0;
do {
ret = read(pipe, rec->errorstr+len, rec->errlen-len);
if (ret == -1) break;
len += ret;
} while (len < rec->errlen && time(NULL) < maxwait);
if (len < rec->errlen) {
/* just ignore the rest of the error message.. */
rec->errorstr[len] = '\0';
}
/* read error string, if we can't read everything for some
reason, just ignore it. */
rec->errorstr = g_malloc0(rec->errlen+1);
g_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
}
return 0;
@ -133,7 +146,7 @@ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec)
/* Get host name, call func when finished */
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data)
{
/*FIXME*/
/* FIXME: not implemented */
return FALSE;
}
@ -147,7 +160,7 @@ void net_disconnect_nonblock(int pid)
#endif
}
static void simple_init(SIMPLE_THREAD_REC *rec, int handle)
static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle)
{
g_return_if_fail(rec != NULL);
@ -155,18 +168,19 @@ static void simple_init(SIMPLE_THREAD_REC *rec, int handle)
if (net_geterror(handle) != 0) {
/* failed */
close(handle);
handle = -1;
g_io_channel_close(handle);
g_io_channel_unref(handle);
handle = NULL;
}
rec->func(handle, rec->data);
g_free(rec);
}
static void simple_readpipe(SIMPLE_THREAD_REC *rec, int pipe)
static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe)
{
RESOLVED_IP_REC iprec;
int handle;
GIOChannel *handle;
g_return_if_fail(rec != NULL);
@ -175,17 +189,19 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, int pipe)
net_gethostbyname_return(pipe, &iprec);
g_free_not_null(iprec.errorstr);
close(rec->pipes[0]);
close(rec->pipes[1]);
g_io_channel_close(rec->pipes[0]);
g_io_channel_unref(rec->pipes[0]);
g_io_channel_close(rec->pipes[1]);
g_io_channel_unref(rec->pipes[1]);
handle = iprec.error == -1 ? -1 :
handle = iprec.error == -1 ? NULL :
net_connect_ip(&iprec.ip, rec->port, rec->my_ip);
g_free_not_null(rec->my_ip);
if (handle == -1) {
if (handle == NULL) {
/* failed */
rec->func(-1, rec->data);
rec->func(NULL, rec->data);
g_free(rec);
return;
}
@ -209,9 +225,6 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
return FALSE;
}
/* start nonblocking host name lookup */
net_gethostbyname_nonblock(server, fd[1]);
rec = g_new0(SIMPLE_THREAD_REC, 1);
rec->port = port;
if (my_ip != NULL) {
@ -220,10 +233,13 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
}
rec->func = func;
rec->data = data;
rec->pipes[0] = fd[0];
rec->pipes[1] = fd[1];
rec->tag = g_input_add(fd[0], G_INPUT_READ,
rec->pipes[0] = g_io_channel_unix_new(fd[0]);
rec->pipes[1] = g_io_channel_unix_new(fd[1]);
/* start nonblocking host name lookup */
net_gethostbyname_nonblock(server, rec->pipes[1]);
rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ,
(GInputFunction) simple_readpipe, rec);
return 1;
return TRUE;
}

View File

@ -20,18 +20,19 @@ typedef struct {
char *errorstr;
} RESOLVED_NAME_REC;
typedef void (*NET_CALLBACK) (int, void *);
typedef void (*NET_CALLBACK) (GIOChannel *, void *);
typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *);
/* nonblocking gethostbyname(), PID of the resolver child is returned. */
int net_gethostbyname_nonblock(const char *addr, int pipe);
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe);
/* Get host's name, call func when finished */
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data);
/* get the resolved IP address. returns -1 if some error occured with read() */
int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec);
int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec);
/* Connect to server, call func when finished */
int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, NET_CALLBACK func, void *data);
int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
NET_CALLBACK func, void *data);
/* Kill the resolver child */
void net_disconnect_nonblock(int pid);

View File

@ -24,7 +24,7 @@
#include "net-sendbuffer.h"
struct _NET_SENDBUF_REC {
int handle;
GIOChannel *handle;
int bufsize;
int bufpos;
@ -36,11 +36,11 @@ static int timeout_tag;
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
is used */
NET_SENDBUF_REC *net_sendbuffer_create(int handle, int bufsize)
NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize)
{
NET_SENDBUF_REC *rec;
g_return_val_if_fail(handle != -1, NULL);
g_return_val_if_fail(handle != NULL, NULL);
rec = g_new0(NET_SENDBUF_REC, 1);
rec->handle = handle;
@ -148,9 +148,9 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
}
/* Returns the socket handle */
int net_sendbuffer_handle(NET_SENDBUF_REC *rec)
GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec)
{
g_return_val_if_fail(rec != NULL, -1);
g_return_val_if_fail(rec != NULL, NULL);
return rec->handle;
}

View File

@ -7,7 +7,7 @@ typedef struct _NET_SENDBUF_REC NET_SENDBUF_REC;
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
is used */
NET_SENDBUF_REC *net_sendbuffer_create(int handle, int bufsize);
NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize);
/* Destroy the buffer. `close' specifies if socket handle should be closed. */
void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close);
@ -17,7 +17,7 @@ void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close);
int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size);
/* Returns the socket handle */
int net_sendbuffer_handle(NET_SENDBUF_REC *rec);
GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec);
void net_sendbuffer_init(void);
void net_sendbuffer_deinit(void);

View File

@ -23,7 +23,11 @@
#include "net-internal.h"
#ifndef INADDR_NONE
#define INADDR_NONE INADDR_BROADCAST
# define INADDR_NONE INADDR_BROADCAST
#endif
#ifndef EINPROGRESS
# define EINPROGESS 0 /* win32 */
#endif
union sockaddr_union {
@ -41,6 +45,12 @@ union sockaddr_union {
# define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
#endif
#ifdef WIN32
# define g_io_channel_new(handle) g_io_channel_win32_new_stream_socket(handle)
#else
# define g_io_channel_new(handle) g_io_channel_unix_new(handle)
#endif
/* Cygwin need this, don't know others.. */
/*#define BLOCKING_SOCKETS 1*/
@ -128,20 +138,20 @@ int sin_get_port(union sockaddr_union *so)
}
/* Connect to socket */
int net_connect(const char *addr, int port, IPADDR *my_ip)
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip)
{
IPADDR ip;
g_return_val_if_fail(addr != NULL, -1);
g_return_val_if_fail(addr != NULL, NULL);
if (net_gethostbyname(addr, &ip) == -1)
return -1;
return NULL;
return net_connect_ip(&ip, port, my_ip);
}
/* Connect to socket with ip address */
int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
{
union sockaddr_union so;
int handle, ret, opt = 1;
@ -152,7 +162,7 @@ int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
handle = socket(ip->family, SOCK_STREAM, 0);
if (handle == -1)
return -1;
return NULL;
/* set socket options */
#ifndef WIN32
@ -174,33 +184,32 @@ int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
sin_set_port(&so, port);
ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so));
#ifndef WIN32
if (ret < 0 && errno != EINPROGRESS) {
close(handle);
return -1;
return NULL;
}
#endif
return handle;
return g_io_channel_new(handle);
}
/* Disconnect socket */
void net_disconnect(int handle)
void net_disconnect(GIOChannel *handle)
{
g_return_if_fail(handle != -1);
g_return_if_fail(handle != NULL);
close(handle);
g_io_channel_close(handle);
g_io_channel_unref(handle);
}
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
address. */
int net_listen(IPADDR *my_ip, int *port)
GIOChannel *net_listen(IPADDR *my_ip, int *port)
{
union sockaddr_union so;
int ret, handle, opt = 1;
socklen_t len;
g_return_val_if_fail(port != NULL, -1);
g_return_val_if_fail(port != NULL, NULL);
memset(&so, 0, sizeof(so));
sin_set_port(&so, *port);
@ -209,7 +218,7 @@ int net_listen(IPADDR *my_ip, int *port)
/* create the socket */
handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
if (handle == -1)
return -1;
return NULL;
/* set socket options */
#ifndef WIN32
@ -222,44 +231,39 @@ int net_listen(IPADDR *my_ip, int *port)
/* specify the address/port we want to listen in */
ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
if (ret < 0) {
close(handle);
return -1;
if (ret >= 0) {
/* get the actual port we started listen */
len = SIZEOF_SOCKADDR(so);
ret = getsockname(handle, &so.sa, &len);
if (ret >= 0) {
*port = sin_get_port(&so);
/* start listening */
if (listen(handle, 1) >= 0)
return g_io_channel_new(handle);
}
}
/* get the actual port we started listen */
len = SIZEOF_SOCKADDR(so);
ret = getsockname(handle, &so.sa, &len);
if (ret < 0) {
close(handle);
return -1;
}
*port = sin_get_port(&so);
/* start listening */
if (listen(handle, 1) < 0) {
close(handle);
return -1;
}
return handle;
/* error */
close(handle);
return NULL;
}
/* Accept a connection on a socket */
int net_accept(int handle, IPADDR *addr, int *port)
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port)
{
union sockaddr_union so;
int ret;
socklen_t addrlen;
g_return_val_if_fail(handle != -1, -1);
g_return_val_if_fail(handle != NULL, NULL);
addrlen = SIZEOF_SOCKADDR(so);
ret = accept(handle, &so.sa, &addrlen);
ret = accept(g_io_channel_unix_get_fd(handle), &so.sa, &addrlen);
if (ret < 0)
return -1;
return NULL;
if (addr != NULL) sin_get_ip(&so, addr);
if (port != NULL) *port = sin_get_port(&so);
@ -267,68 +271,54 @@ int net_accept(int handle, IPADDR *addr, int *port)
#ifndef WIN32
fcntl(ret, F_SETFL, O_NONBLOCK);
#endif
return ret;
return g_io_channel_new(ret);
}
/* Read data from socket, return number of bytes read, -1 = error */
int net_receive(int handle, char *buf, int len)
int net_receive(GIOChannel *handle, char *buf, int len)
{
#ifdef BLOCKING_SOCKETS
fd_set set;
struct timeval tv;
#endif
int ret;
int ret, err;
g_return_val_if_fail(handle != -1, -1);
g_return_val_if_fail(handle != NULL, -1);
g_return_val_if_fail(buf != NULL, -1);
#ifdef BLOCKING_SOCKETS
FD_ZERO(&set);
FD_SET(handle, &set);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (select(handle+1, &set, NULL, NULL, &tv) <= 0 ||
!FD_ISSET(handle, &set)) return 0;
#endif
ret = recv(handle, buf, len, 0);
if (ret == 0)
err = g_io_channel_read(handle, buf, len, &ret);
if (err == 0 && ret == 0)
return -1; /* disconnected */
if (ret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN ||
errno == EINTR))
if (err == G_IO_ERROR_AGAIN || errno == EINTR)
return 0; /* no bytes received */
return ret;
return err == 0 ? ret : -1;
}
/* Transmit data, return number of bytes sent, -1 = error */
int net_transmit(int handle, const char *data, int len)
int net_transmit(GIOChannel *handle, const char *data, int len)
{
int n;
int ret, err;
g_return_val_if_fail(handle != -1, -1);
g_return_val_if_fail(handle != NULL, -1);
g_return_val_if_fail(data != NULL, -1);
n = send(handle, data, len, 0);
if (n == -1 && (errno == EWOULDBLOCK || errno == EAGAIN ||
errno == EINTR || errno == EPIPE))
err = g_io_channel_write(handle, (char *) data, len, &ret);
if (err == G_IO_ERROR_AGAIN || errno == EINTR || errno == EPIPE)
return 0;
return n > 0 ? n : -1;
return err == 0 ? ret : -1;
}
/* Get socket address/port */
int net_getsockname(int handle, IPADDR *addr, int *port)
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
{
union sockaddr_union so;
socklen_t len;
g_return_val_if_fail(handle != -1, -1);
g_return_val_if_fail(handle != NULL, -1);
g_return_val_if_fail(addr != NULL, -1);
len = SIZEOF_SOCKADDR(so);
if (getsockname(handle, (struct sockaddr *) &so, &len) == -1)
if (getsockname(g_io_channel_unix_get_fd(handle),
(struct sockaddr *) &so, &len) == -1)
return -1;
sin_get_ip(&so, addr);
@ -469,12 +459,13 @@ int net_host2ip(const char *host, IPADDR *ip)
}
/* Get socket error */
int net_geterror(int handle)
int net_geterror(GIOChannel *handle)
{
int data;
socklen_t len = sizeof(data);
if (getsockopt(handle, SOL_SOCKET, SO_ERROR, (void *) &data, &len) == -1)
if (getsockopt(g_io_channel_unix_get_fd(handle),
SOL_SOCKET, SO_ERROR, (void *) &data, &len) == -1)
return -1;
return data;

View File

@ -33,24 +33,24 @@ typedef struct _ipaddr IPADDR;
int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
/* Connect to socket */
int net_connect(const char *addr, int port, IPADDR *my_ip);
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip);
/* Connect to socket with ip address */
int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
/* Disconnect socket */
void net_disconnect(int handle);
void net_disconnect(GIOChannel *handle);
/* Try to let the other side close the connection, if it still isn't
disconnected after certain amount of time, close it ourself */
void net_disconnect_later(int handle);
void net_disconnect_later(GIOChannel *handle);
/* Listen for connections on a socket */
int net_listen(IPADDR *my_ip, int *port);
GIOChannel *net_listen(IPADDR *my_ip, int *port);
/* Accept a connection on a socket */
int net_accept(int handle, IPADDR *addr, int *port);
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port);
/* Read data from socket, return number of bytes read, -1 = error */
int net_receive(int handle, char *buf, int len);
int net_receive(GIOChannel *handle, char *buf, int len);
/* Transmit data, return number of bytes sent, -1 = error */
int net_transmit(int handle, const char *data, int len);
int net_transmit(GIOChannel *handle, const char *data, int len);
/* Get IP address for host, returns 0 = ok,
others = error code for net_gethosterror() */
@ -65,13 +65,13 @@ const char *net_gethosterror(int error);
int net_hosterror_notfound(int error);
/* Get socket address/port */
int net_getsockname(int handle, IPADDR *addr, int *port);
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port);
int net_ip2host(IPADDR *ip, char *host);
int net_host2ip(const char *host, IPADDR *ip);
/* Get socket error */
int net_geterror(int handle);
int net_geterror(GIOChannel *handle);
int is_ipv4_address(const char *host);
int is_ipv6_address(const char *host);

View File

@ -17,7 +17,7 @@ void *handle; /* NET_SENDBUF_REC socket */
int readtag; /* input tag */
/* for net_connect_nonblock() */
int connect_pipe[2];
GIOChannel *connect_pipe[2];
int connect_tag;
int connect_pid;

View File

@ -51,9 +51,11 @@ void server_connect_failed(SERVER_REC *server, const char *msg)
if (server->handle != NULL)
net_sendbuffer_destroy(server->handle, TRUE);
if (server->connect_pipe[0] != -1) {
close(server->connect_pipe[0]);
close(server->connect_pipe[1]);
if (server->connect_pipe[0] != NULL) {
g_io_channel_close(server->connect_pipe[0]);
g_io_channel_unref(server->connect_pipe[0]);
g_io_channel_close(server->connect_pipe[1]);
g_io_channel_unref(server->connect_pipe[1]);
}
MODULE_DATA_DEINIT(server);
@ -129,7 +131,7 @@ void server_connect_finished(SERVER_REC *server)
signal_emit("server connected", 1, server);
}
static void server_connect_callback_init(SERVER_REC *server, int handle)
static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
{
int error;
@ -154,7 +156,7 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
SERVER_CONNECT_REC *conn;
RESOLVED_IP_REC iprec;
const char *errormsg;
int handle;
GIOChannel *handle;
g_return_if_fail(IS_SERVER(server));
@ -163,18 +165,20 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
net_gethostbyname_return(server->connect_pipe[0], &iprec);
close(server->connect_pipe[0]);
close(server->connect_pipe[1]);
g_io_channel_close(server->connect_pipe[0]);
g_io_channel_unref(server->connect_pipe[0]);
g_io_channel_close(server->connect_pipe[1]);
g_io_channel_unref(server->connect_pipe[1]);
server->connect_pipe[0] = -1;
server->connect_pipe[1] = -1;
server->connect_pipe[0] = NULL;
server->connect_pipe[1] = NULL;
conn = server->connrec;
handle = iprec.error != 0 ? -1 :
handle = iprec.error != 0 ? NULL :
net_connect_ip(&iprec.ip, conn->proxy != NULL ?
conn->proxy_port : conn->port,
conn->own_ip != NULL ? conn->own_ip : NULL);
if (handle == -1) {
if (handle == NULL) {
/* failed */
if (iprec.error == 0 || !net_hosterror_notfound(iprec.error)) {
/* reconnect back only if either
@ -237,19 +241,23 @@ void server_connect_init(SERVER_REC *server)
int server_start_connect(SERVER_REC *server)
{
const char *connect_address;
int fd[2];
g_return_val_if_fail(server != NULL, FALSE);
if (server->connrec->port <= 0) return FALSE;
server_connect_init(server);
if (pipe(server->connect_pipe) != 0) {
if (pipe(fd) != 0) {
g_warning("server_connect(): pipe() failed.");
g_free(server->tag);
g_free(server->nick);
return FALSE;
}
server->connect_pipe[0] = g_io_channel_unix_new(fd[0]);
server->connect_pipe[1] = g_io_channel_unix_new(fd[1]);
connect_address = server->connrec->proxy != NULL ?
server->connrec->proxy : server->connrec->address;
server->connect_pid =

View File

@ -550,7 +550,9 @@ void gui_readline_init(void)
cutbuffer = NULL;
redir = NULL;
idle_time = time(NULL);
readtag = g_input_add_full(0, G_PRIORITY_HIGH, G_INPUT_READ, (GInputFunction) readline, NULL);
readtag = g_input_add_full(g_io_channel_unix_new(0),
G_PRIORITY_HIGH, G_INPUT_READ,
(GInputFunction) readline, NULL);
settings_add_str("history", "scroll_page_count", "/2");

View File

@ -190,19 +190,20 @@ static void dcc_chat_input(DCC_REC *dcc)
static void dcc_chat_listen(DCC_REC *dcc)
{
IPADDR ip;
int handle, port;
GIOChannel *handle;
int port;
g_return_if_fail(dcc != NULL);
/* accept connection */
handle = net_accept(dcc->handle, &ip, &port);
if (handle == -1)
if (handle == NULL)
return;
/* TODO: add paranoia check - see dcc-files.c */
g_source_remove(dcc->tagconn);
close(dcc->handle);
net_disconnect(dcc->handle);
dcc->starttime = time(NULL);
dcc->handle = handle;
@ -243,14 +244,14 @@ static void dcc_chat_connect(DCC_REC *dcc)
g_return_if_fail(dcc != NULL);
if (dcc->addrstr[0] == '\0' ||
dcc->starttime != 0 || dcc->handle != -1) {
dcc->starttime != 0 || dcc->handle != NULL) {
/* already sent a chat request / already chatting */
return;
}
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
source_host_ok ? source_host_ip : NULL);
if (dcc->handle != -1) {
if (dcc->handle != NULL) {
dcc->tagconn = g_input_add(dcc->handle,
G_INPUT_WRITE | G_INPUT_READ,
(GInputFunction) sig_chat_connected, dcc);
@ -267,8 +268,9 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
void *free_arg;
DCC_REC *dcc;
IPADDR own_ip;
GIOChannel *handle;
char *nick, *str, host[MAX_IP_LEN];
int port, handle;
int port;
g_return_if_fail(data != NULL);
@ -288,12 +290,13 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
if (server == NULL || !server->connected)
cmd_param_error(CMDERR_NOT_CONNECTED);
if (net_getsockname(net_sendbuffer_handle(server->handle), &own_ip, NULL) == -1)
if (net_getsockname(net_sendbuffer_handle(server->handle),
&own_ip, NULL) == -1)
cmd_param_error(CMDERR_ERRNO);
port = settings_get_int("dcc_port");
handle = net_listen(&own_ip, &port);
if (handle == -1)
if (handle == NULL)
cmd_param_error(CMDERR_ERRNO);
dcc = dcc_create(DCC_TYPE_CHAT, handle, nick, "chat", server, NULL);

View File

@ -197,7 +197,7 @@ static void dcc_get_connect(DCC_REC *dcc)
{
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
source_host_ok ? source_host_ip : NULL);
if (dcc->handle != -1) {
if (dcc->handle != NULL) {
dcc->tagconn = g_input_add(dcc->handle,
G_INPUT_WRITE | G_INPUT_READ,
(GInputFunction) sig_dccget_connected, dcc);
@ -209,7 +209,7 @@ static void dcc_get_connect(DCC_REC *dcc)
}
#define dcc_is_unget(dcc) \
((dcc)->type == DCC_TYPE_GET && (dcc)->handle == -1)
((dcc)->type == DCC_TYPE_GET && (dcc)->handle == NULL)
/* SYNTAX: DCC GET <nick> [<file>] */
static void cmd_dcc_get(const char *data)
@ -268,7 +268,7 @@ static void dcc_resume_send(DCC_REC *dcc, int port)
#define is_accept_ok(type, dcc) \
(g_strcasecmp(type, "ACCEPT") != 0 || \
((dcc)->type == DCC_TYPE_GET && \
(dcc)->get_type == DCC_GET_RESUME && (dcc)->handle == -1))
(dcc)->get_type == DCC_GET_RESUME && (dcc)->handle == NULL))
static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
const char *sender, const char *sendaddr,
@ -453,14 +453,15 @@ static void dcc_send_read_size(DCC_REC *dcc)
/* input function: DCC SEND - someone tried to connect to our socket */
static void dcc_send_init(DCC_REC *dcc)
{
int handle, port;
GIOChannel *handle;
IPADDR addr;
int port;
g_return_if_fail(dcc != NULL);
/* accept connection */
handle = net_accept(dcc->handle, &addr, &port);
if (handle == -1)
if (handle == NULL)
return;
/* TODO: some kind of paranoia check would be nice. it would check
@ -468,7 +469,7 @@ static void dcc_send_init(DCC_REC *dcc)
address who connected us. */
g_source_remove(dcc->tagconn);
close(dcc->handle);
net_disconnect(dcc->handle);
dcc->starttime = time(NULL);
dcc->fastsend = settings_get_bool("dcc_fast_send");
@ -501,10 +502,11 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item)
char *target, *fname, *str, *ptr;
void *free_arg;
char host[MAX_IP_LEN];
int hfile, hlisten, port;
int hfile, port;
long fsize;
DCC_REC *dcc, *chat;
IPADDR own_ip;
GIOChannel *handle, *hlisten;
g_return_if_fail(data != NULL);
@ -549,7 +551,9 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item)
lseek(hfile, 0, SEEK_SET);
/* get the IP address we use with IRC server */
if (net_getsockname(chat != NULL ? chat->handle : net_sendbuffer_handle(server->handle), &own_ip, NULL) == -1) {
handle = chat != NULL ? chat->handle :
net_sendbuffer_handle(server->handle);
if (net_getsockname(handle, &own_ip, NULL) == -1) {
close(hfile);
cmd_param_error(CMDERR_ERRNO);
}
@ -557,7 +561,7 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item)
/* start listening */
port = settings_get_int("dcc_port");
hlisten = net_listen(&own_ip, &port);
if (hlisten == -1) {
if (hlisten == NULL) {
close(hfile);
cmd_param_error(CMDERR_ERRNO);
}

View File

@ -52,7 +52,7 @@ GSList *dcc_conns;
static int dcc_timeouttag;
/* Create new DCC record */
DCC_REC *dcc_create(int type, int handle, const char *nick, const char *arg,
DCC_REC *dcc_create(int type, GIOChannel *handle, const char *nick, const char *arg,
IRC_SERVER_REC *server, DCC_REC *chat)
{
DCC_REC *dcc;
@ -110,7 +110,7 @@ void dcc_destroy(DCC_REC *dcc)
signal_emit("dcc destroyed", 1, dcc);
if (dcc->fhandle != -1) close(dcc->fhandle);
if (dcc->handle != -1) net_disconnect(dcc->handle);
if (dcc->handle != NULL) net_disconnect(dcc->handle);
if (dcc->tagconn != -1) g_source_remove(dcc->tagconn);
if (dcc->tagread != -1) g_source_remove(dcc->tagread);
if (dcc->tagwrite != -1) g_source_remove(dcc->tagwrite);
@ -304,21 +304,21 @@ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char
if (olddcc != NULL) {
/* same DCC request offered again */
if (olddcc->type == DCC_TYPE_CHAT &&
olddcc->handle != -1 && olddcc->starttime == 0) {
olddcc->handle != NULL && olddcc->starttime == 0) {
/* we requested dcc chat, they requested
dcc chat from us .. allow it. */
dcc_destroy(olddcc);
} else {
/* if the connection isn't open, update the port,
otherwise just ignore */
if (olddcc->handle == -1)
if (olddcc->handle == NULL)
olddcc->port = port;
cmd_params_free(free_arg);
return;
}
}
dcc = dcc_create(dcctype, -1, sender, arg, server, chat);
dcc = dcc_create(dcctype, NULL, sender, arg, server, chat);
dcc_get_address(addrstr, &dcc->addr);
net_ip2host(&dcc->addr, dcc->addrstr);
dcc->port = port;

View File

@ -40,7 +40,7 @@ typedef struct DCC_REC {
int port; /* port we're connected in */
long size, transfd, skipped; /* file size / bytes transferred / skipped at start */
int handle; /* socket handle */
GIOChannel *handle; /* socket handle */
void *sendbuf;
int tagconn, tagread, tagwrite;
int fhandle; /* file handle */
@ -80,7 +80,7 @@ const char *dcc_type2str(int type);
int dcc_str2type(const char *type);
void dcc_make_address(IPADDR *ip, char *host);
DCC_REC *dcc_create(int type, int handle, const char *nick, const char *arg, IRC_SERVER_REC *server, DCC_REC *chat);
DCC_REC *dcc_create(int type, GIOChannel *handle, const char *nick, const char *arg, IRC_SERVER_REC *server, DCC_REC *chat);
void dcc_destroy(DCC_REC *dcc);
/* Send a CTCP message/notify to target. Send the CTCP via DCC chat if