aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-03-12 19:10:16 +0000
committerWilmer van der Gaast <wilmer@gaast.net>2010-03-12 19:10:16 +0000
commitbe609ff2b0ca885612c0e6d81f82c4f26ed4f58d (patch)
treeb9f83fdc44bd00921ffb9c23035b1f39d565ba93
parent08e5bb2bb2fcc7125f837be4f225d3a9ebf320ed (diff)
parent8b6b7405d3844271f7bff56e527bfeb1a4872975 (diff)
Merging mainline.
-rw-r--r--Makefile8
-rw-r--r--account.c30
-rw-r--r--account.h16
-rw-r--r--bitlbee.conf5
-rw-r--r--conf.c3
-rwxr-xr-xconfigure6
-rw-r--r--crypting.c60
-rw-r--r--doc/user-guide/commands.xml32
-rw-r--r--doc/user-guide/misc.xml22
-rw-r--r--irc.c23
-rw-r--r--irc_commands.c9
-rw-r--r--lib/misc.c1
-rw-r--r--protocols/jabber/jabber.c20
-rw-r--r--protocols/jabber/jabber.h2
-rw-r--r--protocols/jabber/jabber_util.c9
-rw-r--r--protocols/jabber/presence.c17
-rw-r--r--protocols/msn/msn.c18
-rw-r--r--protocols/msn/msn.h1
-rw-r--r--protocols/msn/msn_util.c8
-rw-r--r--protocols/msn/ns.c49
-rw-r--r--protocols/msn/tables.c37
-rw-r--r--protocols/nogaim.c98
-rw-r--r--protocols/nogaim.h7
-rw-r--r--protocols/oscar/oscar.c39
-rw-r--r--protocols/yahoo/libyahoo2.c56
-rw-r--r--protocols/yahoo/yahoo.c41
-rw-r--r--root_commands.c73
-rw-r--r--unix.c71
28 files changed, 383 insertions, 378 deletions
diff --git a/Makefile b/Makefile
index 20feb067..337fcf63 100644
--- a/Makefile
+++ b/Makefile
@@ -48,7 +48,7 @@ Makefile.settings:
@echo
clean: $(subdirs)
- rm -f *.o $(OUTFILE) core utils/bitlbeed encode decode
+ rm -f *.o $(OUTFILE) core utils/bitlbeed
$(MAKE) -C tests clean
distclean: clean $(subdirs)
@@ -123,11 +123,5 @@ ifndef DEBUG
@-$(STRIP) $(OUTFILE)
endif
-encode: crypting.c
- $(CC) crypting.c lib/md5.c $(CFLAGS) -o encode -DCRYPTING_MAIN $(CFLAGS) $(EFLAGS) $(LFLAGS)
-
-decode: encode
- cp encode decode
-
ctags:
ctags `find . -name "*.c"` `find . -name "*.h"`
diff --git a/account.c b/account.c
index 912cba6a..99c3ff53 100644
--- a/account.c
+++ b/account.c
@@ -1,7 +1,7 @@
/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
- * Copyright 2002-2004 Wilmer van der Gaast and others *
+ * Copyright 2002-2010 Wilmer van der Gaast and others *
\********************************************************************/
/* Account management functions */
@@ -68,7 +68,16 @@ account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass )
if( prpl->init )
prpl->init( a );
- return( a );
+ s = set_add( &a->set, "away", NULL, set_eval_account, a );
+ s->flags |= SET_NULL_OK;
+
+ if( a->flags & ACC_FLAG_STATUS_MESSAGE )
+ {
+ s = set_add( &a->set, "status", NULL, set_eval_account, a );
+ s->flags |= SET_NULL_OK;
+ }
+
+ return a;
}
char *set_eval_account( set_t *set, char *value )
@@ -122,6 +131,21 @@ char *set_eval_account( set_t *set, char *value )
acc->auto_connect = bool2int( value );
return value;
}
+ else if( strcmp( set->key, "away" ) == 0 ||
+ strcmp( set->key, "status" ) == 0 )
+ {
+ if( acc->ic && acc->ic->flags & OPT_LOGGED_IN )
+ {
+ /* If we're currently on-line, set the var now already
+ (bit of a hack) and send an update. */
+ g_free( set->value );
+ set->value = g_strdup( value );
+
+ imc_away_send_update( acc->ic );
+ }
+
+ return value;
+ }
return SET_INVALID;
}
@@ -266,7 +290,7 @@ int account_reconnect_delay_parse( char *value, struct account_reconnect_delay *
/* A whole day seems like a sane "maximum maximum". */
p->max = 86400;
- /* Format: /[0-9]+([*+][0-9]+(<[0-9+]))/ */
+ /* Format: /[0-9]+([*+][0-9]+(<[0-9+])?)?/ */
while( *value && isdigit( *value ) )
p->start = p->start * 10 + *value++ - '0';
diff --git a/account.h b/account.h
index cf22482c..984dcfe6 100644
--- a/account.h
+++ b/account.h
@@ -36,6 +36,7 @@ typedef struct account
int auto_connect;
int auto_reconnect_delay;
int reconnect;
+ int flags;
set_t *set;
GHashTable *nicks;
@@ -55,8 +56,17 @@ char *set_eval_account( set_t *set, char *value );
char *set_eval_account_reconnect_delay( set_t *set, char *value );
int account_reconnect_delay( account_t *a );
-#define ACC_SET_NOSAVE 0x01
-#define ACC_SET_OFFLINE_ONLY 0x02
-#define ACC_SET_ONLINE_ONLY 0x04
+typedef enum
+{
+ ACC_SET_NOSAVE = 0x01, /* Don't save this setting (i.e. stored elsewhere). */
+ ACC_SET_OFFLINE_ONLY = 0x02, /* Allow changes only if the acct is offline. */
+ ACC_SET_ONLINE_ONLY = 0x04, /* Allow changes only if the acct is online. */
+} account_set_flag_t;
+
+typedef enum
+{
+ ACC_FLAG_AWAY_MESSAGE = 0x01, /* Supports away messages instead of just states. */
+ ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */
+} account_flag_t;
#endif
diff --git a/bitlbee.conf b/bitlbee.conf
index 5fce2820..4a3bbddf 100644
--- a/bitlbee.conf
+++ b/bitlbee.conf
@@ -54,9 +54,8 @@
## AuthPassword
##
## Password the user should enter when logging into a closed BitlBee server.
-## You can also have an MD5-encrypted password here. Format: "md5:", followed
-## by a hash as generated for the <user password=""> attribute in a BitlBee
-## XML file (for now there's no easier way to generate the hash).
+## You can also have a BitlBee-style MD5 hash here. Format: "md5:", followed
+## by a hash as generated by "bitlbee -x hash <password>".
##
# AuthPassword = ItllBeBitlBee ## Heh.. Our slogan. ;-)
## or
diff --git a/conf.c b/conf.c
index 873aa0e7..c8cfaad8 100644
--- a/conf.c
+++ b/conf.c
@@ -126,7 +126,7 @@ conf_t *conf_load( int argc, char *argv[] )
else if( opt == 'h' )
{
printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
- " [-c <file>] [-d <dir>] [-h]\n"
+ " [-c <file>] [-d <dir>] [-x] [-h]\n"
"\n"
"An IRC-to-other-chat-networks gateway\n"
"\n"
@@ -142,6 +142,7 @@ conf_t *conf_load( int argc, char *argv[] )
" -v Be verbose (only works in combination with -n)\n"
" -c Load alternative configuration file\n"
" -d Specify alternative user configuration directory\n"
+ " -x Command-line interface to password encryption/hashing\n"
" -h Show this help page.\n" );
return NULL;
}
diff --git a/configure b/configure
index 9d92cedf..cac1161e 100755
--- a/configure
+++ b/configure
@@ -359,11 +359,11 @@ elif [ "$ssl" = "bogus" ]; then
echo 'Using bogus SSL code. This means some features will not work properly.'
## Yes, you, at the console! How can you authenticate if you don't have any SSL!?
- if [ "$msn" = "1" ]; then
+ if [ "$msn" = "1" -o "$yahoo" = "1" ]; then
echo
- echo 'Real SSL support is necessary for MSN authentication, will build without'
- echo 'MSN protocol support.'
+ echo 'WARNING: The MSN and Yahoo! modules will not work without SSL. Disabling.'
msn=0
+ yahoo=0
fi
ret=1
diff --git a/crypting.c b/crypting.c
index 34b99034..0a5c937e 100644
--- a/crypting.c
+++ b/crypting.c
@@ -131,63 +131,3 @@ char *deobfucrypt (char *line, const char *password)
return (rv);
}
-
-#ifdef CRYPTING_MAIN
-
-/* A little main() function for people who want a stand-alone program to
- encode/decode BitlCrypted files. */
-
-int main( int argc, char *argv[] )
-{
- char *hash, *action, line[256];
- char* (*func)( char *, const char * );
-
- if( argc < 2 )
- {
- fprintf( stderr, "Usage: %s <password>\n\n"
- "Reads from stdin, writes to stdout.\n"
- "Call as \"encode\" to encode, \"decode\" to decode.\n", argv[0] );
- return( 1 );
- }
-
- hash = hashpass( argv[1] );
- action = argv[0] + strlen( argv[0] ) - strlen( "encode" );
-
- if( strcmp( action, "encode" ) == 0 )
- {
- fwrite( hash, 32, 1, stdout );
- func = obfucrypt;
- }
- else if( strcmp( action, "decode" ) == 0 )
- {
- char hash2[32];
-
- fread( hash2, 32, 1, stdin );
- if( memcmp( hash, hash2, 32 ) != 0 )
- {
- fprintf( stderr, "Passwords don't match. Can't decode.\n" );
- return( 1 );
- }
- func = deobfucrypt;
- }
- else
- {
- return( main( 0, NULL ) );
- }
-
- while( fscanf( stdin, "%[^\n]255s", line ) > 0 )
- {
- char *out;
-
- /* Flush the newline */
- fgetc( stdin );
-
- out = func( line, argv[1] );
- printf( "%s\n", out );
- g_free( out );
- }
-
- return( 0 );
-}
-
-#endif
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index af566de4..a7d06cf1 100644
--- a/doc/user-guide/commands.xml
+++ b/doc/user-guide/commands.xml
@@ -435,6 +435,22 @@
</description>
</bitlbee-setting>
+ <bitlbee-setting name="away" type="string" scope="both">
+ <description>
+ <para>
+ To mark yourself as away, it is recommended to just use <emphasis>/away</emphasis>, like on normal IRC networks. If you want to mark yourself as away on only one IM network, you can use this per-account setting.
+ </para>
+
+ <para>
+ You can set it to any value and BitlBee will try to map it to the most appropriate away state for every open IM connection, or set it as a free-form away message where possible.
+ </para>
+
+ <para>
+ Any per-account away setting will override globally set away states. To un-set the setting, use <emphasis>set -del away</emphasis>.
+ </para>
+ </description>
+ </bitlbee-setting>
+
<bitlbee-setting name="away_devoice" type="boolean" scope="global">
<default>true</default>
@@ -746,6 +762,22 @@
</description>
</bitlbee-setting>
+ <bitlbee-setting name="status" type="string" scope="both">
+ <description>
+ <para>
+ Certain protocols (like Jabber/XMPP) support status messages, similar to away messages. They can be used to indicate things like your location or activity, without showing up as away/busy.
+ </para>
+
+ <para>
+ This setting can be used to set such a message. It will be available as a per-account setting for protocols that support it, and also as a global setting (which will then automatically be used for all protocols that support it).
+ </para>
+
+ <para>
+ Away states set using <emphasis>/away</emphasis> or the <emphasis>away</emphasis> setting will override this setting. To un-set the setting, use <emphasis>set -del status</emphasis>.
+ </para>
+ </description>
+ </bitlbee-setting>
+
<bitlbee-setting name="strip_html" type="boolean" scope="global">
<default>true</default>
diff --git a/doc/user-guide/misc.xml b/doc/user-guide/misc.xml
index 68b44e95..a926775a 100644
--- a/doc/user-guide/misc.xml
+++ b/doc/user-guide/misc.xml
@@ -85,31 +85,35 @@ Some protocols (like Jabber) also support named groupchats. BitlBee now supports
<title>Away states</title>
<para>
-As you might've expected, you can just use the <emphasis>/away</emphasis> command in your IRC client to set an away-state. BitlBee supports most away-states supported by the protocols.
+To mark yourself as away, you can just use the <emphasis>/away</emphasis> command in your IRC client. BitlBee supports most away-states supported by the protocols.
</para>
<para>
-Not all away states are supported by all protocols, and some protocols have different names for them. BitlBee will try to pick the best available alias from this list for every connection:
+Away states have different names accross different protocols. BitlBee will try to pick the best available option for every connection:
</para>
<simplelist>
- <member>Away from computer, Away, Extended away</member>
- <member>NA, N/A, Not available</member>
- <member>Busy, Do not disturb, DND, Occupied</member>
- <member>Be right back, BRB</member>
- <member>On the phone, Phone, On phone</member>
- <member>Out to lunch, Lunch, Food</member>
+ <member>Away</member>
+ <member>NA</member>
+ <member>Busy, DND</member>
+ <member>BRB</member>
+ <member>Phone</member>
+ <member>Lunch, Food</member>
<member>Invisible, Hidden</member>
</simplelist>
<para>
-So <emphasis>/away Food</emphasis> will set your state to "Out to lunch" on your MSN connection, and for most other connections the default, "Away" or "Away from computer" will be chosen.
+So <emphasis>/away Food</emphasis> will set your state to "Out to lunch" on your MSN connection, and for most other connections the default, "Away" will be chosen.
</para>
<para>
You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Most IM-protocols can also show this additional information to your buddies.
</para>
+<para>
+If you want to set an away state for only one of your connections, you can use the per-account <emphasis>away</emphasis> setting. See <emphasis>help set away</emphasis>.
+</para>
+
</sect1>
</chapter>
diff --git a/irc.c b/irc.c
index 2dcc625d..8d503e02 100644
--- a/irc.c
+++ b/irc.c
@@ -77,6 +77,25 @@ static char *set_eval_charset( set_t *set, char *value )
return value;
}
+static char *set_eval_away_status( set_t *set, char *value )
+{
+ irc_t *irc = set->data;
+ account_t *a;
+
+ g_free( set->value );
+ set->value = g_strdup( value );
+
+ for( a = irc->accounts; a; a = a->next )
+ {
+ struct im_connection *ic = a->ic;
+
+ if( ic && ic->flags & OPT_LOGGED_IN )
+ imc_away_send_update( ic );
+ }
+
+ return value;
+}
+
irc_t *irc_new( int fd )
{
irc_t *irc;
@@ -142,6 +161,8 @@ irc_t *irc_new( int fd )
irc_connection_list = g_slist_append( irc_connection_list, irc );
+ s = set_add( &irc->set, "away", NULL, set_eval_away_status, irc );
+ s->flags |= SET_NULL_OK;
s = set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc );
s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
s = set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
@@ -162,6 +183,8 @@ irc_t *irc_new( int fd )
s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );
s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );
+ s = set_add( &irc->set, "status", NULL, set_eval_away_status, irc );
+ s->flags |= SET_NULL_OK;
s = set_add( &irc->set, "strip_html", "true", NULL, irc );
s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
diff --git a/irc_commands.c b/irc_commands.c
index 74334ee9..750bbcf5 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -447,7 +447,6 @@ static void irc_cmd_away( irc_t *irc, char **cmd )
{
user_t *u = user_find( irc, irc->nick );
char *away = cmd[1];
- account_t *a;
if( !u ) return;
@@ -474,13 +473,7 @@ static void irc_cmd_away( irc_t *irc, char **cmd )
irc_reply( irc, 305, ":Welcome back" );
}
- for( a = irc->accounts; a; a = a->next )
- {
- struct im_connection *ic = a->ic;
-
- if( ic && ic->flags & OPT_LOGGED_IN )
- imc_set_away( ic, u->away );
- }
+ set_setstr( &irc->set, "away", u->away );
}
static void irc_cmd_whois( irc_t *irc, char **cmd )
diff --git a/lib/misc.c b/lib/misc.c
index 35e9909b..3976e01b 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -88,6 +88,7 @@ static const htmlentity_t ent[] =
{ "lt", "<" },
{ "gt", ">" },
{ "amp", "&" },
+ { "apos", "'" },
{ "quot", "\"" },
{ "aacute", "á" },
{ "eacute", "é" },
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index 6d63f354..86320ada 100644
--- a/protocols/jabber/jabber.c
+++ b/protocols/jabber/jabber.c
@@ -81,6 +81,8 @@ static void jabber_init( account_t *acc )
s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc );
s->flags |= ACC_SET_OFFLINE_ONLY;
+
+ acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
}
static void jabber_generate_id_hash( struct jabber_data *jd );
@@ -357,10 +359,11 @@ static void jabber_get_info( struct im_connection *ic, char *who )
while( bud )
{
- imcb_log( ic, "Buddy %s (%d) information:\nAway state: %s\nAway message: %s",
- bud->full_jid, bud->priority,
- bud->away_state ? bud->away_state->full_name : "(none)",
- bud->away_message ? : "(none)" );
+ imcb_log( ic, "Buddy %s (%d) information:", bud->full_jid, bud->priority );
+ if( bud->away_state )
+ imcb_log( ic, "Away state: %s", bud->away_state->full_name );
+ imcb_log( ic, "Status message: %s", bud->away_message ? : "(none)" );
+
bud = bud->next;
}
@@ -370,11 +373,12 @@ static void jabber_get_info( struct im_connection *ic, char *who )
static void jabber_set_away( struct im_connection *ic, char *state_txt, char *message )
{
struct jabber_data *jd = ic->proto_data;
- struct jabber_away_state *state;
- /* Save all this info. We need it, for example, when changing the priority setting. */
- state = (void *) jabber_away_state_by_name( state_txt );
- jd->away_state = state ? state : (void *) jabber_away_state_list; /* Fall back to "Away" if necessary. */
+ /* state_txt == NULL -> Not away.
+ Unknown state -> fall back to the first defined away state. */
+ jd->away_state = state_txt ? jabber_away_state_by_name( state_txt )
+ ? : jabber_away_state_list : NULL;
+
g_free( jd->away_message );
jd->away_message = ( message && *message ) ? g_strdup( message ) : NULL;
diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h
index 5eac70d0..5f48cc43 100644
--- a/protocols/jabber/jabber.h
+++ b/protocols/jabber/jabber.h
@@ -83,7 +83,7 @@ struct jabber_data
/* After changing one of these two (or the priority setting), call
presence_send_update() to inform the server about the changes. */
- struct jabber_away_state *away_state;
+ const struct jabber_away_state *away_state;
char *away_message;
md5_state_t cached_id_prefix;
diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c
index 120a56b6..6e103609 100644
--- a/protocols/jabber/jabber_util.c
+++ b/protocols/jabber/jabber_util.c
@@ -227,10 +227,9 @@ xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *
const struct jabber_away_state jabber_away_state_list[] =
{
{ "away", "Away" },
- { "chat", "Free for Chat" },
+ { "chat", "Free for Chat" }, /* WTF actually uses this? */
{ "dnd", "Do not Disturb" },
{ "xa", "Extended Away" },
- { "", "Online" },
{ "", NULL }
};
@@ -238,6 +237,9 @@ const struct jabber_away_state *jabber_away_state_by_code( char *code )
{
int i;
+ if( code == NULL )
+ return NULL;
+
for( i = 0; jabber_away_state_list[i].full_name; i ++ )
if( g_strcasecmp( jabber_away_state_list[i].code, code ) == 0 )
return jabber_away_state_list + i;
@@ -249,6 +251,9 @@ const struct jabber_away_state *jabber_away_state_by_name( char *name )
{
int i;
+ if( name == NULL )
+ return NULL;
+
for( i = 0; jabber_away_state_list[i].full_name; i ++ )
if( g_strcasecmp( jabber_away_state_list[i].full_name, name ) == 0 )
return jabber_away_state_list + i;
diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c
index 68d4e52c..006eeead 100644
--- a/protocols/jabber/presence.c
+++ b/protocols/jabber/presence.c
@@ -186,13 +186,12 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
{
int is_away = 0;
- if( send_presence->away_state && !( *send_presence->away_state->code == 0 ||
- strcmp( send_presence->away_state->code, "chat" ) == 0 ) )
+ if( send_presence->away_state &&
+ strcmp( send_presence->away_state->code, "chat" ) != 0 )
is_away = OPT_AWAY;
imcb_buddy_status( ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away,
- ( is_away && send_presence->away_state ) ?
- send_presence->away_state->full_name : NULL,
+ is_away ? send_presence->away_state->full_name : NULL,
send_presence->away_message );
}
@@ -205,17 +204,15 @@ int presence_send_update( struct im_connection *ic )
{
struct jabber_data *jd = ic->proto_data;
struct xt_node *node, *cap;
- char *show = jd->away_state->code;
- char *status = jd->away_message;
struct groupchat *c;
int st;
node = jabber_make_packet( "presence", NULL, NULL, NULL );
xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
- if( show && *show )
- xt_add_child( node, xt_new_node( "show", show, NULL ) );
- if( status )
- xt_add_child( node, xt_new_node( "status", status, NULL ) );
+ if( jd->away_state )
+ xt_add_child( node, xt_new_node( "show", jd->away_state->code, NULL ) );
+ if( jd->away_message )
+ xt_add_child( node, xt_new_node( "status", jd->away_message, NULL ) );
/* This makes the packet slightly bigger, but clients interested in
capabilities can now cache the discovery info. This reduces the
diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c
index 046b2772..e12fb3a9 100644
--- a/protocols/msn/msn.c
+++ b/protocols/msn/msn.c
@@ -138,8 +138,9 @@ static GList *msn_away_states( struct im_connection *ic )
int i;
if( l == NULL )
- for( i = 0; msn_away_state_list[i].number > -1; i ++ )
- l = g_list_append( l, (void*) msn_away_state_list[i].name );
+ for( i = 0; *msn_away_state_list[i].code; i ++ )
+ if( *msn_away_state_list[i].name )
+ l = g_list_append( l, (void*) msn_away_state_list[i].name );
return l;
}
@@ -148,17 +149,14 @@ static void msn_set_away( struct im_connection *ic, char *state, char *message )
{
char buf[1024];
struct msn_data *md = ic->proto_data;
- const struct msn_away_state *st;
- if( strcmp( state, GAIM_AWAY_CUSTOM ) == 0 )
- st = msn_away_state_by_name( "Away" );
+ if( state )
+ md->away_state = msn_away_state_by_name( state ) ? :
+ msn_away_state_list + 1;
else
- st = msn_away_state_by_name( state );
+ md->away_state = msn_away_state_list;
- if( !st ) st = msn_away_state_list;
- md->away_state = st;
-
- g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, st->code );
+ g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, md->away_state->code );
msn_write( ic, buf, strlen( buf ) );
}
diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h
index 7c849acf..333ae7f0 100644
--- a/protocols/msn/msn.h
+++ b/protocols/msn/msn.h
@@ -96,7 +96,6 @@ struct msn_switchboard
struct msn_away_state
{
- int number;
char code[4];
char name[16];
};
diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c
index 58ad22f8..668a8b8a 100644
--- a/protocols/msn/msn_util.c
+++ b/protocols/msn/msn_util.c
@@ -170,9 +170,9 @@ char *msn_findheader( char *text, char *header, int len )
while( i < len && ( text[i] == '\r' || text[i] == '\n' ) ) i ++;
/* End of headers? */
- if( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||
- strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ||
- strncmp( text + i - 2, "\r\r", 2 ) == 0 )
+ if( ( i >= 4 && strncmp( text + i - 4, "\r\n\r\n", 4 ) == 0 ) ||
+ ( i >= 2 && ( strncmp( text + i - 2, "\n\n", 2 ) == 0 ||
+ strncmp( text + i - 2, "\r\r", 2 ) == 0 ) ) )
{
break;
}
@@ -373,6 +373,6 @@ void msn_msgq_purge( struct im_connection *ic, GSList **list )
g_slist_free( *list );
*list = NULL;
- imcb_log( ic, ret->str );
+ imcb_log( ic, "%s", ret->str );
g_string_free( ret, TRUE );
}
diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c
index fe48f96d..d05d8e0d 100644
--- a/protocols/msn/ns.c
+++ b/protocols/msn/ns.c
@@ -419,11 +419,12 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
if( !st )
{
/* FIXME: Warn/Bomb about unknown away state? */
- st = msn_away_state_list;
+ st = msn_away_state_list + 1;
}
- imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
- ( st->number ? OPT_AWAY : 0 ), st->name, NULL );
+ imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
+ ( st != msn_away_state_list ? OPT_AWAY : 0 ),
+ st->name, NULL );
}
else if( strcmp( cmd[0], "FLN" ) == 0 )
{
@@ -448,11 +449,12 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts )
if( !st )
{
/* FIXME: Warn/Bomb about unknown away state? */
- st = msn_away_state_list;
+ st = msn_away_state_list + 1;
}
- imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
- ( st->number ? OPT_AWAY : 0 ), st->name, NULL );
+ imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
+ ( st != msn_away_state_list ? OPT_AWAY : 0 ),
+ st->name, NULL );
}
else if( strcmp( cmd[0], "RNG" ) == 0 )
{
@@ -662,8 +664,8 @@ static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int
imcb_log( ic, "The server is going down for maintenance in %s minutes.", arg1 );
}
- if( arg1 ) g_free( arg1 );
- if( mtype ) g_free( mtype );
+ g_free( arg1 );
+ g_free( mtype );
}
else if( g_strncasecmp( ct, "text/x-msmsgsprofile", 20 ) == 0 )
{
@@ -671,25 +673,30 @@ static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int
}
else if( g_strncasecmp( ct, "text/x-msmsgsinitialemailnotification", 37 ) == 0 )
{
- char *inbox = msn_findheader( body, "Inbox-Unread:", blen );
- char *folders = msn_findheader( body, "Folders-Unread:", blen );
-
- if( inbox && folders && set_getbool( &ic->acc->set, "mail_notifications" ) )
+ if( set_getbool( &ic->acc->set, "mail_notifications" ) )
{
- imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
+ char *inbox = msn_findheader( body, "Inbox-Unread:", blen );
+ char *folders = msn_findheader( body, "Folders-Unread:", blen );
+
+ if( inbox && folders )
+ imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders );
+
+ g_free( inbox );
+ g_free( folders );
}
-
- g_free( inbox );
- g_free( folders );
}
else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 )
{
- char *from = msn_findheader( body, "From-Addr:", blen );
- char *fromname = msn_findheader( body, "From:", blen );
-
- if( from && fromname && set_getbool( &ic->acc->set, "mail_notifications" ) )
+ if( set_getbool( &ic->acc->set, "mail_notifications" ) )
{
- imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from );
+ char *from = msn_findheader( body, "From-Addr:", blen );
+ char *fromname = msn_findheader( body, "From:", blen );
+
+ if( from && fromname )
+ imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from );
+
+ g_free( from );
+ g_free( fromname );
}
}
else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 )
diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c
index 5ba9ea73..42b12aa9 100644
--- a/protocols/msn/tables.c
+++ b/protocols/msn/tables.c
@@ -28,48 +28,37 @@
const struct msn_away_state msn_away_state_list[] =
{
- { 0, "NLN", "Available" },
- { 1, "BSY", "Busy" },
- { 3, "IDL", "Idle" },
- { 5, "BRB", "Be Right Back" },
- { 7, "AWY", "Away" },
- { 9, "PHN", "On the Phone" },
- { 11, "LUN", "Out to Lunch" },
- { 13, "HDN", "Hidden" },
- { -1, "", "" }
+ { "NLN", "" },
+ { "AWY", "Away" },
+ { "BSY", "Busy" },
+ { "IDL", "Idle" },
+ { "BRB", "Be Right Back" },
+ { "PHN", "On the Phone" },
+ { "LUN", "Out to Lunch" },
+ { "HDN", "Hidden" },
+ { "", "" }
};
-const struct msn_away_state *msn_away_state_by_number( int number )
-{
- int i;
-
- for( i = 0; msn_away_state_list[i].number > -1; i ++ )
- if( msn_away_state_list[i].number == number )
- return( msn_away_state_list + i );
-
- return( NULL );
-}
-
const struct msn_away_state *msn_away_state_by_code( char *code )
{
int i;
- for( i = 0; msn_away_state_list[i].number > -1; i ++ )
+ for( i = 0; *msn_away_state_list[i].code; i ++ )
if( g_strcasecmp( msn_away_state_list[i].code, code ) == 0 )
return( msn_away_state_list + i );
- return( NULL );
+ return NULL;
}
const struct msn_away_state *msn_away_state_by_name( char *name )
{
int i;
- for( i = 0; msn_away_state_list[i].number > -1; i ++ )
+ for( i = 0; *msn_away_state_list[i].code; i ++ )
if( g_strcasecmp( msn_away_state_list[i].name, name ) == 0 )
return( msn_away_state_list + i );
- return( NULL );
+ return NULL;
}
const struct msn_status_code msn_status_code_list[] =
diff --git a/protocols/nogaim.c b/protocols/nogaim.c
index 21f7dcb1..603905ab 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -1,7 +1,7 @@
/********************************************************************\
* BitlBee -- An IRC to other IM-networks gateway *
* *
- * Copyright 2002-2006 Wilmer van der Gaast and others *
+ * Copyright 2002-2010 Wilmer van der Gaast and others *
\********************************************************************/
/*
@@ -267,9 +267,8 @@ void imcb_connected( struct im_connection *ic )
ic->keepalive = b_timeout_add( 60000, send_keepalive, ic );
ic->flags |= OPT_LOGGED_IN;
- /* Also necessary when we're not away, at least for some of the
- protocols. */
- imc_set_away( ic, u->away );
+ /* Necessary to send initial presence status, even if we're not away. */
+ imc_away_send_update( ic );
/* Apparently we're connected successfully, so reset the
exponential backoff timer. */
@@ -1069,51 +1068,30 @@ int imc_chat_msg( struct groupchat *c, char *msg, int flags )
return 1;
}
-static char *imc_away_alias_find( GList *gcm, char *away );
+static char *imc_away_state_find( GList *gcm, char *away, char **message );
-int imc_set_away( struct im_connection *ic, char *away )
+int imc_away_send_update( struct im_connection *ic )
{
- GList *m, *ms;
- char *s;
-
- if( !away ) away = "";
- ms = m = ic->acc->prpl->away_states( ic );
-
- while( m )
- {
- if( *away )
- {
- if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 )
- break;
- }
- else
- {
- if( g_strcasecmp( m->data, "Available" ) == 0 )
- break;
- if( g_strcasecmp( m->data, "Online" ) == 0 )
- break;
- }
- m = m->next;
- }
+ char *away, *msg = NULL;
- if( m )
+ away = set_getstr( &ic->acc->set, "away" ) ?
+ : set_getstr( &ic->irc->set, "away" );
+ if( away && *away )
{
- ic->acc->prpl->set_away( ic, m->data, *away ? away : NULL );
+ GList *m = ic->acc->prpl->away_states( ic );
+ msg = ic->acc->flags & ACC_FLAG_AWAY_MESSAGE ? away : NULL;
+ away = imc_away_state_find( m, away, &msg ) ? : m->data;
}
- else
+ else if( ic->acc->flags & ACC_FLAG_STATUS_MESSAGE )
{
- s = imc_away_alias_find( ms, away );
- if( s )
- {
- ic->acc->prpl->set_away( ic, s, away );
- if( set_getbool( &ic->irc->set, "debug" ) )
- imcb_log( ic, "Setting away state to %s", s );
- }
- else
- ic->acc->prpl->set_away( ic, GAIM_AWAY_CUSTOM, away );
+ away = NULL;
+ msg = set_getstr( &ic->acc->set, "status" ) ?
+ : set_getstr( &ic->irc->set, "status" );
}
- return( 1 );
+ ic->acc->prpl->set_away( ic, away, msg );
+
+ return 1;
}
static char *imc_away_alias_list[8][5] =
@@ -1128,16 +1106,33 @@ static char *imc_away_alias_list[8][5] =
{ NULL }
};
-static char *imc_away_alias_find( GList *gcm, char *away )
+static char *imc_away_state_find( GList *gcm, char *away, char **message )
{
GList *m;
int i, j;
+ for( m = gcm; m; m = m->next )
+ if( g_strncasecmp( m->data, away, strlen( m->data ) ) == 0 )
+ {
+ /* At least the Yahoo! module works better if message
+ contains no data unless it adds something to what
+ we have in state already. */
+ if( strlen( m->data ) == strlen( away ) )
+ *message = NULL;
+
+ return m->data;
+ }
+
for( i = 0; *imc_away_alias_list[i]; i ++ )
{
+ int keep_message;
+
for( j = 0; imc_away_alias_list[i][j]; j ++ )
if( g_strncasecmp( away, imc_away_alias_list[i][j], strlen( imc_away_alias_list[i][j] ) ) == 0 )
+ {
+ keep_message = strlen( away ) != strlen( imc_away_alias_list[i][j] );
break;
+ }
if( !imc_away_alias_list[i][j] ) /* If we reach the end, this row */
continue; /* is not what we want. Next! */
@@ -1145,17 +1140,22 @@ static char *imc_away_alias_find( GList *gcm, char *away )
/* Now find an entry in this row which exists in gcm */
for( j = 0; imc_away_alias_list[i][j]; j ++ )
{
- m = gcm;
- while( m )
- {
+ for( m = gcm; m; m = m->next )
if( g_strcasecmp( imc_away_alias_list[i][j], m->data ) == 0 )
- return( imc_away_alias_list[i][j] );
- m = m->next;
- }
+ {
+ if( !keep_message )
+ *message = NULL;
+
+ return imc_away_alias_list[i][j];
+ }
}
+
+ /* No need to look further, apparently this state doesn't
+ have any good alias for this protocol. */
+ break;
}
- return( NULL );
+ return NULL;
}
void imc_add_allow( struct im_connection *ic, char *handle )
diff --git a/protocols/nogaim.h b/protocols/nogaim.h
index dc6154e2..4fc32281 100644
--- a/protocols/nogaim.h
+++ b/protocols/nogaim.h
@@ -48,7 +48,6 @@
#define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */
#define WEBSITE "http://www.bitlbee.org/"
-#define GAIM_AWAY_CUSTOM "Custom"
/* Sharing flags between all kinds of things. I just hope I won't hit any
limits before 32-bit machines become extinct. ;-) */
@@ -217,8 +216,8 @@ struct prpl {
void (* chat_topic) (struct groupchat *, char *topic);
/* You can tell what away states your protocol supports, so that
- * BitlBee will try to map the IRC away reasons to them, or use
- * GAIM_AWAY_CUSTOM when calling skype_set_away(). */
+ * BitlBee will try to map the IRC away reasons to them. If your
+ * protocol doesn't have any, just return one generic "Away". */
GList *(* away_states)(struct im_connection *ic);
/* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh*
@@ -314,7 +313,7 @@ G_MODULE_EXPORT void imcb_chat_topic( struct groupchat *c, char *who, char *topi
G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );
/* Actions, or whatever. */
-int imc_set_away( struct im_connection *ic, char *away );
+int imc_away_send_update( struct im_connection *ic );
int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags );
int imc_chat_msg( struct groupchat *c, char *msg, int flags );
diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c
index 1118c26d..f0e65f9a 100644
--- a/protocols/oscar/oscar.c
+++ b/protocols/oscar/oscar.c
@@ -379,6 +379,8 @@ static void oscar_init(account_t *acc)
s = set_add( &acc->set, "web_aware", "false", set_eval_bool, acc );
s->flags |= ACC_SET_OFFLINE_ONLY;
}
+
+ acc->flags |= ACC_FLAG_AWAY_MESSAGE;
}
static void oscar_login(account_t *acc) {
@@ -1951,6 +1953,8 @@ static void oscar_get_away(struct im_connection *g, char *who) {
static void oscar_set_away_aim(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message)
{
+ if (state == NULL)
+ state = "";
if (!g_strcasecmp(state, _("Visible"))) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
@@ -1958,7 +1962,9 @@ static void oscar_set_away_aim(struct im_connection *ic, struct oscar_data *od,
} else if (!g_strcasecmp(state, _("Invisible"))) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
return;
- } /* else... */
+ } else if (message == NULL) {
+ message = state;
+ }
if (od->rights.maxawaymsglen == 0)
imcb_error(ic, "oscar_set_away_aim called before locate rights received");
@@ -2001,7 +2007,7 @@ static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od,
no_message = TRUE;
}
- if (!g_strcasecmp(state, "Online")) {
+ if (state == NULL) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
} else if (!g_strcasecmp(state, "Away")) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY);
@@ -2026,7 +2032,7 @@ static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od,
} else if (!g_strcasecmp(state, "Invisible")) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE);
ic->away = g_strdup(msg);
- } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) {
+ } else {
if (no_message) {
aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL);
} else {
@@ -2275,20 +2281,21 @@ static void oscar_rem_deny(struct im_connection *ic, char *who) {
static GList *oscar_away_states(struct im_connection *ic)
{
struct oscar_data *od = ic->proto_data;
- GList *m = NULL;
-
- if (!od->icq)
- return g_list_append(m, GAIM_AWAY_CUSTOM);
- m = g_list_append(m, "Online");
- m = g_list_append(m, "Away");
- m = g_list_append(m, "Do Not Disturb");
- m = g_list_append(m, "Not Available");
- m = g_list_append(m, "Occupied");
- m = g_list_append(m, "Free For Chat");
- m = g_list_append(m, "Invisible");
-
- return m;
+ if (od->icq) {
+ static GList *m = NULL;
+ m = g_list_append(m, "Away");
+ m = g_list_append(m, "Do Not Disturb");
+ m = g_list_append(m, "Not Available");
+ m = g_list_append(m, "Occupied");
+ m = g_list_append(m, "Free For Chat");
+ m = g_list_append(m, "Invisible");
+ return m;
+ } else {
+ static GList *m = NULL;
+ m = g_list_append(m, "Away");
+ return m;
+ }
}
static int gaim_icqinfo(aim_session_t *sess, aim_frame_t *fr, ...)
diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c
index a1755cc9..721f4b7c 100644
--- a/protocols/yahoo/libyahoo2.c
+++ b/protocols/yahoo/libyahoo2.c
@@ -1529,12 +1529,19 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_
case 7:
newbud = y_new0(struct yahoo_buddy, 1);
newbud->id = strdup(pair->value);
- if(cur_group)
+ if (cur_group) {
newbud->group = strdup(cur_group);
- else {
- struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth(
- yd->buddies, y_list_length(yd->buddies)-1)->data;
- newbud->group = strdup(lastbud->group);
+ } else {
+ YList *last;
+ struct yahoo_buddy *lastbud;
+
+ for (last = yd->buddies; last && last->next; last = last->next);
+ if (last) {
+ lastbud = last->data;
+ newbud->group = strdup(lastbud->group);
+ } else {
+ newbud->group = strdup("Buddies");
+ }
}
yd->buddies = y_list_append(yd->buddies, newbud);
@@ -2392,10 +2399,16 @@ static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had)
static void yahoo_https_auth_token_finish(struct http_request *req)
{
struct yahoo_https_auth_data *had = req->data;
- struct yahoo_input_data *yid = had->yid;
- struct yahoo_data *yd = yid->yd;
+ struct yahoo_input_data *yid;
+ struct yahoo_data *yd;
int st;
+ if (y_list_find(inputs, had->yid) == NULL)
+ return;
+
+ yid = had->yid;
+ yd = yid->yd;
+
if (req->status_code != 200) {
YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL);
goto fail;
@@ -2435,12 +2448,18 @@ static void yahoo_https_auth_init(struct yahoo_https_auth_data *had)
static void yahoo_https_auth_finish(struct http_request *req)
{
struct yahoo_https_auth_data *had = req->data;
- struct yahoo_input_data *yid = had->yid;
- struct yahoo_data *yd = yid->yd;
+ struct yahoo_input_data *yid;
+ struct yahoo_data *yd;
struct yahoo_packet *pack;
- char *crumb;
+ char *crumb = NULL;
int st;
+ if (y_list_find(inputs, had->yid) == NULL)
+ return;
+
+ yid = had->yid;
+ yd = yid->yd;
+
md5_byte_t result[16];
md5_state_t ctx;
@@ -4079,14 +4098,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)
return;
yd = yid->yd;
-
old_status = yd->current_status;
-
- if (msg && strncmp(msg,"Invisible",9)) {
- yd->current_status = YAHOO_STATUS_CUSTOM;
- } else {
- yd->current_status = state;
- }
+ yd->current_status = state;
/* Thank you libpurple :) */
if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
@@ -4101,15 +4114,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)
pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id);
snprintf(s, sizeof(s), "%d", yd->current_status);
yahoo_packet_hash(pkt, 10, s);
-
- if (yd->current_status == YAHOO_STATUS_CUSTOM) {
- yahoo_packet_hash(pkt, 19, msg);
- } else {
- yahoo_packet_hash(pkt, 19, "");
- }
-
+ yahoo_packet_hash(pkt, 19, msg && state == YAHOO_STATUS_CUSTOM ? msg : "");
yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0");
-
yahoo_send_packet(yid, pkt, 0);
yahoo_packet_free(pkt);
diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c
index ac57d4b6..a47de966 100644
--- a/protocols/yahoo/yahoo.c
+++ b/protocols/yahoo/yahoo.c
@@ -129,6 +129,8 @@ static char *byahoo_strip( const char *in )
static void byahoo_init( account_t *acc )
{
set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
+
+ acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
}
static void byahoo_login( account_t *acc )
@@ -196,29 +198,12 @@ static int byahoo_send_typing( struct im_connection *ic, char *who, int typing )
static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )
{
struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;
- char *away;
-
- away = NULL;
- if( state && msg && g_strcasecmp( state, msg ) != 0 )
- {
- yd->current_status = YAHOO_STATUS_CUSTOM;
- away = "";
- }
- else if( state )
+ if( state && msg == NULL )
{
- /* Set msg to NULL since (if it isn't NULL already) it's equal
- to state. msg must be empty if we want to use an existing
- away state. */
- msg = NULL;
-
- away = "";
- if( g_strcasecmp( state, "Available" ) == 0 )
- {
- yd->current_status = YAHOO_STATUS_AVAILABLE;
- away = NULL;
- }
- else if( g_strcasecmp( state, "Be Right Back" ) == 0 )
+ /* Use these states only if msg doesn't contain additional
+ info since away messages are only supported with CUSTOM. */
+ if( g_strcasecmp( state, "Be Right Back" ) == 0 )
yd->current_status = YAHOO_STATUS_BRB;
else if( g_strcasecmp( state, "Busy" ) == 0 )
yd->current_status = YAHOO_STATUS_BUSY;
@@ -238,17 +223,15 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg )
yd->current_status = YAHOO_STATUS_STEPPEDOUT;
else if( g_strcasecmp( state, "Invisible" ) == 0 )
yd->current_status = YAHOO_STATUS_INVISIBLE;
- else if( g_strcasecmp( state, GAIM_AWAY_CUSTOM ) == 0 )
- {
- yd->current_status = YAHOO_STATUS_AVAILABLE;
-
- away = NULL;
- }
+ else
+ yd->current_status = YAHOO_STATUS_CUSTOM;
}
+ else if( state )
+ yd->current_status = YAHOO_STATUS_CUSTOM;
else
yd->current_status = YAHOO_STATUS_AVAILABLE;
- yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 );
+ yahoo_set_away( yd->y2_id, yd->current_status, msg, state ? 2 : 0 );
}
static GList *byahoo_away_states( struct im_connection *ic )
@@ -257,7 +240,6 @@ static GList *byahoo_away_states( struct im_connection *ic )
if( m == NULL )
{
- m = g_list_append( m, "Available" );
m = g_list_append( m, "Be Right Back" );
m = g_list_append( m, "Busy" );
m = g_list_append( m, "Not At Home" );
@@ -268,7 +250,6 @@ static GList *byahoo_away_states( struct im_connection *ic )
m = g_list_append( m, "Out To Lunch" );
m = g_list_append( m, "Stepped Out" );
m = g_list_append( m, "Invisible" );
- m = g_list_append( m, GAIM_AWAY_CUSTOM );
}
return m;
diff --git a/root_commands.c b/root_commands.c
index 5de616fb..c79ff325 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -1114,79 +1114,6 @@ static void cmd_chat( irc_t *irc, char **cmd )
{
irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] );
}
-
-
-
-#if 0
- account_t *a;
- struct im_connection *ic;
- char *chat, *channel, *nick = NULL, *password = NULL;
- struct groupchat *c;
-
- if( !( a = account_get( irc, cmd[1] ) ) )
- {
- irc_usermsg( irc, "Invalid account" );
- return;
- }
- else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
- {
- irc_usermsg( irc, "That account is not on-line" );
- return;
- }
- else if( a->prpl->chat_join == NULL )
- {
- irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
- return;
- }
- ic = a->ic;
-
- chat = cmd[2];
- if( cmd[3] )
- {
- if( strchr( CTYPES, cmd[3][0] ) == NULL )
- channel = g_strdup_printf( "&%s", cmd[3] );
- else
- channel = g_strdup( cmd[3] );
- }
- else
- {
- char *s;
-
- channel = g_strdup_printf( "&%s", chat );
- if( ( s = strchr( channel, '@' ) ) )
- *s = 0;
- }
- if( cmd[3] && cmd[4] )
- nick = cmd[4];
- else
- nick = irc->nick;
- if( cmd[3] && cmd[4] && cmd[5] )
- password = cmd[5];
-
- if( !nick_ok( channel + 1 ) )
- {
- irc_usermsg( irc, "Invalid channel name: %s", channel );
- g_free( channel );
- return;
- }
- else if( g_strcasecmp( channel, irc->channel ) == 0 || irc_chat_by_channel( irc, channel ) )
- {
- irc_usermsg( irc, "Channel already exists: %s", channel );
- g_free( channel );
- return;
- }
-
- if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) )
- {
- g_free( c->channel );
- c->channel = channel;
- }
- else
- {
- irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
- g_free( channel );
- }
-#endif
}
const command_t commands[] = {
diff --git a/unix.c b/unix.c
index 56b0ab46..7088d0f8 100644
--- a/unix.c
+++ b/unix.c
@@ -24,11 +24,15 @@
*/
#include "bitlbee.h"
+
+#include "arc.h"
+#include "base64.h"
#include "commands.h"
-#include "crypting.h"
#include "protocols/nogaim.h"
#include "help.h"
#include "ipc.h"
+#include "md5.h"
+#include "misc.h"
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
@@ -39,12 +43,17 @@ global_t global; /* Against global namespace pollution */
static void sighandler( int signal );
+static int crypt_main( int argc, char *argv[] );
+
int main( int argc, char *argv[] )
{
int i = 0;
char *old_cwd = NULL;
struct sigaction sig, old;
+ if( argc > 1 && strcmp( argv[1], "-x" ) == 0 )
+ return crypt_main( argc, argv );
+
log_init();
global.conf_file = g_strdup( CONF_FILE_DEF );
global.conf = conf_load( argc, argv );
@@ -158,6 +167,64 @@ int main( int argc, char *argv[] )
return( 0 );
}
+static int crypt_main( int argc, char *argv[] )
+{
+ int pass_len;
+ unsigned char *pass_cr, *pass_cl;
+
+ if( argc < 4 || ( strcmp( argv[2], "hash" ) != 0 &&
+ strcmp( argv[2], "unhash" ) != 0 && argc < 5 ) )
+ {
+ printf( "Supported:\n"
+ " %s -x enc <key> <cleartext password>\n"
+ " %s -x dec <key> <encrypted password>\n"
+ " %s -x hash <cleartext password>\n"
+ " %s -x unhash <hashed password>\n"
+ " %s -x chkhash <hashed password> <cleartext password>\n",
+ argv[0], argv[0], argv[0], argv[0], argv[0] );
+ }
+ else if( strcmp( argv[2], "enc" ) == 0 )
+ {
+ pass_len = arc_encode( argv[4], strlen( argv[4] ), (unsigned char**) &pass_cr, argv[3], 12 );
+ printf( "%s\n", base64_encode( pass_cr, pass_len ) );
+ }
+ else if( strcmp( argv[2], "dec" ) == 0 )
+ {
+ pass_len = base64_decode( argv[4], (unsigned char**) &pass_cr );
+ arc_decode( pass_cr, pass_len, (char**) &pass_cl, argv[3] );
+ printf( "%s\n", pass_cl );
+ }
+ else if( strcmp( argv[2], "hash" ) == 0 )
+ {
+ md5_byte_t pass_md5[21];
+ md5_state_t md5_state;
+
+ random_bytes( pass_md5 + 16, 5 );
+ md5_init( &md5_state );
+ md5_append( &md5_state, (md5_byte_t*) argv[3], strlen( argv[3] ) );
+ md5_append( &md5_state, pass_md5 + 16, 5 ); /* Add the salt. */
+ md5_finish( &md5_state, pass_md5 );
+
+ printf( "%s\n", base64_encode( pass_md5, 21 ) );
+ }
+ else if( strcmp( argv[2], "unhash" ) == 0 )
+ {
+ printf( "Hash %s submitted to a massive Beowulf cluster of\n"
+ "overclocked 486s. Expect your answer next year somewhere around this time. :-)\n", argv[3] );
+ }
+ else if( strcmp( argv[2], "chkhash" ) == 0 )
+ {
+ char *hash = strncmp( argv[3], "md5:", 4 ) == 0 ? argv[3] + 4 : argv[3];
+ int st = md5_verify_password( argv[4], hash );
+
+ printf( "Hash %s given password.\n", st == 0 ? "matches" : "does not match" );
+
+ return st;
+ }
+
+ return 0;
+}
+
static void sighandler( int signal )
{
/* FIXME: Calling log_message() here is not a very good idea! */
@@ -213,5 +280,3 @@ double gettime()
gettimeofday( time, 0 );
return( (double) time->tv_sec + (double) time->tv_usec / 1000000 );
}
-
-