aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--bitlbee.c219
-rw-r--r--bitlbee.h4
-rw-r--r--commands.c38
-rw-r--r--conf.c6
-rw-r--r--conf.h1
-rw-r--r--crypting.c5
-rw-r--r--crypting.h4
-rw-r--r--irc.c2
-rw-r--r--storage.c58
-rw-r--r--storage.h48
-rw-r--r--storage_text.c308
-rw-r--r--unix.c16
13 files changed, 449 insertions, 262 deletions
diff --git a/Makefile b/Makefile
index e3ca059d..d022c0e1 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
-include Makefile.settings
# Program variables
-objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o
+objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o storage_text.o storage.o
subdirs = protocols
# Expansion of variables
diff --git a/bitlbee.c b/bitlbee.c
index 9f79d544..e920f2cb 100644
--- a/bitlbee.c
+++ b/bitlbee.c
@@ -26,7 +26,6 @@
#define BITLBEE_CORE
#include "bitlbee.h"
#include "commands.h"
-#include "crypting.h"
#include "protocols/nogaim.h"
#include "help.h"
#include <signal.h>
@@ -243,224 +242,6 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi
}
}
-int bitlbee_load( irc_t *irc, char* password )
-{
- char s[512];
- char *line;
- int proto;
- char nick[MAX_NICK_LENGTH+1];
- FILE *fp;
- user_t *ru = user_find( irc, ROOT_NICK );
-
- if( irc->status == USTATUS_IDENTIFIED )
- return( 1 );
-
- g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- fp = fopen( s, "r" );
- if( !fp ) return( 0 );
-
- fscanf( fp, "%32[^\n]s", s );
- if( setpass( irc, password, s ) < 0 )
- {
- fclose( fp );
- return( -1 );
- }
-
- /* 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 );
- line = deobfucrypt( irc, s );
- root_command_string( irc, ru, line, 0 );
- g_free( line );
- }
- fclose( fp );
-
- g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
- fp = fopen( s, "r" );
- if( !fp ) return( 0 );
- while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
- {
- http_decode( s );
- nick_set( irc, s, proto, nick );
- }
- fclose( fp );
-
- if( set_getint( irc, "auto_connect" ) )
- {
- strcpy( s, "account on" ); /* Can't do this directly because r_c_s alters the string */
- root_command_string( irc, ru, s, 0 );
- }
-
- return( 1 );
-}
-
-int bitlbee_save( irc_t *irc )
-{
- char s[512];
- char path[512], new_path[512];
- char *line;
- nick_t *n;
- set_t *set;
- mode_t ou = umask( 0077 );
- account_t *a;
- FILE *fp;
- char *hash;
-
- /*\
- * [SH] Nothing should be saved if no password is set, because the
- * password is not set if it was wrong, or if one is not identified
- * yet. This means that a malicious user could easily overwrite
- * files owned by someone else:
- * a Bad Thing, methinks
- \*/
-
- /* [WVG] No? Really? */
-
- /*\
- * [SH] Okay, okay, it wasn't really Wilmer who said that, it was
- * me. I just thought it was funny.
- \*/
-
- hash = hashpass( irc );
- if( hash == NULL )
- {
- irc_usermsg( irc, "Please register yourself if you want to save your settings." );
- return( 0 );
- }
-
- g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
- fp = fopen( path, "w" );
- if( !fp ) return( 0 );
- for( n = irc->nicks; n; n = n->next )
- {
- strcpy( s, n->handle );
- s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
- http_encode( s );
- g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", n->proto, n->nick );
- if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
- {
- irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
- fclose( fp );
- return( 0 );
- }
- }
- if( fclose( fp ) != 0 )
- {
- irc_usermsg( irc, "fclose() reported an error. Disk full?" );
- return( 0 );
- }
-
- g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
- if( unlink( new_path ) != 0 )
- {
- if( errno != ENOENT )
- {
- irc_usermsg( irc, "Error while removing old .nicks file" );
- return( 0 );
- }
- }
- if( rename( path, new_path ) != 0 )
- {
- irc_usermsg( irc, "Error while renaming new .nicks file" );
- return( 0 );
- }
-
- g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
- fp = fopen( path, "w" );
- if( !fp ) return( 0 );
- if( fprintf( fp, "%s", hash ) != strlen( hash ) )
- {
- irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
- fclose( fp );
- return( 0 );
- }
- g_free( hash );
-
- for( a = irc->accounts; a; a = a->next )
- {
- if( a->protocol == PROTO_OSCAR || a->protocol == PROTO_ICQ || a->protocol == PROTO_TOC )
- g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
- else
- g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
- proto_name[a->protocol], a->user, a->pass, a->server ? a->server : "" );
-
- line = obfucrypt( irc, s );
- if( *line )
- {
- if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
- {
- irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
- fclose( fp );
- return( 0 );
- }
- }
- g_free( line );
- }
-
- for( set = irc->set; set; set = set->next )
- {
- if( set->value && set->def )
- {
- g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
- line = obfucrypt( irc, s );
- if( *line )
- {
- if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
- {
- irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
- fclose( fp );
- return( 0 );
- }
- }
- g_free( line );
- }
- }
-
- if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
- {
- g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
- line = obfucrypt( irc, s );
- if( *line )
- {
- if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
- {
- irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
- fclose( fp );
- return( 0 );
- }
- }
- g_free( line );
- }
- if( fclose( fp ) != 0 )
- {
- irc_usermsg( irc, "fclose() reported an error. Disk full?" );
- return( 0 );
- }
-
- g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- if( unlink( new_path ) != 0 )
- {
- if( errno != ENOENT )
- {
- irc_usermsg( irc, "Error while removing old .accounts file" );
- return( 0 );
- }
- }
- if( rename( path, new_path ) != 0 )
- {
- irc_usermsg( irc, "Error while renaming new .accounts file" );
- return( 0 );
- }
-
- umask( ou );
-
- return( 1 );
-}
-
void bitlbee_shutdown( gpointer data )
{
/* Try to save data for all active connections (if desired). */
diff --git a/bitlbee.h b/bitlbee.h
index 7ecc8d5d..a23ef4a0 100644
--- a/bitlbee.h
+++ b/bitlbee.h
@@ -99,6 +99,7 @@
extern char *CONF_FILE;
#include "irc.h"
+#include "storage.h"
#include "set.h"
#include "protocols/nogaim.h"
#include "commands.h"
@@ -114,6 +115,7 @@ typedef struct global_t {
int listen_socket;
help_t *help;
conf_t *conf;
+ storage_t *storage;
char *helpfile;
GMainLoop *loop;
} global_t;
@@ -126,8 +128,6 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi
int root_command_string( irc_t *irc, user_t *u, char *command, int flags );
int root_command( irc_t *irc, char *command[] );
-int bitlbee_load( irc_t *irc, char *password );
-int bitlbee_save( irc_t *irc );
void bitlbee_shutdown( gpointer data );
double gettime( void );
G_MODULE_EXPORT void http_encode( char *s );
diff --git a/commands.c b/commands.c
index 504a9345..1fe6cae3 100644
--- a/commands.c
+++ b/commands.c
@@ -85,7 +85,7 @@ int cmd_help( irc_t *irc, char **cmd )
int cmd_identify( irc_t *irc, char **cmd )
{
- int checkie = bitlbee_load( irc, cmd[1] );
+ int checkie = global.storage->load( irc->nick, cmd[1], irc );
if( checkie == -1 )
{
@@ -109,22 +109,13 @@ int cmd_identify( irc_t *irc, char **cmd )
int cmd_register( irc_t *irc, char **cmd )
{
- int checkie;
- char path[512];
-
if( global.conf->authmode == AUTHMODE_REGISTERED )
{
irc_usermsg( irc, "This server does not allow registering new accounts" );
return( 0 );
}
-
- g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- checkie = access( path, F_OK );
-
- g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
- checkie += access( path, F_OK );
-
- if( checkie == -2 )
+
+ if( !global.storage->exists( irc->nick ))
{
setpassnc( irc, cmd[1] );
root_command_string( irc, user_find( irc, irc->mynick ), "save", 0 );
@@ -140,30 +131,19 @@ int cmd_register( irc_t *irc, char **cmd )
int cmd_drop( irc_t *irc, char **cmd )
{
- char s[512];
- FILE *fp;
-
- g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- fp = fopen( s, "r" );
- if( !fp )
+ if( ! global.storage->exists (irc->nick) )
{
irc_usermsg( irc, "That account does not exist" );
return( 0 );
}
-
- fscanf( fp, "%32[^\n]s", s );
- fclose( fp );
- if( setpass( irc, cmd[1], s ) < 0 )
+
+ if ( global.storage->check_pass (irc->nick, cmd[1]) )
{
- irc_usermsg( irc, "Incorrect password" );
+ irc_usermsg( irc, "Password invalid" );
return( 0 );
}
- g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- unlink( s );
-
- g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
- unlink( s );
+ global.storage->remove (irc->nick);
setpassnc( irc, NULL );
irc_usermsg( irc, "Files belonging to account `%s' removed", irc->nick );
@@ -633,7 +613,7 @@ int cmd_set( irc_t *irc, char **cmd )
int cmd_save( irc_t *irc, char **cmd )
{
- if( bitlbee_save( irc ) )
+ if( global.storage->save( irc ) )
irc_usermsg( irc, "Configuration saved" );
else
irc_usermsg( irc, "Configuration could not be saved!" );
diff --git a/conf.c b/conf.c
index 51b7fbcc..304a15a8 100644
--- a/conf.c
+++ b/conf.c
@@ -49,6 +49,7 @@ conf_t *conf_load( int argc, char *argv[] )
conf->port = 6667;
conf->nofork = 0;
conf->verbose = 0;
+ conf->storage = "text";
conf->runmode = RUNMODE_INETD;
conf->authmode = AUTHMODE_OPEN;
conf->password = NULL;
@@ -197,6 +198,11 @@ static int conf_loadini( conf_t *conf, char *file )
g_free( conf->motdfile );
conf->motdfile = g_strdup( ini->value );
}
+ else if( g_strcasecmp( ini->key, "storage" ) == 0 )
+ {
+ g_free( conf->storage );
+ conf->storage = g_strdup( ini->value );
+ }
else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
{
if( sscanf( ini->value, "%d", &i ) != 1 )
diff --git a/conf.h b/conf.h
index e31e0982..a4f3ed79 100644
--- a/conf.h
+++ b/conf.h
@@ -41,6 +41,7 @@ typedef struct conf
char *hostname;
char *configdir;
char *motdfile;
+ char *storage;
int ping_interval;
int ping_timeout;
} conf_t;
diff --git a/crypting.c b/crypting.c
index 4091ed08..1cff3be2 100644
--- a/crypting.c
+++ b/crypting.c
@@ -66,7 +66,8 @@ typedef struct irc
/* USE WITH CAUTION!
Sets pass without checking */
-void setpassnc (irc_t *irc, char *pass) {
+void setpassnc (irc_t *irc, const char *pass)
+{
if (!set_find (irc, "password"))
set_add (irc, "password", NULL, passchange);
@@ -85,7 +86,7 @@ char *passchange (irc_t *irc, void *set, char *value) {
return (NULL);
}
-int setpass (irc_t *irc, char *pass, char* md5sum) {
+int setpass (irc_t *irc, const char *pass, char* md5sum) {
md5_state_t md5state;
md5_byte_t digest[16];
int i, j;
diff --git a/crypting.h b/crypting.h
index 0d4f0873..0f026fc0 100644
--- a/crypting.h
+++ b/crypting.h
@@ -23,9 +23,9 @@
Suite 330, Boston, MA 02111-1307 USA
*/
-void setpassnc (irc_t *irc, char *pass); /* USE WITH CAUTION! */
+void setpassnc (irc_t *irc, const char *pass); /* USE WITH CAUTION! */
char *passchange (irc_t *irc, void *set, char *value);
-int setpass (irc_t *irc, char *pass, char* md5sum);
+int setpass (irc_t *irc, const char *pass, char* md5sum);
char *hashpass (irc_t *irc);
char *obfucrypt (irc_t *irc, char *line);
char *deobfucrypt (irc_t *irc, char *line);
diff --git a/irc.c b/irc.c
index c80e138d..9ccfdb33 100644
--- a/irc.c
+++ b/irc.c
@@ -153,7 +153,7 @@ void irc_free(irc_t * irc)
log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
if( irc->status >= USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) )
- if( !bitlbee_save( irc ) )
+ if( !global.storage->save( irc ) )
irc_usermsg( irc, "Error while saving settings!" );
if( irc->ping_source_id > 0 )
diff --git a/storage.c b/storage.c
new file mode 100644
index 00000000..8738a58f
--- /dev/null
+++ b/storage.c
@@ -0,0 +1,58 @@
+ /********************************************************************\
+ * BitlBee -- An IRC to other IM-networks gateway *
+ * *
+ * Copyright 2002-2004 Wilmer van der Gaast and others *
+ \********************************************************************/
+
+/* Support for multiple storage backends */
+
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License with
+ the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define BITLBEE_CORE
+#include "bitlbee.h"
+#include "crypting.h"
+
+extern storage_t storage_text;
+
+static GList text_entry = { &storage_text, NULL, NULL };
+static GList *storage_backends = &text_entry;
+
+void register_storage_backend(storage_t *backend)
+{
+ storage_backends = g_list_append(storage_backends, backend);
+}
+
+storage_t *storage_init(const char *name)
+{
+ GList *gl;
+ storage_t *st;
+
+ for (gl = storage_backends; gl; gl = gl->next) {
+ st = gl->data;
+ if (strcmp(st->name, name) == 0)
+ break;
+ }
+
+ if (gl == NULL)
+ return NULL;
+
+ if (st->init)
+ st->init();
+
+ return st;
+}
diff --git a/storage.h b/storage.h
new file mode 100644
index 00000000..d7c70ddc
--- /dev/null
+++ b/storage.h
@@ -0,0 +1,48 @@
+ /********************************************************************\
+ * BitlBee -- An IRC to other IM-networks gateway *
+ * *
+ * Copyright 2002-2004 Wilmer van der Gaast and others *
+ \********************************************************************/
+
+/* Layer for retrieving and storing buddy information */
+
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License with
+ the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __STORAGE_H__
+#define __STORAGE_H__
+
+typedef struct {
+ const char *name;
+
+ /* May be set to NULL if not required */
+ void (*init) (void);
+
+ int (*load) (const char *nick, const char *password, irc_t * irc);
+ int (*exists) (const char *nick);
+ int (*save) (irc_t *irc);
+ int (*remove) (const char *nick);
+ int (*check_pass) (const char *nick, const char *pass);
+
+ /* May be NULL if not supported by backend */
+ int (*rename) (const char *onick, const char *nnick, const char *password);
+} storage_t;
+
+void register_storage_backend(storage_t *);
+storage_t *storage_init(const char *name);
+
+#endif /* __STORAGE_H__ */
diff --git a/storage_text.c b/storage_text.c
new file mode 100644
index 00000000..7c8b794c
--- /dev/null
+++ b/storage_text.c
@@ -0,0 +1,308 @@
+ /********************************************************************\
+ * BitlBee -- An IRC to other IM-networks gateway *
+ * *
+ * Copyright 2002-2004 Wilmer van der Gaast and others *
+ \********************************************************************/
+
+/* Storage backend that uses the same file format as <=1.0 */
+
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License with
+ the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define BITLBEE_CORE
+#include "bitlbee.h"
+#include "crypting.h"
+
+static void text_init (void)
+{
+ if( access( global.conf->configdir, F_OK ) != 0 )
+ log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG );
+ else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
+ log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
+}
+
+static int text_load ( const char *my_nick, const char* password, irc_t *irc )
+{
+ char s[512];
+ char *line;
+ int proto;
+ char nick[MAX_NICK_LENGTH+1];
+ FILE *fp;
+ user_t *ru = user_find( irc, ROOT_NICK );
+
+ if( irc->status == USTATUS_IDENTIFIED )
+ return( 1 );
+
+ g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" );
+ fp = fopen( s, "r" );
+ if( !fp ) return( 0 );
+
+ fscanf( fp, "%32[^\n]s", s );
+ if( setpass( irc, password, s ) < 0 )
+ {
+ fclose( fp );
+ return( -1 );
+ }
+
+ /* 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 );
+ line = deobfucrypt( irc, s );
+ root_command_string( irc, ru, line, 0 );
+ g_free( line );
+ }
+ fclose( fp );
+
+ g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );
+ fp = fopen( s, "r" );
+ if( !fp ) return( 0 );
+ while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
+ {
+ http_decode( s );
+ nick_set( irc, s, proto, nick );
+ }
+ fclose( fp );
+
+ if( set_getint( irc, "auto_connect" ) )
+ {
+ strcpy( s, "account on" ); /* Can't do this directly because r_c_s alters the string */
+ root_command_string( irc, ru, s, 0 );
+ }
+
+ return( 1 );
+}
+
+static int text_save( irc_t *irc )
+{
+ char s[512];
+ char path[512], new_path[512];
+ char *line;
+ nick_t *n;
+ set_t *set;
+ mode_t ou = umask( 0077 );
+ account_t *a;
+ FILE *fp;
+ char *hash;
+
+ /*\
+ * [SH] Nothing should be saved if no password is set, because the
+ * password is not set if it was wrong, or if one is not identified
+ * yet. This means that a malicious user could easily overwrite
+ * files owned by someone else:
+ * a Bad Thing, methinks
+ \*/
+
+ /* [WVG] No? Really? */
+
+ /*\
+ * [SH] Okay, okay, it wasn't really Wilmer who said that, it was
+ * me. I just thought it was funny.
+ \*/
+
+ hash = hashpass( irc );
+ if( hash == NULL )
+ {
+ irc_usermsg( irc, "Please register yourself if you want to save your settings." );
+ return( 0 );
+ }
+
+ g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
+ fp = fopen( path, "w" );
+ if( !fp ) return( 0 );
+ for( n = irc->nicks; n; n = n->next )
+ {
+ strcpy( s, n->handle );
+ s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
+ http_encode( s );
+ g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", n->proto, n->nick );
+ if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
+ {
+ irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+ fclose( fp );
+ return( 0 );
+ }
+ }
+ if( fclose( fp ) != 0 )
+ {
+ irc_usermsg( irc, "fclose() reported an error. Disk full?" );
+ return( 0 );
+ }
+
+ g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+ if( unlink( new_path ) != 0 )
+ {
+ if( errno != ENOENT )
+ {
+ irc_usermsg( irc, "Error while removing old .nicks file" );
+ return( 0 );
+ }
+ }
+ if( rename( path, new_path ) != 0 )
+ {
+ irc_usermsg( irc, "Error while renaming new .nicks file" );
+ return( 0 );
+ }
+
+ g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
+ fp = fopen( path, "w" );
+ if( !fp ) return( 0 );
+ if( fprintf( fp, "%s", hash ) != strlen( hash ) )
+ {
+ irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+ fclose( fp );
+ return( 0 );
+ }
+ g_free( hash );
+
+ for( a = irc->accounts; a; a = a->next )
+ {
+ if( a->protocol == PROTO_OSCAR || a->protocol == PROTO_ICQ || a->protocol == PROTO_TOC )
+ g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
+ else
+ g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
+ proto_name[a->protocol], a->user, a->pass, a->server ? a->server : "" );
+
+ line = obfucrypt( irc, s );
+ if( *line )
+ {
+ if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+ {
+ irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+ fclose( fp );
+ return( 0 );
+ }
+ }
+ g_free( line );
+ }
+
+ for( set = irc->set; set; set = set->next )
+ {
+ if( set->value && set->def )
+ {
+ g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
+ line = obfucrypt( irc, s );
+ if( *line )
+ {
+ if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+ {
+ irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+ fclose( fp );
+ return( 0 );
+ }
+ }
+ g_free( line );
+ }
+ }
+
+ if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
+ {
+ g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
+ line = obfucrypt( irc, s );
+ if( *line )
+ {
+ if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+ {
+ irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+ fclose( fp );
+ return( 0 );
+ }
+ }
+ g_free( line );
+ }
+ if( fclose( fp ) != 0 )
+ {
+ irc_usermsg( irc, "fclose() reported an error. Disk full?" );
+ return( 0 );
+ }
+
+ g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+ if( unlink( new_path ) != 0 )
+ {
+ if( errno != ENOENT )
+ {
+ irc_usermsg( irc, "Error while removing old .accounts file" );
+ return( 0 );
+ }
+ }
+ if( rename( path, new_path ) != 0 )
+ {
+ irc_usermsg( irc, "Error while renaming new .accounts file" );
+ return( 0 );
+ }
+
+ umask( ou );
+
+ return( 1 );
+}
+
+static int text_exists( const char *nick )
+{
+ char path[512];
+ int checkie;
+
+ g_snprintf( path, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
+ checkie = access( path, F_OK );
+
+ g_snprintf( path, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
+ checkie += access( path, F_OK );
+
+ return ( checkie != -2 );
+}
+
+static int text_remove( const char *nick )
+{
+ char s[512];
+
+ g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
+ if (unlink( s ) == -1)
+ return( 1 );
+
+ g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
+ if (unlink( s ) == -1)
+ return( 1 );
+
+ return( 0 );
+}
+
+static int text_check_pass( const char *nick, const char *password )
+{
+ char s[512];
+ FILE *fp;
+
+ g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
+ fp = fopen( s, "r" );
+
+ fscanf( fp, "%32[^\n]s", s );
+ fclose( fp );
+
+ /* FIXME */
+ return( 0 );
+}
+
+storage_t storage_text = {
+ .name = "text",
+ .init = text_init,
+ .exists = text_exists,
+ .check_pass = text_check_pass,
+ .remove = text_remove,
+ .load = text_load,
+ .save = text_save
+};
diff --git a/unix.c b/unix.c
index c4b3975e..6813be31 100644
--- a/unix.c
+++ b/unix.c
@@ -51,11 +51,12 @@ int main( int argc, char *argv[] )
CONF_FILE = g_strdup( CONF_FILE_DEF );
global.helpfile = g_strdup( HELP_FILE );
-
+
global.conf = conf_load( argc, argv );
if( global.conf == NULL )
return( 1 );
-
+
+
if( global.conf->runmode == RUNMODE_INETD )
{
i = bitlbee_inetd_init();
@@ -69,6 +70,13 @@ int main( int argc, char *argv[] )
}
if( i != 0 )
return( i );
+
+ global.storage = storage_init( global.conf->storage );
+ if ( global.storage == NULL) {
+ log_message( LOGLVL_ERROR, "No such storage backend '%s'", global.conf->storage );
+ return( 1 );
+ }
+
/* Catch some signals to tell the user what's happening before quitting */
memset( &sig, 0, sizeof( sig ) );
@@ -86,10 +94,6 @@ int main( int argc, char *argv[] )
if( !getuid() || !geteuid() )
log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" );
- if( access( global.conf->configdir, F_OK ) != 0 )
- log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG );
- else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
- log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
if( help_init( &(global.help) ) == NULL )
log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );