From a44e8f5f00f2c33b29597acdca9cd31834e59ae2 Mon Sep 17 00:00:00 2001 From: achmizs <1874748+achmizs@users.noreply.github.com> Date: Sun, 5 Dec 2021 05:35:23 -0500 Subject: [PATCH] Miscellaneous fixes and code cleanup to libircclient --- libircclient/include/config.h | 44 +- libircclient/include/dcc.h | 11 +- libircclient/include/libirc_events.h | 33 +- libircclient/include/libirc_options.h | 8 + libircclient/include/libircclient.h | 201 ++++-- libircclient/include/params.h | 2 +- libircclient/include/session.h | 8 +- libircclient/src/colors.c | 325 +++++----- libircclient/src/dcc.c | 644 +++++++++--------- libircclient/src/libircclient.c | 896 ++++++++++++-------------- libircclient/src/portable.c | 7 - libircclient/src/sockets.c | 84 ++- libircclient/src/ssl.c | 236 ++++--- libircclient/src/utils.c | 96 +-- 14 files changed, 1273 insertions(+), 1322 deletions(-) diff --git a/libircclient/include/config.h b/libircclient/include/config.h index 2175374..f61d11b 100644 --- a/libircclient/include/config.h +++ b/libircclient/include/config.h @@ -8,63 +8,63 @@ /* #undef HAVE_GETHOSTBYNAME_R */ /* 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. */ /* #undef HAVE_INET_PTON */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_INTTYPES_H */ +#define HAVE_INTTYPES_H 1 /* 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 to 0 otherwise. */ -#define HAVE_MALLOC 0 +#define HAVE_MALLOC 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_MEMORY_H */ +#define HAVE_MEMORY_H 1 /* 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 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 HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ +#define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_STDLIB_H */ +#define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ +#define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_STRING_H */ +#define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SELECT_H */ +#define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKET_H */ +#define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_STAT_H */ +#define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TYPES_H */ +#define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ +#define HAVE_UNISTD_H 1 /* 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 slash. */ @@ -77,28 +77,28 @@ #define PACKAGE_NAME "libircclient" /* 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 PACKAGE_TARNAME "libircclient" /* 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 SELECT_TYPE_ARG1 int /* 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 SELECT_TYPE_ARG5 (struct timeval *) /* 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 and . */ -/* #undef TIME_WITH_SYS_TIME */ +#define TIME_WITH_SYS_TIME 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/libircclient/include/dcc.h b/libircclient/include/dcc.h index deb3355..5707350 100644 --- a/libircclient/include/dcc.h +++ b/libircclient/include/dcc.h @@ -19,8 +19,7 @@ /* * 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_t id; @@ -35,16 +34,16 @@ struct irc_dcc_session_s time_t timeout; FILE * dccsend_file_fp; - unsigned int received_file_size; - unsigned int file_confirm_offset; + size_t received_file_size; + size_t file_confirm_offset; struct sockaddr_in remote_addr; char incoming_buf[LIBIRC_DCC_BUFFER_SIZE]; - unsigned int incoming_offset; + size_t incoming_offset; char outgoing_buf[LIBIRC_DCC_BUFFER_SIZE]; - unsigned int outgoing_offset; + size_t outgoing_offset; port_mutex_t mutex_outbuf; irc_dcc_callback_t cb; diff --git a/libircclient/include/libirc_events.h b/libircclient/include/libirc_events.h index 208db77..beb25e5 100644 --- a/libircclient/include/libirc_events.h +++ b/libircclient/include/libirc_events.h @@ -52,7 +52,7 @@ * * \ingroup events */ -typedef void (*irc_event_callback_t) (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count); +typedef void (*irc_event_callback_t) (irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); /*! @@ -84,7 +84,7 @@ typedef void (*irc_event_callback_t) (irc_session_t * session, const char * even * * \ingroup events */ -typedef void (*irc_eventcode_callback_t) (irc_session_t * session, unsigned int event, const char * origin, const char ** params, unsigned int count); +typedef void (*irc_eventcode_callback_t) (irc_session_t *session, unsigned int event, const char *origin, const char **params, unsigned int count); /*! @@ -104,15 +104,15 @@ typedef void (*irc_eventcode_callback_t) (irc_session_t * session, unsigned int * \sa irc_dcc_accept or irc_dcc_decline * \ingroup events */ -typedef void (*irc_event_dcc_chat_t) (irc_session_t * session, const char * nick, const char * addr, irc_dcc_t dccid); +typedef void (*irc_event_dcc_chat_t) (irc_session_t *session, const char *nick, const char *addr, 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 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 filename the sent filename. * \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 * \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. @@ -157,6 +157,16 @@ typedef struct */ 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, * meaning that someone (including you) on a channel with the client has @@ -247,6 +257,15 @@ typedef struct */ 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 * 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; /*! - * 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. * * See the params in ::irc_event_dcc_send_t specification. diff --git a/libircclient/include/libirc_options.h b/libircclient/include/libirc_options.h index 7494f23..89fa572 100644 --- a/libircclient/include/libirc_options.h +++ b/libircclient/include/libirc_options.h @@ -52,5 +52,13 @@ */ #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 */ diff --git a/libircclient/include/libircclient.h b/libircclient/include/libircclient.h index 4135383..35527a4 100644 --- a/libircclient/include/libircclient.h +++ b/libircclient/include/libircclient.h @@ -15,7 +15,7 @@ /*! * \file libircclient.h * \author George Yunaev - * \version 1.5 + * \version 1.9 * \date 01.2012 * \brief This file defines all prototypes and functions to use libircclient. * @@ -46,7 +46,7 @@ #include -#if !defined (WIN32) +#if !defined (_WIN32) #include /* fd_set */ #else #include @@ -126,7 +126,7 @@ typedef unsigned int irc_dcc_t; * * \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 @@ -166,7 +166,7 @@ typedef void (*irc_dcc_callback_t) (irc_session_t * session, irc_dcc_t id, int s * \sa irc_destroy_session * \ingroup initclose */ -irc_session_t * irc_create_session (irc_callbacks_t * callbacks); +irc_session_t* irc_create_session (irc_callbacks_t *callbacks); /*! @@ -181,7 +181,7 @@ irc_session_t * irc_create_session (irc_callbacks_t * callbacks); * * \ingroup initclose */ -void irc_destroy_session (irc_session_t * session); +void irc_destroy_session (irc_session_t *session); /*! @@ -222,13 +222,13 @@ void irc_destroy_session (irc_session_t * session); * \sa irc_run * \ingroup conndisc */ -int irc_connect (irc_session_t * session, - const char * server, - unsigned short port, - const char * server_password, - const char * nick, - const char * username, - const char * realname); +int irc_connect (irc_session_t *session, + const char *server, + unsigned short port, + const char *server_password, + const char *nick, + const char *username, + const char *realname); /*! @@ -269,13 +269,13 @@ int irc_connect (irc_session_t * session, * \sa irc_run * \ingroup conndisc */ -int irc_connect6 (irc_session_t * session, - const char * server, - unsigned short port, - const char * server_password, - const char * nick, - const char * username, - const char * realname); +int irc_connect6 (irc_session_t *session, + const char *server, + unsigned short port, + const char *server_password, + const char *nick, + const char *username, + const char *realname); /*! * \fn void irc_disconnect (irc_session_t * session) @@ -292,7 +292,7 @@ int irc_connect6 (irc_session_t * session, * \sa irc_connect irc_run * \ingroup conndisc */ -void irc_disconnect (irc_session_t * session); +void irc_disconnect (irc_session_t *session); /*! @@ -307,7 +307,7 @@ void irc_disconnect (irc_session_t * session); * \sa irc_connect irc_run * \ingroup conndisc */ -int irc_is_connected (irc_session_t * session); +int irc_is_connected (irc_session_t *session); /*! @@ -330,7 +330,7 @@ int irc_is_connected (irc_session_t * session); * * \ingroup running */ -int irc_run (irc_session_t * session); +int irc_run (irc_session_t *session); /*! @@ -355,7 +355,10 @@ int irc_run (irc_session_t * session); * \sa irc_process_select_descriptors * \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 * \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 */ -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 */ -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 */ -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 */ -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 * \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 */ -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 */ -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 * \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 * \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 */ -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 */ -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 */ -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 */ -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 * \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 * \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 * \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 * \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 */ -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) * \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 size A buffer size. If nick is longer than buffer size, it will * be truncated. * * For most events IRC server returns 'origin' (i.e. the person, who * 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 * user-provided buffer. * A buffer of size 90 should be enough for most nicks :) * * \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,20 +1123,22 @@ void irc_target_get_nick (const char * target, char *nick, size_t size); * * \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); /*! * \fn int irc_dcc_chat(irc_session_t * session, void * ctx, const char * nick, irc_dcc_callback_t callback, irc_dcc_t * dccid) * \brief Initiates a DCC CHAT. * - * \param session An initiated and connected session. - * \param ctx A user-supplied DCC session context, which will be passed to - * the DCC callback function. May be NULL. - * \param nick A nick to DCC CHAT with. - * \param callback A DCC callback function, which will be called when - * anything is said by other party. Must not be NULL. - * \param dccid On success, DCC session ID will be stored in this var. + * \param session An initiated and connected session. + * \param ctx A user-supplied DCC session context, which will be passed to + * the DCC callback function. May be NULL. + * \param nick A nick to DCC CHAT with. + * \param callback A DCC callback function, which will be called when + * anything is said by other party. Must not be NULL. + * \param dccid On success, DCC session ID will be stored in this var. * * \return Return code 0 means success. Other value means error, the error * code may be obtained through irc_errno(). Any error, generated by the @@ -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 * \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 * \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 * \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 * \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 * \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 */ -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 */ -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 * \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) @@ -1320,7 +1378,8 @@ void irc_set_ctx (irc_session_t * session, void * ctx); * * \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) @@ -1334,7 +1393,7 @@ void irc_set_ctcp_version(irc_session_t * session, const char * version); * \sa irc_set_ctx * \ingroup contexts */ -void * irc_get_ctx (irc_session_t * session); +void* irc_get_ctx (irc_session_t *session); /*! @@ -1356,7 +1415,7 @@ void * irc_get_ctx (irc_session_t * session); * \sa irc_strerror * \ingroup errors */ -int irc_errno (irc_session_t * session); +int irc_errno (irc_session_t *session); /*! @@ -1370,7 +1429,7 @@ int irc_errno (irc_session_t * session); * \sa irc_errno() * \ingroup errors */ -const char * irc_strerror (int ircerrno); +const char* irc_strerror (int ircerrno); /*! @@ -1386,7 +1445,8 @@ const char * irc_strerror (int ircerrno); * \sa irc_option_reset * \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 * \ingroup options */ -void irc_option_reset (irc_session_t * session, unsigned int option); +void irc_option_reset (irc_session_t *session, + unsigned int option); /*! @@ -1419,7 +1480,7 @@ void irc_option_reset (irc_session_t * session, unsigned int option); * \sa irc_color_convert_from_mirc irc_color_convert_to_mirc * \ingroup colors */ -char * irc_color_strip_from_mirc (const char * message); +char* irc_color_strip_from_mirc (const char *message); /*! @@ -1438,7 +1499,7 @@ char * irc_color_strip_from_mirc (const char * message); * \sa irc_color_strip_from_mirc irc_color_convert_to_mirc * \ingroup colors */ -char * irc_color_convert_from_mirc (const char * message); +char* irc_color_convert_from_mirc (const char *message); /*! @@ -1490,7 +1551,7 @@ char * irc_color_convert_from_mirc (const char * message); * \sa irc_color_strip_from_mirc irc_color_convert_from_mirc * \ingroup colors */ -char * irc_color_convert_to_mirc (const char * message); +char* irc_color_convert_to_mirc (const char *message); #ifdef __cplusplus } diff --git a/libircclient/include/params.h b/libircclient/include/params.h index 2b57c53..35f5e68 100644 --- a/libircclient/include/params.h +++ b/libircclient/include/params.h @@ -17,7 +17,7 @@ #define LIBIRC_VERSION_HIGH 1 -#define LIBIRC_VERSION_LOW 8 +#define LIBIRC_VERSION_LOW 10 #define LIBIRC_BUFFER_SIZE 1024 #define LIBIRC_DCC_BUFFER_SIZE 1024 diff --git a/libircclient/include/session.h b/libircclient/include/session.h index 7e13c8f..869059f 100644 --- a/libircclient/include/session.h +++ b/libircclient/include/session.h @@ -31,8 +31,7 @@ -struct irc_session_s -{ +struct irc_session_s { void * ctx; int dcc_timeout; @@ -40,10 +39,10 @@ struct irc_session_s int lasterror; char incoming_buf[LIBIRC_BUFFER_SIZE]; - unsigned int incoming_offset; + size_t incoming_offset; char outgoing_buf[LIBIRC_BUFFER_SIZE]; - unsigned int outgoing_offset; + size_t outgoing_offset; port_mutex_t mutex_session; socket_t sock; @@ -72,7 +71,6 @@ struct irc_session_s SSL * ssl; #endif - }; diff --git a/libircclient/src/colors.c b/libircclient/src/colors.c index 6e31b13..adc5c68 100644 --- a/libircclient/src/colors.c +++ b/libircclient/src/colors.c @@ -22,8 +22,13 @@ #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", "BLACK", "DARKBLUE", @@ -44,70 +49,70 @@ static const char * color_replacement_table[] = }; -static inline void libirc_colorparser_addorcat (char ** destline, unsigned int * destlen, const char * str) -{ - unsigned int len = strlen(str); +static inline void libirc_colorparser_addorcat (char **destline, + unsigned int *destlen, + const char *str) { + size_t len = strlen(str); - if ( *destline ) - { + if (*destline) { strcpy (*destline, str); *destline += len; - } - else + } else { *destlen += len; + } } -static void libirc_colorparser_applymask (unsigned int * mask, - char ** destline, unsigned int * destlen, - unsigned int bitmask, const char * start, const char * end) -{ - if ( (*mask & bitmask) != 0 ) - { +static void libirc_colorparser_applymask (unsigned int *mask, + char **destline, + unsigned int *destlen, + unsigned int bitmask, + const char *start, + const char *end) { + if ((*mask & bitmask) != 0) { *mask &= ~bitmask; libirc_colorparser_addorcat (destline, destlen, end); - } - else - { + } else { *mask |= bitmask; libirc_colorparser_addorcat (destline, destlen, start); } } -static void libirc_colorparser_applycolor (unsigned int * mask, - char ** destline, unsigned int * destlen, - unsigned int colorid, unsigned int bgcolorid) -{ - const char * end = "[/COLOR]"; +static void libirc_colorparser_applycolor (unsigned int *mask, + char **destline, + unsigned int *destlen, + unsigned int colorid, + unsigned int bgcolorid) { + const char *end = "[/COLOR]"; char startbuf[64]; - if ( bgcolorid != 0 ) + if (bgcolorid != 0) sprintf (startbuf, "[COLOR=%s/%s]", color_replacement_table[colorid], color_replacement_table[bgcolorid]); else sprintf (startbuf, "[COLOR=%s]", color_replacement_table[colorid]); - if ( (*mask & LIBIRC_COLORPARSER_COLOR) != 0 ) + if ((*mask & LIBIRC_COLORPARSER_COLOR) != 0) libirc_colorparser_addorcat (destline, destlen, end); *mask |= LIBIRC_COLORPARSER_COLOR; - libirc_colorparser_addorcat (destline, destlen, startbuf); + libirc_colorparser_addorcat(destline, destlen, startbuf); } -static void libirc_colorparser_closetags (unsigned int * mask, - char ** destline, unsigned int * destlen) -{ - if ( *mask & LIBIRC_COLORPARSER_BOLD ) +static void libirc_colorparser_closetags (unsigned int *mask, + char **destline, + unsigned int *destlen) { + if (*mask & LIBIRC_COLORPARSER_BOLD) libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_BOLD, 0, "[/B]"); - if ( *mask & LIBIRC_COLORPARSER_UNDERLINE ) + if (*mask & LIBIRC_COLORPARSER_UNDERLINE) libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_UNDERLINE, 0, "[/U]"); - if ( *mask & LIBIRC_COLORPARSER_REVERSE ) + if (*mask & LIBIRC_COLORPARSER_REVERSE) libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_REVERSE, 0, "[/I]"); - if ( *mask & LIBIRC_COLORPARSER_COLOR ) + if (*mask & LIBIRC_COLORPARSER_COLOR) libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_COLOR, 0, "[/COLOR]"); } @@ -116,109 +121,101 @@ static void libirc_colorparser_closetags (unsigned int * mask, /* * 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; - char * destline = 0, *d = 0; + char *destline = 0, *d = 0; const char *p; - int current_bg = 0; + unsigned int current_bg = 0; /* * There will be two passes. First pass calculates the total length of * the destination string. The second pass allocates memory for the string, * and fills it. */ - while ( destline == 0 ) // destline will be set after the 2nd pass - { - if ( destlen > 0 ) - { + while (destline == 0) { // destline will be set after the 2nd pass + if (destlen > 0) { // This is the 2nd pass; allocate memory. - if ( (destline = malloc (destlen)) == 0 ) + if ((destline = malloc (destlen)) == 0) return 0; d = destline; } - for ( p = source; *p; p++ ) - { - switch (*p) - { - case 0x02: // bold - if ( strip ) - continue; + for (p = source; *p; p++) { + switch (*p) { + case 0x02: { // bold + if (strip) + continue; - libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]"); - break; - - case 0x1F: // underline - if ( strip ) - continue; + libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]"); + break; + } + case 0x1F: { // underline + if (strip) + continue; - libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]"); - break; + libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]"); + break; + } + case 0x16: { // reverse + if (strip) + continue; - case 0x16: // reverse - if ( strip ) - continue; + libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]"); + break; + } + case 0x0F: { // reset colors + if (strip) + continue; - libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]"); - break; - - case 0x0F: // reset colors - if ( strip ) - continue; - - libirc_colorparser_closetags (&mask, &d, &destlen); - break; - - case 0x03: // set color - if ( isdigit (p[1]) ) - { - // Parse - int bgcolor = -1, color = p[1] - 0x30; - p++; - - if ( isdigit (p[1]) ) - { - color = color * 10 + (p[1] - 0x30); + libirc_colorparser_closetags(&mask, &d, &destlen); + break; + } + case 0x03: { // set color + if (isdigit (p[1])) { + // Parse + int bgcolor = -1, color = p[1] - 0x30; p++; - } - // If there is a comma, search for the following - // background color - if ( p[1] == ',' && isdigit (p[2]) ) - { - bgcolor = p[2] - 0x30; - p += 2; - - if ( isdigit (p[1]) ) - { - bgcolor = bgcolor * 10 + (p[1] - 0x30); + if (isdigit (p[1])) { + color = color * 10 + (p[1] - 0x30); p++; } + + // If there is a comma, search for the following + // background color + if (p[1] == ',' && isdigit (p[2])) { + bgcolor = p[2] - 0x30; + p += 2; + + if (isdigit (p[1])) { + bgcolor = bgcolor * 10 + (p[1] - 0x30); + p++; + } + } + + // Check for range + if ( color <= LIBIRC_COLORPARSER_MAXCOLORS + && bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS) { + if (strip) + continue; + + if (bgcolor != -1) + current_bg = (unsigned int) bgcolor; + + libirc_colorparser_applycolor(&mask, &d, &destlen, (unsigned int) max(color, 0), current_bg); + } } - - // Check for range - if ( color <= LIBIRC_COLORPARSER_MAXCOLORS - && bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS ) - { - if ( strip ) - continue; - - if ( bgcolor != -1 ) - current_bg = bgcolor; - - libirc_colorparser_applycolor (&mask, &d, &destlen, color, current_bg); - } + break; + } + default: { + if (destline) + *d++ = *p; + else + destlen++; + break; } - break; - - default: - if ( destline ) - *d++ = *p; - else - destlen++; - break; } } @@ -232,11 +229,10 @@ 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; - for ( i = 0; color_replacement_table[i]; i++ ) - if ( !strcmp (color, color_replacement_table[i]) ) + for (i = 0; color_replacement_table[i]; i++) + if (!strcmp(color, color_replacement_table[i])) return i; return -1; @@ -246,10 +242,9 @@ static int libirc_colorparser_colorlookup (const char * color) /* * [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; - char * destline = 0, *d = 0; + char *destline = 0, *d = 0; const char *p1, *p2, *cur; /* @@ -257,109 +252,95 @@ char * irc_color_convert_to_mirc (const char * source) * the destination string. The second pass allocates memory for the string, * and fills it. */ - while ( destline == 0 ) // destline will be set after the 2nd pass - { - if ( destlen > 0 ) - { + while (destline == 0) { // destline will be set after the 2nd pass + if (destlen > 0) { // This is the 2nd pass; allocate memory. - if ( (destline = malloc (destlen)) == 0 ) + if ((destline = malloc (destlen)) == 0) return 0; d = destline; } cur = source; - while ( (p1 = strchr (cur, '[')) != 0 ) - { - const char * replacedval = 0; + while ((p1 = strchr(cur, '[')) != 0) { + const char *replacedval = 0; p2 = 0; // Check if the closing bracket is available after p1 // and the tag length is suitable - if ( p1[1] != '\0' - && (p2 = strchr (p1, ']')) != 0 - && (p2 - p1) > 1 - && (p2 - p1) < 31 ) - { + if ( p1[1] != '\0' + && (p2 = strchr (p1, ']')) != 0 + && (p2 - p1) > 1 + && (p2 - p1) < 31) { // Get the tag char tagbuf[32]; - int taglen = p2 - p1 - 1; + ssize_t taglen = p2 - p1 - 1; memcpy (tagbuf, p1 + 1, taglen); tagbuf[taglen] = '\0'; - if ( !strcmp (tagbuf, "/COLOR") ) + if (!strcmp (tagbuf, "/COLOR")) { replacedval = "\x0F"; - else if ( strstr (tagbuf, "COLOR=") == tagbuf ) - { + } else if (strstr(tagbuf, "COLOR=") == tagbuf) { int color, bgcolor = -2; - char * bcol; + char *bcol; - bcol = strchr (tagbuf + 6, '/'); + bcol = strchr(tagbuf + 6, '/'); - if ( bcol ) - { + if (bcol) { *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); replacedval = tagbuf; - } - else if ( color != -1 && bgcolor >= 0 ) - { + } else if (color != -1 && bgcolor >= 0) { sprintf (tagbuf, "\x03%02d,%02d", color, bgcolor); replacedval = tagbuf; } - } - else if ( !strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B") ) + } else if (!strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B")) { replacedval = "\x02"; - else if ( !strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U") ) + } else if (!strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U")) { replacedval = "\x1F"; - else if ( !strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I") ) + } else if (!strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I")) { replacedval = "\x16"; + } } - if ( replacedval ) - { + if (replacedval) { // add a part before the tag - int partlen = p1 - cur; + ssize_t partlen = p1 - cur; - if ( destline ) - { + if (destline) { memcpy (d, cur, partlen); d += partlen; - } - else + } else { destlen += partlen; + } // Add the replacement - libirc_colorparser_addorcat (&d, &destlen, replacedval); + libirc_colorparser_addorcat(&d, &destlen, replacedval); // And move the pointer cur = p2 + 1; - } - else - { + } else { // add a whole part before the end tag - int partlen; + ssize_t partlen; - if ( !p2 ) + if (!p2) p2 = cur + strlen(cur); partlen = p2 - cur + 1; - if ( destline ) - { + if (destline) { memcpy (d, cur, partlen); d += partlen; - } - else + } else { destlen += partlen; + } // And move the pointer cur = p2 + 1; @@ -367,7 +348,7 @@ char * irc_color_convert_to_mirc (const char * source) } // Add the rest of string - libirc_colorparser_addorcat (&d, &destlen, cur); + libirc_colorparser_addorcat(&d, &destlen, cur); destlen++; // for 0-terminator } @@ -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); } -char * irc_color_convert_from_mirc (const char * message) -{ +char* irc_color_convert_from_mirc (const char *message) { return libirc_colorparser_irc2code (message, 0); } diff --git a/libircclient/src/dcc.c b/libircclient/src/dcc.c index b245ae7..e787664 100644 --- a/libircclient/src/dcc.c +++ b/libircclient/src/dcc.c @@ -17,36 +17,34 @@ #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) -{ - irc_dcc_session_t * s, *found = 0; +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; - if ( lock_list ) + if (lock_list) libirc_mutex_lock (&session->mutex_dcc); - for ( s = session->dcc_sessions; s; s = s->next ) - { - if ( s->id == dccid ) - { + for (s = session->dcc_sessions; s; s = s->next) { + if (s->id == dccid) { found = s; break; } } - if ( found == 0 && lock_list ) + if (found == 0 && lock_list) libirc_mutex_unlock (&session->mutex_dcc); return found; } -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); +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); - if ( dcc ) - { - if ( dcc->sock >= 0 ) + if (dcc) { + if (dcc->sock >= 0) socket_close (&dcc->sock); dcc->state = LIBIRC_STATE_REMOVED; @@ -54,46 +52,46 @@ 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) -{ - if ( dcc->sock >= 0 ) +static void libirc_remove_dcc_session (irc_session_t *session, + irc_dcc_session_t *dcc, + int lock_list) { + if (dcc->sock >= 0) socket_close (&dcc->sock); - if ( dcc->dccsend_file_fp ) + if (dcc->dccsend_file_fp) fclose (dcc->dccsend_file_fp); dcc->dccsend_file_fp = 0; libirc_mutex_destroy (&dcc->mutex_outbuf); - if ( lock_list ) + if (lock_list) libirc_mutex_lock (&session->mutex_dcc); - if ( session->dcc_sessions != dcc ) - { - irc_dcc_session_t * s; - for ( s = session->dcc_sessions; s; s = s->next ) - { - if ( s->next == dcc ) - { + if (session->dcc_sessions != dcc) { + irc_dcc_session_t *s; + for (s = session->dcc_sessions; s; s = s->next) { + if (s->next == dcc) { s->next = dcc->next; break; } } - } - else + } else { session->dcc_sessions = dcc->next; + } - if ( lock_list ) + if (lock_list) libirc_mutex_unlock (&session->mutex_dcc); free (dcc); } -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; +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; time_t now = time (0); libirc_mutex_lock (&ircsession->mutex_dcc); @@ -101,30 +99,27 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s // Preprocessing DCC list: // - ask DCC send callbacks for data; // - 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; // Remove timed-out sessions if ( (dcc->state == LIBIRC_STATE_CONNECTING || dcc->state == LIBIRC_STATE_INIT || dcc->state == LIBIRC_STATE_LISTENING) - && now - dcc->timeout > ircsession->dcc_timeout ) - { + && now - dcc->timeout > ircsession->dcc_timeout ) { // Inform the caller about DCC timeout. // Do not inform when state is LIBIRC_STATE_INIT - session // 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); if ( dcc->cb ) (*dcc->cb)(ircsession, dcc->id, LIBIRC_ERR_TIMEOUT, dcc->ctx, 0, 0); - libirc_mutex_lock (&ircsession->mutex_dcc); + libirc_mutex_lock(&ircsession->mutex_dcc); } - libirc_remove_dcc_session (ircsession, dcc, 0); + libirc_remove_dcc_session(ircsession, dcc, 0); } /* @@ -134,73 +129,69 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s if ( dcc->state == LIBIRC_STATE_CONNECTED && dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->dccsend_file_fp - && dcc->outgoing_offset == 0 ) - { - int len = fread (dcc->outgoing_buf, 1, sizeof (dcc->outgoing_buf), dcc->dccsend_file_fp); + && dcc->outgoing_offset == 0) { + size_t len = fread(dcc->outgoing_buf, 1, sizeof(dcc->outgoing_buf), dcc->dccsend_file_fp); - if ( len <= 0 ) - { - int err = (len < 0 ? LIBIRC_ERR_READ : 0); + if (len <= 0) { + int err = (ferror(dcc->dccsend_file_fp) ? 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); - libirc_mutex_lock (&ircsession->mutex_dcc); - libirc_dcc_destroy_nolock (ircsession, dcc->id); - } - else + libirc_mutex_lock(&ircsession->mutex_dcc); + libirc_dcc_destroy_nolock(ircsession, dcc->id); + } else { dcc->outgoing_offset = len; + } } // Clean up unused sessions - if ( dcc->state == LIBIRC_STATE_REMOVED ) + if (dcc->state == LIBIRC_STATE_REMOVED) libirc_remove_dcc_session (ircsession, dcc, 0); } - for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next ) - { - switch (dcc->state) - { - case LIBIRC_STATE_LISTENING: - // While listening, only in_set descriptor should be set - libirc_add_to_set (dcc->sock, in_set, maxfd); - break; + for (dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next) { + switch (dcc->state) { + case LIBIRC_STATE_LISTENING: + // While listening, only in_set descriptor should be set + libirc_add_to_set(dcc->sock, in_set, maxfd); + break; - case LIBIRC_STATE_CONNECTING: - // While connection, only out_set descriptor should be set - libirc_add_to_set (dcc->sock, out_set, maxfd); - break; + case LIBIRC_STATE_CONNECTING: + // While connection, only out_set descriptor should be set + libirc_add_to_set(dcc->sock, out_set, maxfd); + break; - case LIBIRC_STATE_CONNECTED: - // Add input descriptor if there is space in input buffer - // and it is DCC chat (during DCC send, there is nothing to recv) - if ( dcc->incoming_offset < sizeof(dcc->incoming_buf) - 1 ) - libirc_add_to_set (dcc->sock, in_set, maxfd); + case LIBIRC_STATE_CONNECTED: + // Add input descriptor if there is space in input buffer + // and it is DCC chat (during DCC send, there is nothing to recv) + if (dcc->incoming_offset < sizeof(dcc->incoming_buf) - 1) + libirc_add_to_set(dcc->sock, in_set, maxfd); - // Add output descriptor if there is something in output buffer - libirc_mutex_lock (&dcc->mutex_outbuf); + // Add output descriptor if there is something in output buffer + libirc_mutex_lock(&dcc->mutex_outbuf); - if ( dcc->outgoing_offset > 0 ) - libirc_add_to_set (dcc->sock, out_set, maxfd); + if (dcc->outgoing_offset > 0) + libirc_add_to_set(dcc->sock, out_set, maxfd); - libirc_mutex_unlock (&dcc->mutex_outbuf); - break; + libirc_mutex_unlock(&dcc->mutex_outbuf); + break; - case LIBIRC_STATE_CONFIRM_SIZE: - /* - * 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, - * then RECEIVER should confirm the packet, so we have to receive - * data. - * - * We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers - * can't change asynchronously. - */ - if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 ) - libirc_add_to_set (dcc->sock, out_set, maxfd); + case LIBIRC_STATE_CONFIRM_SIZE: + /* + * 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, + * then RECEIVER should confirm the packet, so we have to receive + * data. + * + * We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers + * can't change asynchronously. + */ + if (dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0) + libirc_add_to_set(dcc->sock, out_set, maxfd); - if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 ) - libirc_add_to_set (dcc->sock, in_set, maxfd); + if (dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4) + libirc_add_to_set(dcc->sock, in_set, maxfd); } } @@ -208,34 +199,37 @@ 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) -{ - irc_dcc_session_t * dcc; +static void libirc_dcc_process_descriptors (irc_session_t *ircsession, + fd_set *in_set, + fd_set *out_set) { + irc_dcc_session_t *dcc; /* * We need to use such a complex scheme here, because on every callback * 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 ) - { - if ( dcc->state == LIBIRC_STATE_LISTENING - && FD_ISSET (dcc->sock, in_set) ) - { + for (dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next) { + if (dcc->state == LIBIRC_STATE_LISTENING + && FD_ISSET (dcc->sock, in_set)) { socklen_t len = sizeof(dcc->remote_addr); + +#if defined(_WIN32) + SOCKET nsock, err = 0; +#else int nsock, err = 0; +#endif // 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; // 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 // accepted - socket_close (&dcc->sock); + socket_close(&dcc->sock); dcc->sock = nsock; dcc->state = LIBIRC_STATE_CONNECTED; } @@ -243,119 +237,104 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set * // If this is DCC chat, inform the caller about accept() // success or failure. // 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); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0); - libirc_mutex_lock (&ircsession->mutex_dcc); + libirc_mutex_lock(&ircsession->mutex_dcc); } if ( err ) libirc_dcc_destroy_nolock (ircsession, dcc->id); } - if ( dcc->state == LIBIRC_STATE_CONNECTING - && FD_ISSET (dcc->sock, out_set) ) - { + if (dcc->state == LIBIRC_STATE_CONNECTING + && FD_ISSET (dcc->sock, out_set)) { // Now we have to determine whether the socket is connected // or the connect is failed struct sockaddr_in saddr; socklen_t slen = sizeof(saddr); int err = 0; - if ( getpeername (dcc->sock, (struct sockaddr*)&saddr, &slen) < 0 ) + if (getpeername(dcc->sock, (struct sockaddr *) &saddr, &slen) < 0) err = LIBIRC_ERR_CONNECT; // On success, change the state - if ( err == 0 ) + if (err == 0) dcc->state = LIBIRC_STATE_CONNECTED; // If this is DCC chat, inform the caller about connect() // success or failure. // Otherwise (DCC send) there is no reason. - if ( dcc->dccmode == LIBIRC_DCC_CHAT ) - { - libirc_mutex_unlock (&ircsession->mutex_dcc); + if (dcc->dccmode == LIBIRC_DCC_CHAT) { + libirc_mutex_unlock(&ircsession->mutex_dcc); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0); - libirc_mutex_lock (&ircsession->mutex_dcc); + libirc_mutex_lock(&ircsession->mutex_dcc); } - if ( err ) - libirc_dcc_destroy_nolock (ircsession, dcc->id); + if (err) + libirc_dcc_destroy_nolock(ircsession, dcc->id); } - if ( dcc->state == LIBIRC_STATE_CONNECTED - || dcc->state == LIBIRC_STATE_CONFIRM_SIZE ) - { - if ( FD_ISSET (dcc->sock, in_set) ) - { - int length, offset = 0, err = 0; + if (dcc->state == LIBIRC_STATE_CONNECTED + || dcc->state == LIBIRC_STATE_CONFIRM_SIZE) { + if (FD_ISSET (dcc->sock, in_set)) { + ssize_t length; + size_t offset = 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; - } - else if ( length == 0 ) - { + } else if (length == 0) { err = LIBIRC_ERR_CLOSED; - if ( dcc->dccsend_file_fp ) - { - fclose (dcc->dccsend_file_fp); + if (dcc->dccsend_file_fp) { + fclose(dcc->dccsend_file_fp); dcc->dccsend_file_fp = 0; } - } - else - { - dcc->incoming_offset += length; + } else { + dcc->incoming_offset += (size_t) length; - if ( dcc->dccmode != LIBIRC_DCC_CHAT ) + if (dcc->dccmode != LIBIRC_DCC_CHAT) offset = dcc->incoming_offset; else - offset = libirc_findcrorlf (dcc->incoming_buf, dcc->incoming_offset); + offset = libirc_findcrorlf(dcc->incoming_buf, dcc->incoming_offset); /* * In LIBIRC_STATE_CONFIRM_SIZE state we don't call any * callbacks (except there is an error). We just receive * the data, and compare it with the amount sent. */ - if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE ) - { - if ( dcc->dccmode != LIBIRC_DCC_SENDFILE ) + if (dcc->state == LIBIRC_STATE_CONFIRM_SIZE) { + if (dcc->dccmode != LIBIRC_DCC_SENDFILE) abort(); - if ( dcc->incoming_offset == 4 ) - { + if (dcc->incoming_offset == 4) { // The order is big-endian - 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]; + const unsigned char *bptr = (const unsigned char *) dcc->incoming_buf; + size_t received_size = (size_t) (bptr[0] << 24) | (size_t) (bptr[1] << 16) | (size_t) (bptr[2] << 8) | bptr[3]; // Sent size confirmed - if ( dcc->file_confirm_offset == received_size ) - { + if (dcc->file_confirm_offset == received_size) { dcc->state = LIBIRC_STATE_CONNECTED; dcc->incoming_offset = 0; - } - else + } else { err = LIBIRC_ERR_WRITE; + } } - } - else - { + } else { /* * If it is DCC_CHAT, we send a 0-terminated string * (which is smaller than offset). Otherwise we send * 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_RECVFILE ) + if (dcc->dccmode != LIBIRC_DCC_CHAT) { + if (dcc->dccmode != LIBIRC_DCC_RECVFILE) abort(); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset); @@ -364,8 +343,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set * * If the session is not terminated in callback, * 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->file_confirm_offset += offset; @@ -376,13 +354,13 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set * dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset; dcc->outgoing_offset = 4; } - } - else + } else { (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, strlen(dcc->incoming_buf)); + } libirc_mutex_lock (&ircsession->mutex_dcc); - if ( dcc->incoming_offset - offset > 0 ) + if (dcc->incoming_offset - offset > 0) memmove (dcc->incoming_buf, dcc->incoming_buf + offset, dcc->incoming_offset - offset); dcc->incoming_offset -= offset; @@ -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 * of failure, and destroy this session. */ - if ( err ) - { + if (err) { libirc_mutex_unlock (&ircsession->mutex_dcc); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, 0); libirc_mutex_lock (&ircsession->mutex_dcc); @@ -407,79 +384,73 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set * * processing, so before out_set processing we should check * for this case */ - if ( dcc->state == LIBIRC_STATE_REMOVED ) + if (dcc->state == LIBIRC_STATE_REMOVED) continue; /* * Write bit set - we can send() something, and it won't block. */ - if ( FD_ISSET (dcc->sock, out_set) ) - { - int length, offset, err = 0; + if (FD_ISSET(dcc->sock, out_set)) { + ssize_t length; + size_t offset; + int err = 0; /* * Because in some cases outgoing_buf could be changed * asynchronously (by another thread), we should lock * it. */ - libirc_mutex_lock (&dcc->mutex_outbuf); + libirc_mutex_lock(&dcc->mutex_outbuf); offset = dcc->outgoing_offset; - if ( offset > 0 ) - { - length = socket_send (&dcc->sock, dcc->outgoing_buf, offset); + if (offset > 0) { + length = socket_send(&dcc->sock, dcc->outgoing_buf, offset); - if ( length < 0 ) + if (length < 0) { err = LIBIRC_ERR_WRITE; - else if ( length == 0 ) + } else if (length == 0) { err = LIBIRC_ERR_CLOSED; - else - { + } else { /* * If this was DCC_SENDFILE, and we just sent a packet, * change the state to wait for confirmation (and store * sent packet size) */ - if ( dcc->state == LIBIRC_STATE_CONNECTED - && dcc->dccmode == LIBIRC_DCC_SENDFILE ) - { + if (dcc->state == LIBIRC_STATE_CONNECTED + && dcc->dccmode == LIBIRC_DCC_SENDFILE) { dcc->file_confirm_offset += offset; dcc->state = LIBIRC_STATE_CONFIRM_SIZE; - libirc_mutex_unlock (&ircsession->mutex_dcc); - libirc_mutex_unlock (&dcc->mutex_outbuf); + libirc_mutex_unlock(&ircsession->mutex_dcc); + libirc_mutex_unlock(&dcc->mutex_outbuf); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, 0, offset); - libirc_mutex_lock (&ircsession->mutex_dcc); - libirc_mutex_lock (&dcc->mutex_outbuf); + libirc_mutex_lock(&ircsession->mutex_dcc); + libirc_mutex_lock(&dcc->mutex_outbuf); } - if ( dcc->outgoing_offset - length > 0 ) - memmove (dcc->outgoing_buf, dcc->outgoing_buf + length, dcc->outgoing_offset - length); + if (dcc->outgoing_offset - (size_t) length > 0) + 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 * back. */ - if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE - && dcc->dccmode == LIBIRC_DCC_RECVFILE - && dcc->outgoing_offset == 0 ) - { + if (dcc->state == LIBIRC_STATE_CONFIRM_SIZE + && dcc->dccmode == LIBIRC_DCC_RECVFILE + && dcc->outgoing_offset == 0) { /* * If the file is already received, we should inform * the caller, and close the session. */ - if ( dcc->received_file_size == dcc->file_confirm_offset ) - { - libirc_mutex_unlock (&ircsession->mutex_dcc); - libirc_mutex_unlock (&dcc->mutex_outbuf); + if (dcc->received_file_size == dcc->file_confirm_offset) { + libirc_mutex_unlock(&ircsession->mutex_dcc); + libirc_mutex_unlock(&dcc->mutex_outbuf); (*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0); - libirc_dcc_destroy_nolock (ircsession, dcc->id); - } - else - { + libirc_dcc_destroy_nolock(ircsession, dcc->id); + } else { /* Continue to receive the file */ dcc->state = LIBIRC_STATE_CONNECTED; } @@ -487,19 +458,18 @@ 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 * of failure, and destroy this session. */ - if ( err ) - { - libirc_mutex_unlock (&ircsession->mutex_dcc); + if (err) { + libirc_mutex_unlock(&ircsession->mutex_dcc); (*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); } } } @@ -509,11 +479,15 @@ 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)); - if ( !dcc ) + if (!dcc) return LIBIRC_ERR_NOMEM; // setup @@ -521,53 +495,48 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un dcc->dccsend_file_fp = 0; - if ( libirc_mutex_init (&dcc->mutex_outbuf) ) + if (libirc_mutex_init(&dcc->mutex_outbuf)) goto cleanup_exit_error; - if ( socket_create (PF_INET, SOCK_STREAM, &dcc->sock) ) + if (socket_create(PF_INET, SOCK_STREAM, &dcc->sock)) goto cleanup_exit_error; - if ( !ip ) - { + if (!ip) { 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 ( session->flags & SESSIONFL_USES_IPV6 ) - { + if (session->flags & SESSIONFL_USES_IPV6) { struct sockaddr_in6 saddr6; - memset (&saddr6, 0, sizeof(saddr6)); + memset(&saddr6, 0, sizeof(saddr6)); saddr6.sin6_family = AF_INET6; - memcpy (&saddr6.sin6_addr, &session->local_addr6, sizeof(session->local_addr6)); + memcpy(&saddr6.sin6_addr, &session->local_addr6, sizeof(session->local_addr6)); saddr6.sin6_port = htons (0); - if ( bind (dcc->sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0 ) + if (bind(dcc->sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0) goto cleanup_exit_error; - } - else + } else #endif { struct sockaddr_in saddr; - memset (&saddr, 0, sizeof(saddr)); + memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; - memcpy (&saddr.sin_addr, &session->local_addr, sizeof(session->local_addr)); - saddr.sin_port = htons (0); + memcpy(&saddr.sin_addr, &session->local_addr, sizeof(session->local_addr)); + saddr.sin_port = htons(0); - if ( bind (dcc->sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 ) + if (bind(dcc->sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) goto cleanup_exit_error; } - if ( listen (dcc->sock, 5) < 0 ) + if (listen(dcc->sock, 5) < 0) goto cleanup_exit_error; dcc->state = LIBIRC_STATE_LISTENING; - } - else - { + } else { // 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; memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr)); @@ -580,85 +549,84 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un dcc->dccmode = dccmode; dcc->ctx = ctx; - time (&dcc->timeout); + time(&dcc->timeout); // and store it - libirc_mutex_lock (&session->mutex_dcc); + libirc_mutex_lock(&session->mutex_dcc); dcc->id = session->dcc_last_id++; dcc->next = session->dcc_sessions; session->dcc_sessions = dcc; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); *pdcc = dcc; return 0; cleanup_exit_error: - if ( dcc->sock >= 0 ) - socket_close (&dcc->sock); + if (dcc->sock >= 0) + socket_close(&dcc->sock); free (dcc); return LIBIRC_ERR_SOCKET; } -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 // its state to "removed" and closes the socket. The memory is actually // freed after the processing loop. - 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; - if ( dcc->sock >= 0 ) - socket_close (&dcc->sock); + if (dcc->sock >= 0) + socket_close(&dcc->sock); dcc->state = LIBIRC_STATE_REMOVED; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); return 0; } -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; socklen_t len = sizeof(saddr); char cmdbuf[128], notbuf[128]; irc_dcc_session_t * dcc; int err; - if ( session->state != LIBIRC_STATE_CONNECTED ) - { + if (session->state != LIBIRC_STATE_CONNECTED) { session->lasterror = LIBIRC_ERR_STATE; 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; 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; - libirc_remove_dcc_session (session, dcc, 1); + libirc_remove_dcc_session(session, dcc, 1); return 1; } - sprintf (notbuf, "DCC Chat (%s)", inet_ntoa (saddr.sin_addr)); - sprintf (cmdbuf, "DCC CHAT chat %lu %u", (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs (saddr.sin_port)); + sprintf (notbuf, "DCC Chat (%s)", inet_ntoa(saddr.sin_addr)); + 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) - || irc_cmd_ctcp_request (session, nick, cmdbuf) ) - { - libirc_remove_dcc_session (session, dcc, 1); + if ( irc_cmd_notice(session, nick, notbuf) + || irc_cmd_ctcp_request(session, nick, cmdbuf)) { + libirc_remove_dcc_session(session, dcc, 1); return 1; } @@ -670,24 +638,23 @@ 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) -{ - irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1); +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); - if ( !dcc ) + if (!dcc) return 1; - if ( dcc->dccmode != LIBIRC_DCC_CHAT ) - { + if (dcc->dccmode != LIBIRC_DCC_CHAT) { session->lasterror = LIBIRC_ERR_INVAL; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); 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; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); return 1; } @@ -698,59 +665,53 @@ int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text) dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0D; dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0A; - libirc_mutex_unlock (&dcc->mutex_outbuf); - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&dcc->mutex_outbuf); + libirc_mutex_unlock(&session->mutex_dcc); return 0; } -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]; unsigned long ip, size; unsigned short port; - if ( sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2 ) - { - if ( session->callbacks.event_dcc_chat_req ) - { + if (sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2) { + if (session->callbacks.event_dcc_chat_req) { irc_dcc_session_t * dcc; - int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc); - if ( err ) - { + int err = libirc_new_dcc_session(session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc); + if (err) { session->lasterror = err; return; } - (*session->callbacks.event_dcc_chat_req) (session, - nick, - inet_ntoa (dcc->remote_addr.sin_addr), - dcc->id); + (*session->callbacks.event_dcc_chat_req)(session, + nick, + inet_ntoa (dcc->remote_addr.sin_addr), + dcc->id); } return; - } - else if ( sscanf (req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4 ) - { - if ( session->callbacks.event_dcc_send_req ) - { + } else if (sscanf(req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4) { + if (session->callbacks.event_dcc_send_req) { irc_dcc_session_t * dcc; int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_RECVFILE, 0, &dcc); - if ( err ) - { + if (err) { session->lasterror = err; return; } - (*session->callbacks.event_dcc_send_req) (session, - nick, - inet_ntoa (dcc->remote_addr.sin_addr), - filenamebuf, - size, - dcc->id); + (*session->callbacks.event_dcc_send_req)(session, + nick, + inet_ntoa (dcc->remote_addr.sin_addr), + filenamebuf, + size, + dcc->id); dcc->received_file_size = size; } @@ -764,17 +725,18 @@ 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) -{ - irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1); +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); - if ( !dcc ) + if (!dcc) return 1; - if ( dcc->state != LIBIRC_STATE_INIT ) - { + if (dcc->state != LIBIRC_STATE_INIT) { session->lasterror = LIBIRC_ERR_STATE; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); return 1; } @@ -782,42 +744,44 @@ int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dc dcc->ctx = ctx; // Initiate the connect - if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) ) - { - libirc_dcc_destroy_nolock (session, dccid); - libirc_mutex_unlock (&session->mutex_dcc); + if (socket_connect(&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr))) { + libirc_dcc_destroy_nolock(session, dccid); + libirc_mutex_unlock(&session->mutex_dcc); session->lasterror = LIBIRC_ERR_CONNECT; return 1; } dcc->state = LIBIRC_STATE_CONNECTING; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); return 0; } -int irc_dcc_decline (irc_session_t * session, irc_dcc_t dccid) -{ - irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1); +int irc_dcc_decline (irc_session_t *session, + irc_dcc_t dccid) { + irc_dcc_session_t *dcc = libirc_find_dcc_session(session, dccid, 1); - if ( !dcc ) + if (!dcc) return 1; - if ( dcc->state != LIBIRC_STATE_INIT ) - { + if (dcc->state != LIBIRC_STATE_INIT) { session->lasterror = LIBIRC_ERR_STATE; - libirc_mutex_unlock (&session->mutex_dcc); + libirc_mutex_unlock(&session->mutex_dcc); return 1; } - libirc_dcc_destroy_nolock (session, dccid); - libirc_mutex_unlock (&session->mutex_dcc); + libirc_dcc_destroy_nolock(session, dccid); + libirc_mutex_unlock(&session->mutex_dcc); return 0; } -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; socklen_t len = sizeof(saddr); char cmdbuf[128], notbuf[128]; @@ -826,62 +790,56 @@ int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, co int err; long filesize; - if ( !session || !dccid || !filename || !callback ) - { + if (!session || !dccid || !filename || !callback) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - if ( session->state != LIBIRC_STATE_CONNECTED ) - { + if (session->state != LIBIRC_STATE_CONNECTED) { session->lasterror = LIBIRC_ERR_STATE; 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; return 1; } - if ( (dcc->dccsend_file_fp = fopen (filename, "rb")) == 0 ) - { - libirc_remove_dcc_session (session, dcc, 1); + if ((dcc->dccsend_file_fp = fopen(filename, "rb")) == 0) { + libirc_remove_dcc_session(session, dcc, 1); session->lasterror = LIBIRC_ERR_OPENFILE; return 1; } /* Get file length */ - if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END) - || (filesize = ftell (dcc->dccsend_file_fp)) == -1 - || fseek (dcc->dccsend_file_fp, 0, SEEK_SET) ) - { - libirc_remove_dcc_session (session, dcc, 1); + if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END) + || (filesize = ftell(dcc->dccsend_file_fp)) == -1 + || fseek (dcc->dccsend_file_fp, 0, SEEK_SET)) { + libirc_remove_dcc_session(session, dcc, 1); session->lasterror = LIBIRC_ERR_NODCCSEND; return 1; } - if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 ) - { - libirc_remove_dcc_session (session, dcc, 1); + if (getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0) { + libirc_remove_dcc_session(session, dcc, 1); session->lasterror = LIBIRC_ERR_SOCKET; return 1; } // Remove path from the filename - if ( (p = strrchr (filename, '\\')) == 0 - && (p = strrchr (filename, '/')) == 0 ) + if ( (p = strrchr(filename, '\\')) == 0 + && (p = strrchr(filename, '/')) == 0) { p = filename; - else + } else { p++; // skip directory slash + } - 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 (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); - if ( irc_cmd_notice (session, nick, notbuf) - || irc_cmd_ctcp_request (session, nick, cmdbuf) ) - { - libirc_remove_dcc_session (session, dcc, 1); + if ( irc_cmd_notice(session, nick, notbuf) + || irc_cmd_ctcp_request(session, nick, cmdbuf)) { + libirc_remove_dcc_session(session, dcc, 1); return 1; } diff --git a/libircclient/src/libircclient.c b/libircclient/src/libircclient.c index fa18fa1..9efea32 100644 --- a/libircclient/src/libircclient.c +++ b/libircclient/src/libircclient.c @@ -27,6 +27,12 @@ #include "ssl.c" +#define max(a,b) \ +({ __typeof__ (a) _a = (a); \ +__typeof__ (b) _b = (b); \ +_a > _b ? _a : _b; }) + + #ifdef _MSC_VER /* * The debugger of MSVC 2005 does not like strdup. @@ -37,20 +43,38 @@ #define strdup _strdup #endif +#if defined (WIN32_DLL) +static int winsock_refcount = 0; +#endif -irc_session_t * irc_create_session (irc_callbacks_t * callbacks) -{ - irc_session_t * session = malloc (sizeof(irc_session_t)); +irc_session_t* irc_create_session (irc_callbacks_t *callbacks) { + irc_session_t *session; + +#if defined (WIN32_DLL) + // From MSDN: The WSAStartup function typically leads to protocol-specific helper + // DLLs being loaded. As a result, the WSAStartup function should not be called + // from the DllMain function in a application DLL. This can potentially cause deadlocks. + if (winsock_refcount == 0) { + WORD wVersionRequested = MAKEWORD (1, 1); + WSADATA wsaData; - if ( !session ) + if (WSAStartup (wVersionRequested, &wsaData) != 0) + return 0; + + winsock_refcount++; + } +#endif + + session = malloc (sizeof(irc_session_t)); + + if (!session) return 0; memset (session, 0, sizeof(irc_session_t)); session->sock = -1; - if ( libirc_mutex_init (&session->mutex_session) - || libirc_mutex_init (&session->mutex_dcc) ) - { + if ( libirc_mutex_init (&session->mutex_session) + || libirc_mutex_init (&session->mutex_dcc)) { free (session); return 0; } @@ -60,27 +84,26 @@ irc_session_t * irc_create_session (irc_callbacks_t * callbacks) memcpy (&session->callbacks, callbacks, sizeof(irc_callbacks_t)); - if ( !session->callbacks.event_ctcp_req ) + if (!session->callbacks.event_ctcp_req) session->callbacks.event_ctcp_req = libirc_event_ctcp_internal; return session; } -static void free_ircsession_strings (irc_session_t * session) -{ - if ( session->realname ) +static void free_ircsession_strings (irc_session_t *session) { + if (session->realname) free (session->realname); - if ( session->username ) + if (session->username) free (session->username); - if ( session->nick ) + if (session->nick) free (session->nick); - if ( session->server ) + if (session->server) free (session->server); - if ( session->server_password ) + if (session->server_password) free (session->server_password); session->realname = 0; @@ -90,15 +113,14 @@ static void free_ircsession_strings (irc_session_t * session) session->server_password = 0; } -void irc_destroy_session (irc_session_t * session) -{ - free_ircsession_strings( session ); +void irc_destroy_session (irc_session_t *session) { + free_ircsession_strings(session); // The CTCP VERSION must be freed only now - if ( session->ctcp_version ) + if (session->ctcp_version) free (session->ctcp_version); - if ( session->sock >= 0 ) + if (session->sock >= 0) socket_close (&session->sock); #if defined (ENABLE_THREADS) @@ -106,41 +128,45 @@ void irc_destroy_session (irc_session_t * session) #endif #if defined (ENABLE_SSL) - if ( session->ssl ) - SSL_free( session->ssl ); + if (session->ssl) + SSL_free(session->ssl); #endif /* * delete DCC data * libirc_remove_dcc_session removes the DCC session from the list. */ - while ( session->dcc_sessions ) + while (session->dcc_sessions) libirc_remove_dcc_session (session, session->dcc_sessions, 0); + libirc_mutex_destroy (&session->mutex_dcc); + free (session); + +#if defined (WIN32_DLL) + if (--winsock_refcount == 0) + WSACleanup(); +#endif } -int irc_connect (irc_session_t * session, - const char * server, - unsigned short port, - const char * server_password, - const char * nick, - const char * username, - const char * realname) -{ +int irc_connect (irc_session_t *session, + const char *server, + unsigned short port, + const char *server_password, + const char *nick, + const char *username, + const char *realname) { struct sockaddr_in saddr; - char * p; + char *p; // Check and copy all the specified fields - if ( !server || !nick ) - { + if (!server || !nick) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - if ( session->state != LIBIRC_STATE_INIT ) - { + if (session->state != LIBIRC_STATE_INIT) { session->lasterror = LIBIRC_ERR_STATE; return 1; } @@ -149,8 +175,7 @@ int irc_connect (irc_session_t * session, free_ircsession_strings( session ); // Handle the server # prefix (SSL) - if ( server[0] == SSL_PREFIX ) - { + if (server[0] == SSL_PREFIX) { #if defined (ENABLE_SSL) server++; session->flags |= SESSIONFL_SSL_CONNECTION; @@ -160,47 +185,44 @@ int irc_connect (irc_session_t * session, #endif } - if ( username ) + if (username) session->username = strdup (username); - if ( server_password ) + if (server_password) session->server_password = strdup (server_password); - if ( realname ) + if (realname) session->realname = strdup (realname); session->nick = strdup (nick); session->server = strdup (server); // If port number is zero and server contains the port, parse it - if ( port == 0 && (p = strchr( session->server, ':' )) != 0 ) - { + if (port == 0 && (p = strchr( session->server, ':' )) != 0) { // Terminate the string and parse the port number *p++ = '\0'; - port = atoi( p ); + port = (unsigned short) atoi(p); } // IPv4 address resolving - memset( &saddr, 0, sizeof(saddr) ); + memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons (port); - saddr.sin_addr.s_addr = inet_addr( session->server ); + saddr.sin_addr.s_addr = inet_addr(session->server); - if ( saddr.sin_addr.s_addr == INADDR_NONE ) - { + if (saddr.sin_addr.s_addr == INADDR_NONE) { struct hostent *hp; #if defined HAVE_GETHOSTBYNAME_R int tmp_errno; struct hostent tmp_hostent; char buf[2048]; - if ( gethostbyname_r (session->server, &tmp_hostent, buf, sizeof(buf), &hp, &tmp_errno) ) + if (gethostbyname_r (session->server, &tmp_hostent, buf, sizeof(buf), &hp, &tmp_errno)) hp = 0; #else hp = gethostbyname (session->server); #endif // HAVE_GETHOSTBYNAME_R - if ( !hp ) - { + if (!hp) { session->lasterror = LIBIRC_ERR_RESOLV; return 1; } @@ -209,21 +231,18 @@ int irc_connect (irc_session_t * session, } // create the IRC server socket - if ( socket_create( PF_INET, SOCK_STREAM, &session->sock) - || socket_make_nonblocking (&session->sock) ) - { + if ( socket_create(PF_INET, SOCK_STREAM, &session->sock) + || socket_make_nonblocking(&session->sock)) { session->lasterror = LIBIRC_ERR_SOCKET; return 1; } #if defined (ENABLE_SSL) // Init the SSL stuff - if ( session->flags & SESSIONFL_SSL_CONNECTION ) - { - int rc = ssl_init( session ); + if (session->flags & SESSIONFL_SSL_CONNECTION) { + int rc = ssl_init(session); - if ( rc != 0 ) - { + if (rc != 0) { session->lasterror = rc; return 1; } @@ -231,8 +250,7 @@ int irc_connect (irc_session_t * session, #endif // and connect to the IRC server - if ( socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr)) ) - { + if (socket_connect(&session->sock, (struct sockaddr *) &saddr, sizeof(saddr))) { session->lasterror = LIBIRC_ERR_CONNECT; return 1; } @@ -243,14 +261,13 @@ int irc_connect (irc_session_t * session, } -int irc_connect6 (irc_session_t * session, - const char * server, - unsigned short port, - const char * server_password, - const char * nick, - const char * username, - const char * realname) -{ +int irc_connect6 (irc_session_t *session, + const char *server, + unsigned short port, + const char *server_password, + const char *nick, + const char *username, + const char *realname) { #if defined (ENABLE_IPV6) struct sockaddr_in6 saddr; struct addrinfo ainfo, *res = NULL; @@ -264,14 +281,12 @@ int irc_connect6 (irc_session_t * session, #endif // Check and copy all the specified fields - if ( !server || !nick ) - { + if (!server || !nick) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - if ( session->state != LIBIRC_STATE_INIT ) - { + if (session->state != LIBIRC_STATE_INIT) { session->lasterror = LIBIRC_ERR_STATE; return 1; } @@ -280,8 +295,7 @@ int irc_connect6 (irc_session_t * session, free_ircsession_strings( session ); // Handle the server # prefix (SSL) - if ( server[0] == SSL_PREFIX ) - { + if (server[0] == SSL_PREFIX) { #if defined (ENABLE_SSL) server++; session->flags |= SESSIONFL_SSL_CONNECTION; @@ -291,53 +305,48 @@ int irc_connect6 (irc_session_t * session, #endif } - if ( username ) + if (username) session->username = strdup (username); - if ( server_password ) + if (server_password) session->server_password = strdup (server_password); - if ( realname ) + if (realname) session->realname = strdup (realname); session->nick = strdup (nick); session->server = strdup (server); // If port number is zero and server contains the port, parse it - if ( port == 0 && (p = strchr( session->server, ':' )) != 0 ) - { + if (port == 0 && (p = strchr(session->server, ':')) != 0) { // Terminate the string and parse the port number *p++ = '\0'; - port = atoi( p ); + port = (unsigned short) atoi(p); } - memset( &saddr, 0, sizeof(saddr) ); + memset(&saddr, 0, sizeof(saddr)); saddr.sin6_family = AF_INET6; saddr.sin6_port = htons (port); - sprintf( portStr, "%u", (unsigned)port ); + sprintf(portStr, "%u", port); #if defined (_WIN32) - if ( WSAStringToAddressA( (LPSTR)session->server, AF_INET6, NULL, (struct sockaddr *)&saddr, &addrlen ) == SOCKET_ERROR ) - { + if (WSAStringToAddressA((LPSTR)session->server, AF_INET6, NULL, (struct sockaddr *) &saddr, &addrlen) == SOCKET_ERROR) { hWsock = LoadLibraryA("ws2_32"); - if (hWsock) - { + if (hWsock) { /* Determine functions at runtime, because windows systems < XP do not * support getaddrinfo. */ getaddrinfo_ptr = (getaddrinfo_ptr_t)GetProcAddress(hWsock, "getaddrinfo"); freeaddrinfo_ptr = (freeaddrinfo_ptr_t)GetProcAddress(hWsock, "freeaddrinfo"); - if (getaddrinfo_ptr && freeaddrinfo_ptr) - { + if (getaddrinfo_ptr && freeaddrinfo_ptr) { memset(&ainfo, 0, sizeof(ainfo)); ainfo.ai_family = AF_INET6; ainfo.ai_socktype = SOCK_STREAM; ainfo.ai_protocol = 0; - if ( getaddrinfo_ptr(session->server, portStr, &ainfo, &res) == 0 && res ) - { + if (getaddrinfo_ptr(session->server, portStr, &ainfo, &res) == 0 && res) { resolvesuccess = 1; memcpy( &saddr, res->ai_addr, res->ai_addrlen ); freeaddrinfo_ptr( res ); @@ -345,53 +354,48 @@ int irc_connect6 (irc_session_t * session, } FreeLibrary(hWsock); } - if (!resolvesuccess) - { + if (!resolvesuccess) { session->lasterror = LIBIRC_ERR_RESOLV; return 1; } } #else - if ( inet_pton( AF_INET6, session->server, (void*) &saddr.sin6_addr ) <= 0 ) - { - memset( &ainfo, 0, sizeof(ainfo) ); + if (net_pton(AF_INET6, session->server, (void *) &saddr.sin6_addr) <= 0) { + memset( &ainfo, 0, sizeof(ainfo)); ainfo.ai_family = AF_INET6; ainfo.ai_socktype = SOCK_STREAM; ainfo.ai_protocol = 0; - if ( getaddrinfo( session->server, portStr, &ainfo, &res ) || !res ) - { + if ( getaddrinfo(session->server, portStr, &ainfo, &res) + || !res) { session->lasterror = LIBIRC_ERR_RESOLV; return 1; } - memcpy( &saddr, res->ai_addr, res->ai_addrlen ); - freeaddrinfo( res ); + memcpy(&saddr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res ; } #endif // create the IRC server socket - if ( socket_create( PF_INET6, SOCK_STREAM, &session->sock) - || socket_make_nonblocking (&session->sock) ) - { + if ( socket_create(PF_INET6, SOCK_STREAM, &session->sock) + || socket_make_nonblocking (&session->sock)) { session->lasterror = LIBIRC_ERR_SOCKET; return 1; } #if defined (ENABLE_SSL) // Init the SSL stuff - if ( session->flags & SESSIONFL_SSL_CONNECTION ) - { + if (session->flags & SESSIONFL_SSL_CONNECTION) { int rc = ssl_init( session ); - if ( rc != 0 ) + if (rc != 0) return rc; } #endif // and connect to the IRC server - if ( socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr)) ) - { + if (socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr))) { session->lasterror = LIBIRC_ERR_CONNECT; return 1; } @@ -406,23 +410,19 @@ int irc_connect6 (irc_session_t * session, } -int irc_is_connected (irc_session_t * session) -{ - return (session->state == LIBIRC_STATE_CONNECTED - || session->state == LIBIRC_STATE_CONNECTING) ? 1 : 0; +int irc_is_connected (irc_session_t * session) { + return ( session->state == LIBIRC_STATE_CONNECTED + || session->state == LIBIRC_STATE_CONNECTING) ? 1 : 0; } -int irc_run (irc_session_t * session) -{ - if ( session->state != LIBIRC_STATE_CONNECTING ) - { +int irc_run (irc_session_t * session) { + if (session->state != LIBIRC_STATE_CONNECTING) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - while ( irc_is_connected(session) ) - { + while (irc_is_connected(session)) { struct timeval tv; fd_set in_set, out_set; int maxfd = 0; @@ -431,21 +431,20 @@ int irc_run (irc_session_t * session) tv.tv_sec = 0; // Init sets - FD_ZERO (&in_set); - FD_ZERO (&out_set); + FD_ZERO(&in_set); + FD_ZERO(&out_set); - irc_add_select_descriptors (session, &in_set, &out_set, &maxfd); + irc_add_select_descriptors(session, &in_set, &out_set, &maxfd); - if ( select (maxfd + 1, &in_set, &out_set, 0, &tv) < 0 ) - { - if ( socket_error() == EINTR ) + if (select(maxfd + 1, &in_set, &out_set, 0, &tv) < 0) { + if (socket_error() == EINTR) continue; session->lasterror = LIBIRC_ERR_TERMINATED; return 1; } - if ( irc_process_select_descriptors (session, &in_set, &out_set) ) + if (irc_process_select_descriptors(session, &in_set, &out_set)) return 1; } @@ -453,37 +452,37 @@ int irc_run (irc_session_t * session) } -int irc_add_select_descriptors (irc_session_t * session, fd_set *in_set, fd_set *out_set, int * maxfd) -{ - if ( session->sock < 0 - || session->state == LIBIRC_STATE_INIT - || session->state == LIBIRC_STATE_DISCONNECTED ) - { +int irc_add_select_descriptors (irc_session_t *session, + fd_set *in_set, + fd_set *out_set, + int *maxfd) { + if ( session->sock < 0 + || session->state == LIBIRC_STATE_INIT + || session->state == LIBIRC_STATE_DISCONNECTED) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - libirc_mutex_lock (&session->mutex_session); + libirc_mutex_lock(&session->mutex_session); - switch (session->state) - { - case LIBIRC_STATE_CONNECTING: - // While connection, only out_set descriptor should be set - libirc_add_to_set (session->sock, out_set, maxfd); - break; - - case LIBIRC_STATE_CONNECTED: - // Add input descriptor if there is space in input buffer - if ( session->incoming_offset < (sizeof (session->incoming_buf) - 1) - || (session->flags & SESSIONFL_SSL_WRITE_WANTS_READ) != 0 ) - libirc_add_to_set (session->sock, in_set, maxfd); - - // Add output descriptor if there is something in output buffer - if ( libirc_findcrlf (session->outgoing_buf, session->outgoing_offset) > 0 - || (session->flags & SESSIONFL_SSL_READ_WANTS_WRITE) != 0 ) + switch (session->state) { + case LIBIRC_STATE_CONNECTING: + // While connection, only out_set descriptor should be set libirc_add_to_set (session->sock, out_set, maxfd); + break; - break; + case LIBIRC_STATE_CONNECTED: + // Add input descriptor if there is space in input buffer + if ( session->incoming_offset < (sizeof (session->incoming_buf) - 1) + || (session->flags & SESSIONFL_SSL_WRITE_WANTS_READ) != 0) + libirc_add_to_set (session->sock, in_set, maxfd); + + // Add output descriptor if there is something in output buffer + if ( libirc_findcrlf (session->outgoing_buf, session->outgoing_offset) > 0 + || (session->flags & SESSIONFL_SSL_READ_WANTS_WRITE) != 0) + libirc_add_to_set (session->sock, out_set, maxfd); + + break; } libirc_mutex_unlock (&session->mutex_session); @@ -493,21 +492,21 @@ int irc_add_select_descriptors (irc_session_t * session, fd_set *in_set, fd_set } -static void libirc_process_incoming_data (irc_session_t * session, size_t process_length) -{ +static void libirc_process_incoming_data (irc_session_t *session, + size_t process_length) { #define MAX_PARAMS_ALLOWED 10 char buf[2*512], *p, *s; - const char *command = 0, *prefix = 0, *params[MAX_PARAMS_ALLOWED+1]; - int code = 0, paramindex = 0; + const char *command = 0, *prefix = 0, *params[MAX_PARAMS_ALLOWED + 1]; + unsigned int code = 0, paramindex = 0; char *buf_end = buf + process_length; if (process_length > sizeof(buf)) abort(); // should be impossible - memcpy (buf, session->incoming_buf, process_length); + memcpy(buf, session->incoming_buf, process_length); buf[process_length] = '\0'; - memset ((char *)params, 0, sizeof(params)); + memset((char *)params, 0, sizeof(params)); p = buf; /* @@ -524,8 +523,7 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces */ // Parse - if (buf[0] == ':') - { + if (buf[0] == ':') { while (*p && *p != ' ') p++; @@ -536,12 +534,10 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces // If LIBIRC_OPTION_STRIPNICKS is set, we should 'clean up' nick // right here - if (session->options & LIBIRC_OPTION_STRIPNICKS) - { - for (s = buf + 1; *s; s++) - { - if (*s == '@' || *s == '!') - { + if (session->options & LIBIRC_OPTION_STRIPNICKS) { + for (s = buf + 1; *s; s++) { + if ( *s == '@' + || *s == '!') { *s = '\0'; break; } @@ -550,14 +546,11 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces } // Parse - if (isdigit (p[0]) && isdigit (p[1]) && isdigit (p[2])) - { + if (isdigit (p[0]) && isdigit (p[1]) && isdigit (p[2])) { p[3] = '\0'; - code = atoi (p); + code = (unsigned int) atoi (p); p += 4; - } - else - { + } else { s = p; while (*p && *p != ' ') @@ -569,11 +562,9 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces } // Parse middle/params - while (*p && paramindex < MAX_PARAMS_ALLOWED) - { + while (*p && paramindex < MAX_PARAMS_ALLOWED) { // beginning from ':', this is the last param - if (*p == ':') - { + if (*p == ':') { params[paramindex++] = p + 1; // skip : break; } @@ -591,160 +582,133 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces } // Handle PING/PONG - if (command && !strncmp (command, "PING", buf_end - command) && params[0]) - { - irc_send_raw (session, "PONG %s", params[0]); + if (command && !strncmp (command, "PING", (size_t) max(buf_end - command, 0)) && params[0]) { + if (!(session->options & LIBIRC_OPTION_IGNORE_PING)) + irc_send_raw (session, "PONG %s", params[0]); + if (session->callbacks.event_ping) + (*session->callbacks.event_ping)(session, "PING", prefix, params, paramindex); return; } // and dump - if (code) - { + if (code) { // We use SESSIONFL_MOTD_RECEIVED flag to check whether it is the first // RPL_ENDOFMOTD or ERR_NOMOTD after the connection. - if ((code == 1 || code == 376 || code == 422) && !(session->flags & SESSIONFL_MOTD_RECEIVED)) - { + if (( code == 1 + || code == 376 + || code == 422) + && !(session->flags & SESSIONFL_MOTD_RECEIVED)) { session->flags |= SESSIONFL_MOTD_RECEIVED; if (session->callbacks.event_connect) - (*session->callbacks.event_connect) (session, "CONNECT", prefix, params, paramindex); + (*session->callbacks.event_connect)(session, "CONNECT", prefix, params, paramindex); } if (session->callbacks.event_numeric) (*session->callbacks.event_numeric) (session, code, prefix, params, paramindex); - } - else - { - if (!strncmp (command, "NICK", buf_end - command)) - { + } else { + if (!strncmp(command, "NICK", (size_t) max(buf_end - command, 0))) { /* * If we're changed our nick, we should save it. */ char nickbuf[256]; - irc_target_get_nick (prefix, nickbuf, sizeof(nickbuf)); + irc_target_get_nick(prefix, nickbuf, sizeof(nickbuf)); - if (!strncmp (nickbuf, session->nick, strlen(session->nick)) && paramindex > 0) - { - free (session->nick); + if (!strncmp(nickbuf, session->nick, strlen(session->nick)) && paramindex > 0) { + free(session->nick); session->nick = strdup (params[0]); } if (session->callbacks.event_nick) - (*session->callbacks.event_nick) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "QUIT", buf_end - command)) - { + (*session->callbacks.event_nick)(session, command, prefix, params, paramindex); + } else if (!strncmp (command, "QUIT", (size_t) max(buf_end - command, 0))) { if (session->callbacks.event_quit) - (*session->callbacks.event_quit) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "JOIN", buf_end - command)) - { - if (session->callbacks.event_join) - (*session->callbacks.event_join) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "PART", buf_end - command)) - { - if (session->callbacks.event_part ) - (*session->callbacks.event_part) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "MODE", buf_end - command)) - { - if (paramindex > 0 && !strncmp (params[0], session->nick, strlen(session->nick))) - { + (*session->callbacks.event_quit)(session, command, prefix, params, paramindex); + } else if (!strncmp (command, "JOIN", (size_t) max(buf_end - command, 0))) { + if (session->callbacks.event_join ) + (*session->callbacks.event_join)(session, command, prefix, params, paramindex); + } else if (!strncmp (command, "PART", (size_t) max(buf_end - command, 0))) { + if (session->callbacks.event_part) + (*session->callbacks.event_part)(session, command, prefix, params, paramindex); + } else if (!strncmp (command, "MODE", (size_t) max(buf_end - command, 0))) { + if (paramindex > 0 && !strncmp (params[0], session->nick, strlen(session->nick))) { params[0] = params[1]; paramindex = 1; if (session->callbacks.event_umode) - (*session->callbacks.event_umode) (session, command, prefix, params, paramindex); - } - else - { + (*session->callbacks.event_umode)(session, "UMODE", prefix, params, paramindex); + } else { if (session->callbacks.event_mode) - (*session->callbacks.event_mode) (session, command, prefix, params, paramindex); + (*session->callbacks.event_mode)(session, "MODE", prefix, params, paramindex); } - } - else if (!strncmp (command, "TOPIC", buf_end - command)) - { - if (session->callbacks.event_topic) + } else if (!strncmp(command, "TOPIC", (size_t) max(buf_end - command, 0))) { + if (session->callbacks.event_topic ) (*session->callbacks.event_topic) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "KICK", buf_end - command)) - { + } else if (!strncmp(command, "KICK", (size_t) max(buf_end - command, 0))) { if (session->callbacks.event_kick) (*session->callbacks.event_kick) (session, command, prefix, params, paramindex); - } - else if (!strncmp (command, "PRIVMSG", buf_end - command)) - { - if (paramindex > 1) - { - size_t msglen = strlen (params[1]); + } else if (!strncmp(command, "ERROR", (size_t) max(buf_end - command, 0))) { + if (session->callbacks.event_error) + (*session->callbacks.event_error) (session, command, prefix, params, paramindex); + } else if (!strncmp(command, "PRIVMSG", (size_t) max(buf_end - command, 0))) { + if (paramindex > 1) { + size_t msglen = strlen(params[1]); /* * Check for CTCP request (a CTCP message starts from 0x01 * and ends by 0x01 */ - if (params[1][0] == 0x01 && params[1][msglen-1] == 0x01) - { + if (params[1][0] == 0x01 && params[1][msglen-1] == 0x01) { char ctcp_buf[512]; msglen -= 2; - if ( msglen > sizeof(ctcp_buf) - 1 ) + if (msglen > sizeof(ctcp_buf) - 1) msglen = sizeof(ctcp_buf) - 1; memcpy (ctcp_buf, params[1] + 1, msglen); ctcp_buf[msglen] = '\0'; - if (!strncasecmp(ctcp_buf, "DCC ", 4)) - { + if (!strncasecmp(ctcp_buf, "DCC ", 4)) { libirc_dcc_request (session, prefix, ctcp_buf); - } - else if (!strncasecmp(ctcp_buf, "ACTION ", 7) && session->callbacks.event_ctcp_action) - { + } else if (!strncasecmp( ctcp_buf, "ACTION ", 7) + && session->callbacks.event_ctcp_action) { params[1] = ctcp_buf + 7; // the length of "ACTION " paramindex = 2; - (*session->callbacks.event_ctcp_action) (session, "ACTION", prefix, params, paramindex); - } - else - { + (*session->callbacks.event_ctcp_action)(session, "CTCP_ACTION", prefix, params, paramindex); + } else { params[0] = ctcp_buf; paramindex = 1; if (session->callbacks.event_ctcp_req) - (*session->callbacks.event_ctcp_req) (session, "CTCP", prefix, params, paramindex); + (*session->callbacks.event_ctcp_req)(session, "CTCP_REQ", prefix, params, paramindex); } - } - else if (!strncasecmp (params[0], session->nick, strlen(session->nick))) - { + } else if (!strncasecmp(params[0], session->nick, strlen(session->nick))) { if (session->callbacks.event_privmsg) - (*session->callbacks.event_privmsg) (session, "PRIVMSG", prefix, params, paramindex); - } - /* - * Check to see if first parameter is a channel name - */ - else if (params[0][0] == '#' || params[0][0] == '&' || params[0][0] == '!' || params[0][0] == '+') - { + (*session->callbacks.event_privmsg)(session, "PRIVMSG", prefix, params, paramindex); + } else if ( params[0][0] == '#' + || params[0][0] == '&' + || params[0][0] == '!' + || params[0][0] == '+') { + /* + * Check to see if first parameter is a channel name + */ if (session->callbacks.event_channel) - (*session->callbacks.event_channel) (session, "CHANNEL", prefix, params, paramindex); - } - else - { + (*session->callbacks.event_channel)(session, "CHANMSG", prefix, params, paramindex); + } else { if (session->callbacks.event_server_msg) - (*session->callbacks.event_server_msg) (session, command, prefix, params, paramindex); + (*session->callbacks.event_server_msg)(session, "SERVMSG", prefix, params, paramindex); } } - } - else if (!strncmp (command, "NOTICE", buf_end - command)) - { + } else if (!strncmp (command, "NOTICE", (size_t) max(buf_end - command, 0))) { size_t msglen = strlen (params[1]); /* * Check for CTCP request (a CTCP message starts from 0x01 * and ends by 0x01 */ - if (paramindex > 1 && params[1][0] == 0x01 && params[1][msglen-1] == 0x01) - { + if (paramindex > 1 && params[1][0] == 0x01 && params[1][msglen-1] == 0x01) { char ctcp_buf[512]; msglen -= 2; @@ -758,79 +722,71 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces paramindex = 1; if (session->callbacks.event_ctcp_rep) - (*session->callbacks.event_ctcp_rep) (session, "CTCP", prefix, params, paramindex); - } - else if (!strncasecmp (params[0], session->nick, strlen(session->nick))) - { + (*session->callbacks.event_ctcp_rep)(session, "CTCP_REPL", prefix, params, paramindex); + } else if (!strncasecmp (params[0], session->nick, strlen(session->nick))) { if (session->callbacks.event_notice) - (*session->callbacks.event_notice) (session, command, prefix, params, paramindex); - } - /* - * Check to see if first parameter is a channel name - */ - else if (params[0][0] == '#' || params[0][0] == '&' || params[0][0] == '!' || params[0][0] == '+') - { + (*session->callbacks.event_notice)(session, "PRIVNOTICE", prefix, params, paramindex); + } else if ( params[0][0] == '#' + || params[0][0] == '&' + || params[0][0] == '!' + || params[0][0] == '+') { + /* + * Check to see if first parameter is a channel name + */ if (session->callbacks.event_channel_notice) - (*session->callbacks.event_channel_notice) (session, command, prefix, params, paramindex); - } - else - { + (*session->callbacks.event_channel_notice)(session, "CHANNOTICE", prefix, params, paramindex); + } else { if (session->callbacks.event_server_notice) - (*session->callbacks.event_server_notice) (session, command, prefix, params, paramindex); + (*session->callbacks.event_server_notice)(session, "SERVNOTICE", prefix, params, paramindex); } - } - else if (!strncmp (command, "INVITE", buf_end - command)) - { + } else if (!strncmp(command, "INVITE", (size_t) max(buf_end - command, 0))) { if (session->callbacks.event_invite) (*session->callbacks.event_invite) (session, command, prefix, params, paramindex); - } -// else if (!strncmp (command, "KILL", buf_end - command)) -// { -// ; /* ignore this event - not all servers generate this */ -// } - else - { + } else if (!strncmp(command, "KILL", (size_t) max(buf_end - command, 0))) { + ; /* ignore this event - not all servers generate this */ + } else { /* - * The "unknown" event is triggered upon receipt of any number of - * unclassifiable miscellaneous messages, which aren't handled by + * The ‘unknown’ event is triggered upon receipt of any number of + * unclassifiable miscellaneous messages, which aren’t handled by * the library. */ if (session->callbacks.event_unknown) - (*session->callbacks.event_unknown) (session, command, prefix, params, paramindex); + (*session->callbacks.event_unknown)(session, command, prefix, params, paramindex); } } } -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) { char buf[256], hname[256]; - if ( session->sock < 0 - || session->state == LIBIRC_STATE_INIT - || session->state == LIBIRC_STATE_DISCONNECTED ) - { + if ( session->sock < 0 + || session->state == LIBIRC_STATE_INIT + || session->state == LIBIRC_STATE_DISCONNECTED) { session->lasterror = LIBIRC_ERR_STATE; return 1; } session->lasterror = 0; - libirc_dcc_process_descriptors (session, in_set, out_set); + libirc_dcc_process_descriptors(session, in_set, out_set); // Handle "connection succeed" / "connection failed" - if ( session->state == LIBIRC_STATE_CONNECTING - && FD_ISSET (session->sock, out_set) ) - { + if (session->state == LIBIRC_STATE_CONNECTING) { + // If the socket is not connected yet, wait longer - it is not an error + if (!FD_ISSET (session->sock, out_set)) + return 0; + // Now we have to determine whether the socket is connected // or the connect is failed struct sockaddr_storage saddr, laddr; socklen_t slen = sizeof(saddr); socklen_t llen = sizeof(laddr); - if ( getsockname (session->sock, (struct sockaddr*)&laddr, &llen) < 0 - || getpeername (session->sock, (struct sockaddr*)&saddr, &slen) < 0 ) - { + if ( getsockname(session->sock, (struct sockaddr *)&laddr, &llen) < 0 + || getpeername(session->sock, (struct sockaddr *)&saddr, &slen) < 0) { // connection failed session->lasterror = LIBIRC_ERR_CONNECT; session->state = LIBIRC_STATE_DISCONNECTED; @@ -838,24 +794,23 @@ int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_ } if (saddr.ss_family == AF_INET) - memcpy (&session->local_addr, &((struct sockaddr_in *)&laddr)->sin_addr, sizeof(struct in_addr)); + memcpy(&session->local_addr, &((struct sockaddr_in *) &laddr)->sin_addr, sizeof(struct in_addr)); else - memcpy (&session->local_addr, &((struct sockaddr_in6 *)&laddr)->sin6_addr, sizeof(struct in6_addr)); + memcpy(&session->local_addr, &((struct sockaddr_in6 *) &laddr)->sin6_addr, sizeof(struct in6_addr)); #if defined (ENABLE_DEBUG) - if ( IS_DEBUG_ENABLED(session) ) - fprintf (stderr, "[DEBUG] Detected local address: %s\n", inet_ntoa(session->local_addr)); + if (IS_DEBUG_ENABLED(session)) + fprintf(stderr, "[DEBUG] Detected local address: %s\n", inet_ntoa(session->local_addr)); #endif session->state = LIBIRC_STATE_CONNECTED; // Get the hostname - if ( gethostname (hname, sizeof(hname)) < 0 ) + if (gethostname (hname, sizeof(hname)) < 0) strcpy (hname, "unknown"); // Prepare the data, which should be sent to the server - if ( session->server_password ) - { + if (session->server_password) { snprintf (buf, sizeof(buf), "PASS %s", session->server_password); irc_send_raw (session, buf); } @@ -872,233 +827,224 @@ int irc_process_select_descriptors (irc_session_t * session, fd_set *in_set, fd_ snprintf (buf, sizeof(buf), "USER %s unknown unknown :%s", session->username ? session->username : "nobody", session->realname ? session->realname : "noname"); - irc_send_raw (session, buf); + irc_send_raw(session, buf); return 0; } - if ( session->state != LIBIRC_STATE_CONNECTED ) - { + if (session->state != LIBIRC_STATE_CONNECTED) { session->lasterror = LIBIRC_ERR_STATE; return 1; } // Hey, we've got something to read! - if ( FD_ISSET (session->sock, in_set) ) - { - int offset, length = session_socket_read( session ); + if (FD_ISSET (session->sock, in_set)) { + size_t offset; + ssize_t length = session_socket_read(session); - if ( length < 0 ) - { - if ( session->lasterror == 0 ) + if (length < 0) { + if (session->lasterror == 0) session->lasterror = (length == 0 ? LIBIRC_ERR_CLOSED : LIBIRC_ERR_TERMINATED); session->state = LIBIRC_STATE_DISCONNECTED; return 1; } - session->incoming_offset += length; + session->incoming_offset += (size_t) length; // process the incoming data - while ( (offset = libirc_findcrlf (session->incoming_buf, session->incoming_offset)) > 0 ) - { + while ((offset = libirc_findcrlf(session->incoming_buf, session->incoming_offset)) > 0) { #if defined (ENABLE_DEBUG) - if ( IS_DEBUG_ENABLED(session) ) - libirc_dump_data ("RECV", session->incoming_buf, offset); + if (IS_DEBUG_ENABLED(session)) + libirc_dump_data("RECV", session->incoming_buf, offset); #endif // parse the string - libirc_process_incoming_data (session, offset); + libirc_process_incoming_data(session, offset); offset = libirc_findcrlf_offset(session->incoming_buf, offset, session->incoming_offset); - if ( session->incoming_offset - offset > 0 ) - memmove (session->incoming_buf, session->incoming_buf + offset, session->incoming_offset - offset); + if (session->incoming_offset - offset > 0) + memmove(session->incoming_buf, session->incoming_buf + offset, session->incoming_offset - offset); session->incoming_offset -= offset; } } // We can write a stored buffer - if ( FD_ISSET (session->sock, out_set) ) - { - int length; + if (FD_ISSET(session->sock, out_set)) { + ssize_t length; // Because outgoing_buf could be changed asynchronously, we should lock any change libirc_mutex_lock (&session->mutex_session); - length = session_socket_write( session ); + length = session_socket_write(session); - if ( length < 0 ) - { - if ( session->lasterror == 0 ) + if (length < 0) { + if (session->lasterror == 0) session->lasterror = (length == 0 ? LIBIRC_ERR_CLOSED : LIBIRC_ERR_TERMINATED); session->state = LIBIRC_STATE_DISCONNECTED; - libirc_mutex_unlock (&session->mutex_session); + libirc_mutex_unlock(&session->mutex_session); return 1; } #if defined (ENABLE_DEBUG) - if ( IS_DEBUG_ENABLED(session) ) - libirc_dump_data ("SEND", session->outgoing_buf, length); + if (IS_DEBUG_ENABLED(session)) + libirc_dump_data("SEND", session->outgoing_buf, length); #endif - if ( length > 0 && session->outgoing_offset - length > 0 ) - memmove (session->outgoing_buf, session->outgoing_buf + length, session->outgoing_offset - length); + if (length > 0 && session->outgoing_offset - (size_t) length > 0) + memmove(session->outgoing_buf, session->outgoing_buf + length, session->outgoing_offset - (size_t) length); - session->outgoing_offset -= length; - libirc_mutex_unlock (&session->mutex_session); + session->outgoing_offset -= (size_t) length; + libirc_mutex_unlock(&session->mutex_session); } return 0; } -int irc_send_raw (irc_session_t * session, const char * format, ...) -{ +int irc_send_raw (irc_session_t *session, + const char *format, + ...) { char buf[1024]; va_list va_alist; - if ( session->state != LIBIRC_STATE_CONNECTED ) - { + if (session->state != LIBIRC_STATE_CONNECTED) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - va_start (va_alist, format); - vsnprintf (buf, sizeof(buf), format, va_alist); - va_end (va_alist); + va_start(va_alist, format); + vsnprintf(buf, sizeof(buf), format, va_alist); + va_end(va_alist); - libirc_mutex_lock (&session->mutex_session); + libirc_mutex_lock(&session->mutex_session); - if ( (strlen(buf) + 2) >= (sizeof(session->outgoing_buf) - session->outgoing_offset) ) - { - libirc_mutex_unlock (&session->mutex_session); + if ((strlen(buf) + 2) >= (sizeof(session->outgoing_buf) - session->outgoing_offset)) { + libirc_mutex_unlock(&session->mutex_session); session->lasterror = LIBIRC_ERR_NOMEM; return 1; } - strcpy (session->outgoing_buf + session->outgoing_offset, buf); + strcpy(session->outgoing_buf + session->outgoing_offset, buf); session->outgoing_offset += strlen (buf); session->outgoing_buf[session->outgoing_offset++] = 0x0D; session->outgoing_buf[session->outgoing_offset++] = 0x0A; - libirc_mutex_unlock (&session->mutex_session); + libirc_mutex_unlock(&session->mutex_session); return 0; } -int irc_cmd_quit (irc_session_t * session, const char * reason) -{ - return irc_send_raw (session, "QUIT :%s", reason ? reason : "quit"); +int irc_cmd_quit (irc_session_t *session, + const char *reason) { + return irc_send_raw(session, "QUIT :%s", reason ?: "quit"); } -int irc_cmd_join (irc_session_t * session, const char * channel, const char * key) -{ - if ( !channel ) - { +int irc_cmd_join (irc_session_t *session, + const char *channel, + const char *key) { + if (!channel) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - if ( key ) - return irc_send_raw (session, "JOIN %s :%s", channel, key); + if (key) + return irc_send_raw(session, "JOIN %s :%s", channel, key); else - return irc_send_raw (session, "JOIN %s", channel); + return irc_send_raw(session, "JOIN %s", channel); } -int irc_cmd_part (irc_session_t * session, const char * channel) -{ - if ( !channel ) - { +int irc_cmd_part (irc_session_t *session, + const char *channel) { + if (!channel) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "PART %s", channel); + return irc_send_raw(session, "PART %s", channel); } -int irc_cmd_topic (irc_session_t * session, const char * channel, const char * topic) -{ - if ( !channel ) - { +int irc_cmd_topic (irc_session_t *session, + const char *channel, + const char *topic) { + if (!channel) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - if ( topic ) - return irc_send_raw (session, "TOPIC %s :%s", channel, topic); + if (topic) + return irc_send_raw(session, "TOPIC %s :%s", channel, topic); else - return irc_send_raw (session, "TOPIC %s", channel); + return irc_send_raw(session, "TOPIC %s", channel); } -int irc_cmd_names (irc_session_t * session, const char * channel) -{ - if ( !channel ) - { +int irc_cmd_names (irc_session_t *session, + const char *channel) { + if (!channel) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "NAMES %s", channel); + return irc_send_raw(session, "NAMES %s", channel); } -int irc_cmd_list (irc_session_t * session, const char * channel) -{ - if ( channel ) - return irc_send_raw (session, "LIST %s", channel); +int irc_cmd_list (irc_session_t *session, + const char *channel) { + if (channel) + return irc_send_raw(session, "LIST %s", channel); else - return irc_send_raw (session, "LIST"); + return irc_send_raw(session, "LIST"); } -int irc_cmd_invite (irc_session_t * session, const char * nick, const char * channel) -{ - if ( !channel || !nick ) - { +int irc_cmd_invite (irc_session_t *session, + const char *nick, + const char *channel) { + if (!channel || !nick) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "INVITE %s %s", nick, channel); + return irc_send_raw(session, "INVITE %s %s", nick, channel); } -int irc_cmd_kick (irc_session_t * session, const char * nick, const char * channel, const char * comment) -{ - if ( !channel || !nick ) - { +int irc_cmd_kick (irc_session_t *session, + const char *nick, + const char *channel, + const char *comment) { + if (!channel || !nick) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - if ( comment ) - return irc_send_raw (session, "KICK %s %s :%s", channel, nick, comment); + if (comment) + return irc_send_raw(session, "KICK %s %s :%s", channel, nick, comment); else - return irc_send_raw (session, "KICK %s %s", channel, nick); + return irc_send_raw(session, "KICK %s %s", channel, nick); } -int irc_cmd_msg (irc_session_t * session, const char * nch, const char * text) -{ - if ( !nch || !text ) - { +int irc_cmd_msg (irc_session_t *session, const char *nch, const char *text) { + if (!nch || !text) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "PRIVMSG %s :%s", nch, text); + return irc_send_raw(session, "PRIVMSG %s :%s", nch, text); } -int irc_cmd_notice (irc_session_t * session, const char * nch, const char * text) -{ - if ( !nch || !text ) - { +int irc_cmd_notice (irc_session_t *session, + const char *nch, + const char *text) { + if (!nch || !text) { session->lasterror = LIBIRC_ERR_STATE; return 1; } @@ -1106,35 +1052,37 @@ int irc_cmd_notice (irc_session_t * session, const char * nch, const char * text return irc_send_raw (session, "NOTICE %s :%s", nch, text); } -void irc_target_get_nick (const char * target, char *nick, size_t size) -{ - char *p = strstr (target, "!"); - unsigned int len; +void irc_target_get_nick (const char *target, + char *nick, + size_t size) { + char *p = strstr(target, "!"); + size_t len; - if ( p ) - len = p - target; + if (p) + len = (size_t) (p - target); else - len = strlen (target); + len = strlen(target); - if ( len > size-1 ) + if (len > size - 1) len = size - 1; - memcpy (nick, target, len); + memcpy(nick, target, len); nick[len] = '\0'; } -void irc_target_get_host (const char * target, char *host, size_t size) -{ - unsigned int len; - const char *p = strstr (target, "!"); +void irc_target_get_host (const char *target, + char *host, + size_t size) { + size_t len; + const char *p = strstr(target, "!"); - if ( !p ) + if (!p) p = target; len = strlen (p); - if ( len > size-1 ) + if (len > size - 1) len = size - 1; memcpy (host, p, len); @@ -1142,134 +1090,130 @@ void irc_target_get_host (const char * target, char *host, size_t size) } -int irc_cmd_ctcp_request (irc_session_t * session, const char * nick, const char * reply) -{ - if ( !nick || !reply ) - { +int irc_cmd_ctcp_request (irc_session_t *session, + const char *nick, + const char *reply) { + if (!nick || !reply) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "PRIVMSG %s :\x01%s\x01", nick, reply); + return irc_send_raw(session, "PRIVMSG %s :\x01%s\x01", nick, reply); } -int irc_cmd_ctcp_reply (irc_session_t * session, const char * nick, const char * reply) -{ - if ( !nick || !reply ) - { +int irc_cmd_ctcp_reply (irc_session_t *session, + const char *nick, + const char *reply) { + if (!nick || !reply) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "NOTICE %s :\x01%s\x01", nick, reply); + return irc_send_raw(session, "NOTICE %s :\x01%s\x01", nick, reply); } -void irc_get_version (unsigned int * high, unsigned int * low) -{ +void irc_get_version (unsigned int *high, + unsigned int *low) { *high = LIBIRC_VERSION_HIGH; *low = LIBIRC_VERSION_LOW; } -void irc_set_ctx (irc_session_t * session, void * ctx) -{ +void irc_set_ctx (irc_session_t *session, + void *ctx) { session->ctx = ctx; } -void * irc_get_ctx (irc_session_t * session) -{ +void* irc_get_ctx (irc_session_t *session) { return session->ctx; } -void irc_set_ctcp_version (irc_session_t * session, const char * version) -{ - if ( session->ctcp_version ) +void irc_set_ctcp_version (irc_session_t *session, + const char *version) { + if (session->ctcp_version) free(session->ctcp_version); session->ctcp_version = strdup(version); } -void irc_disconnect (irc_session_t * session) -{ - if ( session->sock >= 0 ) - socket_close (&session->sock); +void irc_disconnect (irc_session_t *session) { + if (session->sock >= 0) + socket_close(&session->sock); session->sock = -1; session->state = LIBIRC_STATE_INIT; } -int irc_cmd_me (irc_session_t * session, const char * nch, const char * text) -{ - if ( !nch || !text ) - { +int irc_cmd_me (irc_session_t *session, + const char *nch, + const char *text) { + if (!nch || !text) { session->lasterror = LIBIRC_ERR_STATE; return 1; } - return irc_send_raw (session, "PRIVMSG %s :\x01" "ACTION %s\x01", nch, text); + return irc_send_raw(session, "PRIVMSG %s :\x01" "ACTION %s\x01", nch, text); } -void irc_option_set (irc_session_t * session, unsigned int option) -{ +void irc_option_set (irc_session_t *session, + unsigned int option) { session->options |= option; } -void irc_option_reset (irc_session_t * session, unsigned int option) -{ +void irc_option_reset (irc_session_t *session, + unsigned int option) { session->options &= ~option; } -int irc_cmd_channel_mode (irc_session_t * session, const char * channel, const char * mode) -{ - if ( !channel ) - { +int irc_cmd_channel_mode (irc_session_t *session, + const char *channel, + const char *mode) { + if (!channel) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - if ( mode ) - return irc_send_raw (session, "MODE %s %s", channel, mode); + if (mode) + return irc_send_raw(session, "MODE %s %s", channel, mode); else - return irc_send_raw (session, "MODE %s", channel); + return irc_send_raw(session, "MODE %s", channel); } -int irc_cmd_user_mode (irc_session_t * session, const char * mode) -{ - if ( mode ) - return irc_send_raw (session, "MODE %s %s", session->nick, mode); +int irc_cmd_user_mode (irc_session_t *session, + const char *mode) { + if (mode) + return irc_send_raw(session, "MODE %s %s", session->nick, mode); else - return irc_send_raw (session, "MODE %s", session->nick); + return irc_send_raw(session, "MODE %s", session->nick); } -int irc_cmd_nick (irc_session_t * session, const char * newnick) -{ - if ( !newnick ) - { +int irc_cmd_nick (irc_session_t *session, + const char *newnick) { + if (!newnick) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - return irc_send_raw (session, "NICK %s", newnick); + return irc_send_raw(session, "NICK %s", newnick); } -int irc_cmd_whois (irc_session_t * session, const char * nick) -{ - if ( !nick ) - { +int irc_cmd_whois (irc_session_t *session, + const char *nick) { + if (!nick) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } - return irc_send_raw (session, "WHOIS %s %s", nick, nick); + return irc_send_raw(session, "WHOIS %s %s", nick, nick); } diff --git a/libircclient/src/portable.c b/libircclient/src/portable.c index 7b6f72b..02ab041 100644 --- a/libircclient/src/portable.c +++ b/libircclient/src/portable.c @@ -134,20 +134,13 @@ static inline void libirc_mutex_unlock (port_mutex_t * mutex) #if defined (WIN32_DLL) BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { - WORD wVersionRequested = MAKEWORD (1, 1); - WSADATA wsaData; - switch(fdwReason) { case DLL_PROCESS_ATTACH: - if ( WSAStartup (wVersionRequested, &wsaData) != 0 ) - return FALSE; - DisableThreadLibraryCalls (hinstDll); break; case DLL_PROCESS_DETACH: - WSACleanup(); break; } diff --git a/libircclient/src/sockets.c b/libircclient/src/sockets.c index 83aca56..9719299 100644 --- a/libircclient/src/sockets.c +++ b/libircclient/src/sockets.c @@ -54,8 +54,7 @@ #endif -static int socket_error() -{ +static int socket_error() { #if !defined (_WIN32) return errno; #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); 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) return fcntl (*sock, F_SETFL, fcntl (*sock, F_GETFL,0 ) | O_NONBLOCK) != 0; #else - unsigned long mode = 0; + unsigned long mode = 1; return ioctlsocket (*sock, FIONBIO, &mode) == SOCKET_ERROR; #endif } -static int socket_close (socket_t * sock) -{ +static int socket_close (socket_t *sock) { #if !defined (_WIN32) close (*sock); #else @@ -95,16 +93,15 @@ static int socket_close (socket_t * sock) } -static int socket_connect (socket_t * sock, const struct sockaddr *saddr, socklen_t len) -{ - while ( 1 ) - { - if ( connect (*sock, saddr, len) < 0 ) - { - if ( socket_error() == EINTR ) +static ssize_t socket_connect (socket_t *sock, + const struct sockaddr *saddr, + socklen_t len) { + while (1) { + if (connect(*sock, saddr, len) < 0) { + if (socket_error() == EINTR) continue; - if ( socket_error() != EINPROGRESS && socket_error() != EWOULDBLOCK ) + if (socket_error() != EINPROGRESS && socket_error() != EWOULDBLOCK) return 1; } @@ -113,11 +110,12 @@ 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) -{ - while ( IS_SOCKET_ERROR(*newsock = accept (*sock, saddr, len)) ) - { - if ( socket_error() == EINTR ) +static ssize_t socket_accept (socket_t *sock, + socket_t *newsock, + struct sockaddr *saddr, + socklen_t *len) { + while (IS_SOCKET_ERROR(*newsock = accept(*sock, saddr, len))) { + if (socket_error() == EINTR) continue; return 1; @@ -127,28 +125,28 @@ static int socket_accept (socket_t * sock, socket_t * newsock, struct sockaddr * } -static int socket_recv (socket_t * sock, void * buf, size_t len) -{ - int length; +static ssize_t socket_recv (socket_t *sock, + void *buf, + size_t len) { + ssize_t length; - while ( (length = recv (*sock, buf, len, 0)) < 0 ) - { - int err = socket_error(); - - if ( err != EINTR && err != EAGAIN ) - break; - } - - return length; -} - - -static int socket_send (socket_t * sock, const void *buf, size_t len) -{ - int length; - - while ( (length = send (*sock, buf, len, 0)) < 0 ) - { + while ((length = recv(*sock, buf, len, 0)) < 0) { + int err = socket_error(); + + if (err != EINTR && err != EAGAIN) + break; + } + + return length; +} + + +static ssize_t socket_send (socket_t *sock, + const void *buf, + size_t len) { + ssize_t length; + + while ((length = send(*sock, buf, len, 0)) < 0) { int err = socket_error(); if ( err != EINTR && err != EAGAIN ) diff --git a/libircclient/src/ssl.c b/libircclient/src/ssl.c index 5af92cc..ae67792 100644 --- a/libircclient/src/ssl.c +++ b/libircclient/src/ssl.c @@ -24,32 +24,32 @@ static SSL_CTX * ssl_context = 0; static CRITICAL_SECTION * mutex_buf = 0; // OpenSSL callback to utilize static locks -static void cb_openssl_locking_function( int mode, int n, const char * file, int line ) -{ - if ( mode & CRYPTO_LOCK) - EnterCriticalSection( &mutex_buf[n] ); +static void cb_openssl_locking_function (int mode, + int n, + const char *file, + int line) { + if (mode & CRYPTO_LOCK) + EnterCriticalSection(&mutex_buf[n]); else - LeaveCriticalSection( &mutex_buf[n] ); + LeaveCriticalSection(&mutex_buf[n]); } // OpenSSL callback to get the thread ID -static unsigned long cb_openssl_id_function(void) -{ - return ((unsigned long) GetCurrentThreadId() ); +static unsigned long cb_openssl_id_function (void) { + return ((unsigned long) GetCurrentThreadId()); } -static int alloc_mutexes( unsigned int total ) -{ +static int alloc_mutexes (unsigned int total) { unsigned int i; // Enable thread safety in OpenSSL - mutex_buf = (CRITICAL_SECTION*) malloc( total * sizeof(CRITICAL_SECTION) ); + mutex_buf = (CRITICAL_SECTION *) malloc(total *sizeof(CRITICAL_SECTION)); - if ( !mutex_buf ) + if (!mutex_buf) return -1; - for ( i = 0; i < total; i++) - InitializeCriticalSection( &(mutex_buf[i]) ); + for (i = 0; i < total; i++) + InitializeCriticalSection(&(mutex_buf[i])); return 0; } @@ -61,86 +61,91 @@ static int alloc_mutexes( unsigned int total ) static pthread_mutex_t * mutex_buf = 0; // 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)line; - if ( mode & CRYPTO_LOCK) - pthread_mutex_lock( &mutex_buf[n] ); + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&mutex_buf[n]); else - pthread_mutex_unlock( &mutex_buf[n] ); + pthread_mutex_unlock(&mutex_buf[n]); } // OpenSSL callback to get the thread ID -static unsigned long cb_openssl_id_function() -{ - return ((unsigned long) pthread_self() ); + +static void cb_openssl_id_function(CRYPTO_THREADID * id) { + CRYPTO_THREADID_set_pointer(id, pthread_self()); } -static int alloc_mutexes( unsigned int total ) -{ +static int alloc_mutexes(unsigned int total) { unsigned i; // 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)); - if ( !mutex_buf ) + if (!mutex_buf) return -1; - for ( i = 0; i < total; i++) - pthread_mutex_init( &(mutex_buf[i]), 0 ); + for (i = 0; i < total; i++) + pthread_mutex_init(&(mutex_buf[i]), 0); return 0; } #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 SSL_load_error_strings(); // Enable thread safety in OpenSSL - if ( alloc_mutexes( CRYPTO_num_locks() ) ) + if (alloc_mutexes( CRYPTO_num_locks())) return LIBIRC_ERR_NOMEM; // Register our callbacks - CRYPTO_set_id_callback( cb_openssl_id_function ); - CRYPTO_set_locking_callback( cb_openssl_locking_function ); + CRYPTO_THREADID_set_callback(cb_openssl_id_function); + CRYPTO_set_locking_callback(cb_openssl_locking_function); // Init it - if ( !SSL_library_init() ) - return LIBIRC_ERR_SSL_INIT_FAILED; +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSL_library_init(); +#else + OPENSSL_init_ssl(0, NULL); +#endif - if ( RAND_status() == 0 ) + if (RAND_status() == 0) return LIBIRC_ERR_SSL_INIT_FAILED; // Create an SSL context; currently a single context is used for all connections - ssl_context = SSL_CTX_new( SSLv23_method() ); + ssl_context = SSL_CTX_new(SSLv23_method()); - if ( !ssl_context ) + if (!ssl_context) return LIBIRC_ERR_SSL_INIT_FAILED; // Disable SSLv2 as it is unsecure - if ( (SSL_CTX_set_options( ssl_context, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) == 0 ) + if ((SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) == 0) return LIBIRC_ERR_SSL_INIT_FAILED; // Enable only strong ciphers - if ( SSL_CTX_set_cipher_list( ssl_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH" ) != 1 ) + if (SSL_CTX_set_cipher_list(ssl_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1) return LIBIRC_ERR_SSL_INIT_FAILED; // Set the verification - if ( session->options & LIBIRC_OPTION_SSL_NO_VERIFY ) - SSL_CTX_set_verify( ssl_context, SSL_VERIFY_NONE, 0 ); + if (session->options & LIBIRC_OPTION_SSL_NO_VERIFY) + SSL_CTX_set_verify(ssl_context, SSL_VERIFY_NONE, 0); else - SSL_CTX_set_verify( ssl_context, SSL_VERIFY_PEER, 0 ); + SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, 0); // 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 - 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; } @@ -155,23 +160,21 @@ static int ssl_init_context( irc_session_t * session ) #endif // 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; #if defined (_WIN32) static HANDLE initmutex = 0; // First time run? Create the mutex - if ( initmutex == 0 ) - { - HANDLE m = CreateMutex( 0, FALSE, 0 ); + if (initmutex == 0) { + HANDLE m = CreateMutex(0, FALSE, 0); // Now we check if the mutex has already been created by another thread performing the init concurrently. // If it was, we close our mutex and use the original one. This could be done synchronously by using the // InterlockedCompareExchangePointer function. - if ( InterlockedCompareExchangePointer( &m, m, 0 ) != 0 ) - CloseHandle( m ); + if (InterlockedCompareExchangePointer(&m, m, 0) != 0) + CloseHandle(m); } #else static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; @@ -181,84 +184,80 @@ static int ssl_init( irc_session_t * session ) // 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 // we do the sabre dance around it. - SSLINIT_LOCK_MUTEX( initmutex ); + SSLINIT_LOCK_MUTEX(initmutex); - if ( ssl_context_initialized == 0 ) - { - int res = ssl_init_context( session ); + if (ssl_context_initialized == 0) { + int res = ssl_init_context(session); - if ( res ) - { - SSLINIT_UNLOCK_MUTEX( initmutex ); + if (res) { + SSLINIT_UNLOCK_MUTEX(initmutex); return res; } ssl_context_initialized = 1; } - SSLINIT_UNLOCK_MUTEX( initmutex ); + SSLINIT_UNLOCK_MUTEX(initmutex); // Get the SSL context - session->ssl = SSL_new( ssl_context ); + session->ssl = SSL_new(ssl_context); - if ( !session->ssl ) + if (!session->ssl) return LIBIRC_ERR_SSL_INIT_FAILED; // 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; // Since we're connecting on our own, tell openssl about it - SSL_set_connect_state( session->ssl ); + SSL_set_connect_state(session->ssl); return 0; } -static void ssl_handle_error( irc_session_t * session, int ssl_error ) -{ - if ( ERR_GET_LIB(ssl_error) == ERR_LIB_SSL ) - { - if ( ERR_GET_REASON(ssl_error) == SSL_R_CERTIFICATE_VERIFY_FAILED ) - { +static void ssl_handle_error (irc_session_t *session, + int ssl_error) { + if (ERR_GET_LIB(ssl_error) == ERR_LIB_SSL) { + if (ERR_GET_REASON(ssl_error) == SSL_R_CERTIFICATE_VERIFY_FAILED) { session->lasterror = LIBIRC_ERR_SSL_CERT_VERIFY_FAILED; 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; return; } } #if defined (ENABLE_DEBUG) - if ( IS_DEBUG_ENABLED(session) ) - 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) ); + if (IS_DEBUG_ENABLED(session)) + 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)); #endif } -static int ssl_recv( irc_session_t * session ) -{ +static int ssl_recv (irc_session_t *session) { int count; unsigned int amount = (sizeof (session->incoming_buf) - 1) - session->incoming_offset; ERR_clear_error(); // 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; - else if ( count == 0 ) + } else if (count == 0) { return -1; // remote connection closed - else - { - int ssl_error = SSL_get_error( session->ssl, count ); + } else { + int ssl_error = SSL_get_error(session->ssl, count); // Handle SSL error since not all of them are actually errors - switch ( ssl_error ) - { + switch (ssl_error) { case SSL_ERROR_WANT_READ: // This is not really an error. We received something, but // OpenSSL gave nothing to us because all it read was @@ -275,30 +274,29 @@ static int ssl_recv( irc_session_t * session ) } // This is an SSL error, handle it - ssl_handle_error( session, ERR_get_error() ); + ssl_handle_error(session, ERR_get_error()); } return -1; } -static int ssl_send( irc_session_t * session ) -{ +static int ssl_send (irc_session_t *session) { int count; 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; - else if ( count == 0 ) + } else if (count == 0) { return -1; - else - { - int ssl_error = SSL_get_error( session->ssl, count ); + } else { + int ssl_error = SSL_get_error(session->ssl, count); - switch ( ssl_error ) - { + switch (ssl_error) { case SSL_ERROR_WANT_READ: // 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. @@ -314,7 +312,7 @@ static int ssl_send( irc_session_t * session ) } // This is an SSL error, handle it - ssl_handle_error( session, ERR_get_error() ); + ssl_handle_error(session, ERR_get_error()); } return -1; @@ -327,31 +325,28 @@ static int ssl_send( irc_session_t * session ) // 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 a positive number if we actually read something -static int session_socket_read( irc_session_t * session ) -{ - int length; +static ssize_t session_socket_read (irc_session_t *session) { + ssize_t length; #if defined (ENABLE_SSL) - if ( session->ssl ) - { + if (session->ssl) { // 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; - ssl_send( session ); + ssl_send(session); return 0; } - return ssl_recv( session ); + return ssl_recv(session); } #endif - length = socket_recv( &session->sock, - session->incoming_buf + session->incoming_offset, - (sizeof (session->incoming_buf) - 1) - session->incoming_offset ); + length = socket_recv(&session->sock, + session->incoming_buf + session->incoming_offset, + (sizeof (session->incoming_buf) - 1) - session->incoming_offset); // There is no "retry" errors for regular sockets - if ( length <= 0 ) + if (length <= 0) return -1; return length; @@ -361,29 +356,28 @@ 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 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 -static int session_socket_write( irc_session_t * session ) -{ - int length; +static ssize_t session_socket_write (irc_session_t *session) { + ssize_t length; #if defined (ENABLE_SSL) - if ( session->ssl ) - { + if (session->ssl) { // Yep - if ( session->flags & SESSIONFL_SSL_WRITE_WANTS_READ ) - { + if (session->flags & SESSIONFL_SSL_WRITE_WANTS_READ) { session->flags &= ~SESSIONFL_SSL_WRITE_WANTS_READ; - ssl_recv( session ); + ssl_recv(session); return 0; } - return ssl_send( session ); + return ssl_send(session); } #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 - if ( length <= 0 ) + if (length <= 0) return -1; return length; diff --git a/libircclient/src/utils.c b/libircclient/src/utils.c index 9305b91..641f053 100644 --- a/libircclient/src/utils.c +++ b/libircclient/src/utils.c @@ -12,19 +12,21 @@ * 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); - if ( *maxfd < fd ) + if (*maxfd < fd) *maxfd = fd; } #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); - for ( ; length > 0; length -- ) + for (; length > 0; length--) printf ("%c", *buf++); } #endif @@ -33,43 +35,45 @@ static void libirc_dump_data (const char * prefix, const char * buf, unsigned in /* * Finds a separator (\x0D\x0A), which separates two lines. */ -static int libirc_findcrlf (const char * buf, int length) -{ - int offset = 0; - for ( ; offset < length; offset++ ) - { - if ( buf[offset] == 0x0D && offset < length - 1 && buf[offset+1] == 0x0A ) +static size_t libirc_findcrlf (const char *buf, + size_t length) { + size_t offset = 0; + for (; offset < length; offset++) { + if ( buf[offset] == 0x0D + && offset < length - 1 + && buf[offset+1] == 0x0A) return offset; - if ( buf[offset] == 0x0A) + if (buf[offset] == 0x0A) return offset; } return 0; } -static int libirc_findcrlf_offset(const char *buf, int offset, const int length) -{ - for(; offset < length; offset++) - { - if(buf[offset] != 0x0D && buf[offset] != 0x0A) - { +static size_t libirc_findcrlf_offset (const char *buf, + size_t offset, + const size_t length) { + for(; offset < length; offset++) { + if ( buf[offset] != 0x0D + && buf[offset] != 0x0A) { break; } } return offset; } -static int libirc_findcrorlf (char * buf, int length) -{ - int offset = 0; - for ( ; offset < length; offset++ ) - { - if ( buf[offset] == 0x0D || buf[offset] == 0x0A ) - { +static size_t libirc_findcrorlf (char *buf, + size_t length) { + size_t offset = 0; + for (; offset < length; offset++) { + if ( buf[offset] == 0x0D + || buf[offset] == 0x0A) { buf[offset++] = '\0'; - if ( offset < (length - 1) - && (buf[offset] == 0x0D || buf[offset] == 0x0A) ) + if ( offset < (length - 1) + && ( buf[offset] == 0x0D + || buf[offset] == 0x0A) + ) offset++; return offset; @@ -80,48 +84,44 @@ 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) -{ - (void)event; - (void)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) count; - if ( origin ) - { + if (origin) { char nickbuf[128], textbuf[256]; 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]); - else if ( !strcmp (params[0], "VERSION") ) - { - if ( !session->ctcp_version ) - { + } else if (!strcmp (params[0], "VERSION")) { + if (!session->ctcp_version) { unsigned int high, low; irc_get_version (&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); + } 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", session->username ? session->username : "nobody", session->realname ? session->realname : "noname"); irc_cmd_ctcp_reply (session, nickbuf, textbuf); - } - else if ( !strcmp (params[0], "TIME") ) - { + } else if (!strcmp (params[0], "TIME")) { time_t now = time(0); #if defined (ENABLE_THREADS) && defined (HAVE_LOCALTIME_R) struct tm tmtmp, *ltime = localtime_r (&now, &tmtmp); #else - struct tm * ltime = localtime (&now); + struct tm *ltime = localtime (&now); #endif strftime (textbuf, sizeof(textbuf), "%a %b %d %H:%M:%S %Z %Y", ltime); irc_cmd_ctcp_reply (session, nickbuf, textbuf);