#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 <libircclient.h> /* do not use members of struct ircxmpp, use opaque ircxmpp type! */
#include <strophe.h>
#include <math.h>
#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