| @@ -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 <inttypes.h> 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 <memory.h> 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 <stdint.h> header file. */ | |||
| /* #undef HAVE_STDINT_H */ | |||
| #define HAVE_STDINT_H 1 | |||
| /* Define to 1 if you have the <stdlib.h> header file. */ | |||
| /* #undef HAVE_STDLIB_H */ | |||
| #define HAVE_STDLIB_H 1 | |||
| /* Define to 1 if you have the <strings.h> header file. */ | |||
| /* #undef HAVE_STRINGS_H */ | |||
| #define HAVE_STRINGS_H 1 | |||
| /* Define to 1 if you have the <string.h> header file. */ | |||
| /* #undef HAVE_STRING_H */ | |||
| #define HAVE_STRING_H 1 | |||
| /* Define to 1 if you have the <sys/select.h> header file. */ | |||
| /* #undef HAVE_SYS_SELECT_H */ | |||
| #define HAVE_SYS_SELECT_H 1 | |||
| /* Define to 1 if you have the <sys/socket.h> header file. */ | |||
| /* #undef HAVE_SYS_SOCKET_H */ | |||
| #define HAVE_SYS_SOCKET_H 1 | |||
| /* Define to 1 if you have the <sys/stat.h> header file. */ | |||
| /* #undef HAVE_SYS_STAT_H */ | |||
| #define HAVE_SYS_STAT_H 1 | |||
| /* Define to 1 if you have the <sys/types.h> header file. */ | |||
| /* #undef HAVE_SYS_TYPES_H */ | |||
| #define HAVE_SYS_TYPES_H 1 | |||
| /* Define to 1 if you have the <unistd.h> header file. */ | |||
| /* #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 <sys/time.h> and <time.h>. */ | |||
| /* #undef TIME_WITH_SYS_TIME */ | |||
| #define TIME_WITH_SYS_TIME 1 | |||
| /* Define to empty if `const' does not conform to ANSI C. */ | |||
| /* #undef const */ | |||
| @@ -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; | |||
| @@ -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. | |||
| @@ -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 */ | |||
| @@ -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 <stdlib.h> | |||
| #if !defined (WIN32) | |||
| #if !defined (_WIN32) | |||
| #include <sys/select.h> /* fd_set */ | |||
| #else | |||
| #include <winsock2.h> | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -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 | |||
| }; | |||
| @@ -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; | |||
| 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; | |||
| 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_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); | |||
| p++; | |||
| } | |||
| 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_UNDERLINE, "[U]", "[/U]"); | |||
| break; | |||
| } | |||
| case 0x16: { // reverse | |||
| if (strip) | |||
| continue; | |||
| // If there is a comma, search for the following | |||
| // background color | |||
| if ( p[1] == ',' && isdigit (p[2]) ) | |||
| { | |||
| bgcolor = p[2] - 0x30; | |||
| p += 2; | |||
| libirc_colorparser_applymask(&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]"); | |||
| break; | |||
| } | |||
| case 0x0F: { // reset colors | |||
| if (strip) | |||
| continue; | |||
| if ( isdigit (p[1]) ) | |||
| { | |||
| bgcolor = bgcolor * 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 (isdigit (p[1])) { | |||
| color = color * 10 + (p[1] - 0x30); | |||
| p++; | |||
| } | |||
| } | |||
| // Check for range | |||
| if ( color <= LIBIRC_COLORPARSER_MAXCOLORS | |||
| && bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS ) | |||
| { | |||
| if ( strip ) | |||
| continue; | |||
| // 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 = bgcolor; | |||
| if (bgcolor != -1) | |||
| current_bg = (unsigned int) bgcolor; | |||
| libirc_colorparser_applycolor (&mask, &d, &destlen, color, current_bg); | |||
| libirc_colorparser_applycolor(&mask, &d, &destlen, (unsigned int) max(color, 0), current_bg); | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| 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); | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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,15 +125,15 @@ 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 ) | |||
| { | |||
| while ((length = recv(*sock, buf, len, 0)) < 0) { | |||
| int err = socket_error(); | |||
| if ( err != EINTR && err != EAGAIN ) | |||
| if (err != EINTR && err != EAGAIN) | |||
| break; | |||
| } | |||
| @@ -143,12 +141,12 @@ static int socket_recv (socket_t * sock, void * buf, size_t len) | |||
| } | |||
| static int socket_send (socket_t * sock, const void *buf, size_t len) | |||
| { | |||
| int 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 ) | |||
| { | |||
| while ((length = send(*sock, buf, len, 0)) < 0) { | |||
| int err = socket_error(); | |||
| if ( err != EINTR && err != EAGAIN ) | |||
| @@ -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; | |||
| @@ -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); | |||