aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--account.c31
-rw-r--r--account.h6
-rw-r--r--irc.c46
-rw-r--r--protocols/jabber/jabber.c2
-rw-r--r--protocols/jabber/jabber_util.c4
-rw-r--r--protocols/nogaim.c12
-rw-r--r--root_commands.c4
-rw-r--r--set.c22
-rw-r--r--set.h8
9 files changed, 79 insertions, 56 deletions
diff --git a/account.c b/account.c
index c7480996..d6b219a9 100644
--- a/account.c
+++ b/account.c
@@ -76,7 +76,7 @@ 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, "server" ) == 0 )
{
@@ -88,14 +88,10 @@ char *set_eval_account( set_t *set, char *value )
}
else
{
- acc->server = NULL;
+ acc->server = g_strdup( set->def );
return g_strdup( set->def );
}
}
- else if( value == NULL )
- {
- /* Noop, the other three can't be NULL. */
- }
else if( strcmp( set->key, "username" ) == 0 )
{
g_free( acc->user );
@@ -104,20 +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! */
+ if( value )
+ {
+ g_free( acc->pass );
+ acc->pass = g_strdup( value );
+ return NULL; /* password shouldn't be visible in plaintext! */
+ }
+ else
+ {
+ /* 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 )
@@ -257,7 +262,7 @@ int account_reconnect_delay_parse( char *value, struct account_reconnect_delay *
p->start = p->start * 10 + *value++ - '0';
/* Sure, call me evil for implementing my own fscanf here, but it's
- dead simple and I'm immediately at the next part to parse. */
+ dead simple and I immediately know where to continue parsing. */
if( *value == 0 )
/* If the string ends now, the delay is constant. */
@@ -290,7 +295,7 @@ char *set_eval_account_reconnect_delay( set_t *set, char *value )
{
struct account_reconnect_delay p;
- return account_reconnect_delay_parse( value, &p ) ? value : NULL;
+ return account_reconnect_delay_parse( value, &p ) ? value : SET_INVALID;
}
int account_reconnect_delay( account_t *a )
diff --git a/account.h b/account.h
index 2aef80a2..cf22482c 100644
--- a/account.h
+++ b/account.h
@@ -55,8 +55,8 @@ 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
diff --git a/irc.c b/irc.c
index 30956bc2..d3f254ed 100644
--- a/irc.c
+++ b/irc.c
@@ -76,6 +76,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 );
@@ -135,28 +136,29 @@ irc_t *irc_new( int fd )
irc_connection_list = g_slist_append( irc_connection_list, irc );
- set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, 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", "5*3<900", set_eval_account_reconnect_delay, 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, "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, "lcnicks", "true", set_eval_bool, irc );
- set_add( &irc->set, "ops", "both", set_eval_ops, 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 );
+ 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 );
+ 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, "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, "lcnicks", "true", set_eval_bool, irc );
+ s = set_add( &irc->set, "ops", "both", set_eval_ops, irc );
+ s = set_add( &irc->set, "password", NULL, passchange, 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 );
conf_loaddefaults( irc );
diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c
index c9c1d0a0..ac8638cf 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/nogaim.c b/protocols/nogaim.c
index b6f8d6e4..6a267adf 100644
--- a/protocols/nogaim.c
+++ b/protocols/nogaim.c
@@ -927,14 +927,10 @@ char *set_eval_away_devoice( set_t *set, char *value )
irc_t *irc = set->data;
int st;
- if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
- st = 1;
- else if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
- st = 0;
- else if( sscanf( value, "%d", &st ) != 1 )
- return( NULL );
+ if( !is_bool( value ) )
+ return SET_INVALID;
- st = st != 0;
+ st = bool2int( value );
/* Horror.... */
@@ -978,7 +974,7 @@ char *set_eval_away_devoice( set_t *set, char *value )
irc->channel, pm, v, list );
}
- return( set_eval_bool( set, value ) );
+ return value;
}
diff --git a/root_commands.c b/root_commands.c
index f55c4b5e..56a405a3 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -609,6 +609,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] );
}
@@ -632,7 +634,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 )
diff --git a/set.c b/set.c
index 112e6937..c83fc6f8 100644
--- a/set.c
+++ b/set.c
@@ -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 )
@@ -186,14 +200,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 )
@@ -225,7 +239,7 @@ char *set_eval_ops( set_t *set, char *value )
irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
irc->channel, "-oo", irc->nick, irc->mynick );
else
- return NULL;
+ return SET_INVALID;
return value;
}
diff --git a/set.h b/set.h
index 8c722877..8ca6f9ec 100644
--- a/set.h
+++ b/set.h
@@ -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;