source: irc.h @ 129e282

Last change on this file since 129e282 was 345577b, checked in by dequis <dx@…>, at 2015-10-30T10:27:20Z

IRC self-message support (messages sent by yourself from other clients)

This adds an OPT_SELFMESSAGE flag that can be passed to imcb_buddy_msg()
or imcb_chat_msg() to indicate that the protocol knows that the message
being sent is a self message.

This needs to be explicit since the old behavior is to silently drop
these messages, which also removed server echoes.

This commit doesn't break API/ABI, the flags parameters that were added
are all internal (between protocols and UI code)

On the irc protocol side, the situation isn't very nice, since some
clients put these messages in the wrong window. Irssi, hexchat and mirc
get this wrong. Irssi 0.8.18 has a fix for it, and the others have
scripts to patch it.

But meanwhile, there's a "self_messages" global setting that lets users
disable this, or get them as normal messages / notices with a "->"
prefix, which loosely imitates the workaround used by the ZNC
"privmsg_prefix" module.

  • Property mode set to 100644
File size: 12.5 KB
Line 
1/********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* The IRC-based UI (for now the only one)                              */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
24*/
25
26#ifndef _IRC_H
27#define _IRC_H
28
29#define IRC_MAX_LINE 512
30#define IRC_MAX_ARGS 16
31
32#define IRC_LOGIN_TIMEOUT 60
33#define IRC_PING_STRING "PinglBee"
34
35#define UMODES "abisw"     /* Allowed umodes (although they mostly do nothing) */
36#define UMODES_PRIV "Ro"   /* Allowed, but not by user directly */
37#define UMODES_KEEP "R"    /* Don't allow unsetting using /MODE */
38#define CMODES "ntC"       /* Allowed modes */
39#define CMODE "t"          /* Default mode */
40#define UMODE "s"          /* Default mode */
41
42#define CTYPES "&#"        /* Valid channel name prefixes */
43
44typedef enum {
45        USTATUS_OFFLINE = 0,
46        USTATUS_AUTHORIZED = 1, /* Gave the correct server password (PASS). */
47        USTATUS_LOGGED_IN = 2,  /* USER+NICK(+PASS) finished. */
48        USTATUS_IDENTIFIED = 4, /* To NickServ (root). */
49        USTATUS_SHUTDOWN = 8,   /* Now used to indicate we're shutting down.
50                                   Currently just blocks irc_vawrite(). */
51        USTATUS_CAP_PENDING = 16,
52        USTATUS_SASL_PLAIN_PENDING = 32,
53
54        /* Not really status stuff, but other kinds of flags: For slightly
55           better password security, since the only way to send passwords
56           to the IRC server securely (i.e. not echoing to screen or written
57           to logfiles) is the /OPER command, try to use that command for
58           stuff that matters. */
59        OPER_HACK_IDENTIFY = 0x100,
60        OPER_HACK_IDENTIFY_NOLOAD = 0x01100,
61        OPER_HACK_IDENTIFY_FORCE  = 0x02100,
62        OPER_HACK_REGISTER = 0x200,
63        OPER_HACK_ACCOUNT_PASSWORD = 0x400,
64        OPER_HACK_ANY = 0x3700, /* To check for them all at once. */
65
66        IRC_UTF8_NICKS = 0x10000, /* Disable ASCII restrictions on buddy nicks. */
67} irc_status_t;
68
69typedef enum {
70        CAP_SASL = (1 << 0),
71        CAP_MULTI_PREFIX = (1 << 1),
72} irc_cap_flag_t;
73
74struct irc_user;
75
76typedef struct irc {
77        int fd;
78        irc_status_t status;
79        double last_pong;
80        int pinging;
81        char *sendbuffer;
82        char *readbuffer;
83        GIConv iconv, oconv;
84
85        struct irc_user *root;
86        struct irc_user *user;
87
88        char *password; /* HACK: Used to save the user's password, but before
89                           logging in, this may contain a password we should
90                           send to identify after USER/NICK are received. */
91
92        char umode[8];
93
94        struct query *queries;
95        GSList *file_transfers;
96
97        GSList *users, *channels;
98        struct irc_channel *default_channel;
99        GHashTable *nick_user_hash;
100        GHashTable *watches; /* See irc_cmd_watch() */
101
102        gint r_watch_source_id;
103        gint w_watch_source_id;
104        gint ping_source_id;
105        gint login_source_id; /* To slightly delay some events at login time. */
106
107        struct otr *otr; /* OTR state and book keeping, used by the OTR plugin.
108                            TODO: Some mechanism for plugindata. */
109
110        struct bee *b;
111        guint32 caps;
112} irc_t;
113
114typedef enum {
115        /* Replaced with iu->last_channel IRC_USER_PRIVATE = 1, */
116        IRC_USER_AWAY = 2,
117
118        IRC_USER_OTR_ENCRYPTED = 0x10000,
119        IRC_USER_OTR_TRUSTED   = 0x20000,
120} irc_user_flags_t;
121
122typedef struct irc_user {
123        irc_t *irc;
124
125        char *nick;
126        char *user;
127        char *host;
128        char *fullname;
129
130        /* Nickname in lowercase for case insensitive searches */
131        char *key;
132
133        irc_user_flags_t flags;
134        struct irc_channel *last_channel;
135
136        GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */
137        guint pastebuf_timer;
138        time_t away_reply_timeout; /* Only send a 301 if this time passed. */
139
140        struct bee_user *bu;
141
142        const struct irc_user_funcs *f;
143} irc_user_t;
144
145struct irc_user_funcs {
146        gboolean (*privmsg)(irc_user_t *iu, const char *msg);
147        gboolean (*ctcp)(irc_user_t *iu, char * const* ctcp);
148};
149
150extern const struct irc_user_funcs irc_user_root_funcs;
151extern const struct irc_user_funcs irc_user_self_funcs;
152
153typedef enum {
154        IRC_CHANNEL_JOINED = 1, /* The user is currently in the channel. */
155        IRC_CHANNEL_TEMP = 2,   /* Erase the channel when the user leaves,
156                                   and don't save it. */
157
158        /* Hack: Set this flag right before jumping into IM when we expect
159           a call to imcb_chat_new(). */
160        IRC_CHANNEL_CHAT_PICKME = 0x10000,
161} irc_channel_flags_t;
162
163typedef struct irc_channel {
164        irc_t *irc;
165        char *name;
166        char mode[8];
167        int flags;
168
169        char *topic;
170        char *topic_who;
171        time_t topic_time;
172
173        GSList *users; /* struct irc_channel_user */
174        struct irc_user *last_target;
175        struct set *set;
176
177        GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */
178        guint pastebuf_timer;
179
180        const struct irc_channel_funcs *f;
181        void *data;
182} irc_channel_t;
183
184struct irc_channel_funcs {
185        gboolean (*privmsg)(irc_channel_t *ic, const char *msg);
186        gboolean (*join)(irc_channel_t *ic);
187        gboolean (*part)(irc_channel_t *ic, const char *msg);
188        gboolean (*topic)(irc_channel_t *ic, const char *new_topic);
189        gboolean (*invite)(irc_channel_t *ic, irc_user_t *iu);
190        void (*kick)(irc_channel_t *ic, irc_user_t *iu, const char *msg);
191
192        gboolean (*_init)(irc_channel_t *ic);
193        gboolean (*_free)(irc_channel_t *ic);
194};
195
196typedef enum {
197        IRC_CHANNEL_USER_OP = 1,
198        IRC_CHANNEL_USER_HALFOP = 2,
199        IRC_CHANNEL_USER_VOICE = 4,
200        IRC_CHANNEL_USER_NONE = 8,
201} irc_channel_user_flags_t;
202
203typedef struct irc_channel_user {
204        irc_user_t *iu;
205        int flags;
206} irc_channel_user_t;
207
208typedef enum {
209        IRC_CC_TYPE_DEFAULT  = 0x00001,
210        IRC_CC_TYPE_REST     = 0x00002, /* Still not implemented. */
211        IRC_CC_TYPE_GROUP    = 0x00004,
212        IRC_CC_TYPE_ACCOUNT  = 0x00008,
213        IRC_CC_TYPE_PROTOCOL = 0x00010,
214        IRC_CC_TYPE_MASK     = 0x000ff,
215        IRC_CC_TYPE_INVERT   = 0x00100,
216} irc_control_channel_type_t;
217
218struct irc_control_channel {
219        irc_control_channel_type_t type;
220        struct bee_group *group;
221        struct account *account;
222        struct prpl *protocol;
223        char modes[5];
224};
225
226extern const struct bee_ui_funcs irc_ui_funcs;
227
228typedef enum {
229        IRC_CDU_SILENT,
230        IRC_CDU_PART,
231        IRC_CDU_KICK,
232} irc_channel_del_user_type_t;
233
234/* These are a glued a little bit to the core/bee layer and a little bit to
235   IRC. The first user is OTR, and I guess at some point we'll get to shape
236   this a little bit more as other uses come up. */
237typedef struct irc_plugin {
238        /* Called at the end of irc_new(). Can be used to add settings, etc. */
239        gboolean (*irc_new)(irc_t *irc);
240        /* At the end of irc_free(). */
241        void (*irc_free)(irc_t *irc);
242
243        /* Problem with the following two functions is ordering if multiple
244           plugins are handling them. Let's keep fixing that problem for
245           whenever it becomes important. */
246
247        /* Called by bee_irc_user_privmsg_cb(). Return NULL if you want to
248           abort sending the msg. */
249        char* (*filter_msg_out)(irc_user_t * iu, char *msg, int flags);
250        /* Called by bee_irc_user_msg(). Return NULL if you swallowed the
251           message and don't want anything to go to the user. */
252        char* (*filter_msg_in)(irc_user_t * iu, char *msg, int flags);
253
254        /* From storage.c functions. Ideally these should not be used
255           and instead data should be stored in settings which will get
256           saved automatically. Consider these deprecated! */
257        void (*storage_load)(irc_t *irc);
258        void (*storage_save)(irc_t *irc);
259        void (*storage_remove)(const char *nick);
260} irc_plugin_t;
261
262extern GSList *irc_plugins; /* struct irc_plugin */
263
264/* irc.c */
265extern GSList *irc_connection_list;
266
267irc_t *irc_new(int fd);
268void irc_abort(irc_t *irc, int immed, char *format, ...) G_GNUC_PRINTF(3, 4);
269void irc_free(irc_t *irc);
270void irc_setpass(irc_t *irc, const char *pass);
271
272void irc_process(irc_t *irc);
273char **irc_parse_line(char *line);
274char *irc_build_line(char **cmd);
275
276void irc_write(irc_t *irc, char *format, ...) G_GNUC_PRINTF(2, 3);
277void irc_write_all(int now, char *format, ...) G_GNUC_PRINTF(2, 3);
278void irc_vawrite(irc_t *irc, char *format, va_list params);
279
280void irc_flush(irc_t *irc);
281void irc_switch_fd(irc_t *irc, int fd);
282void irc_sync(irc_t *irc);
283void irc_desync(irc_t *irc);
284
285int irc_check_login(irc_t *irc);
286
287void irc_umode_set(irc_t *irc, const char *s, gboolean allow_priv);
288
289void register_irc_plugin(const struct irc_plugin *p);
290
291/* irc_channel.c */
292irc_channel_t *irc_channel_new(irc_t *irc, const char *name);
293irc_channel_t *irc_channel_by_name(irc_t *irc, const char *name);
294irc_channel_t *irc_channel_get(irc_t *irc, char *id);
295int irc_channel_free(irc_channel_t *ic);
296void irc_channel_free_soon(irc_channel_t *ic);
297int irc_channel_add_user(irc_channel_t *ic, irc_user_t *iu);
298int irc_channel_del_user(irc_channel_t *ic, irc_user_t *iu, irc_channel_del_user_type_t type, const char *msg);
299irc_channel_user_t *irc_channel_has_user(irc_channel_t *ic, irc_user_t *iu);
300struct irc_channel *irc_channel_with_user(irc_t *irc, irc_user_t *iu);
301int irc_channel_set_topic(irc_channel_t *ic, const char *topic, const irc_user_t *who);
302void irc_channel_user_set_mode(irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags);
303void irc_channel_set_mode(irc_channel_t *ic, const char *s);
304void irc_channel_auto_joins(irc_t *irc, struct account *acc);
305void irc_channel_printf(irc_channel_t *ic, char *format, ...);
306gboolean irc_channel_name_ok(const char *name);
307void irc_channel_name_strip(char *name);
308int irc_channel_name_cmp(const char *a_, const char *b_);
309char *irc_channel_name_gen(irc_t *irc, const char *name);
310gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name);
311void irc_channel_update_ops(irc_channel_t *ic, char *value);
312char irc_channel_user_get_prefix(irc_channel_user_t *icu);
313char *set_eval_irc_channel_ops(struct set *set, char *value);
314gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu);
315
316/* irc_commands.c */
317void irc_exec(irc_t *irc, char **cmd);
318
319/* irc_send.c */
320void irc_send_num(irc_t *irc, int code, char *format, ...) G_GNUC_PRINTF(3, 4);
321void irc_send_login(irc_t *irc);
322void irc_send_motd(irc_t *irc);
323const char *irc_user_msgdest(irc_user_t *iu);
324void irc_rootmsg(irc_t *irc, char *format, ...);
325void irc_usermsg(irc_user_t *iu, char *format, ...);
326void irc_usernotice(irc_user_t *iu, char *format, ...);
327void irc_send_join(irc_channel_t *ic, irc_user_t *iu);
328void irc_send_part(irc_channel_t *ic, irc_user_t *iu, const char *reason);
329void irc_send_quit(irc_user_t *iu, const char *reason);
330void irc_send_kick(irc_channel_t *ic, irc_user_t *iu, irc_user_t *kicker, const char *reason);
331void irc_send_names(irc_channel_t *ic);
332void irc_send_topic(irc_channel_t *ic, gboolean topic_change);
333void irc_send_whois(irc_user_t *iu);
334void irc_send_who(irc_t *irc, GSList *l, const char *channel);
335void irc_send_msg(irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix);
336void irc_send_msg_raw(irc_user_t *iu, const char *type, const char *dst, const char *msg);
337void irc_send_msg_f(irc_user_t *iu, const char *type, const char *dst, const char *format, ...) G_GNUC_PRINTF(4, 5);
338void irc_send_nick(irc_user_t *iu, const char *new_nick);
339void irc_send_channel_user_mode_diff(irc_channel_t *ic, irc_user_t *iu,
340                                     irc_channel_user_flags_t old_flags, irc_channel_user_flags_t new_flags);
341void irc_send_invite(irc_user_t *iu, irc_channel_t *ic);
342void irc_send_cap(irc_t *irc, char *subcommand, char *body);
343
344/* irc_user.c */
345irc_user_t *irc_user_new(irc_t *irc, const char *nick);
346int irc_user_free(irc_t *irc, irc_user_t *iu);
347irc_user_t *irc_user_by_name(irc_t *irc, const char *nick);
348int irc_user_set_nick(irc_user_t *iu, const char *new_nick);
349gint irc_user_cmp(gconstpointer a_, gconstpointer b_);
350const char *irc_user_get_away(irc_user_t *iu);
351void irc_user_quit(irc_user_t *iu, const char *msg);
352
353/* irc_util.c */
354char *set_eval_timezone(struct set *set, char *value);
355char *irc_format_timestamp(irc_t *irc, time_t msg_ts);
356char *set_eval_self_messages(struct set *set, char *value);
357
358/* irc_im.c */
359void bee_irc_channel_update(irc_t *irc, irc_channel_t *ic, irc_user_t *iu);
360void bee_irc_user_nick_reset(irc_user_t *iu);
361
362/* irc_cap.c */
363void irc_cmd_cap(irc_t *irc, char **cmd);
364
365#endif
Note: See TracBrowser for help on using the repository browser.