Miscellaneous fixes and code cleanup to libircclient

This commit is contained in:
achmizs 2021-12-05 05:35:23 -05:00
parent fa85b3a0c1
commit a44e8f5f00
14 changed files with 1273 additions and 1322 deletions

View File

@ -8,63 +8,63 @@
/* #undef HAVE_GETHOSTBYNAME_R */ /* #undef HAVE_GETHOSTBYNAME_R */
/* Define to 1 if you have the `inet_ntoa' function. */ /* Define to 1 if you have the `inet_ntoa' function. */
/* #undef HAVE_INET_NTOA */ #define HAVE_INET_NTOA 1
/* Define to 1 if you have the `inet_pton' function. */ /* Define to 1 if you have the `inet_pton' function. */
/* #undef HAVE_INET_PTON */ /* #undef HAVE_INET_PTON */
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */ #define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `localtime_r' function. */ /* Define to 1 if you have the `localtime_r' function. */
/* #undef HAVE_LOCALTIME_R */ #define HAVE_LOCALTIME_R 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */ to 0 otherwise. */
#define HAVE_MALLOC 0 #define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */ #define HAVE_MEMORY_H 1
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
/* #undef HAVE_SOCKET */ #define HAVE_SOCKET 1
/* Define to 1 if `stat' has the bug that it succeeds when given the /* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */ zero-length file name argument. */
#define HAVE_STAT_EMPTY_STRING_BUG 1 /* #undef HAVE_STAT_EMPTY_STRING_BUG */
/* Define to 1 if stdbool.h conforms to C99. */ /* Define to 1 if stdbool.h conforms to C99. */
#define HAVE_STDBOOL_H 1 #define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */ #define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */ /* Define to 1 if you have the <stdlib.h> header file. */
/* #undef HAVE_STDLIB_H */ #define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */ #define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
/* #undef HAVE_STRING_H */ #define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/select.h> header file. */ /* Define to 1 if you have the <sys/select.h> header file. */
/* #undef HAVE_SYS_SELECT_H */ #define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */ /* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */ #define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/stat.h> header file. */
/* #undef HAVE_SYS_STAT_H */ #define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
/* #undef HAVE_SYS_TYPES_H */ #define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */ #define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `_Bool'. */ /* Define to 1 if the system has the type `_Bool'. */
/* #undef HAVE__BOOL */ #define HAVE__BOOL 1
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing /* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */ slash. */
@ -77,28 +77,28 @@
#define PACKAGE_NAME "libircclient" #define PACKAGE_NAME "libircclient"
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#define PACKAGE_STRING "libircclient 1.8" #define PACKAGE_STRING "libircclient 1.3"
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libircclient" #define PACKAGE_TARNAME "libircclient"
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "1.8" #define PACKAGE_VERSION "1.3"
/* Define to the type of arg 1 for `select'. */ /* Define to the type of arg 1 for `select'. */
#define SELECT_TYPE_ARG1 int #define SELECT_TYPE_ARG1 int
/* Define to the type of args 2, 3 and 4 for `select'. */ /* Define to the type of args 2, 3 and 4 for `select'. */
#define SELECT_TYPE_ARG234 (int *) #define SELECT_TYPE_ARG234 (fd_set *)
/* Define to the type of arg 5 for `select'. */ /* Define to the type of arg 5 for `select'. */
#define SELECT_TYPE_ARG5 (struct timeval *) #define SELECT_TYPE_ARG5 (struct timeval *)
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
/* #undef STDC_HEADERS */ #define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
/* #undef TIME_WITH_SYS_TIME */ #define TIME_WITH_SYS_TIME 1
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */ /* #undef const */

View File

@ -19,8 +19,7 @@
/* /*
* This structure keeps the state of a single DCC connection. * This structure keeps the state of a single DCC connection.
*/ */
struct irc_dcc_session_s struct irc_dcc_session_s {
{
irc_dcc_session_t * next; irc_dcc_session_t * next;
irc_dcc_t id; irc_dcc_t id;
@ -35,16 +34,16 @@ struct irc_dcc_session_s
time_t timeout; time_t timeout;
FILE * dccsend_file_fp; FILE * dccsend_file_fp;
unsigned int received_file_size; size_t received_file_size;
unsigned int file_confirm_offset; size_t file_confirm_offset;
struct sockaddr_in remote_addr; struct sockaddr_in remote_addr;
char incoming_buf[LIBIRC_DCC_BUFFER_SIZE]; char incoming_buf[LIBIRC_DCC_BUFFER_SIZE];
unsigned int incoming_offset; size_t incoming_offset;
char outgoing_buf[LIBIRC_DCC_BUFFER_SIZE]; char outgoing_buf[LIBIRC_DCC_BUFFER_SIZE];
unsigned int outgoing_offset; size_t outgoing_offset;
port_mutex_t mutex_outbuf; port_mutex_t mutex_outbuf;
irc_dcc_callback_t cb; irc_dcc_callback_t cb;

View File

@ -109,10 +109,10 @@ typedef void (*irc_event_dcc_chat_t) (irc_session_t * session, const char * nick
/*! /*!
* \fn typedef void (*irc_event_dcc_send_t) (irc_session_t * session, const char * nick, const char * addr, const char * filename, unsigned long size, irc_dcc_t dccid) * \fn typedef void (*irc_event_dcc_send_t) (irc_session_t * session, const char * nick, const char * addr, const char * filename, unsigned long size, irc_dcc_t dccid)
* \brief A remote DCC CHAT request callback * \brief A remote DCC SEND request callback
* *
* \param session the session, which generates an event * \param session the session, which generates an event
* \param nick the person who requested DCC CHAT with you. * \param nick the person who requested DCC SEND to you.
* \param addr the person's IP address in decimal-dot notation. * \param addr the person's IP address in decimal-dot notation.
* \param filename the sent filename. * \param filename the sent filename.
* \param size the filename size. * \param size the filename size.
@ -127,7 +127,7 @@ typedef void (*irc_event_dcc_chat_t) (irc_session_t * session, const char * nick
* \sa irc_dcc_accept or irc_dcc_decline * \sa irc_dcc_accept or irc_dcc_decline
* \ingroup events * \ingroup events
*/ */
typedef void (*irc_event_dcc_send_t) (irc_session_t * session, const char * nick, const char * addr, const char * filename, unsigned long size, irc_dcc_t dccid); typedef void (*irc_event_dcc_send_t) (irc_session_t *session, const char *nick, const char *addr, const char *filename, size_t size, irc_dcc_t dccid);
/*! \brief Event callbacks structure. /*! \brief Event callbacks structure.
@ -157,6 +157,16 @@ typedef struct
*/ */
irc_event_callback_t event_connect; irc_event_callback_t event_connect;
/*!
* The "ping" event is triggered when the client receives a PING message.
* It is only generated if the LIBIRC_OPTION_PING_PASSTHROUGH option is set;
* otherwise, the library responds to PING messages automatically.
*
* \param origin the person, who generated the ping.
* \param params[0] mandatory, contains who knows what.
*/
irc_event_callback_t event_ping;
/*! /*!
* The "nick" event is triggered when the client receives a NICK message, * The "nick" event is triggered when the client receives a NICK message,
* meaning that someone (including you) on a channel with the client has * meaning that someone (including you) on a channel with the client has
@ -247,6 +257,15 @@ typedef struct
*/ */
irc_event_callback_t event_kick; irc_event_callback_t event_kick;
/*!
* The "error" event is triggered upon receipt of an ERROR message, which
* (when sent to clients) usually means the client has been disconnected.
*
* \param origin the person, who generates the message.
* \param params optional, contains who knows what.
*/
irc_event_callback_t event_error;
/*! /*!
* The "channel" event is triggered upon receipt of a PRIVMSG message * The "channel" event is triggered upon receipt of a PRIVMSG message
* to an entire channel, which means that someone on a channel with * to an entire channel, which means that someone on a channel with
@ -401,7 +420,7 @@ typedef struct
irc_event_dcc_chat_t event_dcc_chat_req; irc_event_dcc_chat_t event_dcc_chat_req;
/*! /*!
* The "dcc chat" event is triggered when someone wants to send a file * The "dcc send" event is triggered when someone wants to send a file
* to you via DCC SEND request. * to you via DCC SEND request.
* *
* See the params in ::irc_event_dcc_send_t specification. * See the params in ::irc_event_dcc_send_t specification.

View File

@ -52,5 +52,13 @@
*/ */
#define LIBIRC_OPTION_SSL_NO_VERIFY (1 << 3) #define LIBIRC_OPTION_SSL_NO_VERIFY (1 << 3)
/*! \brief Disables automatic response to PING messages.
*
* The library will still generate events for PING messages, if an event handler
* is provided.
* \ingroup options
*/
#define LIBIRC_OPTION_IGNORE_PING (1 << 4)
#endif /* INCLUDE_IRC_OPTIONS_H */ #endif /* INCLUDE_IRC_OPTIONS_H */

View File

@ -15,7 +15,7 @@
/*! /*!
* \file libircclient.h * \file libircclient.h
* \author George Yunaev * \author George Yunaev
* \version 1.5 * \version 1.9
* \date 01.2012 * \date 01.2012
* \brief This file defines all prototypes and functions to use libircclient. * \brief This file defines all prototypes and functions to use libircclient.
* *
@ -46,7 +46,7 @@
#include <stdlib.h> #include <stdlib.h>
#if !defined (WIN32) #if !defined (_WIN32)
#include <sys/select.h> /* fd_set */ #include <sys/select.h> /* fd_set */
#else #else
#include <winsock2.h> #include <winsock2.h>
@ -126,7 +126,7 @@ typedef unsigned int irc_dcc_t;
* *
* \ingroup dccstuff * \ingroup dccstuff
*/ */
typedef void (*irc_dcc_callback_t) (irc_session_t * session, irc_dcc_t id, int status, void * ctx, const char * data, unsigned int length); typedef void (*irc_dcc_callback_t) (irc_session_t *session, irc_dcc_t id, int status, void *ctx, const char *data, size_t length);
#define IN_INCLUDE_LIBIRC_H #define IN_INCLUDE_LIBIRC_H
@ -355,7 +355,10 @@ int irc_run (irc_session_t * session);
* \sa irc_process_select_descriptors * \sa irc_process_select_descriptors
* \ingroup running * \ingroup running
*/ */
int irc_add_select_descriptors (irc_session_t * session, fd_set *in_set, fd_set *out_set, int * maxfd); int irc_add_select_descriptors (irc_session_t *session,
fd_set *in_set,
fd_set *out_set,
int *maxfd);
/*! /*!
@ -375,7 +378,9 @@ int irc_add_select_descriptors (irc_session_t * session, fd_set *in_set, fd_set
* \sa irc_add_select_descriptors * \sa irc_add_select_descriptors
* \ingroup running * \ingroup running
*/ */
int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_set *out_set); int irc_process_select_descriptors (irc_session_t *session,
fd_set *in_set,
fd_set *out_set);
/*! /*!
@ -395,7 +400,9 @@ int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_
* *
* \ingroup ircmd_oth * \ingroup ircmd_oth
*/ */
int irc_send_raw (irc_session_t * session, const char * format, ...); int irc_send_raw (irc_session_t *session,
const char *format,
...);
/*! /*!
@ -415,7 +422,8 @@ int irc_send_raw (irc_session_t * session, const char * format, ...);
* *
* \ingroup ircmd_oth * \ingroup ircmd_oth
*/ */
int irc_cmd_quit (irc_session_t * session, const char * reason); int irc_cmd_quit (irc_session_t *session,
const char *reason);
/*! /*!
@ -457,7 +465,9 @@ int irc_cmd_quit (irc_session_t * session, const char * reason);
* *
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_join (irc_session_t * session, const char * channel, const char * key); int irc_cmd_join (irc_session_t *session,
const char *channel,
const char *key);
/*! /*!
@ -482,7 +492,8 @@ int irc_cmd_join (irc_session_t * session, const char * channel, const char * ke
* *
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_part (irc_session_t * session, const char * channel); int irc_cmd_part (irc_session_t *session,
const char *channel);
/*! /*!
@ -517,7 +528,9 @@ int irc_cmd_part (irc_session_t * session, const char * channel);
* \sa irc_callbacks_t::event_invite irc_cmd_channel_mode * \sa irc_callbacks_t::event_invite irc_cmd_channel_mode
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_invite (irc_session_t * session, const char * nick, const char * channel); int irc_cmd_invite (irc_session_t *session,
const char *nick,
const char *channel);
/*! /*!
@ -545,7 +558,8 @@ int irc_cmd_invite (irc_session_t * session, const char * nick, const char * cha
* *
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_names (irc_session_t * session, const char * channel); int irc_cmd_names (irc_session_t *session,
const char *channel);
/*! /*!
@ -580,7 +594,8 @@ int irc_cmd_names (irc_session_t * session, const char * channel);
* *
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_list (irc_session_t * session, const char * channel); int irc_cmd_list (irc_session_t *session,
const char *channel);
/*! /*!
@ -620,7 +635,9 @@ int irc_cmd_list (irc_session_t * session, const char * channel);
* \sa irc_callbacks_t::event_topic irc_cmd_channel_mode * \sa irc_callbacks_t::event_topic irc_cmd_channel_mode
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_topic (irc_session_t * session, const char * channel, const char * topic); int irc_cmd_topic (irc_session_t *session,
const char *channel,
const char *topic);
/*! /*!
@ -713,7 +730,9 @@ int irc_cmd_topic (irc_session_t * session, const char * channel, const char * t
* \sa irc_cmd_topic irc_cmd_list * \sa irc_cmd_topic irc_cmd_list
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_channel_mode (irc_session_t * session, const char * channel, const char * mode); int irc_cmd_channel_mode (irc_session_t *session,
const char *channel,
const char *mode);
/*! /*!
@ -774,7 +793,8 @@ int irc_cmd_channel_mode (irc_session_t * session, const char * channel, const c
* *
* \ingroup ircmd_oth * \ingroup ircmd_oth
*/ */
int irc_cmd_user_mode (irc_session_t * session, const char * mode); int irc_cmd_user_mode (irc_session_t *session,
const char *mode);
/*! /*!
@ -800,7 +820,8 @@ int irc_cmd_user_mode (irc_session_t * session, const char * mode);
* *
* \ingroup ircmd_oth * \ingroup ircmd_oth
*/ */
int irc_cmd_nick (irc_session_t * session, const char * newnick); int irc_cmd_nick (irc_session_t *session,
const char *newnick);
/*! /*!
@ -835,7 +856,8 @@ int irc_cmd_nick (irc_session_t * session, const char * newnick);
* *
* \ingroup ircmd_oth * \ingroup ircmd_oth
*/ */
int irc_cmd_whois (irc_session_t * session, const char * nick); int irc_cmd_whois (irc_session_t *session,
const char *nick);
/*! /*!
@ -870,7 +892,9 @@ int irc_cmd_whois (irc_session_t * session, const char * nick);
* *
* \ingroup ircmd_msg * \ingroup ircmd_msg
*/ */
int irc_cmd_msg (irc_session_t * session, const char * nch, const char * text); int irc_cmd_msg (irc_session_t *session,
const char *nch,
const char *text);
/*! /*!
@ -904,7 +928,9 @@ int irc_cmd_msg (irc_session_t * session, const char * nch, const char * text);
* \sa irc_cmd_msg * \sa irc_cmd_msg
* \ingroup ircmd_msg * \ingroup ircmd_msg
*/ */
int irc_cmd_me (irc_session_t * session, const char * nch, const char * text); int irc_cmd_me (irc_session_t *session,
const char *nch,
const char *text);
/*! /*!
@ -944,7 +970,9 @@ int irc_cmd_me (irc_session_t * session, const char * nch, const char * text);
* \sa irc_cmd_msg * \sa irc_cmd_msg
* \ingroup ircmd_msg * \ingroup ircmd_msg
*/ */
int irc_cmd_notice (irc_session_t * session, const char * nch, const char * text); int irc_cmd_notice (irc_session_t *session,
const char *nch,
const char *text);
/*! /*!
@ -975,7 +1003,10 @@ int irc_cmd_notice (irc_session_t * session, const char * nch, const char * text
* \sa irc_callbacks_t::event_numeric * \sa irc_callbacks_t::event_numeric
* \ingroup ircmd_ch * \ingroup ircmd_ch
*/ */
int irc_cmd_kick (irc_session_t * session, const char * nick, const char * channel, const char * reason); int irc_cmd_kick (irc_session_t *session,
const char *nick,
const char *channel,
const char *reason);
/*! /*!
@ -1013,7 +1044,9 @@ int irc_cmd_kick (irc_session_t * session, const char * nick, const char * chann
* \sa irc_callbacks_t::event_ctcp_rep irc_callbacks_t::event_numeric * \sa irc_callbacks_t::event_ctcp_rep irc_callbacks_t::event_numeric
* \ingroup ctcp * \ingroup ctcp
*/ */
int irc_cmd_ctcp_request (irc_session_t * session, const char * nick, const char * request); int irc_cmd_ctcp_request (irc_session_t *session,
const char *nick,
const char *request);
/*! /*!
@ -1045,28 +1078,32 @@ int irc_cmd_ctcp_request (irc_session_t * session, const char * nick, const char
* *
* \ingroup ctcp * \ingroup ctcp
*/ */
int irc_cmd_ctcp_reply (irc_session_t * session, const char * nick, const char * reply); int irc_cmd_ctcp_reply (irc_session_t *session,
const char *nick,
const char *reply);
/*! /*!
* \fn void irc_target_get_nick (const char * target, char *nick, size_t size) * \fn void irc_target_get_nick (const char * target, char *nick, size_t size)
* \brief Gets the nick part from the target * \brief Gets the nick part from the target
* *
* \param target A nick in common IRC server form like tim!root\@mycomain.com * \param target A nick in common IRC server form like tim!root\@mycomain.com; cannot be NULL
* \param nick A buffer to hold the nickname. * \param nick A buffer to hold the nickname.
* \param size A buffer size. If nick is longer than buffer size, it will * \param size A buffer size. If nick is longer than buffer size, it will
* be truncated. * be truncated.
* *
* For most events IRC server returns 'origin' (i.e. the person, who * For most events IRC server returns 'origin' (i.e. the person, who
* generated this event) in i.e. "common" form, like nick!host\@domain. * generated this event) in i.e. "common" form, like nick!host\@domain.
* However, all the irc_cmd_* functions require just a nick/ * However, all the irc_cmd_* functions require just a nick.
* This function parses this origin, and gets the nick, storing it into * This function parses this origin, and gets the nick, storing it into
* user-provided buffer. * user-provided buffer.
* A buffer of size 90 should be enough for most nicks :) * A buffer of size 90 should be enough for most nicks :)
* *
* \ingroup nnparse * \ingroup nnparse
*/ */
void irc_target_get_nick (const char * target, char *nick, size_t size); void irc_target_get_nick (const char *target,
char *nick,
size_t size);
/*! /*!
@ -1086,7 +1123,9 @@ void irc_target_get_nick (const char * target, char *nick, size_t size);
* *
* \ingroup nnparse * \ingroup nnparse
*/ */
void irc_target_get_host (const char * target, char *nick, size_t size); void irc_target_get_host (const char *target,
char *nick,
size_t size);
/*! /*!
@ -1127,7 +1166,12 @@ void irc_target_get_host (const char * target, char *nick, size_t size);
* \sa irc_dcc_callback_t irc_dcc_msg * \sa irc_dcc_callback_t irc_dcc_msg
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dcc_callback_t callback, irc_dcc_t * dccid); int irc_dcc_chat (irc_session_t *session,
void *ctx,
const char *nick,
irc_dcc_callback_t
callback,
irc_dcc_t *dccid);
/*! /*!
@ -1148,7 +1192,9 @@ int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dc
* \sa irc_dcc_chat * \sa irc_dcc_chat
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text); int irc_dcc_msg (irc_session_t *session,
irc_dcc_t dccid,
const char *text);
/*! /*!
@ -1179,7 +1225,10 @@ int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text);
* \sa irc_dcc_decline event_dcc_chat_req event_dcc_send_req * \sa irc_dcc_decline event_dcc_chat_req event_dcc_send_req
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback); int irc_dcc_accept (irc_session_t *session,
irc_dcc_t dccid,
void *ctx,
irc_dcc_callback_t callback);
/*! /*!
@ -1207,7 +1256,8 @@ int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dc
* \sa irc_dcc_accept irc_callbacks_t::event_dcc_chat_req irc_callbacks_t::event_dcc_send_req irc_dcc_destroy * \sa irc_dcc_accept irc_callbacks_t::event_dcc_chat_req irc_callbacks_t::event_dcc_send_req irc_dcc_destroy
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid); int irc_dcc_decline (irc_session_t *session,
irc_dcc_t dccid);
/*! /*!
@ -1245,7 +1295,12 @@ int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid);
* \sa irc_dcc_callback_t * \sa irc_dcc_callback_t
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, const char * filename, irc_dcc_callback_t callback, irc_dcc_t * dccid); int irc_dcc_sendfile (irc_session_t *session,
void *ctx,
const char *nick,
const char *filename,
irc_dcc_callback_t callback,
irc_dcc_t *dccid);
/*! /*!
@ -1267,7 +1322,8 @@ int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, co
* *
* \ingroup dccstuff * \ingroup dccstuff
*/ */
int irc_dcc_destroy (irc_session_t * session, irc_dcc_t dccid); int irc_dcc_destroy (irc_session_t *session,
irc_dcc_t dccid);
/*! /*!
@ -1285,7 +1341,8 @@ int irc_dcc_destroy (irc_session_t * session, irc_dcc_t dccid);
* *
* \ingroup common * \ingroup common
*/ */
void irc_get_version (unsigned int * high, unsigned int * low); void irc_get_version (unsigned int *high,
unsigned int *low);
/*! /*!
@ -1305,7 +1362,8 @@ void irc_get_version (unsigned int * high, unsigned int * low);
* \sa irc_get_ctx * \sa irc_get_ctx
* \ingroup contexts * \ingroup contexts
*/ */
void irc_set_ctx (irc_session_t * session, void * ctx); void irc_set_ctx (irc_session_t *session,
void *ctx);
/*! /*!
* \fn void irc_set_ctcp_version (irc_session_t * session, const char *version) * \fn void irc_set_ctcp_version (irc_session_t * session, const char *version)
@ -1320,7 +1378,8 @@ void irc_set_ctx (irc_session_t * session, void * ctx);
* *
* \ingroup contexts * \ingroup contexts
*/ */
void irc_set_ctcp_version(irc_session_t * session, const char * version); void irc_set_ctcp_version(irc_session_t *session,
const char *version);
/*! /*!
* \fn void * irc_get_ctx (irc_session_t * session) * \fn void * irc_get_ctx (irc_session_t * session)
@ -1386,7 +1445,8 @@ const char * irc_strerror (int ircerrno);
* \sa irc_option_reset * \sa irc_option_reset
* \ingroup options * \ingroup options
*/ */
void irc_option_set (irc_session_t * session, unsigned int option); void irc_option_set (irc_session_t *session,
unsigned int option);
/*! /*!
@ -1402,7 +1462,8 @@ void irc_option_set (irc_session_t * session, unsigned int option);
* \sa irc_option_set * \sa irc_option_set
* \ingroup options * \ingroup options
*/ */
void irc_option_reset (irc_session_t * session, unsigned int option); void irc_option_reset (irc_session_t *session,
unsigned int option);
/*! /*!

View File

@ -17,7 +17,7 @@
#define LIBIRC_VERSION_HIGH 1 #define LIBIRC_VERSION_HIGH 1
#define LIBIRC_VERSION_LOW 8 #define LIBIRC_VERSION_LOW 10
#define LIBIRC_BUFFER_SIZE 1024 #define LIBIRC_BUFFER_SIZE 1024
#define LIBIRC_DCC_BUFFER_SIZE 1024 #define LIBIRC_DCC_BUFFER_SIZE 1024

View File

@ -31,8 +31,7 @@
struct irc_session_s struct irc_session_s {
{
void * ctx; void * ctx;
int dcc_timeout; int dcc_timeout;
@ -40,10 +39,10 @@ struct irc_session_s
int lasterror; int lasterror;
char incoming_buf[LIBIRC_BUFFER_SIZE]; char incoming_buf[LIBIRC_BUFFER_SIZE];
unsigned int incoming_offset; size_t incoming_offset;
char outgoing_buf[LIBIRC_BUFFER_SIZE]; char outgoing_buf[LIBIRC_BUFFER_SIZE];
unsigned int outgoing_offset; size_t outgoing_offset;
port_mutex_t mutex_session; port_mutex_t mutex_session;
socket_t sock; socket_t sock;
@ -72,7 +71,6 @@ struct irc_session_s
SSL * ssl; SSL * ssl;
#endif #endif
}; };

View File

@ -22,8 +22,13 @@
#define LIBIRC_COLORPARSER_MAXCOLORS 15 #define LIBIRC_COLORPARSER_MAXCOLORS 15
static const char * color_replacement_table[] = #define max(a,b) \
{ ({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
static const char *color_replacement_table[] = {
"WHITE", "WHITE",
"BLACK", "BLACK",
"DARKBLUE", "DARKBLUE",
@ -44,31 +49,30 @@ static const char * color_replacement_table[] =
}; };
static inline void libirc_colorparser_addorcat (char ** destline, unsigned int * destlen, const char * str) static inline void libirc_colorparser_addorcat (char **destline,
{ unsigned int *destlen,
unsigned int len = strlen(str); const char *str) {
size_t len = strlen(str);
if ( *destline ) if (*destline) {
{
strcpy (*destline, str); strcpy (*destline, str);
*destline += len; *destline += len;
} } else {
else
*destlen += len; *destlen += len;
} }
}
static void libirc_colorparser_applymask (unsigned int *mask, static void libirc_colorparser_applymask (unsigned int *mask,
char ** destline, unsigned int * destlen, char **destline,
unsigned int bitmask, const char * start, const char * end) unsigned int *destlen,
{ unsigned int bitmask,
if ( (*mask & bitmask) != 0 ) const char *start,
{ const char *end) {
if ((*mask & bitmask) != 0) {
*mask &= ~bitmask; *mask &= ~bitmask;
libirc_colorparser_addorcat (destline, destlen, end); libirc_colorparser_addorcat (destline, destlen, end);
} } else {
else
{
*mask |= bitmask; *mask |= bitmask;
libirc_colorparser_addorcat (destline, destlen, start); libirc_colorparser_addorcat (destline, destlen, start);
} }
@ -76,9 +80,10 @@ static void libirc_colorparser_applymask (unsigned int * mask,
static void libirc_colorparser_applycolor (unsigned int *mask, static void libirc_colorparser_applycolor (unsigned int *mask,
char ** destline, unsigned int * destlen, char **destline,
unsigned int colorid, unsigned int bgcolorid) unsigned int *destlen,
{ unsigned int colorid,
unsigned int bgcolorid) {
const char *end = "[/COLOR]"; const char *end = "[/COLOR]";
char startbuf[64]; char startbuf[64];
@ -96,8 +101,8 @@ static void libirc_colorparser_applycolor (unsigned int * mask,
static void libirc_colorparser_closetags (unsigned int *mask, static void libirc_colorparser_closetags (unsigned int *mask,
char ** destline, unsigned int * destlen) char **destline,
{ unsigned int *destlen) {
if (*mask & LIBIRC_COLORPARSER_BOLD) if (*mask & LIBIRC_COLORPARSER_BOLD)
libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_BOLD, 0, "[/B]"); libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_BOLD, 0, "[/B]");
@ -116,22 +121,20 @@ static void libirc_colorparser_closetags (unsigned int * mask,
/* /*
* IRC to [code] color conversion. Or strip. * IRC to [code] color conversion. Or strip.
*/ */
static char * libirc_colorparser_irc2code (const char * source, int strip) static char* libirc_colorparser_irc2code (const char *source,
{ int strip) {
unsigned int mask = 0, destlen = 0; unsigned int mask = 0, destlen = 0;
char *destline = 0, *d = 0; char *destline = 0, *d = 0;
const char *p; const char *p;
int current_bg = 0; unsigned int current_bg = 0;
/* /*
* There will be two passes. First pass calculates the total length of * There will be two passes. First pass calculates the total length of
* the destination string. The second pass allocates memory for the string, * the destination string. The second pass allocates memory for the string,
* and fills it. * and fills it.
*/ */
while ( destline == 0 ) // destline will be set after the 2nd pass while (destline == 0) { // destline will be set after the 2nd pass
{ if (destlen > 0) {
if ( destlen > 0 )
{
// This is the 2nd pass; allocate memory. // This is the 2nd pass; allocate memory.
if ((destline = malloc (destlen)) == 0) if ((destline = malloc (destlen)) == 0)
return 0; return 0;
@ -139,60 +142,54 @@ static char * libirc_colorparser_irc2code (const char * source, int strip)
d = destline; d = destline;
} }
for ( p = source; *p; p++ ) for (p = source; *p; p++) {
{ switch (*p) {
switch (*p) case 0x02: { // bold
{
case 0x02: // bold
if (strip) if (strip)
continue; continue;
libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]"); libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]");
break; break;
}
case 0x1F: // underline case 0x1F: { // underline
if (strip) if (strip)
continue; continue;
libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]"); libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]");
break; break;
}
case 0x16: // reverse case 0x16: { // reverse
if (strip) if (strip)
continue; continue;
libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]"); libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]");
break; break;
}
case 0x0F: // reset colors case 0x0F: { // reset colors
if (strip) if (strip)
continue; continue;
libirc_colorparser_closetags(&mask, &d, &destlen); libirc_colorparser_closetags(&mask, &d, &destlen);
break; break;
}
case 0x03: // set color case 0x03: { // set color
if ( isdigit (p[1]) ) if (isdigit (p[1])) {
{
// Parse // Parse
int bgcolor = -1, color = p[1] - 0x30; int bgcolor = -1, color = p[1] - 0x30;
p++; p++;
if ( isdigit (p[1]) ) if (isdigit (p[1])) {
{
color = color * 10 + (p[1] - 0x30); color = color * 10 + (p[1] - 0x30);
p++; p++;
} }
// If there is a comma, search for the following // If there is a comma, search for the following
// background color // background color
if ( p[1] == ',' && isdigit (p[2]) ) if (p[1] == ',' && isdigit (p[2])) {
{
bgcolor = p[2] - 0x30; bgcolor = p[2] - 0x30;
p += 2; p += 2;
if ( isdigit (p[1]) ) if (isdigit (p[1])) {
{
bgcolor = bgcolor * 10 + (p[1] - 0x30); bgcolor = bgcolor * 10 + (p[1] - 0x30);
p++; p++;
} }
@ -200,20 +197,19 @@ static char * libirc_colorparser_irc2code (const char * source, int strip)
// Check for range // Check for range
if ( color <= LIBIRC_COLORPARSER_MAXCOLORS if ( color <= LIBIRC_COLORPARSER_MAXCOLORS
&& bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS ) && bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS) {
{
if (strip) if (strip)
continue; continue;
if (bgcolor != -1) if (bgcolor != -1)
current_bg = bgcolor; current_bg = (unsigned int) bgcolor;
libirc_colorparser_applycolor (&mask, &d, &destlen, color, current_bg); libirc_colorparser_applycolor(&mask, &d, &destlen, (unsigned int) max(color, 0), current_bg);
} }
} }
break; break;
}
default: default: {
if (destline) if (destline)
*d++ = *p; *d++ = *p;
else else
@ -221,6 +217,7 @@ static char * libirc_colorparser_irc2code (const char * source, int strip)
break; break;
} }
} }
}
// Close all the opened tags // Close all the opened tags
libirc_colorparser_closetags (&mask, &d, &destlen); libirc_colorparser_closetags (&mask, &d, &destlen);
@ -232,8 +229,7 @@ static char * libirc_colorparser_irc2code (const char * source, int strip)
} }
static int libirc_colorparser_colorlookup (const char * color) static int libirc_colorparser_colorlookup (const char *color) {
{
int i; int i;
for (i = 0; color_replacement_table[i]; i++) for (i = 0; color_replacement_table[i]; i++)
if (!strcmp(color, color_replacement_table[i])) if (!strcmp(color, color_replacement_table[i]))
@ -246,8 +242,7 @@ static int libirc_colorparser_colorlookup (const char * color)
/* /*
* [code] to IRC color conversion. * [code] to IRC color conversion.
*/ */
char * irc_color_convert_to_mirc (const char * source) char* irc_color_convert_to_mirc (const char *source) {
{
unsigned int destlen = 0; unsigned int destlen = 0;
char *destline = 0, *d = 0; char *destline = 0, *d = 0;
const char *p1, *p2, *cur; const char *p1, *p2, *cur;
@ -257,10 +252,8 @@ char * irc_color_convert_to_mirc (const char * source)
* the destination string. The second pass allocates memory for the string, * the destination string. The second pass allocates memory for the string,
* and fills it. * and fills it.
*/ */
while ( destline == 0 ) // destline will be set after the 2nd pass while (destline == 0) { // destline will be set after the 2nd pass
{ if (destlen > 0) {
if ( destlen > 0 )
{
// This is the 2nd pass; allocate memory. // This is the 2nd pass; allocate memory.
if ((destline = malloc (destlen)) == 0) if ((destline = malloc (destlen)) == 0)
return 0; return 0;
@ -269,8 +262,7 @@ char * irc_color_convert_to_mirc (const char * source)
} }
cur = source; cur = source;
while ( (p1 = strchr (cur, '[')) != 0 ) while ((p1 = strchr(cur, '[')) != 0) {
{
const char *replacedval = 0; const char *replacedval = 0;
p2 = 0; p2 = 0;
@ -279,87 +271,76 @@ char * irc_color_convert_to_mirc (const char * source)
if ( p1[1] != '\0' if ( p1[1] != '\0'
&& (p2 = strchr (p1, ']')) != 0 && (p2 = strchr (p1, ']')) != 0
&& (p2 - p1) > 1 && (p2 - p1) > 1
&& (p2 - p1) < 31 ) && (p2 - p1) < 31) {
{
// Get the tag // Get the tag
char tagbuf[32]; char tagbuf[32];
int taglen = p2 - p1 - 1; ssize_t taglen = p2 - p1 - 1;
memcpy (tagbuf, p1 + 1, taglen); memcpy (tagbuf, p1 + 1, taglen);
tagbuf[taglen] = '\0'; tagbuf[taglen] = '\0';
if ( !strcmp (tagbuf, "/COLOR") ) if (!strcmp (tagbuf, "/COLOR")) {
replacedval = "\x0F"; replacedval = "\x0F";
else if ( strstr (tagbuf, "COLOR=") == tagbuf ) } else if (strstr(tagbuf, "COLOR=") == tagbuf) {
{
int color, bgcolor = -2; int color, bgcolor = -2;
char *bcol; char *bcol;
bcol = strchr(tagbuf + 6, '/'); bcol = strchr(tagbuf + 6, '/');
if ( bcol ) if (bcol) {
{
*bcol++ = '\0'; *bcol++ = '\0';
bgcolor = libirc_colorparser_colorlookup(bcol); bgcolor = libirc_colorparser_colorlookup(bcol);
} }
color = libirc_colorparser_colorlookup(tagbuf + 6); color = libirc_colorparser_colorlookup(tagbuf + 6);
if ( color != -1 && bgcolor == -2 ) if (color != -1 && bgcolor == -2) {
{
sprintf (tagbuf, "\x03%02d", color); sprintf (tagbuf, "\x03%02d", color);
replacedval = tagbuf; replacedval = tagbuf;
} } else if (color != -1 && bgcolor >= 0) {
else if ( color != -1 && bgcolor >= 0 )
{
sprintf (tagbuf, "\x03%02d,%02d", color, bgcolor); sprintf (tagbuf, "\x03%02d,%02d", color, bgcolor);
replacedval = tagbuf; replacedval = tagbuf;
} }
} } else if (!strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B")) {
else if ( !strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B") )
replacedval = "\x02"; replacedval = "\x02";
else if ( !strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U") ) } else if (!strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U")) {
replacedval = "\x1F"; replacedval = "\x1F";
else if ( !strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I") ) } else if (!strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I")) {
replacedval = "\x16"; replacedval = "\x16";
} }
}
if ( replacedval ) if (replacedval) {
{
// add a part before the tag // add a part before the tag
int partlen = p1 - cur; ssize_t partlen = p1 - cur;
if ( destline ) if (destline) {
{
memcpy (d, cur, partlen); memcpy (d, cur, partlen);
d += partlen; d += partlen;
} } else {
else
destlen += partlen; destlen += partlen;
}
// Add the replacement // Add the replacement
libirc_colorparser_addorcat(&d, &destlen, replacedval); libirc_colorparser_addorcat(&d, &destlen, replacedval);
// And move the pointer // And move the pointer
cur = p2 + 1; cur = p2 + 1;
} } else {
else
{
// add a whole part before the end tag // add a whole part before the end tag
int partlen; ssize_t partlen;
if (!p2) if (!p2)
p2 = cur + strlen(cur); p2 = cur + strlen(cur);
partlen = p2 - cur + 1; partlen = p2 - cur + 1;
if ( destline ) if (destline) {
{
memcpy (d, cur, partlen); memcpy (d, cur, partlen);
d += partlen; d += partlen;
} } else {
else
destlen += partlen; destlen += partlen;
}
// And move the pointer // And move the pointer
cur = p2 + 1; cur = p2 + 1;
@ -376,13 +357,11 @@ char * irc_color_convert_to_mirc (const char * source)
} }
char * irc_color_strip_from_mirc (const char * message) char* irc_color_strip_from_mirc (const char *message) {
{
return libirc_colorparser_irc2code (message, 1); return libirc_colorparser_irc2code (message, 1);
} }
char * irc_color_convert_from_mirc (const char * message) char* irc_color_convert_from_mirc (const char *message) {
{
return libirc_colorparser_irc2code (message, 0); return libirc_colorparser_irc2code (message, 0);
} }

View File

@ -17,17 +17,16 @@
#define LIBIRC_DCC_RECVFILE 3 #define LIBIRC_DCC_RECVFILE 3
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) {
irc_dcc_session_t *s, *found = 0; irc_dcc_session_t *s, *found = 0;
if (lock_list) if (lock_list)
libirc_mutex_lock (&session->mutex_dcc); libirc_mutex_lock (&session->mutex_dcc);
for ( s = session->dcc_sessions; s; s = s->next ) for (s = session->dcc_sessions; s; s = s->next) {
{ if (s->id == dccid) {
if ( s->id == dccid )
{
found = s; found = s;
break; break;
} }
@ -40,12 +39,11 @@ static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc
} }
static void libirc_dcc_destroy_nolock (irc_session_t * session, irc_dcc_t dccid) static void libirc_dcc_destroy_nolock (irc_session_t *session,
{ irc_dcc_t dccid) {
irc_dcc_session_t *dcc = libirc_find_dcc_session (session, dccid, 0); irc_dcc_session_t *dcc = libirc_find_dcc_session (session, dccid, 0);
if ( dcc ) if (dcc) {
{
if (dcc->sock >= 0) if (dcc->sock >= 0)
socket_close (&dcc->sock); socket_close (&dcc->sock);
@ -54,8 +52,9 @@ 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) static 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);
@ -69,20 +68,17 @@ static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_
if (lock_list) if (lock_list)
libirc_mutex_lock (&session->mutex_dcc); libirc_mutex_lock (&session->mutex_dcc);
if ( session->dcc_sessions != dcc ) if (session->dcc_sessions != dcc) {
{
irc_dcc_session_t *s; irc_dcc_session_t *s;
for ( s = session->dcc_sessions; s; s = s->next ) for (s = session->dcc_sessions; s; s = s->next) {
{ if (s->next == dcc) {
if ( s->next == dcc )
{
s->next = dcc->next; s->next = dcc->next;
break; break;
} }
} }
} } else {
else
session->dcc_sessions = dcc->next; session->dcc_sessions = dcc->next;
}
if (lock_list) if (lock_list)
libirc_mutex_unlock (&session->mutex_dcc); libirc_mutex_unlock (&session->mutex_dcc);
@ -91,8 +87,10 @@ 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) static 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);
@ -101,21 +99,18 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
// Preprocessing DCC list: // Preprocessing DCC list:
// - ask DCC send callbacks for data; // - ask DCC send callbacks for data;
// - remove unused DCC structures // - remove unused DCC structures
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc_next ) for (dcc = ircsession->dcc_sessions; dcc; dcc = dcc_next) {
{
dcc_next = dcc->next; dcc_next = dcc->next;
// Remove timed-out sessions // Remove timed-out sessions
if ( (dcc->state == LIBIRC_STATE_CONNECTING if ( (dcc->state == LIBIRC_STATE_CONNECTING
|| dcc->state == LIBIRC_STATE_INIT || dcc->state == LIBIRC_STATE_INIT
|| dcc->state == LIBIRC_STATE_LISTENING) || dcc->state == LIBIRC_STATE_LISTENING)
&& now - dcc->timeout > ircsession->dcc_timeout ) && now - dcc->timeout > ircsession->dcc_timeout ) {
{
// Inform the caller about DCC timeout. // Inform the caller about DCC timeout.
// Do not inform when state is LIBIRC_STATE_INIT - session // Do not inform when state is LIBIRC_STATE_INIT - session
// was initiated from someone else, and callbacks aren't set yet. // was initiated from someone else, and callbacks aren't set yet.
if ( dcc->state != LIBIRC_STATE_INIT ) if (dcc->state != LIBIRC_STATE_INIT) {
{
libirc_mutex_unlock (&ircsession->mutex_dcc); libirc_mutex_unlock (&ircsession->mutex_dcc);
if ( dcc->cb ) if ( dcc->cb )
@ -134,33 +129,29 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
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
&& dcc->outgoing_offset == 0 ) && dcc->outgoing_offset == 0) {
{ size_t len = fread(dcc->outgoing_buf, 1, sizeof(dcc->outgoing_buf), dcc->dccsend_file_fp);
int len = fread (dcc->outgoing_buf, 1, sizeof (dcc->outgoing_buf), dcc->dccsend_file_fp);
if ( len <= 0 ) if (len <= 0) {
{ int err = (ferror(dcc->dccsend_file_fp) ? 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);
libirc_mutex_lock(&ircsession->mutex_dcc); libirc_mutex_lock(&ircsession->mutex_dcc);
libirc_dcc_destroy_nolock(ircsession, dcc->id); libirc_dcc_destroy_nolock(ircsession, dcc->id);
} } else {
else
dcc->outgoing_offset = len; dcc->outgoing_offset = len;
} }
}
// Clean up unused sessions // Clean up unused sessions
if (dcc->state == LIBIRC_STATE_REMOVED) if (dcc->state == LIBIRC_STATE_REMOVED)
libirc_remove_dcc_session (ircsession, dcc, 0); libirc_remove_dcc_session (ircsession, dcc, 0);
} }
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next ) for (dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next) {
{ switch (dcc->state) {
switch (dcc->state)
{
case LIBIRC_STATE_LISTENING: case LIBIRC_STATE_LISTENING:
// While listening, only in_set descriptor should be set // While listening, only in_set descriptor should be set
libirc_add_to_set(dcc->sock, in_set, maxfd); libirc_add_to_set(dcc->sock, in_set, maxfd);
@ -208,8 +199,9 @@ 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) static 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;
/* /*
@ -218,21 +210,23 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
*/ */
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) {
{
if (dcc->state == LIBIRC_STATE_LISTENING if (dcc->state == LIBIRC_STATE_LISTENING
&& FD_ISSET (dcc->sock, in_set) ) && FD_ISSET (dcc->sock, in_set)) {
{
socklen_t len = sizeof(dcc->remote_addr); socklen_t len = sizeof(dcc->remote_addr);
#if defined(_WIN32)
SOCKET nsock, err = 0;
#else
int nsock, err = 0; int nsock, err = 0;
#endif
// New connection is available; accept it. // New connection is available; accept it.
if (socket_accept(&dcc->sock, &nsock, (struct sockaddr *) &dcc->remote_addr, &len)) if (socket_accept(&dcc->sock, &nsock, (struct sockaddr *) &dcc->remote_addr, &len))
err = LIBIRC_ERR_ACCEPT; err = LIBIRC_ERR_ACCEPT;
// 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);
@ -243,8 +237,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
// 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) {
{
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);
libirc_mutex_lock(&ircsession->mutex_dcc); libirc_mutex_lock(&ircsession->mutex_dcc);
@ -255,8 +248,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;
@ -273,8 +265,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
// If this is DCC chat, inform the caller about connect() // If this is DCC chat, inform the caller about connect()
// 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) {
{
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);
libirc_mutex_lock(&ircsession->mutex_dcc); libirc_mutex_lock(&ircsession->mutex_dcc);
@ -285,33 +276,27 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
} }
if (dcc->state == LIBIRC_STATE_CONNECTED if (dcc->state == LIBIRC_STATE_CONNECTED
|| dcc->state == LIBIRC_STATE_CONFIRM_SIZE ) || dcc->state == LIBIRC_STATE_CONFIRM_SIZE) {
{ if (FD_ISSET (dcc->sock, in_set)) {
if ( FD_ISSET (dcc->sock, in_set) ) ssize_t length;
{ size_t offset = 0;
int length, offset = 0, err = 0; int err = 0;
unsigned int amount = sizeof (dcc->incoming_buf) - dcc->incoming_offset; size_t 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);
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;
if ( dcc->dccsend_file_fp ) if (dcc->dccsend_file_fp) {
{
fclose(dcc->dccsend_file_fp); fclose(dcc->dccsend_file_fp);
dcc->dccsend_file_fp = 0; dcc->dccsend_file_fp = 0;
} }
} } else {
else dcc->incoming_offset += (size_t) length;
{
dcc->incoming_offset += length;
if (dcc->dccmode != LIBIRC_DCC_CHAT) if (dcc->dccmode != LIBIRC_DCC_CHAT)
offset = dcc->incoming_offset; offset = dcc->incoming_offset;
@ -323,29 +308,24 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
* 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)
abort(); abort();
if ( dcc->incoming_offset == 4 ) if (dcc->incoming_offset == 4) {
{
// The order is big-endian // The order is big-endian
const unsigned char *bptr = (const unsigned char *) dcc->incoming_buf; const unsigned char *bptr = (const unsigned char *) dcc->incoming_buf;
unsigned int received_size = (bptr[0] << 24) | (bptr[1] << 16) | (bptr[2] << 8) | bptr[3]; size_t received_size = (size_t) (bptr[0] << 24) | (size_t) (bptr[1] << 16) | (size_t) (bptr[2] << 8) | bptr[3];
// Sent size confirmed // Sent size confirmed
if ( dcc->file_confirm_offset == received_size ) if (dcc->file_confirm_offset == received_size) {
{
dcc->state = LIBIRC_STATE_CONNECTED; dcc->state = LIBIRC_STATE_CONNECTED;
dcc->incoming_offset = 0; dcc->incoming_offset = 0;
} } else {
else
err = LIBIRC_ERR_WRITE; err = LIBIRC_ERR_WRITE;
} }
} }
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
@ -353,8 +333,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
*/ */
libirc_mutex_unlock(&ircsession->mutex_dcc); libirc_mutex_unlock(&ircsession->mutex_dcc);
if ( dcc->dccmode != LIBIRC_DCC_CHAT ) if (dcc->dccmode != LIBIRC_DCC_CHAT) {
{
if (dcc->dccmode != LIBIRC_DCC_RECVFILE) if (dcc->dccmode != LIBIRC_DCC_RECVFILE)
abort(); abort();
@ -364,8 +343,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
* 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;
@ -376,9 +354,9 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
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
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, strlen(dcc->incoming_buf)); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, strlen(dcc->incoming_buf));
}
libirc_mutex_lock (&ircsession->mutex_dcc); libirc_mutex_lock (&ircsession->mutex_dcc);
@ -393,8 +371,7 @@ 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);
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
libirc_mutex_lock (&ircsession->mutex_dcc); libirc_mutex_lock (&ircsession->mutex_dcc);
@ -413,9 +390,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
/* /*
* 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)) {
{ ssize_t length;
int length, offset, err = 0; size_t offset;
int err = 0;
/* /*
* Because in some cases outgoing_buf could be changed * Because in some cases outgoing_buf could be changed
@ -426,24 +404,21 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
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);
if ( length < 0 ) if (length < 0) {
err = LIBIRC_ERR_WRITE; err = LIBIRC_ERR_WRITE;
else if ( length == 0 ) } else if (length == 0) {
err = LIBIRC_ERR_CLOSED; err = LIBIRC_ERR_CLOSED;
else } else {
{
/* /*
* 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) {
{
dcc->file_confirm_offset += offset; dcc->file_confirm_offset += offset;
dcc->state = LIBIRC_STATE_CONFIRM_SIZE; dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
@ -454,10 +429,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
libirc_mutex_lock(&dcc->mutex_outbuf); libirc_mutex_lock(&dcc->mutex_outbuf);
} }
if ( dcc->outgoing_offset - length > 0 ) if (dcc->outgoing_offset - (size_t) length > 0)
memmove (dcc->outgoing_buf, dcc->outgoing_buf + length, dcc->outgoing_offset - length); memmove(dcc->outgoing_buf, dcc->outgoing_buf + length, dcc->outgoing_offset - (size_t) length);
dcc->outgoing_offset -= length; dcc->outgoing_offset -= (size_t) length;
/* /*
* If we just sent the confirmation data, change state * If we just sent the confirmation data, change state
@ -465,21 +440,17 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
*/ */
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;
} }
@ -493,8 +464,7 @@ 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);
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0);
libirc_mutex_lock(&ircsession->mutex_dcc); libirc_mutex_lock(&ircsession->mutex_dcc);
@ -509,8 +479,12 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
} }
static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, unsigned short port, int dccmode, void * ctx, irc_dcc_session_t ** pdcc) static int libirc_new_dcc_session (irc_session_t *session,
{ unsigned long ip,
unsigned short port,
int dccmode,
void *ctx,
irc_dcc_session_t **pdcc) {
irc_dcc_session_t * dcc = malloc (sizeof(irc_dcc_session_t)); irc_dcc_session_t * dcc = malloc (sizeof(irc_dcc_session_t));
if (!dcc) if (!dcc)
@ -527,15 +501,13 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
if (socket_create(PF_INET, SOCK_STREAM, &dcc->sock)) if (socket_create(PF_INET, SOCK_STREAM, &dcc->sock))
goto cleanup_exit_error; goto cleanup_exit_error;
if ( !ip ) if (!ip) {
{
unsigned long arg = 1; unsigned long arg = 1;
setsockopt (dcc->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg)); setsockopt (dcc->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
#if defined (ENABLE_IPV6) #if defined (ENABLE_IPV6)
if ( session->flags & SESSIONFL_USES_IPV6 ) if (session->flags & SESSIONFL_USES_IPV6) {
{
struct sockaddr_in6 saddr6; struct sockaddr_in6 saddr6;
memset(&saddr6, 0, sizeof(saddr6)); memset(&saddr6, 0, sizeof(saddr6));
@ -545,8 +517,7 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
if (bind(dcc->sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0) if (bind(dcc->sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0)
goto cleanup_exit_error; goto cleanup_exit_error;
} } else
else
#endif #endif
{ {
struct sockaddr_in saddr; struct sockaddr_in saddr;
@ -563,9 +534,7 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
goto cleanup_exit_error; goto cleanup_exit_error;
dcc->state = LIBIRC_STATE_LISTENING; dcc->state = LIBIRC_STATE_LISTENING;
} } else {
else
{
// make socket non-blocking, so connect() call won't block // make socket non-blocking, so connect() call won't block
if (socket_make_nonblocking(&dcc->sock)) if (socket_make_nonblocking(&dcc->sock))
goto cleanup_exit_error; goto cleanup_exit_error;
@ -603,8 +572,8 @@ cleanup_exit_error:
} }
int irc_dcc_destroy (irc_session_t * session, irc_dcc_t dccid) int irc_dcc_destroy (irc_session_t *session,
{ irc_dcc_t dccid) {
// This function doesn't actually destroy the session; it just changes // This function doesn't actually destroy the session; it just changes
// its state to "removed" and closes the socket. The memory is actually // its state to "removed" and closes the socket. The memory is actually
// freed after the processing loop. // freed after the processing loop.
@ -623,30 +592,30 @@ int irc_dcc_destroy (irc_session_t * session, irc_dcc_t dccid)
} }
int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dcc_callback_t callback, irc_dcc_t * dccid) int irc_dcc_chat (irc_session_t *session,
{ void *ctx,
const char *nick,
irc_dcc_callback_t callback,
irc_dcc_t *dccid) {
struct sockaddr_in saddr; struct sockaddr_in saddr;
socklen_t len = sizeof(saddr); socklen_t len = sizeof(saddr);
char cmdbuf[128], notbuf[128]; char cmdbuf[128], notbuf[128];
irc_dcc_session_t * dcc; irc_dcc_session_t * dcc;
int err; int err;
if ( session->state != LIBIRC_STATE_CONNECTED ) if (session->state != LIBIRC_STATE_CONNECTED) {
{
session->lasterror = LIBIRC_ERR_STATE; session->lasterror = LIBIRC_ERR_STATE;
return 1; return 1;
} }
err = libirc_new_dcc_session(session, 0, 0, LIBIRC_DCC_CHAT, ctx, &dcc); err = libirc_new_dcc_session(session, 0, 0, LIBIRC_DCC_CHAT, ctx, &dcc);
if ( err ) if (err) {
{
session->lasterror = err; session->lasterror = err;
return 1; return 1;
} }
if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 ) if (getsockname(dcc->sock, (struct sockaddr *) &saddr, &len) < 0) {
{
session->lasterror = LIBIRC_ERR_SOCKET; session->lasterror = LIBIRC_ERR_SOCKET;
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
return 1; return 1;
@ -656,8 +625,7 @@ int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dc
sprintf (cmdbuf, "DCC CHAT chat %lu %u", (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs(saddr.sin_port)); sprintf (cmdbuf, "DCC CHAT chat %lu %u", (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs(saddr.sin_port));
if ( irc_cmd_notice(session, nick, notbuf) if ( irc_cmd_notice(session, nick, notbuf)
|| irc_cmd_ctcp_request (session, nick, cmdbuf) ) || irc_cmd_ctcp_request(session, nick, cmdbuf)) {
{
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
return 1; return 1;
} }
@ -670,22 +638,21 @@ int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dc
} }
int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text) int irc_dcc_msg (irc_session_t *session,
{ irc_dcc_t dccid,
const char *text) {
irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1); irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1);
if (!dcc) if (!dcc)
return 1; return 1;
if ( dcc->dccmode != LIBIRC_DCC_CHAT ) if (dcc->dccmode != LIBIRC_DCC_CHAT) {
{
session->lasterror = LIBIRC_ERR_INVAL; session->lasterror = LIBIRC_ERR_INVAL;
libirc_mutex_unlock(&session->mutex_dcc); libirc_mutex_unlock(&session->mutex_dcc);
return 1; return 1;
} }
if ( (strlen(text) + 2) >= (sizeof(dcc->outgoing_buf) - dcc->outgoing_offset) ) if ((strlen(text) + 2) >= (sizeof(dcc->outgoing_buf) - dcc->outgoing_offset)) {
{
session->lasterror = LIBIRC_ERR_NOMEM; session->lasterror = LIBIRC_ERR_NOMEM;
libirc_mutex_unlock(&session->mutex_dcc); libirc_mutex_unlock(&session->mutex_dcc);
return 1; return 1;
@ -705,21 +672,19 @@ 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) static 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;
unsigned short port; unsigned short port;
if ( sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2 ) if (sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2) {
{ if (session->callbacks.event_dcc_chat_req) {
if ( session->callbacks.event_dcc_chat_req )
{
irc_dcc_session_t * dcc; irc_dcc_session_t * dcc;
int err = libirc_new_dcc_session(session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc); int err = libirc_new_dcc_session(session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc);
if ( err ) if (err) {
{
session->lasterror = err; session->lasterror = err;
return; return;
} }
@ -731,16 +696,12 @@ static void libirc_dcc_request (irc_session_t * session, const char * nick, cons
} }
return; return;
} } else if (sscanf(req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4) {
else if ( sscanf (req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4 ) if (session->callbacks.event_dcc_send_req) {
{
if ( session->callbacks.event_dcc_send_req )
{
irc_dcc_session_t * dcc; irc_dcc_session_t * dcc;
int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_RECVFILE, 0, &dcc); int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_RECVFILE, 0, &dcc);
if ( err ) if (err) {
{
session->lasterror = err; session->lasterror = err;
return; return;
} }
@ -764,15 +725,16 @@ static void libirc_dcc_request (irc_session_t * session, const char * nick, cons
} }
int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback) int irc_dcc_accept (irc_session_t *session,
{ irc_dcc_t dccid,
void *ctx,
irc_dcc_callback_t callback) {
irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1); irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1);
if (!dcc) if (!dcc)
return 1; return 1;
if ( dcc->state != LIBIRC_STATE_INIT ) if (dcc->state != LIBIRC_STATE_INIT) {
{
session->lasterror = LIBIRC_ERR_STATE; session->lasterror = LIBIRC_ERR_STATE;
libirc_mutex_unlock(&session->mutex_dcc); libirc_mutex_unlock(&session->mutex_dcc);
return 1; return 1;
@ -782,8 +744,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);
session->lasterror = LIBIRC_ERR_CONNECT; session->lasterror = LIBIRC_ERR_CONNECT;
@ -796,15 +757,14 @@ int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dc
} }
int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid) int irc_dcc_decline (irc_session_t *session,
{ irc_dcc_t dccid) {
irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1); irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1);
if (!dcc) if (!dcc)
return 1; return 1;
if ( dcc->state != LIBIRC_STATE_INIT ) if (dcc->state != LIBIRC_STATE_INIT) {
{
session->lasterror = LIBIRC_ERR_STATE; session->lasterror = LIBIRC_ERR_STATE;
libirc_mutex_unlock(&session->mutex_dcc); libirc_mutex_unlock(&session->mutex_dcc);
return 1; return 1;
@ -816,8 +776,12 @@ int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid)
} }
int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, const char * filename, irc_dcc_callback_t callback, irc_dcc_t * dccid) int irc_dcc_sendfile (irc_session_t *session,
{ void *ctx,
const char *nick,
const char *filename,
irc_dcc_callback_t callback,
irc_dcc_t *dccid) {
struct sockaddr_in saddr; struct sockaddr_in saddr;
socklen_t len = sizeof(saddr); socklen_t len = sizeof(saddr);
char cmdbuf[128], notbuf[128]; char cmdbuf[128], notbuf[128];
@ -826,26 +790,22 @@ int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, co
int err; int err;
long filesize; long filesize;
if ( !session || !dccid || !filename || !callback ) if (!session || !dccid || !filename || !callback) {
{
session->lasterror = LIBIRC_ERR_INVAL; session->lasterror = LIBIRC_ERR_INVAL;
return 1; return 1;
} }
if ( session->state != LIBIRC_STATE_CONNECTED ) if (session->state != LIBIRC_STATE_CONNECTED) {
{
session->lasterror = LIBIRC_ERR_STATE; session->lasterror = LIBIRC_ERR_STATE;
return 1; return 1;
} }
if ( (err = libirc_new_dcc_session (session, 0, 0, LIBIRC_DCC_SENDFILE, ctx, &dcc)) != 0 ) if ((err = libirc_new_dcc_session(session, 0, 0, LIBIRC_DCC_SENDFILE, ctx, &dcc)) != 0) {
{
session->lasterror = err; session->lasterror = err;
return 1; return 1;
} }
if ( (dcc->dccsend_file_fp = fopen (filename, "rb")) == 0 ) if ((dcc->dccsend_file_fp = fopen(filename, "rb")) == 0) {
{
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
session->lasterror = LIBIRC_ERR_OPENFILE; session->lasterror = LIBIRC_ERR_OPENFILE;
return 1; return 1;
@ -854,15 +814,13 @@ int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, co
/* Get file length */ /* Get file length */
if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END) if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END)
|| (filesize = ftell(dcc->dccsend_file_fp)) == -1 || (filesize = ftell(dcc->dccsend_file_fp)) == -1
|| fseek (dcc->dccsend_file_fp, 0, SEEK_SET) ) || fseek (dcc->dccsend_file_fp, 0, SEEK_SET)) {
{
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
session->lasterror = LIBIRC_ERR_NODCCSEND; session->lasterror = LIBIRC_ERR_NODCCSEND;
return 1; return 1;
} }
if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 ) if (getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0) {
{
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
session->lasterror = LIBIRC_ERR_SOCKET; session->lasterror = LIBIRC_ERR_SOCKET;
return 1; return 1;
@ -870,17 +828,17 @@ int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, co
// Remove path from the filename // Remove path from the filename
if ( (p = strrchr(filename, '\\')) == 0 if ( (p = strrchr(filename, '\\')) == 0
&& (p = strrchr (filename, '/')) == 0 ) && (p = strrchr(filename, '/')) == 0) {
p = filename; p = filename;
else } else {
p++; // skip directory slash p++; // skip directory slash
}
sprintf (notbuf, "DCC Send %s (%s)", p, inet_ntoa(saddr.sin_addr)); sprintf (notbuf, "DCC Send %s (%s)", p, inet_ntoa(saddr.sin_addr));
sprintf (cmdbuf, "DCC SEND %s %lu %u %ld", p, (unsigned long) ntohl(saddr.sin_addr.s_addr), ntohs(saddr.sin_port), filesize); sprintf (cmdbuf, "DCC SEND %s %lu %u %ld", p, (unsigned long) ntohl(saddr.sin_addr.s_addr), ntohs(saddr.sin_port), filesize);
if ( irc_cmd_notice(session, nick, notbuf) if ( irc_cmd_notice(session, nick, notbuf)
|| irc_cmd_ctcp_request (session, nick, cmdbuf) ) || irc_cmd_ctcp_request(session, nick, cmdbuf)) {
{
libirc_remove_dcc_session(session, dcc, 1); libirc_remove_dcc_session(session, dcc, 1);
return 1; return 1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -134,20 +134,13 @@ static inline void libirc_mutex_unlock (port_mutex_t * mutex)
#if defined (WIN32_DLL) #if defined (WIN32_DLL)
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{ {
WORD wVersionRequested = MAKEWORD (1, 1);
WSADATA wsaData;
switch(fdwReason) switch(fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
if ( WSAStartup (wVersionRequested, &wsaData) != 0 )
return FALSE;
DisableThreadLibraryCalls (hinstDll); DisableThreadLibraryCalls (hinstDll);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
WSACleanup();
break; break;
} }

View File

@ -54,8 +54,7 @@
#endif #endif
static int socket_error() static int socket_error() {
{
#if !defined (_WIN32) #if !defined (_WIN32)
return errno; return errno;
#else #else
@ -64,26 +63,25 @@ static int socket_error()
} }
static int socket_create (int domain, int type, socket_t * sock) static int socket_create (int domain,
{ int type,
socket_t *sock) {
*sock = socket (domain, type, 0); *sock = socket (domain, type, 0);
return IS_SOCKET_ERROR(*sock) ? 1 : 0; return IS_SOCKET_ERROR(*sock) ? 1 : 0;
} }
static int socket_make_nonblocking (socket_t * sock) static int socket_make_nonblocking (socket_t *sock) {
{
#if !defined (_WIN32) #if !defined (_WIN32)
return fcntl (*sock, F_SETFL, fcntl (*sock, F_GETFL,0 ) | O_NONBLOCK) != 0; return fcntl (*sock, F_SETFL, fcntl (*sock, F_GETFL,0 ) | O_NONBLOCK) != 0;
#else #else
unsigned long mode = 0; unsigned long mode = 1;
return ioctlsocket (*sock, FIONBIO, &mode) == SOCKET_ERROR; return ioctlsocket (*sock, FIONBIO, &mode) == SOCKET_ERROR;
#endif #endif
} }
static int socket_close (socket_t * sock) static int socket_close (socket_t *sock) {
{
#if !defined (_WIN32) #if !defined (_WIN32)
close (*sock); close (*sock);
#else #else
@ -95,12 +93,11 @@ static int socket_close (socket_t * sock)
} }
static int socket_connect (socket_t * sock, const struct sockaddr *saddr, socklen_t len) static ssize_t socket_connect (socket_t *sock,
{ const struct sockaddr *saddr,
while ( 1 ) socklen_t len) {
{ while (1) {
if ( connect (*sock, saddr, len) < 0 ) if (connect(*sock, saddr, len) < 0) {
{
if (socket_error() == EINTR) if (socket_error() == EINTR)
continue; continue;
@ -113,10 +110,11 @@ static int socket_connect (socket_t * sock, const struct sockaddr *saddr, sockle
} }
static int socket_accept (socket_t * sock, socket_t * newsock, struct sockaddr *saddr, socklen_t * len) static ssize_t socket_accept (socket_t *sock,
{ socket_t *newsock,
while ( IS_SOCKET_ERROR(*newsock = accept (*sock, saddr, len)) ) struct sockaddr *saddr,
{ socklen_t *len) {
while (IS_SOCKET_ERROR(*newsock = accept(*sock, saddr, len))) {
if (socket_error() == EINTR) if (socket_error() == EINTR)
continue; continue;
@ -127,12 +125,12 @@ static int socket_accept (socket_t * sock, socket_t * newsock, struct sockaddr *
} }
static int socket_recv (socket_t * sock, void * buf, size_t len) static ssize_t socket_recv (socket_t *sock,
{ void *buf,
int length; size_t len) {
ssize_t length;
while ( (length = recv (*sock, buf, len, 0)) < 0 ) while ((length = recv(*sock, buf, len, 0)) < 0) {
{
int err = socket_error(); int err = socket_error();
if (err != EINTR && err != EAGAIN) if (err != EINTR && err != EAGAIN)
@ -143,12 +141,12 @@ static int socket_recv (socket_t * sock, void * buf, size_t len)
} }
static int socket_send (socket_t * sock, const void *buf, size_t len) static ssize_t socket_send (socket_t *sock,
{ const void *buf,
int length; size_t len) {
ssize_t length;
while ( (length = send (*sock, buf, len, 0)) < 0 ) while ((length = send(*sock, buf, len, 0)) < 0) {
{
int err = socket_error(); int err = socket_error();
if ( err != EINTR && err != EAGAIN ) if ( err != EINTR && err != EAGAIN )

View File

@ -24,8 +24,10 @@ static SSL_CTX * ssl_context = 0;
static CRITICAL_SECTION * mutex_buf = 0; 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
@ -33,13 +35,11 @@ static void cb_openssl_locking_function( int mode, int n, const char * file, int
} }
// 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
@ -61,8 +61,10 @@ static int alloc_mutexes( unsigned int total )
static pthread_mutex_t * mutex_buf = 0; 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;
@ -73,13 +75,12 @@ static void cb_openssl_locking_function( int mode, int n, const char * file, int
} }
// OpenSSL callback to get the thread ID // OpenSSL callback to get the thread ID
static unsigned long cb_openssl_id_function()
{ static void cb_openssl_id_function(CRYPTO_THREADID * id) {
return ((unsigned long) pthread_self() ); CRYPTO_THREADID_set_pointer(id, pthread_self());
} }
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
@ -96,8 +97,7 @@ static int alloc_mutexes( unsigned int total )
#endif #endif
static int ssl_init_context( irc_session_t * session ) static int ssl_init_context(irc_session_t *session) {
{
// Load the strings and init the library // Load the strings and init the library
SSL_load_error_strings(); SSL_load_error_strings();
@ -106,12 +106,15 @@ static int ssl_init_context( irc_session_t * session )
return LIBIRC_ERR_NOMEM; return LIBIRC_ERR_NOMEM;
// Register our callbacks // Register our callbacks
CRYPTO_set_id_callback( cb_openssl_id_function ); CRYPTO_THREADID_set_callback(cb_openssl_id_function);
CRYPTO_set_locking_callback(cb_openssl_locking_function); CRYPTO_set_locking_callback(cb_openssl_locking_function);
// Init it // Init it
if ( !SSL_library_init() ) #if OPENSSL_VERSION_NUMBER < 0x10100000L
return LIBIRC_ERR_SSL_INIT_FAILED; SSL_library_init();
#else
OPENSSL_init_ssl(0, NULL);
#endif
if (RAND_status() == 0) if (RAND_status() == 0)
return LIBIRC_ERR_SSL_INIT_FAILED; return LIBIRC_ERR_SSL_INIT_FAILED;
@ -140,7 +143,9 @@ static int ssl_init_context( irc_session_t * session )
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;
} }
@ -155,16 +160,14 @@ static int ssl_init_context( irc_session_t * session )
#endif #endif
// Initializes the SSL context. Must be called after the socket is created. // Initializes the SSL context. Must be called after the socket is created.
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.
@ -183,12 +186,10 @@ static int ssl_init( irc_session_t * session )
// 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;
} }
@ -214,18 +215,15 @@ static int ssl_init( irc_session_t * session )
return 0; return 0;
} }
static void ssl_handle_error( irc_session_t * session, int ssl_error ) static void ssl_handle_error (irc_session_t *session,
{ int ssl_error) {
if ( ERR_GET_LIB(ssl_error) == ERR_LIB_SSL ) if (ERR_GET_LIB(ssl_error) == ERR_LIB_SSL) {
{ if (ERR_GET_REASON(ssl_error) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
if ( ERR_GET_REASON(ssl_error) == SSL_R_CERTIFICATE_VERIFY_FAILED )
{
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;
return; return;
} }
@ -234,31 +232,32 @@ 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
} }
static int ssl_recv( irc_session_t * session ) 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
@ -282,23 +281,22 @@ 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.
@ -327,16 +325,13 @@ 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 ) static ssize_t session_socket_read (irc_session_t *session) {
{ ssize_t length;
int length;
#if defined (ENABLE_SSL) #if defined (ENABLE_SSL)
if ( session->ssl ) if (session->ssl) {
{
// Yes, I know this is tricky // Yes, I know this is tricky
if ( session->flags & SESSIONFL_SSL_READ_WANTS_WRITE ) if (session->flags & SESSIONFL_SSL_READ_WANTS_WRITE) {
{
session->flags &= ~SESSIONFL_SSL_READ_WANTS_WRITE; session->flags &= ~SESSIONFL_SSL_READ_WANTS_WRITE;
ssl_send(session); ssl_send(session);
return 0; return 0;
@ -361,16 +356,13 @@ 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 ) static ssize_t session_socket_write (irc_session_t *session) {
{ ssize_t length;
int length;
#if defined (ENABLE_SSL) #if defined (ENABLE_SSL)
if ( session->ssl ) if (session->ssl) {
{
// Yep // Yep
if ( session->flags & SESSIONFL_SSL_WRITE_WANTS_READ ) if (session->flags & SESSIONFL_SSL_WRITE_WANTS_READ) {
{
session->flags &= ~SESSIONFL_SSL_WRITE_WANTS_READ; session->flags &= ~SESSIONFL_SSL_WRITE_WANTS_READ;
ssl_recv(session); ssl_recv(session);
return 0; return 0;
@ -380,7 +372,9 @@ static int session_socket_write( irc_session_t * 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)

View File

@ -12,8 +12,9 @@
* License for more details. * License for more details.
*/ */
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);
if (*maxfd < fd) if (*maxfd < fd)
@ -21,8 +22,9 @@ static void libirc_add_to_set (int fd, fd_set *set, int * maxfd)
} }
#if defined (ENABLE_DEBUG) #if defined (ENABLE_DEBUG)
static void libirc_dump_data (const char * prefix, const char * buf, unsigned int length) static void libirc_dump_data (const char *prefix,
{ const char *buf,
unsigned int length) {
printf ("%s: ", prefix); printf ("%s: ", prefix);
for (; length > 0; length--) for (; length > 0; length--)
printf ("%c", *buf++); printf ("%c", *buf++);
@ -33,12 +35,13 @@ static void libirc_dump_data (const char * prefix, const char * buf, unsigned in
/* /*
* Finds a separator (\x0D\x0A), which separates two lines. * Finds a separator (\x0D\x0A), which separates two lines.
*/ */
static int libirc_findcrlf (const char * buf, int length) static size_t libirc_findcrlf (const char *buf,
{ size_t length) {
int offset = 0; size_t offset = 0;
for ( ; offset < length; offset++ ) for (; offset < length; offset++) {
{ if ( buf[offset] == 0x0D
if ( buf[offset] == 0x0D && offset < length - 1 && buf[offset+1] == 0x0A ) && offset < length - 1
&& buf[offset+1] == 0x0A)
return offset; return offset;
if (buf[offset] == 0x0A) if (buf[offset] == 0x0A)
return offset; return offset;
@ -47,29 +50,30 @@ static int libirc_findcrlf (const char * buf, int length)
return 0; return 0;
} }
static int libirc_findcrlf_offset(const char *buf, int offset, const int length) static size_t libirc_findcrlf_offset (const char *buf,
{ size_t offset,
for(; offset < length; offset++) const size_t length) {
{ for(; offset < length; offset++) {
if(buf[offset] != 0x0D && buf[offset] != 0x0A) if ( buf[offset] != 0x0D
{ && buf[offset] != 0x0A) {
break; break;
} }
} }
return offset; return offset;
} }
static int libirc_findcrorlf (char * buf, int length) static size_t libirc_findcrorlf (char *buf,
{ size_t length) {
int offset = 0; size_t offset = 0;
for ( ; offset < length; offset++ ) for (; offset < length; offset++) {
{ if ( buf[offset] == 0x0D
if ( buf[offset] == 0x0D || buf[offset] == 0x0A ) || 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++;
return offset; return offset;
@ -80,42 +84,38 @@ static int libirc_findcrorlf (char * buf, int length)
} }
static void libirc_event_ctcp_internal (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) static void libirc_event_ctcp_internal (irc_session_t *session,
{ const char *event,
const char *origin,
const char **params,
unsigned int count) {
(void) event; (void) event;
(void) count; (void) count;
if ( origin ) if (origin) {
{
char nickbuf[128], textbuf[256]; char nickbuf[128], textbuf[256];
irc_target_get_nick (origin, nickbuf, sizeof(nickbuf)); irc_target_get_nick (origin, nickbuf, sizeof(nickbuf));
if ( strstr (params[0], "PING") == params[0] ) if (strstr (params[0], "PING") == params[0]) {
irc_cmd_ctcp_reply (session, nickbuf, params[0]); irc_cmd_ctcp_reply (session, nickbuf, params[0]);
else if ( !strcmp (params[0], "VERSION") ) } else if (!strcmp (params[0], "VERSION")) {
{ if (!session->ctcp_version) {
if ( !session->ctcp_version )
{
unsigned int high, low; unsigned int high, low;
irc_get_version (&high, &low); irc_get_version (&high, &low);
snprintf (textbuf, sizeof (textbuf), "VERSION libircclient by Georgy Yunaev ver.%d.%d", high, low); snprintf (textbuf, sizeof (textbuf), "VERSION libircclient by Georgy Yunaev ver.%d.%d", high, low);
} } else {
else
snprintf (textbuf, sizeof (textbuf), "VERSION %s", session->ctcp_version); snprintf (textbuf, sizeof (textbuf), "VERSION %s", session->ctcp_version);
}
irc_cmd_ctcp_reply (session, nickbuf, textbuf); irc_cmd_ctcp_reply (session, nickbuf, textbuf);
} } 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");
irc_cmd_ctcp_reply (session, nickbuf, textbuf); irc_cmd_ctcp_reply (session, nickbuf, textbuf);
} } else if (!strcmp (params[0], "TIME")) {
else if ( !strcmp (params[0], "TIME") )
{
time_t now = time(0); time_t now = time(0);
#if defined (ENABLE_THREADS) && defined (HAVE_LOCALTIME_R) #if defined (ENABLE_THREADS) && defined (HAVE_LOCALTIME_R)