File: irc.h

package info (click to toggle)
bitlbee 3.6-1.2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,320 kB
  • sloc: ansic: 29,135; xml: 2,282; sh: 905; makefile: 427; python: 221; perl: 41
file content (380 lines) | stat: -rw-r--r-- 13,596 bytes parent folder | download | duplicates (3)
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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2002-2013 Wilmer van der Gaast and others                *
  \********************************************************************/

/* The IRC-based UI (for now the only one)                              */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License with
  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
  Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef _IRC_H
#define _IRC_H

#include <sys/socket.h>

#define IRC_MAX_LINE 512
#define IRC_MAX_ARGS 16
#define IRC_WORD_WRAP 425

#define IRC_LOGIN_TIMEOUT 60
#define IRC_PING_STRING "PinglBee"

#define UMODES "abisw"     /* Allowed umodes (although they mostly do nothing) */
#define UMODES_PRIV "Ro"   /* Allowed, but not by user directly */
#define UMODES_KEEP "R"    /* Don't allow unsetting using /MODE */
#define CMODES "ntC"       /* Allowed modes */
#define CMODE "t"          /* Default mode */
#define UMODE "s"          /* Default mode */

#define CTYPES "&#"        /* Valid channel name prefixes */

typedef enum {
	USTATUS_OFFLINE = 0,
	USTATUS_AUTHORIZED = 1, /* Gave the correct server password (PASS). */
	USTATUS_LOGGED_IN = 2,  /* USER+NICK(+PASS) finished. */
	USTATUS_IDENTIFIED = 4, /* To NickServ (root). */
	USTATUS_SHUTDOWN = 8,   /* Now used to indicate we're shutting down.
	                           Currently just blocks irc_vawrite(). */
	USTATUS_CAP_PENDING = 16,
	USTATUS_SASL_PLAIN_PENDING = 32,

	/* Not really status stuff, but other kinds of flags: For slightly
	   better password security, since the only way to send passwords
	   to the IRC server securely (i.e. not echoing to screen or written
	   to logfiles) is the /OPER command, try to use that command for
	   stuff that matters. */
	OPER_HACK_IDENTIFY = 0x100,
	OPER_HACK_IDENTIFY_NOLOAD = 0x01100,
	OPER_HACK_IDENTIFY_FORCE  = 0x02100,
	OPER_HACK_REGISTER = 0x200,
	OPER_HACK_ACCOUNT_PASSWORD = 0x400,
	OPER_HACK_ANY = 0x3700, /* To check for them all at once. */

	IRC_UTF8_NICKS = 0x10000, /* Disable ASCII restrictions on buddy nicks. */
} irc_status_t;

typedef enum {
	CAP_SASL = (1 << 0),
	CAP_MULTI_PREFIX = (1 << 1),
	CAP_EXTENDED_JOIN = (1 << 2),
	CAP_AWAY_NOTIFY = (1 << 3),
	CAP_USERHOST_IN_NAMES = (1 << 4),
	CAP_SERVER_TIME = (1 << 5),
} irc_cap_flag_t;

struct irc_user;

typedef struct irc {
	int fd;
	irc_status_t status;
	double last_pong;
	int pinging;
	GString *sendbuffer;
	char *readbuffer;
	GIConv iconv, oconv;

	struct irc_user *root;
	struct irc_user *user;

	char *password; /* HACK: Used to save the user's password, but before
	                   logging in, this may contain a password we should
	                   send to identify after USER/NICK are received. */
	char *auth_backend;

	char umode[8];

	struct query *queries;
	GSList *file_transfers;

	GSList *users G_GNUC_DEPRECATED;
	GSList *channels;
	struct irc_channel *default_channel;
	GHashTable *nick_user_hash;
	GHashTable *watches; /* See irc_cmd_watch() */

	gint r_watch_source_id;
	gint w_watch_source_id;
	gint ping_source_id;
	gint login_source_id; /* To slightly delay some events at login time. */

	struct otr *otr; /* OTR state and book keeping, used by the OTR plugin.
	                    TODO: Some mechanism for plugindata. */

	struct bee *b;
	guint32 caps;
} irc_t;

typedef enum {
	/* Replaced with iu->last_channel IRC_USER_PRIVATE = 1, */
	IRC_USER_AWAY = 2,

	IRC_USER_OTR_ENCRYPTED = 0x10000,
	IRC_USER_OTR_TRUSTED   = 0x20000,
} irc_user_flags_t;

typedef struct irc_user {
	irc_t *irc;

	char *nick;
	char *user;
	char *host;
	char *fullname;

	/* Nickname in lowercase for case insensitive searches */
	char *key;

	irc_user_flags_t flags;
	struct irc_channel *last_channel;

	GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */
	guint pastebuf_timer;
	time_t away_reply_timeout; /* Only send a 301 if this time passed. */

	struct bee_user *bu;

	const struct irc_user_funcs *f;
} irc_user_t;

struct irc_user_funcs {
	gboolean (*privmsg)(irc_user_t *iu, const char *msg);
	gboolean (*ctcp)(irc_user_t *iu, char * const* ctcp);
};

extern const struct irc_user_funcs irc_user_root_funcs;
extern const struct irc_user_funcs irc_user_self_funcs;

typedef enum {
	IRC_CHANNEL_JOINED = 1, /* The user is currently in the channel. */
	IRC_CHANNEL_TEMP = 2,   /* Erase the channel when the user leaves,
	                           and don't save it. */

	/* Hack: Set this flag right before jumping into IM when we expect
	   a call to imcb_chat_new(). */
	IRC_CHANNEL_CHAT_PICKME = 0x10000,
} irc_channel_flags_t;

typedef struct irc_channel {
	irc_t *irc;
	char *name;
	char mode[8];
	int flags;

	char *topic;
	char *topic_who;
	time_t topic_time;

	GSList *users; /* struct irc_channel_user */
	struct irc_user *last_target;
	struct set *set;

	GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */
	guint pastebuf_timer;

	const struct irc_channel_funcs *f;
	void *data;
} irc_channel_t;

struct irc_channel_funcs {
	gboolean (*privmsg)(irc_channel_t *ic, const char *msg);
	gboolean (*join)(irc_channel_t *ic);
	gboolean (*part)(irc_channel_t *ic, const char *msg);
	gboolean (*topic)(irc_channel_t *ic, const char *new_topic);
	gboolean (*invite)(irc_channel_t *ic, irc_user_t *iu);
	void (*kick)(irc_channel_t *ic, irc_user_t *iu, const char *msg);

	gboolean (*_init)(irc_channel_t *ic);
	gboolean (*_free)(irc_channel_t *ic);
};

typedef enum {
	IRC_CHANNEL_USER_OP = 1,
	IRC_CHANNEL_USER_HALFOP = 2,
	IRC_CHANNEL_USER_VOICE = 4,
	IRC_CHANNEL_USER_NONE = 8,
} irc_channel_user_flags_t;

typedef struct irc_channel_user {
	irc_user_t *iu;
	int flags;
} irc_channel_user_t;

typedef enum {
	IRC_CC_TYPE_DEFAULT  = 0x00001,
	IRC_CC_TYPE_REST     = 0x00002, /* Still not implemented. */
	IRC_CC_TYPE_GROUP    = 0x00004,
	IRC_CC_TYPE_ACCOUNT  = 0x00008,
	IRC_CC_TYPE_PROTOCOL = 0x00010,
	IRC_CC_TYPE_MASK     = 0x000ff,
	IRC_CC_TYPE_INVERT   = 0x00100,
} irc_control_channel_type_t;

struct irc_control_channel {
	irc_control_channel_type_t type;
	struct bee_group *group;
	struct account *account;
	struct prpl *protocol;
	char modes[5];
};

extern const struct bee_ui_funcs irc_ui_funcs;

typedef enum {
	IRC_CDU_SILENT,
	IRC_CDU_PART,
	IRC_CDU_KICK,
} irc_channel_del_user_type_t;

/* These are a glued a little bit to the core/bee layer and a little bit to
   IRC. The first user is OTR, and I guess at some point we'll get to shape
   this a little bit more as other uses come up. */
typedef struct irc_plugin {
	/* Called at the end of irc_new(). Can be used to add settings, etc. */
	gboolean (*irc_new)(irc_t *irc);
	/* At the end of irc_free(). */
	void (*irc_free)(irc_t *irc);

	/* Problem with the following two functions is ordering if multiple
	   plugins are handling them. Let's keep fixing that problem for
	   whenever it becomes important. */

	/* Called by bee_irc_user_privmsg_cb(). Return NULL if you want to
	   abort sending the msg. */
	char* (*filter_msg_out)(irc_user_t * iu, char *msg, int flags);
	/* Called by bee_irc_user_msg(). Return NULL if you swallowed the
	   message and don't want anything to go to the user. */
	char* (*filter_msg_in)(irc_user_t * iu, char *msg, int flags);

	/* From storage.c functions. Ideally these should not be used
	   and instead data should be stored in settings which will get
	   saved automatically. Consider these deprecated! */
	void (*storage_load)(irc_t *irc);
	void (*storage_save)(irc_t *irc);
	void (*storage_remove)(const char *nick);
} irc_plugin_t;

extern GSList *irc_plugins; /* struct irc_plugin */

/* irc.c */
extern GSList *irc_connection_list;

irc_t *irc_new(int fd);
void irc_set_hosts(irc_t *irc, const struct sockaddr *remote_addr, const socklen_t remote_addrlen);
void irc_abort(irc_t *irc, int immed, char *format, ...) G_GNUC_PRINTF(3, 4);
void irc_free(irc_t *irc);
void irc_setpass(irc_t *irc, const char *pass);

void irc_process(irc_t *irc);
char **irc_parse_line(char *line);
char *irc_build_line(char **cmd);

void irc_write(irc_t *irc, char *format, ...) G_GNUC_PRINTF(2, 3);
void irc_write_all(int now, char *format, ...) G_GNUC_PRINTF(2, 3);
void irc_vawrite(irc_t *irc, char *format, va_list params);

void irc_flush(irc_t *irc);
void irc_switch_fd(irc_t *irc, int fd);
void irc_sync(irc_t *irc);
void irc_desync(irc_t *irc);

int irc_check_login(irc_t *irc);

void irc_umode_set(irc_t *irc, const char *s, gboolean allow_priv);

void register_irc_plugin(const struct irc_plugin *p);

/* irc_channel.c */
irc_channel_t *irc_channel_new(irc_t *irc, const char *name);
irc_channel_t *irc_channel_by_name(irc_t *irc, const char *name);
irc_channel_t *irc_channel_get(irc_t *irc, char *id);
int irc_channel_free(irc_channel_t *ic);
void irc_channel_free_soon(irc_channel_t *ic);
int irc_channel_add_user(irc_channel_t *ic, irc_user_t *iu);
int irc_channel_del_user(irc_channel_t *ic, irc_user_t *iu, irc_channel_del_user_type_t type, const char *msg);
irc_channel_user_t *irc_channel_has_user(irc_channel_t *ic, irc_user_t *iu);
struct irc_channel *irc_channel_with_user(irc_t *irc, irc_user_t *iu);
int irc_channel_set_topic(irc_channel_t *ic, const char *topic, const irc_user_t *who);
void irc_channel_user_set_mode(irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags);
void irc_channel_set_mode(irc_channel_t *ic, const char *s);
void irc_channel_auto_joins(irc_t *irc, struct account *acc);
void irc_channel_printf(irc_channel_t *ic, char *format, ...) G_GNUC_PRINTF(2, 3);
gboolean irc_channel_name_ok(const char *name);
void irc_channel_name_strip(char *name);
int irc_channel_name_cmp(const char *a_, const char *b_);
char *irc_channel_name_gen(irc_t *irc, const char *name);
gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name);
void irc_channel_update_ops(irc_channel_t *ic, char *value);
char irc_channel_user_get_prefix(irc_channel_user_t *icu);
char *set_eval_irc_channel_ops(struct set *set, char *value);
gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu);

/* irc_commands.c */
void irc_exec(irc_t *irc, char **cmd);

/* irc_send.c */
void irc_send_num(irc_t *irc, int code, char *format, ...) G_GNUC_PRINTF(3, 4);
void irc_send_login(irc_t *irc);
void irc_send_motd(irc_t *irc);
const char *irc_user_msgdest(irc_user_t *iu);
void irc_rootmsg(irc_t *irc, char *format, ...) G_GNUC_PRINTF(2, 3);
void irc_usermsg(irc_user_t *iu, char *format, ...) G_GNUC_PRINTF(2, 3);
void irc_usernotice(irc_user_t *iu, char *format, ...) G_GNUC_PRINTF(2, 3);
void irc_send_join(irc_channel_t *ic, irc_user_t *iu);
void irc_send_part(irc_channel_t *ic, irc_user_t *iu, const char *reason);
void irc_send_quit(irc_user_t *iu, const char *reason);
void irc_send_kick(irc_channel_t *ic, irc_user_t *iu, irc_user_t *kicker, const char *reason);
void irc_send_names(irc_channel_t *ic);
void irc_send_topic(irc_channel_t *ic, gboolean topic_change);
void irc_send_whois(irc_user_t *iu);
void irc_send_who(irc_t *irc, GSList *l, const char *channel);
void irc_send_msg(irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix);
void irc_send_msg_raw(irc_user_t *iu, const char *type, const char *dst, const char *msg);
void irc_send_msg_f(irc_user_t *iu, const char *type, const char *dst, const char *format, ...) G_GNUC_PRINTF(4, 5);
void irc_send_nick(irc_user_t *iu, const char *new_nick);
void irc_send_channel_user_mode_diff(irc_channel_t *ic, irc_user_t *iu,
                                     irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags);
void irc_send_invite(irc_user_t *iu, irc_channel_t *ic);
void irc_send_cap(irc_t *irc, char *subcommand, char *body);
void irc_send_away_notify(irc_user_t *iu);

G_GNUC_INTERNAL void irc_send_msg_ts(irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix, time_t ts);
G_GNUC_INTERNAL void irc_send_msg_raw_tags(irc_user_t *iu, const char *type, const char *dst, const char* tags, const char *msg);

/* irc_user.c */
irc_user_t *irc_user_new(irc_t *irc, const char *nick);
int irc_user_free(irc_t *irc, irc_user_t *iu);
irc_user_t *irc_user_by_name(irc_t *irc, const char *nick);
int irc_user_set_nick(irc_user_t *iu, const char *new_nick);
gint irc_user_cmp(gconstpointer a_, gconstpointer b_);
const char *irc_user_get_away(irc_user_t *iu);
void irc_user_quit(irc_user_t *iu, const char *msg);

/* irc_util.c */
char *set_eval_timezone(struct set *set, char *value);
char *irc_format_timestamp(irc_t *irc, time_t msg_ts);
G_GNUC_INTERNAL char *irc_format_servertime(irc_t *irc, time_t msg_ts);
char *set_eval_self_messages(struct set *set, char *value);

/* irc_im.c */
void bee_irc_channel_update(irc_t *irc, irc_channel_t *ic, irc_user_t *iu);
void bee_irc_user_nick_reset(irc_user_t *iu);

/* irc_cap.c */
void irc_cmd_cap(irc_t *irc, char **cmd);

#endif