Index: commands.c
===================================================================
--- commands.c	(revision 1ee6c18cfb5eb03f33a5938b37e357dd3fd2c164)
+++ commands.c	(revision a1f17d45fae99428c8024168b55b4279c59ac867)
@@ -116,13 +116,17 @@
 	}
 
-	if( !global.storage->exists( irc->nick )) 
-	{
-		setpassnc( irc, cmd[1] );
-		root_command_string( irc, user_find( irc, irc->mynick ), "save", 0 );
-		irc->status = USTATUS_IDENTIFIED;
-	}
-	else
-	{
-		irc_usermsg( irc, "Nick is already registered" );
+	setpassnc( irc, cmd[1] );
+	switch( global.storage->save( irc, FALSE )) {
+		case STORAGE_ALREADY_EXISTS:
+			irc_usermsg( irc, "Nick is already registered" );
+			break;
+			
+		case STORAGE_OK:
+			irc->status = USTATUS_IDENTIFIED;
+			break;
+
+		default:
+			irc_usermsg( irc, "Error registering" );
+			break;
 	}
 	
@@ -132,22 +136,22 @@
 int cmd_drop( irc_t *irc, char **cmd )
 {
-	if( ! global.storage->exists (irc->nick) )
-	{
+	storage_status_t status;
+	
+	status = global.storage->remove (irc->nick, cmd[1]);
+	switch (status) {
+	case STORAGE_NO_SUCH_USER:
 		irc_usermsg( irc, "That account does not exist" );
 		return( 0 );
-	}
-
-	if ( global.storage->check_pass (irc->nick, cmd[1]) ) 
-	{
+	case STORAGE_INVALID_PASSWORD:
 		irc_usermsg( irc, "Password invalid" );
 		return( 0 );
-	}
-	
-	global.storage->remove (irc->nick);
-	
-	setpassnc( irc, NULL );
-	irc_usermsg( irc, "Files belonging to account `%s' removed", irc->nick );
-	
-	return( 0 );
+	case STORAGE_OK:
+		setpassnc( irc, NULL );
+		irc_usermsg( irc, "Account `%s' removed", irc->nick );
+		return( 0 );
+	default:
+		irc_usermsg( irc, "Error: '%d'", status );
+		return( 0 );
+	}
 }
 
@@ -614,5 +618,5 @@
 int cmd_save( irc_t *irc, char **cmd )
 {
-	if( global.storage->save( irc ) )
+	if( global.storage->save( irc, TRUE ) )
 		irc_usermsg( irc, "Configuration saved" );
 	else
Index: irc.c
===================================================================
--- irc.c	(revision 1ee6c18cfb5eb03f33a5938b37e357dd3fd2c164)
+++ irc.c	(revision a1f17d45fae99428c8024168b55b4279c59ac867)
@@ -154,5 +154,5 @@
 	
 	if( irc->status >= USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) 
-		if( !global.storage->save( irc ) )
+		if( !global.storage->save( irc, TRUE ) )
 			irc_usermsg( irc, "Error while saving settings!" );
 	
Index: storage.h
===================================================================
--- storage.h	(revision 1ee6c18cfb5eb03f33a5938b37e357dd3fd2c164)
+++ storage.h	(revision a1f17d45fae99428c8024168b55b4279c59ac867)
@@ -27,4 +27,14 @@
 #define __STORAGE_H__
 
+typedef enum {
+	STORAGE_OK = 0,
+	STORAGE_NO_SUCH_USER,
+	STORAGE_INVALID_PASSWORD,
+	STORAGE_ALREADY_EXISTS,
+	STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as 
+						   a database that is unreachable. log() will be 
+						   used for the exact error message */
+} storage_status_t;
+
 typedef struct {
 	const char *name;
@@ -33,12 +43,10 @@
 	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);
+	storage_status_t (*load) (const char *nick, const char *password, irc_t * irc);
+	storage_status_t (*save) (irc_t *irc, int overwrite);
+	storage_status_t (*remove) (const char *nick, const char *password);
 
 	/* May be NULL if not supported by backend */
-	int (*rename) (const char *onick, const char *nnick, const char *password);
+	storage_status_t (*rename) (const char *onick, const char *nnick, const char *password);
 } storage_t;
 
Index: storage_text.c
===================================================================
--- storage_text.c	(revision 1ee6c18cfb5eb03f33a5938b37e357dd3fd2c164)
+++ storage_text.c	(revision a1f17d45fae99428c8024168b55b4279c59ac867)
@@ -36,5 +36,5 @@
 }
 
-static int text_load ( const char *my_nick, const char* password, irc_t *irc )
+static storage_status_t text_load ( const char *my_nick, const char* password, irc_t *irc )
 {
 	char s[512];
@@ -50,5 +50,5 @@
 	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" );
    	fp = fopen( s, "r" );
-   	if( !fp ) return( 0 );
+   	if( !fp ) return STORAGE_NO_SUCH_USER;
 	
 	fscanf( fp, "%32[^\n]s", s );
@@ -56,5 +56,5 @@
 	{
 		fclose( fp );
-		return( -1 );
+		return STORAGE_INVALID_PASSWORD;
 	}
 	
@@ -74,5 +74,5 @@
 	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );
 	fp = fopen( s, "r" );
-	if( !fp ) return( 0 );
+	if( !fp ) return STORAGE_NO_SUCH_USER;
 	while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
 	{
@@ -88,8 +88,8 @@
 	}
 	
-	return( 1 );
-}
-
-static int text_save( irc_t *irc )
+	return STORAGE_OK;
+}
+
+static storage_status_t text_save( irc_t *irc, int overwrite )
 {
 	char s[512];
@@ -102,4 +102,14 @@
 	FILE *fp;
 	char *hash;
+
+	if (!overwrite) {
+		g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+		if (access( path, F_OK ) != -1)
+			return STORAGE_ALREADY_EXISTS;
+	
+		g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+		if (access( path, F_OK ) != -1)
+			return STORAGE_ALREADY_EXISTS;
+	}
 	
 	/*\
@@ -127,5 +137,5 @@
 	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
 	fp = fopen( path, "w" );
-	if( !fp ) return( 0 );
+	if( !fp ) return STORAGE_OTHER_ERROR;
 	for( n = irc->nicks; n; n = n->next )
 	{
@@ -138,5 +148,5 @@
 			irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
 			fclose( fp );
-			return( 0 );
+			return STORAGE_OTHER_ERROR;
 		}
 	}
@@ -144,5 +154,5 @@
 	{
 		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
-		return( 0 );
+		return STORAGE_OTHER_ERROR;
 	}
   
@@ -153,5 +163,5 @@
 		{
 			irc_usermsg( irc, "Error while removing old .nicks file" );
-			return( 0 );
+			return STORAGE_OTHER_ERROR;
 		}
 	}
@@ -159,15 +169,15 @@
 	{
 		irc_usermsg( irc, "Error while renaming new .nicks file" );
-		return( 0 );
+		return STORAGE_OTHER_ERROR;
 	}
 	
 	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
 	fp = fopen( path, "w" );
-	if( !fp ) return( 0 );
+	if( !fp ) return STORAGE_OTHER_ERROR;
 	if( fprintf( fp, "%s", hash ) != strlen( hash ) )
 	{
 		irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
 		fclose( fp );
-		return( 0 );
+		return STORAGE_OTHER_ERROR;
 	}
 	g_free( hash );
@@ -188,5 +198,5 @@
 				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
 				fclose( fp );
-				return( 0 );
+				return STORAGE_OTHER_ERROR;
 			}
 		}
@@ -206,5 +216,5 @@
 					irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
 					fclose( fp );
-					return( 0 );
+					return STORAGE_OTHER_ERROR;
 				}
 			}
@@ -223,5 +233,5 @@
 				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
 				fclose( fp );
-				return( 0 );
+				return STORAGE_OTHER_ERROR;
 			}
 		}
@@ -231,5 +241,5 @@
 	{
 		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
-		return( 0 );
+		return STORAGE_OTHER_ERROR;
 	}
 	
@@ -240,5 +250,5 @@
 		{
 			irc_usermsg( irc, "Error while removing old .accounts file" );
-			return( 0 );
+			return STORAGE_OTHER_ERROR;
 		}
 	}
@@ -246,54 +256,36 @@
 	{
 		irc_usermsg( irc, "Error while renaming new .accounts file" );
-		return( 0 );
+		return STORAGE_OTHER_ERROR;
 	}
 	
 	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 )
+	return STORAGE_OK;
+}
+
+static storage_status_t text_remove( 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" );
+	if (!fp)
+		return STORAGE_NO_SUCH_USER;
+
+	fscanf( fp, "%32[^\n]s", s );
+	fclose( fp );
+
+	/*FIXME Test if password is correct */
 
 	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
 	if (unlink( s ) == -1)
-		return( 1 );
+		return STORAGE_OTHER_ERROR;
 	
 	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 );
+		return STORAGE_OTHER_ERROR;
+
+	return STORAGE_OK;
 }
 
@@ -301,6 +293,4 @@
 	.name = "text",
 	.init = text_init,
-	.exists = text_exists,
-	.check_pass = text_check_pass,
 	.remove = text_remove,
 	.load = text_load,
