mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05: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:
parent
e81fdd7307
commit
1c9f45b4a4
@ -53,11 +53,11 @@
|
|||||||
#define G_INPUT_READ (1 << 0)
|
#define G_INPUT_READ (1 << 0)
|
||||||
#define G_INPUT_WRITE (1 << 1)
|
#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);
|
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);
|
GInputFunction function, void *data);
|
||||||
|
|
||||||
#define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)
|
#define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)
|
||||||
|
@ -52,20 +52,17 @@ static int irssi_io_invoke(GIOChannel *source, GIOCondition condition,
|
|||||||
if (condition & G_IO_OUT)
|
if (condition & G_IO_OUT)
|
||||||
icond |= G_INPUT_WRITE;
|
icond |= G_INPUT_WRITE;
|
||||||
|
|
||||||
if (rec->condition & icond) {
|
if (rec->condition & icond)
|
||||||
rec->function(rec->data, g_io_channel_unix_get_fd(source),
|
rec->function(rec->data, source, icond);
|
||||||
icond);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
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)
|
GInputFunction function, void *data)
|
||||||
{
|
{
|
||||||
IRSSI_INPUT_REC *rec;
|
IRSSI_INPUT_REC *rec;
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
GIOChannel *channel;
|
|
||||||
GIOCondition cond;
|
GIOCondition cond;
|
||||||
|
|
||||||
rec = g_new(IRSSI_INPUT_REC, 1);
|
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)
|
if (condition & G_INPUT_WRITE)
|
||||||
cond |= G_IO_OUT;
|
cond |= G_IO_OUT;
|
||||||
|
|
||||||
channel = g_io_channel_unix_new (source);
|
result = g_io_add_watch_full(source, priority, cond,
|
||||||
result = g_io_add_watch_full(channel, priority, cond,
|
|
||||||
irssi_io_invoke, rec, g_free);
|
irssi_io_invoke, rec, g_free);
|
||||||
g_io_channel_unref(channel);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int g_input_add(int source, int condition,
|
int g_input_add(GIOChannel *source, int condition,
|
||||||
GInputFunction function, void *data)
|
GInputFunction function, void *data)
|
||||||
{
|
{
|
||||||
return g_input_add_full(source, G_PRIORITY_DEFAULT, condition,
|
return g_input_add_full(source, G_PRIORITY_DEFAULT, condition,
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
time_t created;
|
time_t created;
|
||||||
int handle;
|
GIOChannel *handle;
|
||||||
int tag;
|
int tag;
|
||||||
} NET_DISCONNECT_REC;
|
} 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
|
/* Try to let the other side close the connection, if it still isn't
|
||||||
disconnected after certain amount of time, close it ourself */
|
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;
|
NET_DISCONNECT_REC *rec;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ void net_disconnect_deinit(void)
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
NET_DISCONNECT_REC *rec;
|
NET_DISCONNECT_REC *rec;
|
||||||
time_t now, max;
|
time_t now, max;
|
||||||
int first;
|
int first, fd;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set set;
|
fd_set set;
|
||||||
|
|
||||||
@ -131,12 +131,13 @@ void net_disconnect_deinit(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd = g_io_channel_unix_get_fd(rec->handle);
|
||||||
FD_ZERO(&set);
|
FD_ZERO(&set);
|
||||||
FD_SET(rec->handle, &set);
|
FD_SET(fd, &set);
|
||||||
tv.tv_sec = first ? 0 : max-now;
|
tv.tv_sec = first ? 0 : max-now;
|
||||||
tv.tv_usec = first ? 100000 : 0;
|
tv.tv_usec = first ? 100000 : 0;
|
||||||
if (select(rec->handle+1, &set, NULL, NULL, &tv) > 0 &&
|
if (select(fd+1, &set, NULL, NULL, &tv) > 0 &&
|
||||||
FD_ISSET(rec->handle, &set)) {
|
FD_ISSET(fd, &set)) {
|
||||||
/* data coming .. check if we can close the handle */
|
/* data coming .. check if we can close the handle */
|
||||||
sig_disconnect(rec);
|
sig_disconnect(rec);
|
||||||
} else if (first) {
|
} else if (first) {
|
||||||
|
@ -29,15 +29,49 @@ typedef struct {
|
|||||||
NET_CALLBACK func;
|
NET_CALLBACK func;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
int pipes[2];
|
GIOChannel *pipes[2];
|
||||||
int port;
|
int port;
|
||||||
IPADDR *my_ip;
|
IPADDR *my_ip;
|
||||||
int tag;
|
int tag;
|
||||||
} SIMPLE_THREAD_REC;
|
} 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
|
/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is
|
||||||
written to pipe when found PID of the resolver child is returned */
|
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;
|
RESOLVED_IP_REC rec;
|
||||||
const char *errorstr;
|
const char *errorstr;
|
||||||
@ -72,9 +106,9 @@ int net_gethostbyname_nonblock(const char *addr, int pipe)
|
|||||||
rec.errlen = strlen(errorstr)+1;
|
rec.errlen = strlen(errorstr)+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(pipe, &rec, sizeof(rec));
|
g_io_channel_write_block(pipe, &rec, sizeof(rec));
|
||||||
if (rec.error != 0)
|
if (rec.error != 0)
|
||||||
write(pipe, errorstr, rec.errlen);
|
g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
@ -86,45 +120,24 @@ int net_gethostbyname_nonblock(const char *addr, int pipe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the resolved IP address */
|
/* 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->error = -1;
|
||||||
rec->errorstr = NULL;
|
rec->errorstr = NULL;
|
||||||
|
|
||||||
/* get ip+error - try for max. 1-2 seconds */
|
/* get ip+error - try for max. 1-2 seconds */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
fcntl(pipe, F_SETFL, O_NONBLOCK);
|
fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
maxwait = time(NULL)+2;
|
if (g_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1)
|
||||||
len = 0;
|
return -1;
|
||||||
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 (rec->error) {
|
if (rec->error) {
|
||||||
/* read error string */
|
/* read error string, if we can't read everything for some
|
||||||
rec->errorstr = g_malloc(rec->errlen+1);
|
reason, just ignore it. */
|
||||||
len = 0;
|
rec->errorstr = g_malloc0(rec->errlen+1);
|
||||||
do {
|
g_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -133,7 +146,7 @@ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec)
|
|||||||
/* Get host name, call func when finished */
|
/* Get host name, call func when finished */
|
||||||
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data)
|
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data)
|
||||||
{
|
{
|
||||||
/*FIXME*/
|
/* FIXME: not implemented */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +160,7 @@ void net_disconnect_nonblock(int pid)
|
|||||||
#endif
|
#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);
|
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) {
|
if (net_geterror(handle) != 0) {
|
||||||
/* failed */
|
/* failed */
|
||||||
close(handle);
|
g_io_channel_close(handle);
|
||||||
handle = -1;
|
g_io_channel_unref(handle);
|
||||||
|
handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec->func(handle, rec->data);
|
rec->func(handle, rec->data);
|
||||||
g_free(rec);
|
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;
|
RESOLVED_IP_REC iprec;
|
||||||
int handle;
|
GIOChannel *handle;
|
||||||
|
|
||||||
g_return_if_fail(rec != NULL);
|
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);
|
net_gethostbyname_return(pipe, &iprec);
|
||||||
g_free_not_null(iprec.errorstr);
|
g_free_not_null(iprec.errorstr);
|
||||||
|
|
||||||
close(rec->pipes[0]);
|
g_io_channel_close(rec->pipes[0]);
|
||||||
close(rec->pipes[1]);
|
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);
|
net_connect_ip(&iprec.ip, rec->port, rec->my_ip);
|
||||||
|
|
||||||
g_free_not_null(rec->my_ip);
|
g_free_not_null(rec->my_ip);
|
||||||
|
|
||||||
if (handle == -1) {
|
if (handle == NULL) {
|
||||||
/* failed */
|
/* failed */
|
||||||
rec->func(-1, rec->data);
|
rec->func(NULL, rec->data);
|
||||||
g_free(rec);
|
g_free(rec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -209,9 +225,6 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start nonblocking host name lookup */
|
|
||||||
net_gethostbyname_nonblock(server, fd[1]);
|
|
||||||
|
|
||||||
rec = g_new0(SIMPLE_THREAD_REC, 1);
|
rec = g_new0(SIMPLE_THREAD_REC, 1);
|
||||||
rec->port = port;
|
rec->port = port;
|
||||||
if (my_ip != NULL) {
|
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->func = func;
|
||||||
rec->data = data;
|
rec->data = data;
|
||||||
rec->pipes[0] = fd[0];
|
rec->pipes[0] = g_io_channel_unix_new(fd[0]);
|
||||||
rec->pipes[1] = fd[1];
|
rec->pipes[1] = g_io_channel_unix_new(fd[1]);
|
||||||
rec->tag = g_input_add(fd[0], G_INPUT_READ,
|
|
||||||
|
/* 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);
|
(GInputFunction) simple_readpipe, rec);
|
||||||
|
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -20,18 +20,19 @@ typedef struct {
|
|||||||
char *errorstr;
|
char *errorstr;
|
||||||
} RESOLVED_NAME_REC;
|
} RESOLVED_NAME_REC;
|
||||||
|
|
||||||
typedef void (*NET_CALLBACK) (int, void *);
|
typedef void (*NET_CALLBACK) (GIOChannel *, void *);
|
||||||
typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *);
|
typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *);
|
||||||
|
|
||||||
/* nonblocking gethostbyname(), PID of the resolver child is returned. */
|
/* 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 */
|
/* Get host's name, call func when finished */
|
||||||
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data);
|
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() */
|
/* 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 */
|
/* 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 */
|
/* Kill the resolver child */
|
||||||
void net_disconnect_nonblock(int pid);
|
void net_disconnect_nonblock(int pid);
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "net-sendbuffer.h"
|
#include "net-sendbuffer.h"
|
||||||
|
|
||||||
struct _NET_SENDBUF_REC {
|
struct _NET_SENDBUF_REC {
|
||||||
int handle;
|
GIOChannel *handle;
|
||||||
|
|
||||||
int bufsize;
|
int bufsize;
|
||||||
int bufpos;
|
int bufpos;
|
||||||
@ -36,11 +36,11 @@ static int timeout_tag;
|
|||||||
|
|
||||||
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
||||||
is used */
|
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;
|
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 = g_new0(NET_SENDBUF_REC, 1);
|
||||||
rec->handle = handle;
|
rec->handle = handle;
|
||||||
@ -148,9 +148,9 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the socket handle */
|
/* 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;
|
return rec->handle;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ typedef struct _NET_SENDBUF_REC NET_SENDBUF_REC;
|
|||||||
|
|
||||||
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
||||||
is used */
|
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. */
|
/* Destroy the buffer. `close' specifies if socket handle should be closed. */
|
||||||
void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close);
|
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);
|
int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size);
|
||||||
|
|
||||||
/* Returns the socket handle */
|
/* 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_init(void);
|
||||||
void net_sendbuffer_deinit(void);
|
void net_sendbuffer_deinit(void);
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
# define INADDR_NONE INADDR_BROADCAST
|
# define INADDR_NONE INADDR_BROADCAST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EINPROGRESS
|
||||||
|
# define EINPROGESS 0 /* win32 */
|
||||||
|
#endif
|
||||||
|
|
||||||
union sockaddr_union {
|
union sockaddr_union {
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
@ -41,6 +45,12 @@ union sockaddr_union {
|
|||||||
# define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
|
# define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
|
||||||
#endif
|
#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.. */
|
/* Cygwin need this, don't know others.. */
|
||||||
/*#define BLOCKING_SOCKETS 1*/
|
/*#define BLOCKING_SOCKETS 1*/
|
||||||
|
|
||||||
@ -128,20 +138,20 @@ int sin_get_port(union sockaddr_union *so)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to socket */
|
/* 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;
|
IPADDR ip;
|
||||||
|
|
||||||
g_return_val_if_fail(addr != NULL, -1);
|
g_return_val_if_fail(addr != NULL, NULL);
|
||||||
|
|
||||||
if (net_gethostbyname(addr, &ip) == -1)
|
if (net_gethostbyname(addr, &ip) == -1)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
return net_connect_ip(&ip, port, my_ip);
|
return net_connect_ip(&ip, port, my_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to socket with ip address */
|
/* 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;
|
union sockaddr_union so;
|
||||||
int handle, ret, opt = 1;
|
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);
|
handle = socket(ip->family, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
/* set socket options */
|
/* set socket options */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -174,33 +184,32 @@ int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
|||||||
sin_set_port(&so, port);
|
sin_set_port(&so, port);
|
||||||
ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so));
|
ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so));
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
if (ret < 0 && errno != EINPROGRESS) {
|
if (ret < 0 && errno != EINPROGRESS) {
|
||||||
close(handle);
|
close(handle);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return handle;
|
return g_io_channel_new(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disconnect socket */
|
/* 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
|
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
|
||||||
address. */
|
address. */
|
||||||
int net_listen(IPADDR *my_ip, int *port)
|
GIOChannel *net_listen(IPADDR *my_ip, int *port)
|
||||||
{
|
{
|
||||||
union sockaddr_union so;
|
union sockaddr_union so;
|
||||||
int ret, handle, opt = 1;
|
int ret, handle, opt = 1;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
g_return_val_if_fail(port != NULL, -1);
|
g_return_val_if_fail(port != NULL, NULL);
|
||||||
|
|
||||||
memset(&so, 0, sizeof(so));
|
memset(&so, 0, sizeof(so));
|
||||||
sin_set_port(&so, *port);
|
sin_set_port(&so, *port);
|
||||||
@ -209,7 +218,7 @@ int net_listen(IPADDR *my_ip, int *port)
|
|||||||
/* create the socket */
|
/* create the socket */
|
||||||
handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
|
handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
/* set socket options */
|
/* set socket options */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -222,44 +231,39 @@ int net_listen(IPADDR *my_ip, int *port)
|
|||||||
|
|
||||||
/* specify the address/port we want to listen in */
|
/* specify the address/port we want to listen in */
|
||||||
ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
|
ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
|
||||||
if (ret < 0) {
|
if (ret >= 0) {
|
||||||
close(handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the actual port we started listen */
|
/* get the actual port we started listen */
|
||||||
len = SIZEOF_SOCKADDR(so);
|
len = SIZEOF_SOCKADDR(so);
|
||||||
ret = getsockname(handle, &so.sa, &len);
|
ret = getsockname(handle, &so.sa, &len);
|
||||||
if (ret < 0) {
|
if (ret >= 0) {
|
||||||
close(handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*port = sin_get_port(&so);
|
*port = sin_get_port(&so);
|
||||||
|
|
||||||
/* start listening */
|
/* start listening */
|
||||||
if (listen(handle, 1) < 0) {
|
if (listen(handle, 1) >= 0)
|
||||||
close(handle);
|
return g_io_channel_new(handle);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
}
|
||||||
|
|
||||||
|
/* error */
|
||||||
|
close(handle);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept a connection on a socket */
|
/* 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;
|
union sockaddr_union so;
|
||||||
int ret;
|
int ret;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
g_return_val_if_fail(handle != -1, -1);
|
g_return_val_if_fail(handle != NULL, NULL);
|
||||||
|
|
||||||
addrlen = SIZEOF_SOCKADDR(so);
|
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)
|
if (ret < 0)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
if (addr != NULL) sin_get_ip(&so, addr);
|
if (addr != NULL) sin_get_ip(&so, addr);
|
||||||
if (port != NULL) *port = sin_get_port(&so);
|
if (port != NULL) *port = sin_get_port(&so);
|
||||||
@ -267,68 +271,54 @@ int net_accept(int handle, IPADDR *addr, int *port)
|
|||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
fcntl(ret, F_SETFL, O_NONBLOCK);
|
fcntl(ret, F_SETFL, O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return g_io_channel_new(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read data from socket, return number of bytes read, -1 = error */
|
/* 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
|
int ret, err;
|
||||||
fd_set set;
|
|
||||||
struct timeval tv;
|
|
||||||
#endif
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
g_return_val_if_fail(handle != -1, -1);
|
g_return_val_if_fail(handle != NULL, -1);
|
||||||
g_return_val_if_fail(buf != NULL, -1);
|
g_return_val_if_fail(buf != NULL, -1);
|
||||||
|
|
||||||
#ifdef BLOCKING_SOCKETS
|
err = g_io_channel_read(handle, buf, len, &ret);
|
||||||
FD_ZERO(&set);
|
if (err == 0 && ret == 0)
|
||||||
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)
|
|
||||||
return -1; /* disconnected */
|
return -1; /* disconnected */
|
||||||
|
|
||||||
if (ret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN ||
|
if (err == G_IO_ERROR_AGAIN || errno == EINTR)
|
||||||
errno == EINTR))
|
|
||||||
return 0; /* no bytes received */
|
return 0; /* no bytes received */
|
||||||
|
|
||||||
return ret;
|
return err == 0 ? ret : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transmit data, return number of bytes sent, -1 = error */
|
/* 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);
|
g_return_val_if_fail(data != NULL, -1);
|
||||||
|
|
||||||
n = send(handle, data, len, 0);
|
err = g_io_channel_write(handle, (char *) data, len, &ret);
|
||||||
if (n == -1 && (errno == EWOULDBLOCK || errno == EAGAIN ||
|
if (err == G_IO_ERROR_AGAIN || errno == EINTR || errno == EPIPE)
|
||||||
errno == EINTR || errno == EPIPE))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return n > 0 ? n : -1;
|
return err == 0 ? ret : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get socket address/port */
|
/* 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;
|
union sockaddr_union so;
|
||||||
socklen_t len;
|
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);
|
g_return_val_if_fail(addr != NULL, -1);
|
||||||
|
|
||||||
len = SIZEOF_SOCKADDR(so);
|
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;
|
return -1;
|
||||||
|
|
||||||
sin_get_ip(&so, addr);
|
sin_get_ip(&so, addr);
|
||||||
@ -469,12 +459,13 @@ int net_host2ip(const char *host, IPADDR *ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get socket error */
|
/* Get socket error */
|
||||||
int net_geterror(int handle)
|
int net_geterror(GIOChannel *handle)
|
||||||
{
|
{
|
||||||
int data;
|
int data;
|
||||||
socklen_t len = sizeof(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 -1;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -33,24 +33,24 @@ typedef struct _ipaddr IPADDR;
|
|||||||
int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
|
int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
|
||||||
|
|
||||||
/* Connect to socket */
|
/* 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 */
|
/* 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 */
|
/* 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
|
/* Try to let the other side close the connection, if it still isn't
|
||||||
disconnected after certain amount of time, close it ourself */
|
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 */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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,
|
/* Get IP address for host, returns 0 = ok,
|
||||||
others = error code for net_gethosterror() */
|
others = error code for net_gethosterror() */
|
||||||
@ -65,13 +65,13 @@ const char *net_gethosterror(int error);
|
|||||||
int net_hosterror_notfound(int error);
|
int net_hosterror_notfound(int error);
|
||||||
|
|
||||||
/* Get socket address/port */
|
/* 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_ip2host(IPADDR *ip, char *host);
|
||||||
int net_host2ip(const char *host, IPADDR *ip);
|
int net_host2ip(const char *host, IPADDR *ip);
|
||||||
|
|
||||||
/* Get socket error */
|
/* Get socket error */
|
||||||
int net_geterror(int handle);
|
int net_geterror(GIOChannel *handle);
|
||||||
|
|
||||||
int is_ipv4_address(const char *host);
|
int is_ipv4_address(const char *host);
|
||||||
int is_ipv6_address(const char *host);
|
int is_ipv6_address(const char *host);
|
||||||
|
@ -17,7 +17,7 @@ void *handle; /* NET_SENDBUF_REC socket */
|
|||||||
int readtag; /* input tag */
|
int readtag; /* input tag */
|
||||||
|
|
||||||
/* for net_connect_nonblock() */
|
/* for net_connect_nonblock() */
|
||||||
int connect_pipe[2];
|
GIOChannel *connect_pipe[2];
|
||||||
int connect_tag;
|
int connect_tag;
|
||||||
int connect_pid;
|
int connect_pid;
|
||||||
|
|
||||||
|
@ -51,9 +51,11 @@ void server_connect_failed(SERVER_REC *server, const char *msg)
|
|||||||
if (server->handle != NULL)
|
if (server->handle != NULL)
|
||||||
net_sendbuffer_destroy(server->handle, TRUE);
|
net_sendbuffer_destroy(server->handle, TRUE);
|
||||||
|
|
||||||
if (server->connect_pipe[0] != -1) {
|
if (server->connect_pipe[0] != NULL) {
|
||||||
close(server->connect_pipe[0]);
|
g_io_channel_close(server->connect_pipe[0]);
|
||||||
close(server->connect_pipe[1]);
|
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);
|
MODULE_DATA_DEINIT(server);
|
||||||
@ -129,7 +131,7 @@ void server_connect_finished(SERVER_REC *server)
|
|||||||
signal_emit("server connected", 1, 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;
|
int error;
|
||||||
|
|
||||||
@ -154,7 +156,7 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
|
|||||||
SERVER_CONNECT_REC *conn;
|
SERVER_CONNECT_REC *conn;
|
||||||
RESOLVED_IP_REC iprec;
|
RESOLVED_IP_REC iprec;
|
||||||
const char *errormsg;
|
const char *errormsg;
|
||||||
int handle;
|
GIOChannel *handle;
|
||||||
|
|
||||||
g_return_if_fail(IS_SERVER(server));
|
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);
|
net_gethostbyname_return(server->connect_pipe[0], &iprec);
|
||||||
|
|
||||||
close(server->connect_pipe[0]);
|
g_io_channel_close(server->connect_pipe[0]);
|
||||||
close(server->connect_pipe[1]);
|
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[0] = NULL;
|
||||||
server->connect_pipe[1] = -1;
|
server->connect_pipe[1] = NULL;
|
||||||
|
|
||||||
conn = server->connrec;
|
conn = server->connrec;
|
||||||
handle = iprec.error != 0 ? -1 :
|
handle = iprec.error != 0 ? NULL :
|
||||||
net_connect_ip(&iprec.ip, conn->proxy != NULL ?
|
net_connect_ip(&iprec.ip, conn->proxy != NULL ?
|
||||||
conn->proxy_port : conn->port,
|
conn->proxy_port : conn->port,
|
||||||
conn->own_ip != NULL ? conn->own_ip : NULL);
|
conn->own_ip != NULL ? conn->own_ip : NULL);
|
||||||
if (handle == -1) {
|
if (handle == NULL) {
|
||||||
/* failed */
|
/* failed */
|
||||||
if (iprec.error == 0 || !net_hosterror_notfound(iprec.error)) {
|
if (iprec.error == 0 || !net_hosterror_notfound(iprec.error)) {
|
||||||
/* reconnect back only if either
|
/* reconnect back only if either
|
||||||
@ -237,19 +241,23 @@ void server_connect_init(SERVER_REC *server)
|
|||||||
int server_start_connect(SERVER_REC *server)
|
int server_start_connect(SERVER_REC *server)
|
||||||
{
|
{
|
||||||
const char *connect_address;
|
const char *connect_address;
|
||||||
|
int fd[2];
|
||||||
|
|
||||||
g_return_val_if_fail(server != NULL, FALSE);
|
g_return_val_if_fail(server != NULL, FALSE);
|
||||||
if (server->connrec->port <= 0) return FALSE;
|
if (server->connrec->port <= 0) return FALSE;
|
||||||
|
|
||||||
server_connect_init(server);
|
server_connect_init(server);
|
||||||
|
|
||||||
if (pipe(server->connect_pipe) != 0) {
|
if (pipe(fd) != 0) {
|
||||||
g_warning("server_connect(): pipe() failed.");
|
g_warning("server_connect(): pipe() failed.");
|
||||||
g_free(server->tag);
|
g_free(server->tag);
|
||||||
g_free(server->nick);
|
g_free(server->nick);
|
||||||
return FALSE;
|
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 ?
|
connect_address = server->connrec->proxy != NULL ?
|
||||||
server->connrec->proxy : server->connrec->address;
|
server->connrec->proxy : server->connrec->address;
|
||||||
server->connect_pid =
|
server->connect_pid =
|
||||||
|
@ -550,7 +550,9 @@ void gui_readline_init(void)
|
|||||||
cutbuffer = NULL;
|
cutbuffer = NULL;
|
||||||
redir = NULL;
|
redir = NULL;
|
||||||
idle_time = time(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");
|
settings_add_str("history", "scroll_page_count", "/2");
|
||||||
|
|
||||||
|
@ -190,19 +190,20 @@ static void dcc_chat_input(DCC_REC *dcc)
|
|||||||
static void dcc_chat_listen(DCC_REC *dcc)
|
static void dcc_chat_listen(DCC_REC *dcc)
|
||||||
{
|
{
|
||||||
IPADDR ip;
|
IPADDR ip;
|
||||||
int handle, port;
|
GIOChannel *handle;
|
||||||
|
int port;
|
||||||
|
|
||||||
g_return_if_fail(dcc != NULL);
|
g_return_if_fail(dcc != NULL);
|
||||||
|
|
||||||
/* accept connection */
|
/* accept connection */
|
||||||
handle = net_accept(dcc->handle, &ip, &port);
|
handle = net_accept(dcc->handle, &ip, &port);
|
||||||
if (handle == -1)
|
if (handle == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* TODO: add paranoia check - see dcc-files.c */
|
/* TODO: add paranoia check - see dcc-files.c */
|
||||||
|
|
||||||
g_source_remove(dcc->tagconn);
|
g_source_remove(dcc->tagconn);
|
||||||
close(dcc->handle);
|
net_disconnect(dcc->handle);
|
||||||
|
|
||||||
dcc->starttime = time(NULL);
|
dcc->starttime = time(NULL);
|
||||||
dcc->handle = handle;
|
dcc->handle = handle;
|
||||||
@ -243,14 +244,14 @@ static void dcc_chat_connect(DCC_REC *dcc)
|
|||||||
g_return_if_fail(dcc != NULL);
|
g_return_if_fail(dcc != NULL);
|
||||||
|
|
||||||
if (dcc->addrstr[0] == '\0' ||
|
if (dcc->addrstr[0] == '\0' ||
|
||||||
dcc->starttime != 0 || dcc->handle != -1) {
|
dcc->starttime != 0 || dcc->handle != NULL) {
|
||||||
/* already sent a chat request / already chatting */
|
/* already sent a chat request / already chatting */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
|
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
|
||||||
source_host_ok ? source_host_ip : NULL);
|
source_host_ok ? source_host_ip : NULL);
|
||||||
if (dcc->handle != -1) {
|
if (dcc->handle != NULL) {
|
||||||
dcc->tagconn = g_input_add(dcc->handle,
|
dcc->tagconn = g_input_add(dcc->handle,
|
||||||
G_INPUT_WRITE | G_INPUT_READ,
|
G_INPUT_WRITE | G_INPUT_READ,
|
||||||
(GInputFunction) sig_chat_connected, dcc);
|
(GInputFunction) sig_chat_connected, dcc);
|
||||||
@ -267,8 +268,9 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
|
|||||||
void *free_arg;
|
void *free_arg;
|
||||||
DCC_REC *dcc;
|
DCC_REC *dcc;
|
||||||
IPADDR own_ip;
|
IPADDR own_ip;
|
||||||
|
GIOChannel *handle;
|
||||||
char *nick, *str, host[MAX_IP_LEN];
|
char *nick, *str, host[MAX_IP_LEN];
|
||||||
int port, handle;
|
int port;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
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)
|
if (server == NULL || !server->connected)
|
||||||
cmd_param_error(CMDERR_NOT_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);
|
cmd_param_error(CMDERR_ERRNO);
|
||||||
|
|
||||||
port = settings_get_int("dcc_port");
|
port = settings_get_int("dcc_port");
|
||||||
handle = net_listen(&own_ip, &port);
|
handle = net_listen(&own_ip, &port);
|
||||||
if (handle == -1)
|
if (handle == NULL)
|
||||||
cmd_param_error(CMDERR_ERRNO);
|
cmd_param_error(CMDERR_ERRNO);
|
||||||
|
|
||||||
dcc = dcc_create(DCC_TYPE_CHAT, handle, nick, "chat", server, NULL);
|
dcc = dcc_create(DCC_TYPE_CHAT, handle, nick, "chat", server, NULL);
|
||||||
|
@ -197,7 +197,7 @@ static void dcc_get_connect(DCC_REC *dcc)
|
|||||||
{
|
{
|
||||||
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
|
dcc->handle = net_connect_ip(&dcc->addr, dcc->port,
|
||||||
source_host_ok ? source_host_ip : NULL);
|
source_host_ok ? source_host_ip : NULL);
|
||||||
if (dcc->handle != -1) {
|
if (dcc->handle != NULL) {
|
||||||
dcc->tagconn = g_input_add(dcc->handle,
|
dcc->tagconn = g_input_add(dcc->handle,
|
||||||
G_INPUT_WRITE | G_INPUT_READ,
|
G_INPUT_WRITE | G_INPUT_READ,
|
||||||
(GInputFunction) sig_dccget_connected, dcc);
|
(GInputFunction) sig_dccget_connected, dcc);
|
||||||
@ -209,7 +209,7 @@ static void dcc_get_connect(DCC_REC *dcc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define dcc_is_unget(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>] */
|
/* SYNTAX: DCC GET <nick> [<file>] */
|
||||||
static void cmd_dcc_get(const char *data)
|
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) \
|
#define is_accept_ok(type, dcc) \
|
||||||
(g_strcasecmp(type, "ACCEPT") != 0 || \
|
(g_strcasecmp(type, "ACCEPT") != 0 || \
|
||||||
((dcc)->type == DCC_TYPE_GET && \
|
((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,
|
static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
|
||||||
const char *sender, const char *sendaddr,
|
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 */
|
/* input function: DCC SEND - someone tried to connect to our socket */
|
||||||
static void dcc_send_init(DCC_REC *dcc)
|
static void dcc_send_init(DCC_REC *dcc)
|
||||||
{
|
{
|
||||||
int handle, port;
|
GIOChannel *handle;
|
||||||
IPADDR addr;
|
IPADDR addr;
|
||||||
|
int port;
|
||||||
|
|
||||||
g_return_if_fail(dcc != NULL);
|
g_return_if_fail(dcc != NULL);
|
||||||
|
|
||||||
/* accept connection */
|
/* accept connection */
|
||||||
handle = net_accept(dcc->handle, &addr, &port);
|
handle = net_accept(dcc->handle, &addr, &port);
|
||||||
if (handle == -1)
|
if (handle == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* TODO: some kind of paranoia check would be nice. it would check
|
/* 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. */
|
address who connected us. */
|
||||||
|
|
||||||
g_source_remove(dcc->tagconn);
|
g_source_remove(dcc->tagconn);
|
||||||
close(dcc->handle);
|
net_disconnect(dcc->handle);
|
||||||
|
|
||||||
dcc->starttime = time(NULL);
|
dcc->starttime = time(NULL);
|
||||||
dcc->fastsend = settings_get_bool("dcc_fast_send");
|
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;
|
char *target, *fname, *str, *ptr;
|
||||||
void *free_arg;
|
void *free_arg;
|
||||||
char host[MAX_IP_LEN];
|
char host[MAX_IP_LEN];
|
||||||
int hfile, hlisten, port;
|
int hfile, port;
|
||||||
long fsize;
|
long fsize;
|
||||||
DCC_REC *dcc, *chat;
|
DCC_REC *dcc, *chat;
|
||||||
IPADDR own_ip;
|
IPADDR own_ip;
|
||||||
|
GIOChannel *handle, *hlisten;
|
||||||
|
|
||||||
g_return_if_fail(data != NULL);
|
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);
|
lseek(hfile, 0, SEEK_SET);
|
||||||
|
|
||||||
/* get the IP address we use with IRC server */
|
/* 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);
|
close(hfile);
|
||||||
cmd_param_error(CMDERR_ERRNO);
|
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 */
|
/* start listening */
|
||||||
port = settings_get_int("dcc_port");
|
port = settings_get_int("dcc_port");
|
||||||
hlisten = net_listen(&own_ip, &port);
|
hlisten = net_listen(&own_ip, &port);
|
||||||
if (hlisten == -1) {
|
if (hlisten == NULL) {
|
||||||
close(hfile);
|
close(hfile);
|
||||||
cmd_param_error(CMDERR_ERRNO);
|
cmd_param_error(CMDERR_ERRNO);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ GSList *dcc_conns;
|
|||||||
static int dcc_timeouttag;
|
static int dcc_timeouttag;
|
||||||
|
|
||||||
/* Create new DCC record */
|
/* 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)
|
IRC_SERVER_REC *server, DCC_REC *chat)
|
||||||
{
|
{
|
||||||
DCC_REC *dcc;
|
DCC_REC *dcc;
|
||||||
@ -110,7 +110,7 @@ void dcc_destroy(DCC_REC *dcc)
|
|||||||
signal_emit("dcc destroyed", 1, dcc);
|
signal_emit("dcc destroyed", 1, dcc);
|
||||||
|
|
||||||
if (dcc->fhandle != -1) close(dcc->fhandle);
|
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->tagconn != -1) g_source_remove(dcc->tagconn);
|
||||||
if (dcc->tagread != -1) g_source_remove(dcc->tagread);
|
if (dcc->tagread != -1) g_source_remove(dcc->tagread);
|
||||||
if (dcc->tagwrite != -1) g_source_remove(dcc->tagwrite);
|
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) {
|
if (olddcc != NULL) {
|
||||||
/* same DCC request offered again */
|
/* same DCC request offered again */
|
||||||
if (olddcc->type == DCC_TYPE_CHAT &&
|
if (olddcc->type == DCC_TYPE_CHAT &&
|
||||||
olddcc->handle != -1 && olddcc->starttime == 0) {
|
olddcc->handle != NULL && olddcc->starttime == 0) {
|
||||||
/* we requested dcc chat, they requested
|
/* we requested dcc chat, they requested
|
||||||
dcc chat from us .. allow it. */
|
dcc chat from us .. allow it. */
|
||||||
dcc_destroy(olddcc);
|
dcc_destroy(olddcc);
|
||||||
} else {
|
} else {
|
||||||
/* if the connection isn't open, update the port,
|
/* if the connection isn't open, update the port,
|
||||||
otherwise just ignore */
|
otherwise just ignore */
|
||||||
if (olddcc->handle == -1)
|
if (olddcc->handle == NULL)
|
||||||
olddcc->port = port;
|
olddcc->port = port;
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
return;
|
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);
|
dcc_get_address(addrstr, &dcc->addr);
|
||||||
net_ip2host(&dcc->addr, dcc->addrstr);
|
net_ip2host(&dcc->addr, dcc->addrstr);
|
||||||
dcc->port = port;
|
dcc->port = port;
|
||||||
|
@ -40,7 +40,7 @@ typedef struct DCC_REC {
|
|||||||
int port; /* port we're connected in */
|
int port; /* port we're connected in */
|
||||||
|
|
||||||
long size, transfd, skipped; /* file size / bytes transferred / skipped at start */
|
long size, transfd, skipped; /* file size / bytes transferred / skipped at start */
|
||||||
int handle; /* socket handle */
|
GIOChannel *handle; /* socket handle */
|
||||||
void *sendbuf;
|
void *sendbuf;
|
||||||
int tagconn, tagread, tagwrite;
|
int tagconn, tagread, tagwrite;
|
||||||
int fhandle; /* file handle */
|
int fhandle; /* file handle */
|
||||||
@ -80,7 +80,7 @@ const char *dcc_type2str(int type);
|
|||||||
int dcc_str2type(const char *type);
|
int dcc_str2type(const char *type);
|
||||||
void dcc_make_address(IPADDR *ip, char *host);
|
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);
|
void dcc_destroy(DCC_REC *dcc);
|
||||||
|
|
||||||
/* Send a CTCP message/notify to target. Send the CTCP via DCC chat if
|
/* Send a CTCP message/notify to target. Send the CTCP via DCC chat if
|
||||||
|
Loading…
Reference in New Issue
Block a user