diff options
author | Sven Moritz Hallberg <pesco@khjk.org> | 2009-03-12 20:10:06 +0100 |
---|---|---|
committer | Sven Moritz Hallberg <pesco@khjk.org> | 2009-03-12 20:10:06 +0100 |
commit | 823de9d44f262ea2364ac8ec6a1e18e0f7dab658 (patch) | |
tree | bfe64e4fafbcd13aaef6a436cab6ad91619e2821 | |
parent | 9b55485a6f9d72334b372e6fb6b60bbde943170d (diff) |
commit updates by ashish shukla <wahjava@gmail.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | account.c | 123 | ||||
-rw-r--r-- | account.h | 9 | ||||
-rw-r--r-- | bitlbee.h | 5 | ||||
-rw-r--r-- | conf.c | 7 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/CHANGES | 21 | ||||
-rw-r--r-- | doc/user-guide/commands.xml | 10 | ||||
-rw-r--r-- | ipc.c | 35 | ||||
-rw-r--r-- | ipc.h | 3 | ||||
-rw-r--r-- | irc.c | 79 | ||||
-rw-r--r-- | irc_commands.c | 1 | ||||
-rw-r--r-- | lib/ssl_bogus.c | 5 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 2 | ||||
-rw-r--r-- | protocols/jabber/jabber_util.c | 4 | ||||
-rw-r--r-- | protocols/msn/msn.c | 61 | ||||
-rw-r--r-- | protocols/msn/msn.h | 6 | ||||
-rw-r--r-- | protocols/msn/ns.c | 23 | ||||
-rw-r--r-- | protocols/msn/sb.c | 42 | ||||
-rw-r--r-- | protocols/nogaim.c | 10 | ||||
-rw-r--r-- | protocols/yahoo/libyahoo2.c | 2 | ||||
-rw-r--r-- | protocols/yahoo/yahoo.c | 3 | ||||
-rw-r--r-- | protocols/yahoo/yahoo_httplib.c | 2 | ||||
-rw-r--r-- | root_commands.c | 91 | ||||
-rw-r--r-- | set.c | 55 | ||||
-rw-r--r-- | set.h | 10 | ||||
-rw-r--r-- | sock.h | 8 | ||||
-rw-r--r-- | storage.c | 37 | ||||
-rw-r--r-- | storage.h | 8 | ||||
-rw-r--r-- | storage_text.c | 21 | ||||
-rw-r--r-- | storage_xml.c | 26 | ||||
-rw-r--r-- | unix.c | 16 |
32 files changed, 445 insertions, 284 deletions
@@ -106,7 +106,7 @@ tar: fakeroot debian/rules clean || make distclean x=$$(basename $$(pwd)); \ cd ..; \ - tar czf $$x.tar.gz --exclude=debian --exclude=.bzr $$x + tar czf $$x.tar.gz --exclude=debian --exclude=.bzr* $$x $(subdirs): @$(MAKE) -C $@ $(MAKECMDGOALS) @@ -54,7 +54,7 @@ account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass ) s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a ); s = set_add( &a->set, "password", NULL, set_eval_account, a ); - s->flags |= ACC_SET_NOSAVE; + s->flags |= ACC_SET_NOSAVE | SET_NULL_OK; s = set_add( &a->set, "username", NULL, set_eval_account, a ); s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; @@ -76,9 +76,23 @@ char *set_eval_account( set_t *set, char *value ) /* Double-check: We refuse to edit on-line accounts. */ if( set->flags & ACC_SET_OFFLINE_ONLY && acc->ic ) - return NULL; + return SET_INVALID; - if( strcmp( set->key, "username" ) == 0 ) + if( strcmp( set->key, "server" ) == 0 ) + { + g_free( acc->server ); + if( value && *value ) + { + acc->server = g_strdup( value ); + return value; + } + else + { + acc->server = g_strdup( set->def ); + return g_strdup( set->def ); + } + } + else if( strcmp( set->key, "username" ) == 0 ) { g_free( acc->user ); acc->user = g_strdup( value ); @@ -86,34 +100,29 @@ char *set_eval_account( set_t *set, char *value ) } else if( strcmp( set->key, "password" ) == 0 ) { - g_free( acc->pass ); - acc->pass = g_strdup( value ); - return NULL; /* password shouldn't be visible in plaintext! */ - } - else if( strcmp( set->key, "server" ) == 0 ) - { - g_free( acc->server ); - if( *value ) + if( value ) { - acc->server = g_strdup( value ); - return value; + g_free( acc->pass ); + acc->pass = g_strdup( value ); + return NULL; /* password shouldn't be visible in plaintext! */ } else { - acc->server = NULL; - return g_strdup( set->def ); + /* NULL can (should) be stored in the set_t + variable, but is otherwise not correct. */ + return SET_INVALID; } } else if( strcmp( set->key, "auto_connect" ) == 0 ) { if( !is_bool( value ) ) - return NULL; + return SET_INVALID; acc->auto_connect = bool2int( value ); return value; } - return NULL; + return SET_INVALID; } account_t *account_get( irc_t *irc, char *id ) @@ -233,3 +242,83 @@ void account_off( irc_t *irc, account_t *a ) cancel_auto_reconnect( a ); } } + +struct account_reconnect_delay +{ + int start; + char op; + int step; + int max; +}; + +int account_reconnect_delay_parse( char *value, struct account_reconnect_delay *p ) +{ + memset( p, 0, sizeof( *p ) ); + /* A whole day seems like a sane "maximum maximum". */ + p->max = 86400; + + /* Format: /[0-9]+([*+][0-9]+(<[0-9+]))/ */ + while( *value && isdigit( *value ) ) + p->start = p->start * 10 + *value++ - '0'; + + /* Sure, call me evil for implementing my own fscanf here, but it's + dead simple and I immediately know where to continue parsing. */ + + if( *value == 0 ) + /* If the string ends now, the delay is constant. */ + return 1; + else if( *value != '+' && *value != '*' ) + /* Otherwise allow either a + or a * */ + return 0; + + p->op = *value++; + + /* + or * the delay by this number every time. */ + while( *value && isdigit( *value ) ) + p->step = p->step * 10 + *value++ - '0'; + + if( *value == 0 ) + /* Use the default maximum (one day). */ + return 1; + else if( *value != '<' ) + return 0; + + p->max = 0; + value ++; + while( *value && isdigit( *value ) ) + p->max = p->max * 10 + *value++ - '0'; + + return p->max > 0; +} + +char *set_eval_account_reconnect_delay( set_t *set, char *value ) +{ + struct account_reconnect_delay p; + + return account_reconnect_delay_parse( value, &p ) ? value : SET_INVALID; +} + +int account_reconnect_delay( account_t *a ) +{ + char *setting = set_getstr( &a->irc->set, "auto_reconnect_delay" ); + struct account_reconnect_delay p; + + if( account_reconnect_delay_parse( setting, &p ) ) + { + if( a->auto_reconnect_delay == 0 ) + a->auto_reconnect_delay = p.start; + else if( p.op == '+' ) + a->auto_reconnect_delay += p.step; + else if( p.op == '*' ) + a->auto_reconnect_delay *= p.step; + + if( a->auto_reconnect_delay > p.max ) + a->auto_reconnect_delay = p.max; + } + else + { + a->auto_reconnect_delay = 0; + } + + return a->auto_reconnect_delay; +} @@ -34,6 +34,7 @@ typedef struct account char *server; int auto_connect; + int auto_reconnect_delay; int reconnect; set_t *set; @@ -51,9 +52,11 @@ void account_on( irc_t *irc, account_t *a ); void account_off( irc_t *irc, account_t *a ); 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 1 -#define ACC_SET_OFFLINE_ONLY 2 -#define ACC_SET_ONLINE_ONLY 4 +#define ACC_SET_NOSAVE 0x01 +#define ACC_SET_OFFLINE_ONLY 0x02 +#define ACC_SET_ONLINE_ONLY 0x04 #endif @@ -31,8 +31,11 @@ /* Depend on Windows 2000 for now since we need getaddrinfo() */ #define _WIN32_WINNT 0x0501 +/* Depend on Windows 2000 for now since we need getaddrinfo() */ +#define _WIN32_WINNT 0x0501 + #define PACKAGE "BitlBee" -#define BITLBEE_VERSION "1.2.1" +#define BITLBEE_VERSION "1.2.3" #define VERSION BITLBEE_VERSION #define MAX_STRING 511 @@ -146,6 +146,13 @@ conf_t *conf_load( int argc, char *argv[] ) " -h Show this help page.\n" ); return NULL; } + else if( opt == 'R' ) + { + /* Backward compatibility; older BitlBees passed this + info using a command-line flag. Allow people to + upgrade from such a version for now. */ + setenv( "_BITLBEE_RESTART_STATE", optarg, 0 ); + } else if( opt == 'u' ) { g_free( conf->user ); @@ -71,7 +71,7 @@ Option Description Default --strip=0/1 Disable/enable binary stripping $strip --gcov=0/1 Disable/enable test coverage reporting $gcov --plugins=0/1 Disable/enable plugins support $plugins ---otr=0/1/auto Disable/enable OTR encryption support $otr +--otr=0/1 Disable/enable OTR encryption support $otr --events=... Event handler (glib, libevent) $events --ssl=... SSL library to use (gnutls, nss, openssl, bogus, auto) diff --git a/doc/CHANGES b/doc/CHANGES index ac1f1f02..84dbe162 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -3,6 +3,27 @@ found in the bzr commit logs, for example you can try: http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on +Version 1.2.3: +- Fixed one more flaw similar to the previous hijacking bug, caused by incon- + sistent handling of the USTATUS_IDENTIFIED state. All code touching these + variables was reviewed and should be correct now. + +Finished 7 Sep 2008 + +Version 1.2.2: +- Security bugfix: It was possible to hijack accounts (without gaining access + to the old account, it's simply an overwrite) +- Some more stability improvements. +- Fixed bug where people with non-lowercase nicks couldn't drop their account. +- Easier upgrades of non-forking daemon mode servers (using the DEAF + command). +- Can be cross-compiled for Win32 now! (No support for SSL yet though, which + makes it less useful for now.) +- Exponential backoff on auto-reconnect. +- Changing passwords gives less confusing feedback ("password is empty") now. + +Finished 26 Aug 2008 + Version 1.2.1: - Fixed proxy support. - Fixed stalling issues while connecting to Jabber when using the OpenSSL diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index f0653232..3a7bd5a8 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -469,12 +469,16 @@ </description> </bitlbee-setting> - <bitlbee-setting name="auto_reconnect_delay" type="integer" scope="global"> - <default>300</default> + <bitlbee-setting name="auto_reconnect_delay" type="string" scope="global"> + <default>5*3<900</default> <description> <para> - Tell BitlBee after how many seconds it should attempt to bring an IM-connection back up after a crash. It's not a good idea to set this value very low, it will cause too much useless traffic when an IM-server is down for a few hours. + Tell BitlBee after how many seconds it should attempt to bring a broken IM-connection back up. + </para> + + <para> + This can be one integer, for a constant delay. One can also set it to something like "10*10", which means wait for ten seconds on the first reconnect, multiply it by ten on every failure. Once successfully connected, this delay is re-set to the initial value. With < you can give a maximum delay. </para> <para> @@ -32,6 +32,7 @@ #endif GSList *child_list = NULL; +static char *statefile = NULL; static void ipc_master_cmd_client( irc_t *data, char **cmd ) { @@ -61,25 +62,6 @@ static void ipc_master_cmd_die( irc_t *data, char **cmd ) bitlbee_shutdown( NULL, -1, 0 ); } -static void ipc_master_cmd_deaf( irc_t *data, char **cmd ) -{ - if( global.conf->runmode == RUNMODE_DAEMON ) - { - b_event_remove( global.listen_watch_source_id ); - close( global.listen_socket ); - - global.listen_socket = global.listen_watch_source_id = -1; - - ipc_to_children_str( "OPERMSG :Closed listening socket, waiting " - "for all users to disconnect." ); - } - else - { - ipc_to_children_str( "OPERMSG :The DEAF command only works in " - "normal daemon mode. Try DIE instead." ); - } -} - void ipc_master_cmd_rehash( irc_t *data, char **cmd ) { runmode_t oldmode; @@ -115,7 +97,6 @@ static const command_t ipc_master_commands[] = { { "client", 3, ipc_master_cmd_client, 0 }, { "hello", 0, ipc_master_cmd_client, 0 }, { "die", 0, ipc_master_cmd_die, 0 }, - { "deaf", 0, ipc_master_cmd_deaf, 0 }, { "wallops", 1, NULL, IPC_CMD_TO_CHILDREN }, { "wall", 1, NULL, IPC_CMD_TO_CHILDREN }, { "opermsg", 1, NULL, IPC_CMD_TO_CHILDREN }, @@ -459,7 +440,6 @@ void ipc_child_disable() global.listen_socket = -1; } -#ifndef _WIN32 char *ipc_master_save_state() { char *fn = g_strdup( "/tmp/bee-restart.XXXXXX" ); @@ -500,6 +480,11 @@ char *ipc_master_save_state() } } +void ipc_master_set_statefile( char *fn ) +{ + statefile = g_strdup( fn ); +} + static gboolean new_ipc_client( gpointer data, gint serversock, b_input_condition cond ) { @@ -520,6 +505,7 @@ static gboolean new_ipc_client( gpointer data, gint serversock, b_input_conditio return TRUE; } +#ifndef _WIN32 int ipc_master_listen_socket() { struct sockaddr_un un_addr; @@ -556,14 +542,10 @@ int ipc_master_listen_socket() return 1; } #else -int ipc_master_listen_socket() -{ /* FIXME: Open named pipe \\.\BITLBEE */ - return 0; -} #endif -int ipc_master_load_state( char *statefile ) +int ipc_master_load_state() { struct bitlbee_child *child; FILE *fp; @@ -571,7 +553,6 @@ int ipc_master_load_state( char *statefile ) if( statefile == NULL ) return 0; - fp = fopen( statefile, "r" ); unlink( statefile ); /* Why do it later? :-) */ if( fp == NULL ) @@ -57,7 +57,8 @@ void ipc_to_children_str( char *format, ... ) G_GNUC_PRINTF( 1, 2 ); void ipc_master_cmd_rehash( irc_t *data, char **cmd ); char *ipc_master_save_state(); -int ipc_master_load_state( char *statefile ); +void ipc_master_set_statefile( char *fn ); +int ipc_master_load_state(); int ipc_master_listen_socket(); extern GSList *child_list; @@ -32,17 +32,23 @@ #include <sys/wait.h> static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); -static void irc_welcome( irc_t *irc ); +static void irc_welcome( irc_t* irc ); GSList *irc_connection_list = NULL; -static char *passchange( set_t *set, char *value ) +static char *set_eval_password( set_t *set, char *value ) { irc_t *irc = set->data; - irc_setpass( irc, value ); - irc_usermsg( irc, "Password successfully changed" ); - return NULL; + if( irc->status & USTATUS_IDENTIFIED && value ) + { + irc_setpass( irc, value ); + return NULL; + } + else + { + return SET_INVALID; + } } static char *set_eval_charset( set_t *set, char *value ) @@ -79,6 +85,7 @@ irc_t *irc_new( int fd ) irc_t *irc; struct sockaddr_storage sock; socklen_t socklen = sizeof( sock ); + set_t *s; irc = g_new0( irc_t, 1 ); @@ -138,38 +145,38 @@ irc_t *irc_new( int fd ) irc_connection_list = g_slist_append( irc_connection_list, irc ); - set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); - set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); - set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); - set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); - set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); - set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); - set_add( &irc->set, "color_encrypted", "true", set_eval_bool, irc ); - set_add( &irc->set, "debug", "false", set_eval_bool, irc ); - set_add( &irc->set, "default_target", "root", NULL, irc ); - set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); - set_add( &irc->set, "handle_unknown", "root", NULL, irc ); - set_add( &irc->set, "halfop_buddies", "encrypted", set_eval_halfop_buddies, irc ); - set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); - set_add( &irc->set, "op_buddies", "trusted", set_eval_op_buddies, irc ); - set_add( &irc->set, "op_root", "true", set_eval_op_root, irc ); - set_add( &irc->set, "op_user", "true", set_eval_op_user, irc ); - set_add( &irc->set, "otr_policy", "opportunistic", set_eval_otr_policy, irc ); - set_add( &irc->set, "password", NULL, passchange, irc ); - set_add( &irc->set, "private", "true", set_eval_bool, irc ); - set_add( &irc->set, "query_order", "lifo", NULL, irc ); - set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); - set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); - set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); - set_add( &irc->set, "strip_html", "true", NULL, irc ); - set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); - set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); - set_add( &irc->set, "voice_buddies", "notaway", set_eval_voice_buddies, 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 ); + s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); + s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); + s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); + s = set_add( &irc->set, "color_encrypted", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "debug", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "default_target", "root", NULL, irc ); + s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); + s = set_add( &irc->set, "handle_unknown", "root", NULL, irc ); + s = set_add( &irc->set, "halfop_buddies", "encrypted", set_eval_halfop_buddies, irc ); + s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "op_buddies", "trusted", set_eval_op_buddies, irc ); + s = set_add( &irc->set, "op_root", "true", set_eval_op_root, irc ); + s = set_add( &irc->set, "otr_policy", "oppurtunistic", set_eval_otr_policy, irc ); + s = set_add( &irc->set, "password", NULL, set_eval_password, irc ); + s->flags |= SET_NULL_OK; + s = set_add( &irc->set, "private", "true", set_eval_bool, irc ); + s = set_add( &irc->set, "query_order", "lifo", NULL, irc ); + 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, "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 ); + s = set_add( &irc->set, "voice_buddies", "notaway", set_eval_voice_buddies, irc); conf_loaddefaults( irc ); irc->otr = otr_new(); - + /* Evaluator sets the iconv/oconv structures. */ set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); @@ -240,7 +247,7 @@ void irc_free( irc_t * irc ) log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) - if( storage_save( irc, TRUE ) != STORAGE_OK ) + if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) irc_usermsg( irc, "Error while saving settings!" ); irc_connection_list = g_slist_remove( irc_connection_list, irc ); @@ -321,11 +328,11 @@ void irc_free( irc_t * irc ) g_free( irc->channel ); g_free( irc->last_target ); - + otr_free(irc->otr); g_free( irc ); - + if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON || ( global.conf->runmode == RUNMODE_DAEMON && diff --git a/irc_commands.c b/irc_commands.c index fb2bc7cf..6a47007a 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -625,7 +625,6 @@ static const command_t irc_commands[] = { { "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN }, { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN }, { "die", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, - { "deaf", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, { "wallops", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, { "wall", 1, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, { "rehash", 0, irc_cmd_rehash, IRC_CMD_OPER_ONLY }, diff --git a/lib/ssl_bogus.c b/lib/ssl_bogus.c index 6eea18c7..22226592 100644 --- a/lib/ssl_bogus.c +++ b/lib/ssl_bogus.c @@ -69,3 +69,8 @@ int ssl_pending( void *conn ) { return 0; } + +int ssl_pending( void *conn ) +{ + return 0; +} diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index 5fb2c4fc..518c9506 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -69,7 +69,7 @@ static void jabber_init( account_t *acc ) s = set_add( &acc->set, "resource_select", "priority", NULL, acc ); s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); - s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; + s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 1bee5009..19a73b6a 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -36,10 +36,10 @@ char *set_eval_priority( set_t *set, char *value ) { /* Priority is a signed 8-bit integer, according to RFC 3921. */ if( i < -128 || i > 127 ) - return NULL; + return SET_INVALID; } else - return NULL; + return SET_INVALID; /* Only run this stuff if the account is online ATM, and if the setting seems to be acceptable. */ diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 335ae894..05eae541 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -112,7 +112,6 @@ static void msn_logout( struct im_connection *ic ) static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) { struct msn_switchboard *sb; - struct msn_data *md = ic->proto_data; if( ( sb = msn_sb_by_handle( ic, who ) ) ) { @@ -121,47 +120,13 @@ static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, in else { struct msn_message *m; - char buf[1024]; /* Create a message. We have to arrange a usable switchboard, and send the message later. */ m = g_new0( struct msn_message, 1 ); m->who = g_strdup( who ); m->text = g_strdup( message ); - /* FIXME: *CHECK* the reliability of using spare sb's! */ - if( ( sb = msn_sb_spare( ic ) ) ) - { - debug( "Trying to use a spare switchboard to message %s", who ); - - sb->who = g_strdup( who ); - g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who ); - if( msn_sb_write( sb, buf, strlen( buf ) ) ) - { - /* He/She should join the switchboard soon, let's queue the message. */ - sb->msgq = g_slist_append( sb->msgq, m ); - return( 1 ); - } - } - - debug( "Creating a new switchboard to message %s", who ); - - /* If we reach this line, there was no spare switchboard, so let's make one. */ - g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); - if( !msn_write( ic, buf, strlen( buf ) ) ) - { - g_free( m->who ); - g_free( m->text ); - g_free( m ); - - return( 0 ); - } - - /* And queue the message to md. We'll pick it up when the switchboard comes up. */ - md->msgq = g_slist_append( md->msgq, m ); - - /* FIXME: If the switchboard creation fails, the message will not be sent. */ - - return( 1 ); + return msn_sb_write_msg( ic, m ); } return( 0 ); @@ -251,8 +216,6 @@ static void msn_chat_leave( struct groupchat *c ) static struct groupchat *msn_chat_with( struct im_connection *ic, char *who ) { struct msn_switchboard *sb; - struct msn_data *md = ic->proto_data; - char buf[1024]; if( ( sb = msn_sb_by_handle( ic, who ) ) ) { @@ -263,31 +226,13 @@ static struct groupchat *msn_chat_with( struct im_connection *ic, char *who ) { struct msn_message *m; - if( ( sb = msn_sb_spare( ic ) ) ) - { - debug( "Trying to reuse an existing switchboard as a groupchat with %s", who ); - g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who ); - if( msn_sb_write( sb, buf, strlen( buf ) ) ) - return msn_sb_to_chat( sb ); - } - - /* If the stuff above failed for some reason: */ - debug( "Creating a new switchboard to groupchat with %s", who ); - - /* Request a new switchboard. */ - g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); - if( !msn_write( ic, buf, strlen( buf ) ) ) - return( 0 ); - /* Create a magic message. This is quite hackish, but who cares? :-P */ m = g_new0( struct msn_message, 1 ); m->who = g_strdup( who ); m->text = g_strdup( GROUPCHAT_SWITCHBOARD_MESSAGE ); - /* Queue the magic message and cross your fingers. */ - md->msgq = g_slist_append( md->msgq, m ); - - /* FIXME: Can I try to return something here already? */ + msn_sb_write_msg( ic, m ); + return NULL; } diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 63759303..7c849acf 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -23,6 +23,9 @@ Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _MSN_H +#define _MSN_H + /* Some hackish magicstrings to make special-purpose messages/switchboards. */ #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r" @@ -175,3 +178,6 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text ); struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb ); void msn_sb_destroy( struct msn_switchboard *sb ); gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); +int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); + +#endif //_MSN_H diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index fe48f96d..ffaa90a7 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -277,25 +277,11 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) { if( num_parts == 5 ) { - int i, groupcount; - - groupcount = atoi( cmd[4] ); - if( groupcount > 0 ) - { - /* valgrind says this is leaking memory, I'm guessing - that this happens during server redirects. */ - if( md->grouplist ) - { - for( i = 0; i < md->groupcount; i ++ ) - g_free( md->grouplist[i] ); - g_free( md->grouplist ); - } - - md->groupcount = groupcount; + md->buddycount = atoi( cmd[3] ); + md->groupcount = atoi( cmd[4] ); + if( md->groupcount > 0 ) md->grouplist = g_new0( char *, md->groupcount ); - } - md->buddycount = atoi( cmd[3] ); if( !*cmd[3] || md->buddycount == 0 ) msn_logged_in( ic ); } @@ -678,9 +664,6 @@ static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int { imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders ); } - - g_free( inbox ); - g_free( folders ); } else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 ) { diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 18c41ef5..e9526234 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -47,6 +47,48 @@ int msn_sb_write( struct msn_switchboard *sb, char *s, int len ) return( 1 ); } +int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ) +{ + struct msn_data *md = ic->proto_data; + struct msn_switchboard *sb; + char buf[1024]; + + /* FIXME: *CHECK* the reliability of using spare sb's! */ + if( ( sb = msn_sb_spare( ic ) ) ) + { + debug( "Trying to use a spare switchboard to message %s", m->who ); + + sb->who = g_strdup( m->who ); + g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, m->who ); + if( msn_sb_write( sb, buf, strlen( buf ) ) ) + { + /* He/She should join the switchboard soon, let's queue the message. */ + sb->msgq = g_slist_append( sb->msgq, m ); + return( 1 ); + } + } + + debug( "Creating a new switchboard to message %s", m->who ); + + /* If we reach this line, there was no spare switchboard, so let's make one. */ + g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); + if( !msn_write( ic, buf, strlen( buf ) ) ) + { + g_free( m->who ); + g_free( m->text ); + g_free( m ); + + return( 0 ); + } + + /* And queue the message to md. We'll pick it up when the switchboard comes up. */ + md->msgq = g_slist_append( md->msgq, m ); + + /* FIXME: If the switchboard creation fails, the message will not be sent. */ + + return( 1 ); +} + struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session ) { struct msn_data *md = ic->proto_data; diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 95d950ca..e6a89dfd 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -266,6 +266,10 @@ void imcb_connected( struct im_connection *ic ) /* Also necessary when we're not away, at least for some of the protocols. */ imc_set_away( ic, u->away ); + + /* Apparently we're connected successfully, so reset the + exponential backoff timer. */ + ic->acc->auto_reconnect_delay = 0; } gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) @@ -289,6 +293,7 @@ void imc_logout( struct im_connection *ic, int allow_reconnect ) irc_t *irc = ic->irc; user_t *t, *u; account_t *a; + int delay; /* Nested calls might happen sometimes, this is probably the best place to catch them. */ @@ -328,10 +333,9 @@ void imc_logout( struct im_connection *ic, int allow_reconnect ) /* Uhm... This is very sick. */ } else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) && - set_getbool( &a->set, "auto_reconnect" ) ) + set_getbool( &a->set, "auto_reconnect" ) && + ( delay = account_reconnect_delay( a ) ) > 0 ) { - int delay = set_getint( &irc->set, "auto_reconnect_delay" ); - imcb_log( ic, "Reconnecting in %d seconds..", delay ); a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a ); } diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index a61955c4..897ba27b 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -68,6 +68,8 @@ char *strchr (), *strrchr (); #ifdef __MINGW32__ # include <winsock2.h> +# define write(a,b,c) send(a,b,c,0) +# define read(a,b,c) recv(a,b,c,0) #endif #include <stdlib.h> diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 0db6e27a..8feb6639 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -665,9 +665,6 @@ void ext_yahoo_error( int id, const char *err, int fatal, int num ) struct im_connection *ic = byahoo_get_ic_by_id( id ); imcb_error( ic, "%s", err ); - - if( fatal ) - imc_logout( ic, TRUE ); } /* TODO: Clear up the mess of inp and d structures */ diff --git a/protocols/yahoo/yahoo_httplib.c b/protocols/yahoo/yahoo_httplib.c index 1b084992..dbbe2a84 100644 --- a/protocols/yahoo/yahoo_httplib.c +++ b/protocols/yahoo/yahoo_httplib.c @@ -50,6 +50,8 @@ char *strchr (), *strrchr (); #include "yahoo_debug.h" #ifdef __MINGW32__ # include <winsock2.h> +# define write(a,b,c) send(a,b,c,0) +# define read(a,b,c) recv(a,b,c,0) # define snprintf _snprintf #endif diff --git a/root_commands.c b/root_commands.c index 2f00eca8..ffa163bb 100644 --- a/root_commands.c +++ b/root_commands.c @@ -131,7 +131,7 @@ static void cmd_account( irc_t *irc, char **cmd ); static void cmd_identify( irc_t *irc, char **cmd ) { - storage_status_t status = storage_load( irc->nick, cmd[1], irc ); + storage_status_t status = storage_load( irc, cmd[1] ); char *account_on[] = { "account", "on", NULL }; switch (status) { @@ -143,6 +143,8 @@ static void cmd_identify( irc_t *irc, char **cmd ) break; case STORAGE_OK: irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); + irc_setpass( irc, cmd[1] ); + irc->status |= USTATUS_IDENTIFIED; irc_umode_set( irc, "+R", 1 ); if( set_getbool( &irc->set, "auto_connect" ) ) cmd_account( irc, account_on ); @@ -162,14 +164,14 @@ static void cmd_register( irc_t *irc, char **cmd ) return; } - irc_setpass( irc, cmd[1] ); - switch( storage_save( irc, FALSE )) { + switch( storage_save( irc, cmd[1], FALSE ) ) { case STORAGE_ALREADY_EXISTS: irc_usermsg( irc, "Nick is already registered" ); break; case STORAGE_OK: irc_usermsg( irc, "Account successfully created" ); + irc_setpass( irc, cmd[1] ); irc->status |= USTATUS_IDENTIFIED; irc_umode_set( irc, "+R", 1 ); break; @@ -238,6 +240,16 @@ void cmd_account_del_no( void *data ) g_free( data ); } +static void cmd_showset( irc_t *irc, set_t **head, char *key ) +{ + char *val; + + if( ( val = set_getstr( head, key ) ) ) + irc_usermsg( irc, "%s = `%s'", key, val ); + else + irc_usermsg( irc, "%s is empty", key ); +} + static void cmd_account( irc_t *irc, char **cmd ) { account_t *a; @@ -449,6 +461,7 @@ static void cmd_account( irc_t *irc, char **cmd ) if( cmd[3] && set_name ) { set_t *s = set_find( &a->set, set_name ); + int st; if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) { @@ -464,27 +477,32 @@ static void cmd_account( irc_t *irc, char **cmd ) } if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) - set_reset( &a->set, set_name ); + st = set_reset( &a->set, set_name ); + else + st = set_setstr( &a->set, set_name, cmd[3] ); + + if( set_getstr( &a->set, set_name ) == NULL ) + { + if( st ) + irc_usermsg( irc, "Setting changed successfully" ); + else + irc_usermsg( irc, "Failed to change setting" ); + } else - set_setstr( &a->set, set_name, cmd[3] ); + { + cmd_showset( irc, &a->set, set_name ); + } } - if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ + else if( set_name ) { - char *s = set_getstr( &a->set, set_name ); - if( s ) - irc_usermsg( irc, "%s = `%s'", set_name, s ); - else - irc_usermsg( irc, "%s is empty", set_name ); + cmd_showset( irc, &a->set, set_name ); } else { set_t *s = a->set; while( s ) { - if( s->value || s->def ) - irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); - else - irc_usermsg( irc, "%s is empty", s->key ); + cmd_showset( irc, &s, s->key ); s = s->next; } } @@ -614,6 +632,8 @@ static void cmd_rename( irc_t *irc, char **cmd ) g_free( irc->mynick ); irc->mynick = g_strdup( cmd[2] ); + /* If we're called internally (user did "set root_nick"), + let's not go O(INF). :-) */ if( strcmp( cmd[0], "set_rename" ) != 0 ) set_setstr( &irc->set, "root_nick", cmd[2] ); } @@ -637,7 +657,7 @@ char *set_eval_root_nick( set_t *set, char *new_nick ) cmd_rename( irc, cmd ); } - return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL; + return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID; } static void cmd_remove( irc_t *irc, char **cmd ) @@ -825,23 +845,37 @@ static void cmd_set( irc_t *irc, char **cmd ) if( cmd[1] && cmd[2] ) { + int st; + if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) { - set_reset( &irc->set, cmd[2] ); + st = set_reset( &irc->set, cmd[2] ); set_name = cmd[2]; } else { - set_setstr( &irc->set, cmd[1], cmd[2] ); + st = set_setstr( &irc->set, cmd[1], cmd[2] ); + } + + /* Normally we just show the variable's new/unchanged + value as feedback to the user, but this has always + caused confusion when changing the password. Give + other feedback instead: */ + if( set_getstr( &irc->set, set_name ) == NULL ) + { + if( st ) + irc_usermsg( irc, "Setting changed successfully" ); + else + irc_usermsg( irc, "Failed to change setting" ); + } + else + { + cmd_showset( irc, &irc->set, set_name ); } } - if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ + else if( set_name ) { - char *s = set_getstr( &irc->set, set_name ); - if( s ) - irc_usermsg( irc, "%s = `%s'", set_name, s ); - else - irc_usermsg( irc, "%s is empty", set_name ); + cmd_showset( irc, &irc->set, set_name ); if( strchr( set_name, '/' ) ) irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); @@ -851,10 +885,7 @@ static void cmd_set( irc_t *irc, char **cmd ) set_t *s = irc->set; while( s ) { - if( s->value || s->def ) - irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); - else - irc_usermsg( irc, "%s is empty", s->key ); + cmd_showset( irc, &s, s->key ); s = s->next; } } @@ -862,7 +893,9 @@ static void cmd_set( irc_t *irc, char **cmd ) static void cmd_save( irc_t *irc, char **cmd ) { - if( storage_save( irc, TRUE ) == STORAGE_OK ) + if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) + irc_usermsg( irc, "Please create an account first" ); + else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) irc_usermsg( irc, "Configuration saved" ); else irc_usermsg( irc, "Configuration could not be saved!" ); @@ -25,6 +25,9 @@ #define BITLBEE_CORE #include "bitlbee.h" +/* Used to use NULL for this, but NULL is actually a "valid" value. */ +char *SET_INVALID = "nee"; + set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ) { set_t *s = set_find( head, key ); @@ -113,9 +116,20 @@ int set_setstr( set_t **head, char *key, char *value ) char *nv = value; if( !s ) + /* + Used to do this, but it never really made sense. s = set_add( head, key, NULL, NULL, NULL ); + */ + return 0; - if( s->eval && !( nv = s->eval( s, value ) ) ) + if( value == NULL && ( s->flags & SET_NULL_OK ) == 0 ) + return 0; + + /* Call the evaluator. For invalid values, evaluators should now + return SET_INVALID, but previously this was NULL. Try to handle + that too if NULL is not an allowed value for this setting. */ + if( s->eval && ( ( nv = s->eval( s, value ) ) == SET_INVALID || + ( ( s->flags & SET_NULL_OK ) == 0 && nv == NULL ) ) ) return 0; if( s->value ) @@ -167,13 +181,15 @@ void set_del( set_t **head, char *key ) } } -void set_reset( set_t **head, char *key ) +int set_reset( set_t **head, char *key ) { set_t *s; s = set_find( head, key ); if( s ) - set_setstr( head, key, s->def ); + return set_setstr( head, key, s->def ); + + return 0; } char *set_eval_int( set_t *set, char *value ) @@ -186,14 +202,14 @@ char *set_eval_int( set_t *set, char *value ) for( ; *s; s ++ ) if( !isdigit( *s ) ) - return NULL; + return SET_INVALID; return value; } char *set_eval_bool( set_t *set, char *value ) { - return is_bool( value ) ? value : NULL; + return is_bool( value ) ? value : SET_INVALID; } char *set_eval_to_char( set_t *set, char *value ) @@ -208,25 +224,27 @@ char *set_eval_to_char( set_t *set, char *value ) return s; } -char *set_eval_op_root( set_t *set, char *value ) +char* set_eval_op_root( set_t *set, char* value ) { irc_t *irc = set->data; - char *ret = set_eval_bool(set, value); + char* ret = set_eval_bool(set, value); int b = bool2int(ret); - + irc_write( irc, ":%s!%s@%s MODE %s %s %s", irc->mynick, irc->mynick, irc->myhost, - irc->channel, b?"+o":"-o", irc->mynick ); + irc->channel, b?"+o":"-o", irc->mynick); + return ret; } -char *set_eval_op_user( set_t *set, char *value ) +char* set_eval_op_user( set_t *set, char* value ) { irc_t *irc = set->data; - char *ret = set_eval_bool(set, value); + char* ret = set_eval_bool(set, value); int b = bool2int(ret); - + irc_write( irc, ":%s!%s@%s MODE %s %s %s", irc->mynick, irc->mynick, irc->myhost, - irc->channel, b?"+o":"-o", irc->nick ); + irc->channel, b?"+o":"-o", irc->nick); + return ret; } @@ -249,7 +267,7 @@ char *set_eval_mode_buddies( set_t *set, char *value, char modeflag ) mode=3; else return NULL; - + /* sorry for calling them op/deop - too lazy for search+replace :P */ op[0]='\0'; deop[0]='\0'; @@ -334,10 +352,10 @@ char *set_eval_mode_buddies( set_t *set, char *value, char modeflag ) if(*deop) { char *flags = g_strnfill(ndeop, modeflag); irc_write( irc, ":%s!%s@%s MODE %s -%s%s", irc->mynick, irc->mynick, irc->myhost, - irc->channel, flags, deop ); - g_free(flags); - } - + irc->channel, flags, deop ); + g_free(flags); + } + return value; } @@ -369,3 +387,4 @@ char *set_eval_otr_policy( set_t *set, char *value ) return value; return NULL; } + @@ -43,6 +43,10 @@ struct set; typedef char *(*set_eval) ( struct set *set, char *value ); +extern char *SET_INVALID; + +#define SET_NULL_OK 0x0100 + typedef struct set { void *data; /* Here you can save a pointer to the @@ -60,8 +64,8 @@ typedef struct set int flags; /* See account.h, for example. set.c doesn't use this (yet?). */ - /* Eval: Returns NULL if the value is incorrect or exactly the - passed value variable. When returning a corrected value, + /* 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! */ set_eval eval; struct set *next; @@ -87,7 +91,7 @@ G_MODULE_EXPORT int set_getbool( set_t **head, char *key ); int set_setstr( set_t **head, char *key, char *value ); int set_setint( set_t **head, char *key, int value ); void set_del( set_t **head, char *key ); -void set_reset( set_t **head, char *key ); +int set_reset( set_t **head, char *key ); /* Two very useful generic evaluators. */ char *set_eval_int( set_t *set, char *value ); @@ -15,11 +15,17 @@ #endif #else # include <winsock2.h> -# include <ws2tcpip.h> +# ifndef _MSC_VER +# include <ws2tcpip.h> +# endif # if !defined(BITLBEE_CORE) && defined(_MSC_VER) # pragma comment(lib,"bitlbee.lib") # endif # include <io.h> +# define read(a,b,c) recv(a,b,c,0) +# define write(a,b,c) send(a,b,c,0) +# define umask _umask +# define mode_t int # define sock_make_nonblocking(fd) { int non_block = 1; ioctlsocket(fd, FIONBIO, &non_block); } # define sock_make_blocking(fd) { int non_block = 0; ioctlsocket(fd, FIONBIO, &non_block); } # define sockerr_again() (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK) @@ -103,36 +103,52 @@ storage_status_t storage_check_pass (const char *nick, const char *password) return STORAGE_NO_SUCH_USER; } -storage_status_t storage_load (const char *nick, const char *password, irc_t * irc) +storage_status_t storage_load (irc_t * irc, const char *password) { GList *gl; + if (irc && irc->status & USTATUS_IDENTIFIED) + return STORAGE_OTHER_ERROR; + /* Loop until we don't get NO_SUCH_USER */ for (gl = global.storage; gl; gl = gl->next) { storage_t *st = gl->data; storage_status_t status; - status = st->load(nick, password, irc); + status = st->load(irc, password); if (status == STORAGE_OK) { - irc_setpass(irc, password); - otr_load(irc); /* load our OTR userstate */ + otr_load(irc); return status; } - if (status != STORAGE_NO_SUCH_USER) { + if (status != STORAGE_NO_SUCH_USER) return status; - } } return STORAGE_NO_SUCH_USER; } -storage_status_t storage_save (irc_t *irc, int overwrite) +storage_status_t storage_save (irc_t *irc, char *password, int overwrite) { storage_status_t st; + if (password != NULL) { + /* Should only use this in the "register" command. */ + if (irc->password || overwrite) + return STORAGE_OTHER_ERROR; + + irc_setpass(irc, password); + } else if ((irc->status & USTATUS_IDENTIFIED) == 0) { + return STORAGE_NO_SUCH_USER; + } + otr_save(irc); st = ((storage_t *)global.storage->data)->save(irc, overwrite); + + if (password != NULL) { + irc_setpass(irc, NULL); + } + return st; } @@ -149,8 +165,7 @@ storage_status_t storage_remove (const char *nick, const char *password) storage_status_t status; status = st->remove(nick, password); - if (status != STORAGE_NO_SUCH_USER && - status != STORAGE_OK) + if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) ret = status; } if (ret == STORAGE_OK) { @@ -160,6 +175,9 @@ storage_status_t storage_remove (const char *nick, const char *password) return ret; } +#if 0 +Not using this yet. Test thoroughly before adding UI hooks to this function. + storage_status_t storage_rename (const char *onick, const char *nnick, const char *password) { storage_status_t status; @@ -201,3 +219,4 @@ storage_status_t storage_rename (const char *onick, const char *nnick, const cha return STORAGE_OK; } +#endif @@ -44,7 +44,7 @@ typedef struct { storage_status_t (*check_pass) (const char *nick, const char *password); - storage_status_t (*load) (const char *nick, const char *password, irc_t * irc); + storage_status_t (*load) (irc_t *irc, const char *password); storage_status_t (*save) (irc_t *irc, int overwrite); storage_status_t (*remove) (const char *nick, const char *password); @@ -54,11 +54,11 @@ typedef struct { storage_status_t storage_check_pass (const char *nick, const char *password); -storage_status_t storage_load (const char *nick, const char *password, irc_t * irc); -storage_status_t storage_save (irc_t *irc, int overwrite); +storage_status_t storage_load (irc_t * irc, const char *password); +storage_status_t storage_save (irc_t *irc, char *password, int overwrite); storage_status_t storage_remove (const char *nick, const char *password); -storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); +/* storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); */ void register_storage_backend(storage_t *); G_GNUC_MALLOC GList *storage_init(const char *primary, char **migrate); diff --git a/storage_text.c b/storage_text.c index 78f7e3bd..003bde44 100644 --- a/storage_text.c +++ b/storage_text.c @@ -26,14 +26,6 @@ #define BITLBEE_CORE #include "bitlbee.h" #include "crypting.h" -#ifdef _WIN32 -# define umask _umask -# define mode_t int -#endif - -#ifndef F_OK -#define F_OK 0 -#endif static void text_init (void) { @@ -43,7 +35,7 @@ static void text_init (void) it's read only! */ } -static storage_status_t text_load ( const char *my_nick, const char* password, irc_t *irc ) +static storage_status_t text_load( irc_t *irc, const char* password ) { char s[512]; char *line; @@ -53,10 +45,7 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i user_t *ru = user_find( irc, ROOT_NICK ); account_t *acc, *acc_lookup[9]; - if( irc->status & USTATUS_IDENTIFIED ) - return( 1 ); - - g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" ); + g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" ); fp = fopen( s, "r" ); if( !fp ) return STORAGE_NO_SUCH_USER; @@ -68,10 +57,6 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i return STORAGE_INVALID_PASSWORD; } - /* Do this now. If the user runs with AuthMode = Registered, the - account command will not work otherwise. */ - irc->status |= USTATUS_IDENTIFIED; - while( fscanf( fp, "%511[^\n]s", s ) > 0 ) { fgetc( fp ); @@ -100,7 +85,7 @@ static storage_status_t text_load ( const char *my_nick, const char* password, i acc_lookup[8] = acc; } - g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" ); + g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" ); fp = fopen( s, "r" ); if( !fp ) return STORAGE_NO_SUCH_USER; while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 ) diff --git a/storage_xml.c b/storage_xml.c index 240206f1..09e2f328 100644 --- a/storage_xml.c +++ b/storage_xml.c @@ -28,7 +28,14 @@ #include "base64.h" #include "arc.h" #include "md5.h" + +#if GLIB_CHECK_VERSION(2,8,0) #include <glib/gstdio.h> +#else +/* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */ +#include <unistd.h> +#define g_access access +#endif #if !GLIB_CHECK_VERSION(2,8,0) /* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */ @@ -255,7 +262,7 @@ static void xml_init( void ) log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to `%s'.", global.conf->configdir ); } -static storage_status_t xml_load_real( const char *my_nick, const char *password, irc_t *irc, xml_pass_st action ) +static storage_status_t xml_load_real( irc_t *irc, const char *my_nick, const char *password, xml_pass_st action ) { GMarkupParseContext *ctx; struct xml_parsedata *xd; @@ -263,9 +270,6 @@ static storage_status_t xml_load_real( const char *my_nick, const char *password GError *gerr = NULL; int fd, st; - if( irc && irc->status & USTATUS_IDENTIFIED ) - return( 1 ); - xd = g_new0( struct xml_parsedata, 1 ); xd->irc = irc; xd->given_nick = g_strdup( my_nick ); @@ -317,21 +321,19 @@ static storage_status_t xml_load_real( const char *my_nick, const char *password if( action == XML_PASS_CHECK_ONLY ) return STORAGE_OK; - irc->status |= USTATUS_IDENTIFIED; - return STORAGE_OK; } -static storage_status_t xml_load( const char *my_nick, const char *password, irc_t *irc ) +static storage_status_t xml_load( irc_t *irc, const char *password ) { - return xml_load_real( my_nick, password, irc, XML_PASS_UNKNOWN ); + return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN ); } static storage_status_t xml_check_pass( const char *my_nick, const char *password ) { /* This is a little bit risky because we have to pass NULL for the irc_t argument. This *should* be fine, if I didn't miss anything... */ - return xml_load_real( my_nick, password, NULL, XML_PASS_CHECK_ONLY ); + return xml_load_real( NULL, my_nick, password, XML_PASS_CHECK_ONLY ); } static int xml_printf( int fd, int indent, char *fmt, ... ) @@ -367,12 +369,6 @@ static storage_status_t xml_save( irc_t *irc, int overwrite ) md5_byte_t pass_md5[21]; md5_state_t md5_state; - if( irc->password == NULL ) - { - irc_usermsg( irc, "Please register yourself if you want to save your settings." ); - return STORAGE_OTHER_ERROR; - } - path2 = g_strdup( irc->nick ); nick_lc( path2 ); g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" ); @@ -55,13 +55,13 @@ int main( int argc, char *argv[] ) b_main_init(); nogaim_init(); - /* Ugly Note: libotr and gnutls both use libgcrypt. libgcrypt - has a process-global config state whose initialization happpens - twice if libotr and gnutls are used together. libotr installs custom - memory management functions for libgcrypt while our gnutls module - uses the defaults. Therefore we initialize OTR after SSL. *sigh* */ - ssl_init(); - otr_init(); + /* Ugly Note: libotr and gnutls both use libgcrypt. libgcrypt + has a process-global config state whose initialization happpens + twice if libotr and gnutls are used together. libotr installs custom + memory management functions for libgcrypt while our gnutls module + uses the defaults. Therefore we initialize OTR after SSL. *sigh* */ + ssl_init(); + otr_init(); srand( time( NULL ) ^ getpid() ); global.helpfile = g_strdup( HELP_FILE ); @@ -222,5 +222,3 @@ double gettime() gettimeofday( time, 0 ); return( (double) time->tv_sec + (double) time->tv_usec / 1000000 ); } - - |