more fixes, should work now
This commit is contained in:
parent
3b3b50b7ec
commit
3bf7660b85
@ -17,11 +17,13 @@ add_library(libircclient
|
|||||||
./libircclient/src/errors.c
|
./libircclient/src/errors.c
|
||||||
./libircclient/src/libircclient.c
|
./libircclient/src/libircclient.c
|
||||||
./libircclient/src/params.h
|
./libircclient/src/params.h
|
||||||
|
./libircclient/src/portable.h
|
||||||
./libircclient/src/portable.c
|
./libircclient/src/portable.c
|
||||||
./libircclient/src/session.h
|
./libircclient/src/session.h
|
||||||
./libircclient/src/sockets.c
|
./libircclient/src/sockets.h
|
||||||
|
./libircclient/src/ssl.h
|
||||||
./libircclient/src/ssl.c
|
./libircclient/src/ssl.c
|
||||||
./libircclient/src/utils.c
|
./libircclient/src/utils.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(libircclient PUBLIC ./libircclient/include)
|
target_include_directories(libircclient PUBLIC ./libircclient/include)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -16,6 +16,11 @@
|
|||||||
#define LIBIRC_DCC_SENDFILE 2
|
#define LIBIRC_DCC_SENDFILE 2
|
||||||
#define LIBIRC_DCC_RECVFILE 3
|
#define LIBIRC_DCC_RECVFILE 3
|
||||||
|
|
||||||
|
#include "./session.h"
|
||||||
|
#include "./utils.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc_dcc_t dccid, int lock_list)
|
static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc_dcc_t dccid, int lock_list)
|
||||||
{
|
{
|
||||||
@ -54,7 +59,7 @@ static void libirc_dcc_destroy_nolock (irc_session_t * session, irc_dcc_t dccid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list)
|
void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list)
|
||||||
{
|
{
|
||||||
if ( dcc->sock >= 0 )
|
if ( dcc->sock >= 0 )
|
||||||
socket_close (&dcc->sock);
|
socket_close (&dcc->sock);
|
||||||
@ -91,7 +96,7 @@ static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd)
|
void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd)
|
||||||
{
|
{
|
||||||
irc_dcc_session_t * dcc, *dcc_next;
|
irc_dcc_session_t * dcc, *dcc_next;
|
||||||
time_t now = time (0);
|
time_t now = time (0);
|
||||||
@ -129,8 +134,8 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're sending file, and the output buffer is empty, we need
|
* If we're sending file, and the output buffer is empty, we need
|
||||||
* to provide some data.
|
* to provide some data.
|
||||||
*/
|
*/
|
||||||
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
||||||
&& dcc->dccmode == LIBIRC_DCC_SENDFILE
|
&& dcc->dccmode == LIBIRC_DCC_SENDFILE
|
||||||
&& dcc->dccsend_file_fp
|
&& dcc->dccsend_file_fp
|
||||||
@ -141,7 +146,7 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
|
|||||||
if ( len <= 0 )
|
if ( len <= 0 )
|
||||||
{
|
{
|
||||||
int err = (len < 0 ? LIBIRC_ERR_READ : 0);
|
int err = (len < 0 ? LIBIRC_ERR_READ : 0);
|
||||||
|
|
||||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||||
|
|
||||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
|
||||||
@ -189,17 +194,17 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
|
|||||||
case LIBIRC_STATE_CONFIRM_SIZE:
|
case LIBIRC_STATE_CONFIRM_SIZE:
|
||||||
/*
|
/*
|
||||||
* If we're receiving file, then WE should confirm the transferred
|
* If we're receiving file, then WE should confirm the transferred
|
||||||
* part (so we have to sent data). But if we're sending the file,
|
* part (so we have to sent data). But if we're sending the file,
|
||||||
* then RECEIVER should confirm the packet, so we have to receive
|
* then RECEIVER should confirm the packet, so we have to receive
|
||||||
* data.
|
* data.
|
||||||
*
|
*
|
||||||
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
|
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
|
||||||
* can't change asynchronously.
|
* can't change asynchronously.
|
||||||
*/
|
*/
|
||||||
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
|
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
|
||||||
libirc_add_to_set (dcc->sock, out_set, maxfd);
|
libirc_add_to_set (dcc->sock, out_set, maxfd);
|
||||||
|
|
||||||
if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 )
|
if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 )
|
||||||
libirc_add_to_set (dcc->sock, in_set, maxfd);
|
libirc_add_to_set (dcc->sock, in_set, maxfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,14 +213,14 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set)
|
void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set)
|
||||||
{
|
{
|
||||||
irc_dcc_session_t * dcc;
|
irc_dcc_session_t * dcc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to use such a complex scheme here, because on every callback
|
* We need to use such a complex scheme here, because on every callback
|
||||||
* a number of DCC sessions could be destroyed.
|
* a number of DCC sessions could be destroyed.
|
||||||
*/
|
*/
|
||||||
libirc_mutex_lock (&ircsession->mutex_dcc);
|
libirc_mutex_lock (&ircsession->mutex_dcc);
|
||||||
|
|
||||||
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next )
|
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next )
|
||||||
@ -238,14 +243,14 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
// On success, change the active socket and change the state
|
// On success, change the active socket and change the state
|
||||||
if ( err == 0 )
|
if ( err == 0 )
|
||||||
{
|
{
|
||||||
// close the listen socket, and replace it by a newly
|
// close the listen socket, and replace it by a newly
|
||||||
// accepted
|
// accepted
|
||||||
socket_close (&dcc->sock);
|
socket_close (&dcc->sock);
|
||||||
dcc->sock = nsock;
|
dcc->sock = nsock;
|
||||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is DCC chat, inform the caller about accept()
|
// If this is DCC chat, inform the caller about accept()
|
||||||
// success or failure.
|
// success or failure.
|
||||||
// Otherwise (DCC send) there is no reason.
|
// Otherwise (DCC send) there is no reason.
|
||||||
if ( dcc->dccmode == LIBIRC_DCC_CHAT )
|
if ( dcc->dccmode == LIBIRC_DCC_CHAT )
|
||||||
@ -262,7 +267,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
if ( dcc->state == LIBIRC_STATE_CONNECTING
|
if ( dcc->state == LIBIRC_STATE_CONNECTING
|
||||||
&& FD_ISSET (dcc->sock, out_set) )
|
&& FD_ISSET (dcc->sock, out_set) )
|
||||||
{
|
{
|
||||||
// Now we have to determine whether the socket is connected
|
// Now we have to determine whether the socket is connected
|
||||||
// or the connect is failed
|
// or the connect is failed
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
socklen_t slen = sizeof(saddr);
|
socklen_t slen = sizeof(saddr);
|
||||||
@ -295,7 +300,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
if ( FD_ISSET (dcc->sock, in_set) )
|
if ( FD_ISSET (dcc->sock, in_set) )
|
||||||
{
|
{
|
||||||
int length, offset = 0, err = 0;
|
int length, offset = 0, err = 0;
|
||||||
|
|
||||||
unsigned int amount = sizeof (dcc->incoming_buf) - dcc->incoming_offset;
|
unsigned int amount = sizeof (dcc->incoming_buf) - dcc->incoming_offset;
|
||||||
|
|
||||||
length = socket_recv (&dcc->sock, dcc->incoming_buf + dcc->incoming_offset, amount);
|
length = socket_recv (&dcc->sock, dcc->incoming_buf + dcc->incoming_offset, amount);
|
||||||
@ -303,7 +308,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
if ( length < 0 )
|
if ( length < 0 )
|
||||||
{
|
{
|
||||||
err = LIBIRC_ERR_READ;
|
err = LIBIRC_ERR_READ;
|
||||||
}
|
}
|
||||||
else if ( length == 0 )
|
else if ( length == 0 )
|
||||||
{
|
{
|
||||||
err = LIBIRC_ERR_CLOSED;
|
err = LIBIRC_ERR_CLOSED;
|
||||||
@ -325,9 +330,9 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* In LIBIRC_STATE_CONFIRM_SIZE state we don't call any
|
* In LIBIRC_STATE_CONFIRM_SIZE state we don't call any
|
||||||
* callbacks (except there is an error). We just receive
|
* callbacks (except there is an error). We just receive
|
||||||
* the data, and compare it with the amount sent.
|
* the data, and compare it with the amount sent.
|
||||||
*/
|
*/
|
||||||
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
|
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
|
||||||
{
|
{
|
||||||
if ( dcc->dccmode != LIBIRC_DCC_SENDFILE )
|
if ( dcc->dccmode != LIBIRC_DCC_SENDFILE )
|
||||||
@ -352,10 +357,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If it is DCC_CHAT, we send a 0-terminated string
|
* If it is DCC_CHAT, we send a 0-terminated string
|
||||||
* (which is smaller than offset). Otherwise we send
|
* (which is smaller than offset). Otherwise we send
|
||||||
* a full buffer.
|
* a full buffer.
|
||||||
*/
|
*/
|
||||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||||
|
|
||||||
if ( dcc->dccmode != LIBIRC_DCC_CHAT )
|
if ( dcc->dccmode != LIBIRC_DCC_CHAT )
|
||||||
@ -365,21 +370,21 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
|
|
||||||
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset);
|
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the session is not terminated in callback,
|
* If the session is not terminated in callback,
|
||||||
* put the sent amount into the sent_packet_size_net_byteorder
|
* put the sent amount into the sent_packet_size_net_byteorder
|
||||||
*/
|
*/
|
||||||
if ( dcc->state != LIBIRC_STATE_REMOVED )
|
if ( dcc->state != LIBIRC_STATE_REMOVED )
|
||||||
{
|
{
|
||||||
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
|
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
|
||||||
dcc->file_confirm_offset += offset;
|
dcc->file_confirm_offset += offset;
|
||||||
|
|
||||||
// Store as big endian
|
// Store as big endian
|
||||||
dcc->outgoing_buf[0] = (char) dcc->file_confirm_offset >> 24;
|
dcc->outgoing_buf[0] = (char) dcc->file_confirm_offset >> 24;
|
||||||
dcc->outgoing_buf[1] = (char) dcc->file_confirm_offset >> 16;
|
dcc->outgoing_buf[1] = (char) dcc->file_confirm_offset >> 16;
|
||||||
dcc->outgoing_buf[2] = (char) dcc->file_confirm_offset >> 8;
|
dcc->outgoing_buf[2] = (char) dcc->file_confirm_offset >> 8;
|
||||||
dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset;
|
dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset;
|
||||||
dcc->outgoing_offset = 4;
|
dcc->outgoing_offset = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -394,10 +399,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If error arises somewhere above, we inform the caller
|
* If error arises somewhere above, we inform the caller
|
||||||
* of failure, and destroy this session.
|
* of failure, and destroy this session.
|
||||||
*/
|
*/
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||||
@ -407,30 +412,30 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Session might be closed (with sock = -1) after the in_set
|
* Session might be closed (with sock = -1) after the in_set
|
||||||
* processing, so before out_set processing we should check
|
* processing, so before out_set processing we should check
|
||||||
* for this case
|
* for this case
|
||||||
*/
|
*/
|
||||||
if ( dcc->state == LIBIRC_STATE_REMOVED )
|
if ( dcc->state == LIBIRC_STATE_REMOVED )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write bit set - we can send() something, and it won't block.
|
* Write bit set - we can send() something, and it won't block.
|
||||||
*/
|
*/
|
||||||
if ( FD_ISSET (dcc->sock, out_set) )
|
if ( FD_ISSET (dcc->sock, out_set) )
|
||||||
{
|
{
|
||||||
int length, offset, err = 0;
|
int length, offset, err = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because in some cases outgoing_buf could be changed
|
* Because in some cases outgoing_buf could be changed
|
||||||
* asynchronously (by another thread), we should lock
|
* asynchronously (by another thread), we should lock
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
libirc_mutex_lock (&dcc->mutex_outbuf);
|
libirc_mutex_lock (&dcc->mutex_outbuf);
|
||||||
|
|
||||||
offset = dcc->outgoing_offset;
|
offset = dcc->outgoing_offset;
|
||||||
|
|
||||||
if ( offset > 0 )
|
if ( offset > 0 )
|
||||||
{
|
{
|
||||||
length = socket_send (&dcc->sock, dcc->outgoing_buf, offset);
|
length = socket_send (&dcc->sock, dcc->outgoing_buf, offset);
|
||||||
@ -445,7 +450,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
* If this was DCC_SENDFILE, and we just sent a packet,
|
* If this was DCC_SENDFILE, and we just sent a packet,
|
||||||
* change the state to wait for confirmation (and store
|
* change the state to wait for confirmation (and store
|
||||||
* sent packet size)
|
* sent packet size)
|
||||||
*/
|
*/
|
||||||
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
if ( dcc->state == LIBIRC_STATE_CONNECTED
|
||||||
&& dcc->dccmode == LIBIRC_DCC_SENDFILE )
|
&& dcc->dccmode == LIBIRC_DCC_SENDFILE )
|
||||||
{
|
{
|
||||||
@ -465,27 +470,27 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
dcc->outgoing_offset -= length;
|
dcc->outgoing_offset -= length;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we just sent the confirmation data, change state
|
* If we just sent the confirmation data, change state
|
||||||
* back.
|
* back.
|
||||||
*/
|
*/
|
||||||
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE
|
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE
|
||||||
&& dcc->dccmode == LIBIRC_DCC_RECVFILE
|
&& dcc->dccmode == LIBIRC_DCC_RECVFILE
|
||||||
&& dcc->outgoing_offset == 0 )
|
&& dcc->outgoing_offset == 0 )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If the file is already received, we should inform
|
* If the file is already received, we should inform
|
||||||
* the caller, and close the session.
|
* the caller, and close the session.
|
||||||
*/
|
*/
|
||||||
if ( dcc->received_file_size == dcc->file_confirm_offset )
|
if ( dcc->received_file_size == dcc->file_confirm_offset )
|
||||||
{
|
{
|
||||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||||
(*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0);
|
(*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0);
|
||||||
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
libirc_dcc_destroy_nolock (ircsession, dcc->id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Continue to receive the file */
|
/* Continue to receive the file */
|
||||||
dcc->state = LIBIRC_STATE_CONNECTED;
|
dcc->state = LIBIRC_STATE_CONNECTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,10 +499,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
|
|||||||
|
|
||||||
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
libirc_mutex_unlock (&dcc->mutex_outbuf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If error arises somewhere above, we inform the caller
|
* If error arises somewhere above, we inform the caller
|
||||||
* of failure, and destroy this session.
|
* of failure, and destroy this session.
|
||||||
*/
|
*/
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
libirc_mutex_unlock (&ircsession->mutex_dcc);
|
||||||
@ -578,7 +583,7 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
|
|||||||
memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr));
|
memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr));
|
||||||
dcc->remote_addr.sin_family = AF_INET;
|
dcc->remote_addr.sin_family = AF_INET;
|
||||||
dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder?
|
dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder?
|
||||||
dcc->remote_addr.sin_port = htons(port);
|
dcc->remote_addr.sin_port = htons(port);
|
||||||
|
|
||||||
dcc->state = LIBIRC_STATE_INIT;
|
dcc->state = LIBIRC_STATE_INIT;
|
||||||
}
|
}
|
||||||
@ -596,8 +601,8 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
|
|||||||
|
|
||||||
libirc_mutex_unlock (&session->mutex_dcc);
|
libirc_mutex_unlock (&session->mutex_dcc);
|
||||||
|
|
||||||
*pdcc = dcc;
|
*pdcc = dcc;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup_exit_error:
|
cleanup_exit_error:
|
||||||
if ( dcc->sock >= 0 )
|
if ( dcc->sock >= 0 )
|
||||||
@ -710,7 +715,7 @@ int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req)
|
void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req)
|
||||||
{
|
{
|
||||||
char filenamebuf[256];
|
char filenamebuf[256];
|
||||||
unsigned long ip, size;
|
unsigned long ip, size;
|
||||||
@ -729,8 +734,8 @@ static void libirc_dcc_request (irc_session_t * session, const char * nick, cons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*session->callbacks.event_dcc_chat_req) (session,
|
(*session->callbacks.event_dcc_chat_req) (session,
|
||||||
nick,
|
nick,
|
||||||
inet_ntoa (dcc->remote_addr.sin_addr),
|
inet_ntoa (dcc->remote_addr.sin_addr),
|
||||||
dcc->id);
|
dcc->id);
|
||||||
}
|
}
|
||||||
@ -750,8 +755,8 @@ static void libirc_dcc_request (irc_session_t * session, const char * nick, cons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*session->callbacks.event_dcc_send_req) (session,
|
(*session->callbacks.event_dcc_send_req) (session,
|
||||||
nick,
|
nick,
|
||||||
inet_ntoa (dcc->remote_addr.sin_addr),
|
inet_ntoa (dcc->remote_addr.sin_addr),
|
||||||
filenamebuf,
|
filenamebuf,
|
||||||
size,
|
size,
|
||||||
@ -787,7 +792,7 @@ int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dc
|
|||||||
dcc->ctx = ctx;
|
dcc->ctx = ctx;
|
||||||
|
|
||||||
// Initiate the connect
|
// Initiate the connect
|
||||||
if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) )
|
if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) )
|
||||||
{
|
{
|
||||||
libirc_dcc_destroy_nolock (session, dccid);
|
libirc_dcc_destroy_nolock (session, dccid);
|
||||||
libirc_mutex_unlock (&session->mutex_dcc);
|
libirc_mutex_unlock (&session->mutex_dcc);
|
||||||
|
@ -1,20 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INCLUDE_IRC_DCC_H
|
#ifndef INCLUDE_IRC_DCC_H
|
||||||
#define INCLUDE_IRC_DCC_H
|
#define INCLUDE_IRC_DCC_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../include/libircclient.h"
|
||||||
|
|
||||||
|
#include "./sockets.h"
|
||||||
|
#include "./portable.h"
|
||||||
|
#include "./params.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure keeps the state of a single DCC connection.
|
* This structure keeps the state of a single DCC connection.
|
||||||
@ -26,11 +33,11 @@ struct irc_dcc_session_s
|
|||||||
irc_dcc_t id;
|
irc_dcc_t id;
|
||||||
void * ctx;
|
void * ctx;
|
||||||
socket_t sock; /*!< DCC socket */
|
socket_t sock; /*!< DCC socket */
|
||||||
int dccmode; /*!< Boolean value to differ chat vs send
|
int dccmode; /*!< Boolean value to differ chat vs send
|
||||||
requests. Changes the cb behavior - when
|
requests. Changes the cb behavior - when
|
||||||
it is chat, data is sent by lines with
|
it is chat, data is sent by lines with
|
||||||
stripped CRLFs. In file mode, the data
|
stripped CRLFs. In file mode, the data
|
||||||
is sent as-is */
|
is sent as-is */
|
||||||
int state;
|
int state;
|
||||||
time_t timeout;
|
time_t timeout;
|
||||||
|
|
||||||
@ -50,5 +57,9 @@ struct irc_dcc_session_s
|
|||||||
irc_dcc_callback_t cb;
|
irc_dcc_callback_t cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list);
|
||||||
|
void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd);
|
||||||
|
void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req);
|
||||||
|
void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set);
|
||||||
|
|
||||||
#endif /* INCLUDE_IRC_DCC_H */
|
#endif /* INCLUDE_IRC_DCC_H */
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char * libirc_strerror[LIBIRC_ERR_MAX] =
|
#include "../include/libircclient.h"
|
||||||
|
#include "./session.h"
|
||||||
|
|
||||||
|
static const char * libirc_strerror[LIBIRC_ERR_MAX] =
|
||||||
{
|
{
|
||||||
"No error",
|
"No error",
|
||||||
"Invalid argument",
|
"Invalid argument",
|
||||||
|
@ -14,17 +14,19 @@
|
|||||||
|
|
||||||
#define IS_DEBUG_ENABLED(s) ((s)->options & LIBIRC_OPTION_DEBUG)
|
#define IS_DEBUG_ENABLED(s) ((s)->options & LIBIRC_OPTION_DEBUG)
|
||||||
|
|
||||||
#include "portable.c"
|
#include "./portable.h"
|
||||||
#include "sockets.c"
|
#include "./sockets.h"
|
||||||
|
|
||||||
#include "libircclient.h"
|
#include "../include/libircclient.h"
|
||||||
#include "session.h"
|
#include "./session.h"
|
||||||
|
|
||||||
#include "utils.c"
|
#include "./utils.h"
|
||||||
#include "errors.c"
|
/*#include "errors.c"*/
|
||||||
#include "colors.c"
|
/*#include "colors.c"*/
|
||||||
#include "dcc.c"
|
#include "./dcc.h"
|
||||||
#include "ssl.c"
|
/*#include "dcc.c"*/
|
||||||
|
/*#include "ssl.c"*/
|
||||||
|
#include "./ssl.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -797,11 +799,11 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces
|
|||||||
{
|
{
|
||||||
; /* ignore this event - not all servers generate this */
|
; /* ignore this event - not all servers generate this */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The "unknown" event is triggered upon receipt of any number of
|
* The "unknown" event is triggered upon receipt of any number of
|
||||||
* unclassifiable miscellaneous messages, which aren't handled by
|
* unclassifiable miscellaneous messages, which aren't handled by
|
||||||
* the library.
|
* the library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -816,7 +818,7 @@ int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_
|
|||||||
{
|
{
|
||||||
char buf[256], hname[256];
|
char buf[256], hname[256];
|
||||||
|
|
||||||
if ( session->sock < 0
|
if ( session->sock < 0
|
||||||
|| session->state == LIBIRC_STATE_INIT
|
|| session->state == LIBIRC_STATE_INIT
|
||||||
|| session->state == LIBIRC_STATE_DISCONNECTED )
|
|| session->state == LIBIRC_STATE_DISCONNECTED )
|
||||||
{
|
{
|
||||||
@ -833,7 +835,7 @@ int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_
|
|||||||
// If the socket is not connected yet, wait longer - it is not an error
|
// If the socket is not connected yet, wait longer - it is not an error
|
||||||
if ( !FD_ISSET (session->sock, out_set) )
|
if ( !FD_ISSET (session->sock, out_set) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Now we have to determine whether the socket is connected
|
// Now we have to determine whether the socket is connected
|
||||||
// or the connect is failed
|
// or the connect is failed
|
||||||
struct sockaddr_storage saddr, laddr;
|
struct sockaddr_storage saddr, laddr;
|
||||||
|
@ -1,132 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined (_WIN32)
|
#include "./portable.h"
|
||||||
#include "config.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if defined (ENABLE_THREADS)
|
|
||||||
#include <pthread.h>
|
|
||||||
typedef pthread_mutex_t port_mutex_t;
|
|
||||||
|
|
||||||
#if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP)
|
|
||||||
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#if defined (ENABLE_THREADS)
|
|
||||||
typedef CRITICAL_SECTION port_mutex_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define inline
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
#define strncasecmp _strnicmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (ENABLE_SSL)
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (ENABLE_THREADS)
|
|
||||||
static inline int libirc_mutex_init (port_mutex_t * mutex)
|
|
||||||
{
|
|
||||||
#if defined (_WIN32)
|
|
||||||
InitializeCriticalSection (mutex);
|
|
||||||
return 0;
|
|
||||||
#elif defined (PTHREAD_MUTEX_RECURSIVE)
|
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
|
|
||||||
return (pthread_mutexattr_init (&attr)
|
|
||||||
|| pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)
|
|
||||||
|| pthread_mutex_init (mutex, &attr));
|
|
||||||
#else /* !defined (PTHREAD_MUTEX_RECURSIVE) */
|
|
||||||
|
|
||||||
return pthread_mutex_init (mutex, 0);
|
|
||||||
|
|
||||||
#endif /* defined (_WIN32) */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void libirc_mutex_destroy (port_mutex_t * mutex)
|
|
||||||
{
|
|
||||||
#if defined (_WIN32)
|
|
||||||
DeleteCriticalSection (mutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_destroy (mutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void libirc_mutex_lock (port_mutex_t * mutex)
|
|
||||||
{
|
|
||||||
#if defined (_WIN32)
|
|
||||||
EnterCriticalSection (mutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_lock (mutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void libirc_mutex_unlock (port_mutex_t * mutex)
|
|
||||||
{
|
|
||||||
#if defined (_WIN32)
|
|
||||||
LeaveCriticalSection (mutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_unlock (mutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef void * port_mutex_t;
|
|
||||||
|
|
||||||
static inline int libirc_mutex_init (port_mutex_t * mutex) { return 0; }
|
|
||||||
static inline void libirc_mutex_destroy (port_mutex_t * mutex) {}
|
|
||||||
static inline void libirc_mutex_lock (port_mutex_t * mutex) {}
|
|
||||||
static inline void libirc_mutex_unlock (port_mutex_t * mutex) {}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stub for WIN32 dll to initialize winsock API
|
* Stub for WIN32 dll to initialize winsock API
|
||||||
|
133
libircclient/src/portable.h
Normal file
133
libircclient/src/portable.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDE_IRC_PORTABLE_H
|
||||||
|
#define INCLUDE_IRC_PORTABLE_H
|
||||||
|
|
||||||
|
#if !defined (_WIN32)
|
||||||
|
//#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if defined (ENABLE_THREADS)
|
||||||
|
#include <pthread.h>
|
||||||
|
typedef pthread_mutex_t port_mutex_t;
|
||||||
|
|
||||||
|
#if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP)
|
||||||
|
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#if defined (ENABLE_THREADS)
|
||||||
|
typedef CRITICAL_SECTION port_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define inline
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (ENABLE_SSL)
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (ENABLE_THREADS)
|
||||||
|
static inline int libirc_mutex_init (port_mutex_t * mutex)
|
||||||
|
{
|
||||||
|
#if defined (_WIN32)
|
||||||
|
InitializeCriticalSection (mutex);
|
||||||
|
return 0;
|
||||||
|
#elif defined (PTHREAD_MUTEX_RECURSIVE)
|
||||||
|
pthread_mutexattr_t attr;
|
||||||
|
|
||||||
|
return (pthread_mutexattr_init (&attr)
|
||||||
|
|| pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)
|
||||||
|
|| pthread_mutex_init (mutex, &attr));
|
||||||
|
#else /* !defined (PTHREAD_MUTEX_RECURSIVE) */
|
||||||
|
|
||||||
|
return pthread_mutex_init (mutex, 0);
|
||||||
|
|
||||||
|
#endif /* defined (_WIN32) */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void libirc_mutex_destroy (port_mutex_t * mutex)
|
||||||
|
{
|
||||||
|
#if defined (_WIN32)
|
||||||
|
DeleteCriticalSection (mutex);
|
||||||
|
#else
|
||||||
|
pthread_mutex_destroy (mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void libirc_mutex_lock (port_mutex_t * mutex)
|
||||||
|
{
|
||||||
|
#if defined (_WIN32)
|
||||||
|
EnterCriticalSection (mutex);
|
||||||
|
#else
|
||||||
|
pthread_mutex_lock (mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void libirc_mutex_unlock (port_mutex_t * mutex)
|
||||||
|
{
|
||||||
|
#if defined (_WIN32)
|
||||||
|
LeaveCriticalSection (mutex);
|
||||||
|
#else
|
||||||
|
pthread_mutex_unlock (mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef void * port_mutex_t;
|
||||||
|
|
||||||
|
static inline int libirc_mutex_init (port_mutex_t * mutex) { return 0; }
|
||||||
|
static inline void libirc_mutex_destroy (port_mutex_t * mutex) {}
|
||||||
|
static inline void libirc_mutex_lock (port_mutex_t * mutex) {}
|
||||||
|
static inline void libirc_mutex_unlock (port_mutex_t * mutex) {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INCLUDE_IRC_PORTABLE_H */
|
@ -17,9 +17,9 @@
|
|||||||
#define INCLUDE_IRC_SESSION_H
|
#define INCLUDE_IRC_SESSION_H
|
||||||
|
|
||||||
|
|
||||||
#include "params.h"
|
#include "./params.h"
|
||||||
#include "dcc.h"
|
#include "./dcc.h"
|
||||||
#include "libirc_events.h"
|
#include "../include/libirc_events.h"
|
||||||
|
|
||||||
|
|
||||||
// Session flags
|
// Session flags
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDE_IRC_SOCKET_H
|
||||||
|
#define INCLUDE_IRC_SOCKET_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sockets interface was moved out to simplify going OpenSSL integration.
|
* The sockets interface was moved out to simplify going OpenSSL integration.
|
||||||
*/
|
*/
|
||||||
@ -159,3 +162,5 @@ static int socket_send (socket_t * sock, const void *buf, size_t len)
|
|||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_IRC_SOCKET_H */
|
@ -1,17 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "./ssl.h"
|
||||||
|
|
||||||
|
#include "../include/libircclient.h"
|
||||||
|
#include "./session.h"
|
||||||
|
|
||||||
#if defined (ENABLE_SSL)
|
#if defined (ENABLE_SSL)
|
||||||
|
|
||||||
@ -26,22 +30,22 @@ static CRITICAL_SECTION * mutex_buf = 0;
|
|||||||
// OpenSSL callback to utilize static locks
|
// OpenSSL callback to utilize static locks
|
||||||
static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
|
static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
|
||||||
{
|
{
|
||||||
if ( mode & CRYPTO_LOCK)
|
if ( mode & CRYPTO_LOCK)
|
||||||
EnterCriticalSection( &mutex_buf[n] );
|
EnterCriticalSection( &mutex_buf[n] );
|
||||||
else
|
else
|
||||||
LeaveCriticalSection( &mutex_buf[n] );
|
LeaveCriticalSection( &mutex_buf[n] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenSSL callback to get the thread ID
|
// OpenSSL callback to get the thread ID
|
||||||
static unsigned long cb_openssl_id_function(void)
|
static unsigned long cb_openssl_id_function(void)
|
||||||
{
|
{
|
||||||
return ((unsigned long) GetCurrentThreadId() );
|
return ((unsigned long) GetCurrentThreadId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alloc_mutexes( unsigned int total )
|
static int alloc_mutexes( unsigned int total )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// Enable thread safety in OpenSSL
|
// Enable thread safety in OpenSSL
|
||||||
mutex_buf = (CRITICAL_SECTION*) malloc( total * sizeof(CRITICAL_SECTION) );
|
mutex_buf = (CRITICAL_SECTION*) malloc( total * sizeof(CRITICAL_SECTION) );
|
||||||
|
|
||||||
@ -50,7 +54,7 @@ static int alloc_mutexes( unsigned int total )
|
|||||||
|
|
||||||
for ( i = 0; i < total; i++)
|
for ( i = 0; i < total; i++)
|
||||||
InitializeCriticalSection( &(mutex_buf[i]) );
|
InitializeCriticalSection( &(mutex_buf[i]) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,13 +67,13 @@ static pthread_mutex_t * mutex_buf = 0;
|
|||||||
// OpenSSL callback to utilize static locks
|
// OpenSSL callback to utilize static locks
|
||||||
static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
|
static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
|
||||||
{
|
{
|
||||||
(void)file;
|
(void)file;
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
if ( mode & CRYPTO_LOCK)
|
if ( mode & CRYPTO_LOCK)
|
||||||
pthread_mutex_lock( &mutex_buf[n] );
|
pthread_mutex_lock( &mutex_buf[n] );
|
||||||
else
|
else
|
||||||
pthread_mutex_unlock( &mutex_buf[n] );
|
pthread_mutex_unlock( &mutex_buf[n] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenSSL callback to get the thread ID
|
// OpenSSL callback to get the thread ID
|
||||||
@ -82,7 +86,7 @@ static void cb_openssl_id_function( CRYPTO_THREADID * id )
|
|||||||
static int alloc_mutexes( unsigned int total )
|
static int alloc_mutexes( unsigned int total )
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
// Enable thread safety in OpenSSL
|
// Enable thread safety in OpenSSL
|
||||||
mutex_buf = (pthread_mutex_t*) malloc( total * sizeof(pthread_mutex_t) );
|
mutex_buf = (pthread_mutex_t*) malloc( total * sizeof(pthread_mutex_t) );
|
||||||
|
|
||||||
@ -91,7 +95,7 @@ static int alloc_mutexes( unsigned int total )
|
|||||||
|
|
||||||
for ( i = 0; i < total; i++)
|
for ( i = 0; i < total; i++)
|
||||||
pthread_mutex_init( &(mutex_buf[i]), 0 );
|
pthread_mutex_init( &(mutex_buf[i]), 0 );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +119,7 @@ static int ssl_init_context( irc_session_t * session )
|
|||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
#else
|
#else
|
||||||
OPENSSL_init_ssl(0, NULL);
|
OPENSSL_init_ssl(0, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( RAND_status() == 0 )
|
if ( RAND_status() == 0 )
|
||||||
return LIBIRC_ERR_SSL_INIT_FAILED;
|
return LIBIRC_ERR_SSL_INIT_FAILED;
|
||||||
@ -139,13 +143,13 @@ static int ssl_init_context( irc_session_t * session )
|
|||||||
SSL_CTX_set_verify( ssl_context, SSL_VERIFY_NONE, 0 );
|
SSL_CTX_set_verify( ssl_context, SSL_VERIFY_NONE, 0 );
|
||||||
else
|
else
|
||||||
SSL_CTX_set_verify( ssl_context, SSL_VERIFY_PEER, 0 );
|
SSL_CTX_set_verify( ssl_context, SSL_VERIFY_PEER, 0 );
|
||||||
|
|
||||||
// Disable session caching
|
// Disable session caching
|
||||||
SSL_CTX_set_session_cache_mode( ssl_context, SSL_SESS_CACHE_OFF );
|
SSL_CTX_set_session_cache_mode( ssl_context, SSL_SESS_CACHE_OFF );
|
||||||
|
|
||||||
// Enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER so we can move the buffer during sending
|
// Enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER so we can move the buffer during sending
|
||||||
SSL_CTX_set_mode( ssl_context, SSL_CTX_get_mode(ssl_context) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE );
|
SSL_CTX_set_mode( ssl_context, SSL_CTX_get_mode(ssl_context) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,13 +166,13 @@ static int ssl_init_context( irc_session_t * session )
|
|||||||
static int ssl_init( irc_session_t * session )
|
static int ssl_init( irc_session_t * session )
|
||||||
{
|
{
|
||||||
static int ssl_context_initialized = 0;
|
static int ssl_context_initialized = 0;
|
||||||
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
static HANDLE initmutex = 0;
|
static HANDLE initmutex = 0;
|
||||||
|
|
||||||
// First time run? Create the mutex
|
// First time run? Create the mutex
|
||||||
if ( initmutex == 0 )
|
if ( initmutex == 0 )
|
||||||
{
|
{
|
||||||
HANDLE m = CreateMutex( 0, FALSE, 0 );
|
HANDLE m = CreateMutex( 0, FALSE, 0 );
|
||||||
|
|
||||||
// Now we check if the mutex has already been created by another thread performing the init concurrently.
|
// Now we check if the mutex has already been created by another thread performing the init concurrently.
|
||||||
@ -180,28 +184,28 @@ static int ssl_init( irc_session_t * session )
|
|||||||
#else
|
#else
|
||||||
static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This initialization needs to be performed only once. The problem is that it is called from
|
// This initialization needs to be performed only once. The problem is that it is called from
|
||||||
// irc_connect() and this function may be called simultaneously from different threads. So we have
|
// irc_connect() and this function may be called simultaneously from different threads. So we have
|
||||||
// to use mutex on Linux because it allows static mutex initialization. Windows doesn't, so here
|
// to use mutex on Linux because it allows static mutex initialization. Windows doesn't, so here
|
||||||
// we do the sabre dance around it.
|
// we do the sabre dance around it.
|
||||||
SSLINIT_LOCK_MUTEX( initmutex );
|
SSLINIT_LOCK_MUTEX( initmutex );
|
||||||
|
|
||||||
if ( ssl_context_initialized == 0 )
|
if ( ssl_context_initialized == 0 )
|
||||||
{
|
{
|
||||||
int res = ssl_init_context( session );
|
int res = ssl_init_context( session );
|
||||||
|
|
||||||
if ( res )
|
if ( res )
|
||||||
{
|
{
|
||||||
SSLINIT_UNLOCK_MUTEX( initmutex );
|
SSLINIT_UNLOCK_MUTEX( initmutex );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_context_initialized = 1;
|
ssl_context_initialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSLINIT_UNLOCK_MUTEX( initmutex );
|
SSLINIT_UNLOCK_MUTEX( initmutex );
|
||||||
|
|
||||||
// Get the SSL context
|
// Get the SSL context
|
||||||
session->ssl = SSL_new( ssl_context );
|
session->ssl = SSL_new( ssl_context );
|
||||||
|
|
||||||
@ -211,7 +215,7 @@ static int ssl_init( irc_session_t * session )
|
|||||||
// Let OpenSSL use our socket
|
// Let OpenSSL use our socket
|
||||||
if ( SSL_set_fd( session->ssl, session->sock) != 1 )
|
if ( SSL_set_fd( session->ssl, session->sock) != 1 )
|
||||||
return LIBIRC_ERR_SSL_INIT_FAILED;
|
return LIBIRC_ERR_SSL_INIT_FAILED;
|
||||||
|
|
||||||
// Since we're connecting on our own, tell openssl about it
|
// Since we're connecting on our own, tell openssl about it
|
||||||
SSL_set_connect_state( session->ssl );
|
SSL_set_connect_state( session->ssl );
|
||||||
|
|
||||||
@ -227,7 +231,7 @@ static void ssl_handle_error( irc_session_t * session, int ssl_error )
|
|||||||
session->lasterror = LIBIRC_ERR_SSL_CERT_VERIFY_FAILED;
|
session->lasterror = LIBIRC_ERR_SSL_CERT_VERIFY_FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ERR_GET_REASON(ssl_error) == SSL_R_UNKNOWN_PROTOCOL )
|
if ( ERR_GET_REASON(ssl_error) == SSL_R_UNKNOWN_PROTOCOL )
|
||||||
{
|
{
|
||||||
session->lasterror = LIBIRC_ERR_CONNECT_SSL_FAILED;
|
session->lasterror = LIBIRC_ERR_CONNECT_SSL_FAILED;
|
||||||
@ -237,7 +241,7 @@ static void ssl_handle_error( irc_session_t * session, int ssl_error )
|
|||||||
|
|
||||||
#if defined (ENABLE_DEBUG)
|
#if defined (ENABLE_DEBUG)
|
||||||
if ( IS_DEBUG_ENABLED(session) )
|
if ( IS_DEBUG_ENABLED(session) )
|
||||||
fprintf (stderr, "[DEBUG] SSL error: %s\n\t(%d, %d)\n",
|
fprintf (stderr, "[DEBUG] SSL error: %s\n\t(%d, %d)\n",
|
||||||
ERR_error_string( ssl_error, NULL), ERR_GET_LIB( ssl_error), ERR_GET_REASON(ssl_error) );
|
ERR_error_string( ssl_error, NULL), ERR_GET_LIB( ssl_error), ERR_GET_REASON(ssl_error) );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -246,42 +250,42 @@ static int ssl_recv( irc_session_t * session )
|
|||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
unsigned int amount = (sizeof (session->incoming_buf) - 1) - session->incoming_offset;
|
unsigned int amount = (sizeof (session->incoming_buf) - 1) - session->incoming_offset;
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
// Read up to m_bufferLength bytes
|
// Read up to m_bufferLength bytes
|
||||||
count = SSL_read( session->ssl, session->incoming_buf + session->incoming_offset, amount );
|
count = SSL_read( session->ssl, session->incoming_buf + session->incoming_offset, amount );
|
||||||
|
|
||||||
if ( count > 0 )
|
if ( count > 0 )
|
||||||
return count;
|
return count;
|
||||||
else if ( count == 0 )
|
else if ( count == 0 )
|
||||||
return -1; // remote connection closed
|
return -1; // remote connection closed
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ssl_error = SSL_get_error( session->ssl, count );
|
int ssl_error = SSL_get_error( session->ssl, count );
|
||||||
|
|
||||||
// Handle SSL error since not all of them are actually errors
|
// Handle SSL error since not all of them are actually errors
|
||||||
switch ( ssl_error )
|
switch ( ssl_error )
|
||||||
{
|
{
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
// This is not really an error. We received something, but
|
// This is not really an error. We received something, but
|
||||||
// OpenSSL gave nothing to us because all it read was
|
// OpenSSL gave nothing to us because all it read was
|
||||||
// internal data. Repeat the same read.
|
// internal data. Repeat the same read.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
// This is not really an error. We received something, but
|
// This is not really an error. We received something, but
|
||||||
// now OpenSSL needs to send the data before returning any
|
// now OpenSSL needs to send the data before returning any
|
||||||
// data to us (like negotiations). This means we'd need
|
// data to us (like negotiations). This means we'd need
|
||||||
// to wait for WRITE event, but call SSL_read() again.
|
// to wait for WRITE event, but call SSL_read() again.
|
||||||
session->flags |= SESSIONFL_SSL_READ_WANTS_WRITE;
|
session->flags |= SESSIONFL_SSL_READ_WANTS_WRITE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an SSL error, handle it
|
// This is an SSL error, handle it
|
||||||
ssl_handle_error( session, ERR_get_error() );
|
ssl_handle_error( session, ERR_get_error() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,37 +293,37 @@ static int ssl_recv( irc_session_t * session )
|
|||||||
static int ssl_send( irc_session_t * session )
|
static int ssl_send( irc_session_t * session )
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
count = SSL_write( session->ssl, session->outgoing_buf, session->outgoing_offset );
|
count = SSL_write( session->ssl, session->outgoing_buf, session->outgoing_offset );
|
||||||
|
|
||||||
if ( count > 0 )
|
if ( count > 0 )
|
||||||
return count;
|
return count;
|
||||||
else if ( count == 0 )
|
else if ( count == 0 )
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ssl_error = SSL_get_error( session->ssl, count );
|
int ssl_error = SSL_get_error( session->ssl, count );
|
||||||
|
|
||||||
switch ( ssl_error )
|
switch ( ssl_error )
|
||||||
{
|
{
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
// This is not really an error. We sent some internal OpenSSL data,
|
// This is not really an error. We sent some internal OpenSSL data,
|
||||||
// but now it needs to read more data before it can send anything.
|
// but now it needs to read more data before it can send anything.
|
||||||
// Thus we wait for READ event, but will call SSL_write() again.
|
// Thus we wait for READ event, but will call SSL_write() again.
|
||||||
session->flags |= SESSIONFL_SSL_WRITE_WANTS_READ;
|
session->flags |= SESSIONFL_SSL_WRITE_WANTS_READ;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
// This is not really an error. We sent some data, but now OpenSSL
|
// This is not really an error. We sent some data, but now OpenSSL
|
||||||
// wants to send some internal data before sending ours.
|
// wants to send some internal data before sending ours.
|
||||||
// Repeat the same write.
|
// Repeat the same write.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an SSL error, handle it
|
// This is an SSL error, handle it
|
||||||
ssl_handle_error( session, ERR_get_error() );
|
ssl_handle_error( session, ERR_get_error() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -331,7 +335,7 @@ static int ssl_send( irc_session_t * session )
|
|||||||
// Returns -1 in case there is an error and socket should be closed/connection terminated
|
// Returns -1 in case there is an error and socket should be closed/connection terminated
|
||||||
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
|
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
|
||||||
// Returns a positive number if we actually read something
|
// Returns a positive number if we actually read something
|
||||||
static int session_socket_read( irc_session_t * session )
|
int session_socket_read( irc_session_t * session )
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
@ -345,19 +349,19 @@ static int session_socket_read( irc_session_t * session )
|
|||||||
ssl_send( session );
|
ssl_send( session );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ssl_recv( session );
|
return ssl_recv( session );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
length = socket_recv( &session->sock,
|
length = socket_recv( &session->sock,
|
||||||
session->incoming_buf + session->incoming_offset,
|
session->incoming_buf + session->incoming_offset,
|
||||||
(sizeof (session->incoming_buf) - 1) - session->incoming_offset );
|
(sizeof (session->incoming_buf) - 1) - session->incoming_offset );
|
||||||
|
|
||||||
// There is no "retry" errors for regular sockets
|
// There is no "retry" errors for regular sockets
|
||||||
if ( length <= 0 )
|
if ( length <= 0 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +369,7 @@ static int session_socket_read( irc_session_t * session )
|
|||||||
// Returns -1 in case there is an error and socket should be closed/connection terminated
|
// Returns -1 in case there is an error and socket should be closed/connection terminated
|
||||||
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
|
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
|
||||||
// Returns a positive number if we actually sent something
|
// Returns a positive number if we actually sent something
|
||||||
static int session_socket_write( irc_session_t * session )
|
int session_socket_write( irc_session_t * session )
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
@ -379,16 +383,16 @@ static int session_socket_write( irc_session_t * session )
|
|||||||
ssl_recv( session );
|
ssl_recv( session );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ssl_send( session );
|
return ssl_send( session );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
length = socket_send (&session->sock, session->outgoing_buf, session->outgoing_offset);
|
length = socket_send (&session->sock, session->outgoing_buf, session->outgoing_offset);
|
||||||
|
|
||||||
// There is no "retry" errors for regular sockets
|
// There is no "retry" errors for regular sockets
|
||||||
if ( length <= 0 )
|
if ( length <= 0 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
23
libircclient/src/ssl.h
Normal file
23
libircclient/src/ssl.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "./session.h"
|
||||||
|
|
||||||
|
#ifndef INCLUDE_IRC_SSL_H
|
||||||
|
#define INCLUDE_IRC_SSL_H
|
||||||
|
|
||||||
|
int session_socket_read( irc_session_t * session );
|
||||||
|
int session_socket_write( irc_session_t * session );
|
||||||
|
|
||||||
|
#endif /* INCLUDE_IRC_SSL_H */
|
@ -1,17 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or (at your
|
* the Free Software Foundation; either version 3 of the License, or (at your
|
||||||
* option) any later version.
|
* option) any later version.
|
||||||
*
|
*
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
* License for more details.
|
* License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDE_IRC_UTILS_H
|
||||||
|
#define INCLUDE_IRC_UTILS_H
|
||||||
|
|
||||||
|
//#include <sys/select.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "./session.h"
|
||||||
|
|
||||||
static void libirc_add_to_set (int fd, fd_set *set, int * maxfd)
|
static void libirc_add_to_set (int fd, fd_set *set, int * maxfd)
|
||||||
{
|
{
|
||||||
FD_SET (fd, set);
|
FD_SET (fd, set);
|
||||||
@ -62,13 +73,13 @@ static int libirc_findcrlf_offset(const char *buf, int offset, const int length)
|
|||||||
static int libirc_findcrorlf (char * buf, int length)
|
static int libirc_findcrorlf (char * buf, int length)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for ( ; offset < length; offset++ )
|
for ( ; offset < length; offset++ )
|
||||||
{
|
{
|
||||||
if ( buf[offset] == 0x0D || buf[offset] == 0x0A )
|
if ( buf[offset] == 0x0D || buf[offset] == 0x0A )
|
||||||
{
|
{
|
||||||
buf[offset++] = '\0';
|
buf[offset++] = '\0';
|
||||||
|
|
||||||
if ( offset < (length - 1)
|
if ( offset < (length - 1)
|
||||||
&& (buf[offset] == 0x0D || buf[offset] == 0x0A) )
|
&& (buf[offset] == 0x0D || buf[offset] == 0x0A) )
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
@ -108,7 +119,7 @@ static void libirc_event_ctcp_internal (irc_session_t * session, const char * ev
|
|||||||
}
|
}
|
||||||
else if ( !strcmp (params[0], "FINGER") )
|
else if ( !strcmp (params[0], "FINGER") )
|
||||||
{
|
{
|
||||||
sprintf (textbuf, "FINGER %s (%s) Idle 0 seconds",
|
sprintf (textbuf, "FINGER %s (%s) Idle 0 seconds",
|
||||||
session->username ? session->username : "nobody",
|
session->username ? session->username : "nobody",
|
||||||
session->realname ? session->realname : "noname");
|
session->realname ? session->realname : "noname");
|
||||||
|
|
||||||
@ -128,3 +139,5 @@ static void libirc_event_ctcp_internal (irc_session_t * session, const char * ev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_IRC_UTILS_H */
|
Loading…
Reference in New Issue
Block a user