diff options
-rw-r--r-- | doc/HACKING | 125 | ||||
-rw-r--r-- | doc/user-guide/misc.xml | 2 | ||||
-rw-r--r-- | irc.h | 9 | ||||
-rw-r--r-- | protocols/bee.h | 62 | ||||
-rw-r--r-- | protocols/nogaim.c | 11 | ||||
-rw-r--r-- | protocols/nogaim.h | 21 | ||||
-rw-r--r-- | set.h | 11 |
7 files changed, 178 insertions, 63 deletions
diff --git a/doc/HACKING b/doc/HACKING new file mode 100644 index 00000000..9d064d58 --- /dev/null +++ b/doc/HACKING @@ -0,0 +1,125 @@ +BitlBee post-1.x "architecture" + +DISCLAIMER: The messy architecture is being cleaned up. Although lots of +progress was made already, this is still a work in progress, and possibly +parts of this document aren't entirely accurate anymore by the time you +read this. + +It's been a while since BitlBee started, as a semi-fork of Gaim (version +0.58 at the time). Some people believe nothing changed, but fortunately, +many things have. + +The API is gone for a while already - which wasn't incredibly intrusive, +just a few functions renamed for slightly better consistency, added some +calls and arguments where that seemed useful, etc. + +However, up to late in the 1.2 series, the IRC core was still spread accross +several files, mostly irc.c + irc_commands.c and pieces and bits in +nogaim.c. If you're looking for a textbook example of layer violation, start +there. + +This was all finally redone. Most of the IRC protocol code was rewritten, +as was most of the glue between that and the IM modules. + +The core of BitlBee is now protocols/bee*. Some pieces are still left in +protocols/nogaim*. Most stuff in the "root" directory belongs to the IRC +UI, which should be considered "a" frontend (although currently, and +possibly forever, the only one). Every subdirectory of protocols/ is another +IM protocol backend (including purple/ which uses libpurple to define +many different protocols). + + +/ + +The IRC core has code to show an IRC interface to a user, with contacts, +channels, etc. To make channels and contacts do something, you add event +handlers (that translate a message sent to a nick into an instant message +to an IM contact, or translates joining a channel into joining an IM +chatroom). + +To get events back from the BitlBee core, the bee_t object has a bunch of +functions (struct bee_ui_funcs) that catch them and convert them back to +IRC. + +Short description of what all irc*.c files (and some related ones) do: + +bitlbee.c: BitlBee bootstrap code, doing bits of I/O as well. +ipc.c: For inter-process communication - communication between BitlBee + sessions. Also used in daemon mode (in which it's not so much inter- + process). +irc.c: The main core, with bits of I/O handling, parsing, etc. +irc_channel.c: Most things related to standard channels (also defines some + of the control channel behaviour). +irc_commands.c: Defines all IRC commands (JOIN, NICK, PRIVMSG, etc.). +irc_im.c: Most of the glue between IRC and the IM core live here. This is + where instant messages are converted to IRC and vice versa, contacts + coming online is translated to one or more joins and/or mode changes. +irc_send.c: Simple functions that send pieces of IRC output. Somewhat + random, but if an IRC response is slightly more complicated than just a + simple line, make it a function here. +irc_user.c: Defines all IRC user details. Mostly defines the user "object". +irc_util.c: Misc. stuff. Not much ATM. +nick.c: Handling of nicknames: compare, ucase/lcase, generating and storing + nicks for IM contacts. +set.c: Settings management, used for user-changeable global/account/channel + settings. Should really be considered part of the core. +storage*.c: Storing user accounts. (The stuff you normally find in + /var/lib/bitlbee) + + +/protocols + +The IM core lives in protocols/. Whenever you write code there, try to avoid +using any IRCisms there. + +Most header files in there have some of their details explained in comments. +bee*.c and nogaim.c are the layer between the IM modules and the IRC +frontend. They keep track of IM accounts, contacts and their status, +groupchats, etc. + +You can control them by calling functions in there if available, and +otherwise by just calling the functions exported via the prpl struct. Most +of these functions are briefly explained in the header files, otherwise the +best documentation is sadly in irc_im.c and root_commands.c. + +Events from the IM module go back to the core + frontend via imcb_* +functions defined in bee*.c and nogaim.c. They're all described in the +header files. + + +/lib + +BitlBee uses GLib, which is a pretty nifty library adding a bunch of things +that make life of a C coder better. Please try to not use features from +recent GLib versions as whenever this happens, some people get cranky. :> + +There's also a whole bunch of nice stuff in lib/ that you can use: + +arc.c: ARC4 encryption, mostly used for encrypting IM passwords in the XML + storage module. +base64.c +events_*.c: Event handling, using either GLib (default) or libevent (may + make non-forking daemon mode with many users a little bit more efficient). +ftutil.c: Some small utility functions currently just used for file transfers. +http_client.c: A simple (but asynchronous) HTTP(S) client, used by the MSN, + Yahoo! and Twitter module by now. +ini.c: Simple INI file parser, used to parse bitlbee.conf. +md5.c +misc.c: What the name says, really. +oauth.c: What the name says. If you don't know what OAuth is, ask Google. + Currently only used by the Twitter module. Implements just version 1a ATM. +proxy.c: Used together with events_*.c for asynchronous I/O directly or via + proxies. +sha1.c +ssl_*.c: SSL client stuff, using GnuTLS (preferred) or OpenSSL. Other modules + aren't working well ATM. +url.c: URL parser. +xmltree.c: Uses the GLib stream parser to build XML parse trees from a stream + and convert the same structs back into XML. Good enough to do Jabber but + not very aware of stuff like XML namespaces. Used for Jabber and Twitter. + +This, together with the headerfile comments, is most of the documentation we +have right now. If you're trying to make some changes to BitlBee, do feel +free to join #bitlbee on irc.oftc.net to ask any question you have. +Suggestions for specific parts to document a little bit more are also +welcome. diff --git a/doc/user-guide/misc.xml b/doc/user-guide/misc.xml index 330e18bb..bb06a658 100644 --- a/doc/user-guide/misc.xml +++ b/doc/user-guide/misc.xml @@ -217,7 +217,7 @@ See <emphasis>set nick_format2</emphasis> for some more information. <title>Nickname formatting - modifiers</title> <para> -Two modifiers ares currently available: You can include only the first few +Two modifiers are currently available: You can include only the first few characters of a variable by putting a number right after the %. For example, <emphasis>[%3group]%-@nick</emphasis> will include only the first three characters of the group name in the nick. @@ -44,10 +44,11 @@ typedef enum { USTATUS_OFFLINE = 0, - USTATUS_AUTHORIZED = 1, - USTATUS_LOGGED_IN = 2, - USTATUS_IDENTIFIED = 4, - USTATUS_SHUTDOWN = 8 + 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(). */ } irc_status_t; struct irc_user; diff --git a/protocols/bee.h b/protocols/bee.h index 4b6a1f4a..a8517f2e 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -31,18 +31,24 @@ struct groupchat; typedef struct bee { + /* Settings. See set.h for how these work. The UI can add its + own settings here. */ struct set *set; - GSList *users; - GSList *groups; + GSList *users; /* struct bee_user */ + GSList *groups; /* struct bee_group */ struct account *accounts; /* TODO(wilmer): Use GSList here too? */ /* Symbolic, to refer to the local user (who has no real bee_user object). Not to be used by anything except so far imcb_chat_add/ - remove_buddy(). This seems slightly cleaner than abusing NULL. */ + remove_buddy(). */ struct bee_user *user; + /* Fill in the callbacks for events you care about. */ const struct bee_ui_funcs *ui; + + /* And this one will be passed to every callback for any state the + UI may want to keep. */ void *ui_data; } bee_t; @@ -65,18 +71,21 @@ typedef struct bee_user struct bee_group *group; bee_user_flags_t flags; - char *status; - char *status_msg; + char *status; /* NULL means available, anything else is an away state. */ + char *status_msg; /* Status and/or away message. */ + /* Set using imcb_buddy_times(). */ time_t login_time, idle_time; bee_t *bee; void *ui_data; } bee_user_t; +/* This one's mostly used so save space and make it easier (cheaper) to + compare groups of contacts, etc. */ typedef struct bee_group { - char *key; + char *key; /* Lower case version of the name. */ char *name; } bee_group_t; @@ -87,15 +96,23 @@ typedef struct bee_ui_funcs gboolean (*user_new)( bee_t *bee, struct bee_user *bu ); gboolean (*user_free)( bee_t *bee, struct bee_user *bu ); + /* Set the fullname first, then call this one to notify the UI. */ gboolean (*user_fullname)( bee_t *bee, bee_user_t *bu ); gboolean (*user_nick_hint)( bee_t *bee, bee_user_t *bu, const char *hint ); + /* Notify the UI when an existing user is moved between groups. */ gboolean (*user_group)( bee_t *bee, bee_user_t *bu ); + /* State info is already updated, old is provided in case the UI needs a diff. */ gboolean (*user_status)( bee_t *bee, struct bee_user *bu, struct bee_user *old ); + /* On every incoming message. sent_at = 0 means unknown. */ gboolean (*user_msg)( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at ); + /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */ gboolean (*user_typing)( bee_t *bee, bee_user_t *bu, guint32 flags ); + /* Called at creation time. Don't show to the user until s/he is + added using chat_add_user(). UI state can be stored via c->data. */ gboolean (*chat_new)( bee_t *bee, struct groupchat *c ); gboolean (*chat_free)( bee_t *bee, struct groupchat *c ); + /* System messages of any kind. */ gboolean (*chat_log)( bee_t *bee, struct groupchat *c, const char *text ); gboolean (*chat_msg)( bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at ); gboolean (*chat_add_user)( bee_t *bee, struct groupchat *c, bee_user_t *bu ); @@ -134,18 +151,25 @@ G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *han G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, guint32 flags, time_t sent_at ); /* bee_chat.c */ -#if 0 -struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); -void imcb_chat_name_hint( struct groupchat *c, const char *name ); -void imcb_chat_free( struct groupchat *c ); -void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ); -void imcb_chat_log( struct groupchat *c, char *format, ... ); -void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ); -void imcb_chat_add_buddy( struct groupchat *b, const char *handle ); -void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ); -static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); -#endif -int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags ); -struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title ); +/* These two functions are to create a group chat. + * - imcb_chat_new(): the 'handle' parameter identifies the chat, like the + * channel name on IRC. + * - After you have a groupchat pointer, you should add the handles, finally + * the user her/himself. At that point the group chat will be visible to the + * user, too. */ +G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); +G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name ); +G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c ); +/* To tell BitlBee 'who' said 'msg' in 'c'. 'flags' and 'sent_at' can be 0. */ +G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at ); +/* System messages specific to a groupchat, so they can be displayed in the right context. */ +G_MODULE_EXPORT void imcb_chat_log( struct groupchat *c, char *format, ... ); +/* To tell BitlBee 'who' changed the topic of 'c' to 'topic'. */ +G_MODULE_EXPORT void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ); +G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *c, const char *handle ); +/* To remove a handle from a group chat. Reason can be NULL. */ +G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason ); +G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags ); +G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title ); #endif /* __BEE_H__ */ diff --git a/protocols/nogaim.c b/protocols/nogaim.c index e628126f..d8c7d05a 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -288,17 +288,6 @@ void imcb_connected( struct im_connection *ic ) if( ic->bee->ui->imc_connected ) ic->bee->ui->imc_connected( ic ); - - /* - for( c = irc->chatrooms; c; c = c->next ) - { - if( c->acc != ic->acc ) - continue; - - if( set_getbool( &c->set, "auto_join" ) ) - chat_join( irc, c, NULL ); - } - */ } gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 46f6535a..a12ce89b 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -304,27 +304,6 @@ G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ); G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle ); -/* Groupchats */ -G_MODULE_EXPORT void imcb_chat_invited( struct im_connection *ic, char *handle, char *who, char *msg, GList *data ); -/* These two functions are to create a group chat. - * - imcb_chat_new(): the 'handle' parameter identifies the chat, like the - * channel name on IRC. - * - After you have a groupchat pointer, you should add the handles, finally - * the user her/himself. At that point the group chat will be visible to the - * user, too. */ -G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); -G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name ); -G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, const char *handle ); -/* To remove a handle from a group chat. Reason can be NULL. */ -G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ); -/* To tell BitlBee 'who' said 'msg' in 'c'. 'flags' and 'sent_at' can be 0. */ -G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ); -/* System messages specific to a groupchat, so they can be displayed in the right context. */ -G_MODULE_EXPORT void imcb_chat_log( struct groupchat *c, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); -/* To tell BitlBee 'who' changed the topic of 'c' to 'topic'. */ -G_MODULE_EXPORT void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ); -G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c ); - /* Actions, or whatever. */ int imc_away_send_update( struct im_connection *ic ); int imc_chat_msg( struct groupchat *c, char *msg, int flags ); @@ -36,10 +36,7 @@ struct set; remembers a default value for every setting. And to prevent the user from setting invalid values, you can write an evaluator function for every setting, which can check a new value and block it by returning - NULL, or replace it by returning a new value. See struct set.eval. - One thing that is really missing here is additional data for the - evaluator. This could be useful to add minimum and maximum values for - integers, for example. */ + NULL, or replace it by returning a new value. See struct set.eval. */ typedef char *(*set_eval) ( struct set *set, char *value ); @@ -65,9 +62,9 @@ typedef struct set int flags; /* See account.h, for example. set.c doesn't use this (yet?). */ - /* Eval: Returns SET_INVALID if the value is incorrect or exactly - the passed value variable. When returning a corrected value, - set_setstr() should be able to free() the returned string! */ + /* Eval: Returns SET_INVALID if the value is incorrect, exactly + the passed value variable, or a corrected value. In case of + the latter, set_setstr() will free() the returned string! */ set_eval eval; void *eval_data; struct set *next; |