#define IX_S0(x) (x ? x : "") enum ircxmpp_loglevel { IRCXMPP_DEBUG, IRCXMPP_INFO, IRCXMPP_WARN, IRCXMPP_ERROR }; typedef void (* ircxmpp_logger) (void * const, const enum ircxmpp_loglevel, const char * const, const char * const); typedef void (* ircxmpp_domain_setter) (void *, const char *); #ifdef IX_LIB /* do not use functions until #endif in programs that use libircxmpp. */ #include /* do not use members of struct ircxmpp, use opaque ircxmpp type! */ #include #include #define ISA(type, name) type * name; size_t name##_sizeof; size_t name##_length #define ALLOC_CHUNK 1 // \\ note: this ISA is array of type not array of type * #define REALLOC_K 1.5 #define BIGGER_ARRAY(name) do { \ name = realloc(name, sizeof(name[0])*ceil(name##_sizeof*REALLOC_K)); \ for (int BA = name##_sizeof; BA < ceil(name##_sizeof*REALLOC_K); BA++) \ name[BA] = NULL; \ name##_sizeof = ceil(name##_sizeof*REALLOC_K); \ } while (0) #define MR(n) if (n##_sizeof <= n##_length) /* make room */ \ BIGGER_ARRAY(n) enum irc_numeric { /* numerics from rfc 1459 */ ERR_NOSUCHNICK = 401, ERR_NOSUCHSERVER, ERR_NOSUCHCHANNEL, ERR_CANNOTSENDTOCHAN, ERR_TOOMANYCHANNELS, ERR_WASNOSUCHNICK, ERR_TOOMANYTARGETS, ERR_NOORIGIN = 409, ERR_NORECIPIENT = 411, ERR_NOTEXTTOSEND, ERR_NOTOPLEVEL, ERR_WILDTOPLEVEL, ERR_UNKNOWNCOMMAND = 421, ERR_NOMOTD, ERR_NOADMININFO, ERR_FILEERROR, ERR_NONICKNAMEGIVEN = 431, ERR_ERRONEUSNICKNAME, ERR_NICKNAMEINUSE, ERR_NICKCOLLISION = 436, ERR_USERNOTINCHANNEL = 441, ERR_NOTONCHANNEL, ERR_USERONCHANNEL, ERR_NOLOGIN, ERR_SUMMONDISABLED, ERR_USERDISABLED, ERR_NOTREGISTERED = 451, ERR_NEEDMOREPARAMS = 461, ERR_ALREADYREGISTERED, ERR_NOPERMFORHOST, ERR_PASSWDMISMATCH, ERR_YOUREBANNEDCREEP, ERR_KEYSET = 467, ERR_CHANNELISFULL = 471, ERR_UNKNOWNMODE, ERR_INVITEONLYCHAN, ERR_BANNEDFROMCHAN, ERR_BADCHANNELKEY, ERR_NOPRIVILEGES = 481, ERR_CHANOPRIVSNEEDED, ERR_CANTKILLSERVER, ERR_NOOPERHOST = 491, ERR_UMODEUNKNOWNFLAG = 501, ERR_USERSDONTMATCH, RPL_NONE = 300, RPL_AWAY, RPL_USERHOST, RPL_ISON, RPL_UNAWAY, RPL_NOWAWAY, RPL_WHOISUSER = 311, RPL_WHOISSERVER, RPL_WHOISOPERATOR, RPL_WHOISIDLE = 317, RPL_ENDOFWHOIS, RPL_WHOISCHANNELS, RPL_WHOWASUSER = 314, RPL_ENDOFWHOWAS = 369, RPL_LISTSTART = 321, RPL_LIST, RPL_LISTEND, RPL_CHANNELMODEIS, RPL_NOTOPIC = 331, RPL_TOPIC, RPL_INVITING = 341, RPL_SUMMONING = 342, RPL_VERSION = 351, RPL_WHOREPLY = 352, RPL_ENDOFWHO = 315, RPL_NAMREPLY = 353, RPL_ENDOFNAMES = 366, RPL_LINKS = 364, RPL_ENDOFLINKS, RPL_BANLIST = 367, RPL_ENDOFBANLIST, RPL_INFO = 371, RPL_ENDOFINFO = 374, RPL_MOTDSTART, RPL_MOTD = 372, RPL_ENDOFMOTD = 376, RPL_YOUREOPER = 381, RPL_REHASHING = 382, RPL_TIME = 391, RPL_USERSSTART, RPL_USERS, RPL_ENDOFUSERS, RPL_NOUSERS, RPL_TRACELINK = 200, RPL_TRACECONNECTING, RPL_TRACEHANDSHAKE, RPL_TRACEUNKNOWN, RPL_TRACEOPERATOR, RPL_TRACEUSER, RPL_TRACESERVER, RPL_TRACENEWTYPE = 208, RPL_TRACELOG = 261, RPL_STATSLINKINFO = 211, RPL_STATSCOMMANDS, RPL_STATSCLINE, RPL_STATSNLINE, RPL_STATSILINE, RPL_STATSKLINE, RPL_STATSYLINE = 218, RPL_ENDOFSTATS, RPL_STATSLLINE = 241, RPL_STATSUPTIME, RPL_STATSOLINE, RPL_STATSHLINE, RPL_UMODEIS = 221, RPL_LUSERCLIENT = 251, RPL_LUSEROP, RPL_LUSERUNKNOWN, RPL_LUSERCHANNELS, RPL_LUSERME, RPL_ADMINME, RPL_ADMINLOC1, RPL_ADMINLOC2, RPL_ADMINEMAIL, RPL_TRACECLASS = 209, RPL_SERVICEINFO = 231, RPL_SERVICE = 233, RPL_SERVLISTEND = 235, RPL_WHOISCHANOP = 316, RPL_CLOSING = 362, RPL_INFOSTART = 373, ERR_YOUWILLBEBANNED = 466, ERR_NOSERVICEHOST = 492, RPL_STATSQLINE = 217, RPL_ENDOFSERVICES = 232, RPL_SERVLIST = 234, RPL_KILLDONE = 361, RPL_CLOSEEND = 363, RPL_MYPORTIS = 384, ERR_BADCHANMASK = 476 }; enum side { IRC, XMPP }; struct bridge { // xmpp connection is the same for every user, only IRC connection differs struct ircxmpp * ircxmpp; char * identifier; /* jid if side is XMPP or nickname if side is IRC */ irc_session_t * irc; xmpp_conn_t * conn; /* isti xmpp_ctx_t ima lahko več connov */ enum side side; /* which side is the real user */ size_t messages_length; char ** messages; }; struct ircxmpp { void * bridges; irc_session_t * irc; char * ircnick; char * irchost; xmpp_ctx_t * ctx; xmpp_conn_t * conn; char * jid; char * password; char * hostname; int port; char * channel; char * muc; char * channel_password; void * log_userdata; ircxmpp_logger log_handler; xmpp_log_t xmpp_logger; ircxmpp_domain_setter domain_setter; void * domain_setter_userdata; char * domain; ISA(struct bridge *, to_free_bridges); ISA(char *, to_free_reasons); // static reason strings, do not free them }; static void send_xmpp_logs_to_me ( void * const, const xmpp_log_level_t, const char * const, const char * const); static void logwrite (struct ircxmpp *, enum ircxmpp_loglevel, const char *, int, const char *, const char *, ...); static int bridge_compare (const void *, const void *); static void free_bridge (struct bridge *, const char *); static void free_bridges (void **); static void free_bridge_from_tdestroy (void *); static struct bridge * find_bridge (void **, const char *, enum side); static void jid2ircnick (char *); static void jid2ircuser (char *); static void bridge_forward (const char *, const char *, struct ircxmpp *, enum side); static int message_handler (xmpp_conn_t * const, xmpp_stanza_t * const, void * const); static int presence_handler (xmpp_conn_t * const, xmpp_stanza_t * const, void * const); static void conn_handler (xmpp_conn_t * const, const xmpp_conn_event_t, const int, xmpp_stream_error_t * const, void * const); static void conn_handler_bridge (xmpp_conn_t * const, const xmpp_conn_event_t, const int, xmpp_stream_error_t * const, void * const); // IRC static void dump_event_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void dump_event (irc_session_t *, const char *, const char *, const char **, unsigned); static void event_connect (irc_session_t *, const char *, const char *, const char **, unsigned); static void event_connect_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void event_privmsg (irc_session_t *, const char *, const char *, const char **, unsigned); static void event_partquit_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void event_join_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void event_channel_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void event_nick_control(irc_session_t *, const char *, const char *, const char **, unsigned); static void event_topic_control ( irc_session_t *, const char *, const char *, const char **, unsigned); static void event_numeric ( irc_session_t *, unsigned int, const char *, const char **, unsigned); static void event_numeric_control ( irc_session_t *, unsigned int, const char *, const char **, unsigned); static int irc_run_once (struct bridge *); static void init_irc (struct bridge *); static void init_irc_control (struct ircxmpp *); // /IRC static void obdelaj_bridge (const void *, VISIT, int); static void default_log_handler ( void * const, const enum ircxmpp_loglevel, const char * const, const char * const); static void default_domain_setter (void *, const char *); #endif // IX_LIB // ZUNANJE typedef struct ircxmpp ircxmpp; /* opaque handle */ ircxmpp * ircxmpp_init (void); void ircxmpp_set_log_handler (ircxmpp *, ircxmpp_logger); void ircxmpp_set_log_userdata (ircxmpp *, void *); void ircxmpp_set_jid (ircxmpp *, const char *); void ircxmpp_set_password (ircxmpp *, const char *); void ircxmpp_set_hostname (ircxmpp *, const char *); void ircxmpp_set_port (ircxmpp *, unsigned short int); void ircxmpp_set_channel (ircxmpp *, const char *); void ircxmpp_set_muc (ircxmpp *, const char *); void ircxmpp_set_channel_password (ircxmpp *, const char *); void ircxmpp_set_domain_setter (ircxmpp *, ircxmpp_domain_setter); void ircxmpp_set_domain_setter_userdata (ircxmpp *, void *); void ircxmpp_set_domain (ircxmpp *, const char *); void ircxmpp_run_once (ircxmpp *); void ircxmpp_free (ircxmpp *); // /ZUNANJE