summaryrefslogtreecommitdiffstats
path: root/ircxmpp.h
blob: 19cf1c90f69d64a3f2d2090487fb900ab95f5574 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#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