source: irc.h @ f7cc734

Last change on this file since f7cc734 was f7cc734, checked in by dequis <dx@…>, at 2018-07-31T04:41:25Z

irc: implement server-time capability

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