aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/HACKING125
-rw-r--r--doc/user-guide/misc.xml2
-rw-r--r--irc.h9
-rw-r--r--protocols/bee.h62
-rw-r--r--protocols/nogaim.c11
-rw-r--r--protocols/nogaim.h21
-rw-r--r--set.h11
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.
diff --git a/irc.h b/irc.h
index 69f9dfd0..bbfeed82 100644
--- a/irc.h
+++ b/irc.h
@@ -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 );
diff --git a/set.h b/set.h
index 9b012405..4bd1ce18 100644
--- a/set.h
+++ b/set.h
@@ -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;