Index: Makefile
===================================================================
--- Makefile	(revision b52e478f9cfea9c0319d3f0203b31e4b5d03f38b)
+++ Makefile	(revision 7c9db249e4d94413f561841495d1e147d53327d5)
@@ -49,5 +49,5 @@
 
 clean: $(subdirs)
-	rm -f *.o $(OUTFILE) core utils/bitlbeed encode decode
+	rm -f *.o $(OUTFILE) core utils/bitlbeed
 	$(MAKE) -C tests clean
 
@@ -124,10 +124,4 @@
 endif
 
-encode: crypting.c
-	$(CC) crypting.c lib/md5.c $(CFLAGS) -o encode -DCRYPTING_MAIN $(CFLAGS) $(EFLAGS) $(LFLAGS)
-
-decode: encode
-	cp encode decode
-
 ctags: 
 	ctags `find . -name "*.c"` `find . -name "*.h"`
Index: conf.c
===================================================================
--- conf.c	(revision b52e478f9cfea9c0319d3f0203b31e4b5d03f38b)
+++ conf.c	(revision 7c9db249e4d94413f561841495d1e147d53327d5)
@@ -127,5 +127,5 @@
 		{
 			printf( "Usage: bitlbee [-D/-F [-i <interface>] [-p <port>] [-n] [-v]] [-I]\n"
-			        "               [-c <file>] [-d <dir>] [-h]\n"
+			        "               [-c <file>] [-d <dir>] [-x] [-h]\n"
 			        "\n"
 			        "An IRC-to-other-chat-networks gateway\n"
@@ -143,4 +143,5 @@
 			        "  -c  Load alternative configuration file\n"
 			        "  -d  Specify alternative user configuration directory\n"
+			        "  -x  Command-line interface to password encryption/hashing\n"
 			        "  -h  Show this help page.\n" );
 			return NULL;
Index: crypting.c
===================================================================
--- crypting.c	(revision b52e478f9cfea9c0319d3f0203b31e4b5d03f38b)
+++ crypting.c	(revision 7c9db249e4d94413f561841495d1e147d53327d5)
@@ -132,62 +132,2 @@
 	return (rv);
 }
-
-#ifdef CRYPTING_MAIN
-
-/* A little main() function for people who want a stand-alone program to
-   encode/decode BitlCrypted files. */
-
-int main( int argc, char *argv[] )
-{
-	char *hash, *action, line[256];
-	char* (*func)( char *, const char * );
-	
-	if( argc < 2 )
-	{
-		fprintf( stderr, "Usage: %s <password>\n\n"
-		                 "Reads from stdin, writes to stdout.\n"
-		                 "Call as \"encode\" to encode, \"decode\" to decode.\n", argv[0] );
-		return( 1 );
-	}
-	
-	hash = hashpass( argv[1] );
-	action = argv[0] + strlen( argv[0] ) - strlen( "encode" );
-	
-	if( strcmp( action, "encode" ) == 0 )
-	{
-		fwrite( hash, 32, 1, stdout );
-		func = obfucrypt;
-	}
-	else if( strcmp( action, "decode" ) == 0 )
-	{
-		char hash2[32];
-		
-		fread( hash2, 32, 1, stdin );
-		if( memcmp( hash, hash2, 32 ) != 0 )
-		{
-			fprintf( stderr, "Passwords don't match. Can't decode.\n" );
-			return( 1 );
-		}
-		func = deobfucrypt;
-	}
-	else
-	{
-		return( main( 0, NULL ) );
-	}
-	
-	while( fscanf( stdin, "%[^\n]255s", line ) > 0 )
-	{
-		char *out;
-		
-		/* Flush the newline */
-		fgetc( stdin );
-		
-		out = func( line, argv[1] );
-		printf( "%s\n", out );
-		g_free( out );
-	}
-	
-	return( 0 );
-}
-
-#endif
Index: unix.c
===================================================================
--- unix.c	(revision b52e478f9cfea9c0319d3f0203b31e4b5d03f38b)
+++ unix.c	(revision 7c9db249e4d94413f561841495d1e147d53327d5)
@@ -25,9 +25,13 @@
 
 #include "bitlbee.h"
+
+#include "arc.h"
+#include "base64.h"
 #include "commands.h"
-#include "crypting.h"
 #include "protocols/nogaim.h"
 #include "help.h"
 #include "ipc.h"
+#include "md5.h"
+#include "misc.h"
 #include <signal.h>
 #include <unistd.h>
@@ -40,4 +44,6 @@
 static void sighandler( int signal );
 
+static int crypt_main( int argc, char *argv[] );
+
 int main( int argc, char *argv[] )
 {
@@ -45,4 +51,7 @@
 	char *old_cwd = NULL;
 	struct sigaction sig, old;
+	
+	if( argc > 1 && strcmp( argv[1], "-x" ) == 0 )
+		return crypt_main( argc, argv );
 	
 	log_init();
@@ -159,4 +168,60 @@
 }
 
+static int crypt_main( int argc, char *argv[] )
+{
+	int pass_len;
+	unsigned char *pass_cr, *pass_cl;
+	
+	if( argc < 3 )
+	{
+		printf( "Supported:\n"
+		        "  %s -x enc <key> <cleartext password>\n"
+		        "  %s -x dec <key> <encrypted password>\n"
+		        "  %s -x hash <cleartext password>\n"
+		        "  %s -x unhash <hashed password>\n"
+		        "  %s -x chkhash <hashed password> <cleartext password>\n",
+		        argv[0], argv[0], argv[0], argv[0], argv[0] );
+	}
+	else if( strcmp( argv[2], "enc" ) == 0 )
+	{
+		pass_len = arc_encode( argv[4], strlen( argv[4] ), (unsigned char**) &pass_cr, argv[3], 12 );
+		printf( "%s\n", base64_encode( pass_cr, pass_len ) );
+	}
+	else if( strcmp( argv[2], "dec" ) == 0 )
+	{
+		pass_len = base64_decode( argv[4], (unsigned char**) &pass_cr );
+		arc_decode( pass_cr, pass_len, (char**) &pass_cl, argv[3] );
+		printf( "%s\n", pass_cl );
+	}
+	else if( strcmp( argv[2], "hash" ) == 0 )
+	{
+		md5_byte_t pass_md5[21];
+		md5_state_t md5_state;
+		
+		random_bytes( pass_md5 + 16, 5 );
+		md5_init( &md5_state );
+		md5_append( &md5_state, (md5_byte_t*) argv[3], strlen( argv[3] ) );
+		md5_append( &md5_state, pass_md5 + 16, 5 ); /* Add the salt. */
+		md5_finish( &md5_state, pass_md5 );
+		
+		printf( "%s\n", base64_encode( pass_md5, 21 ) );
+	}
+	else if( strcmp( argv[2], "unhash" ) == 0 )
+	{
+		printf( "Hash %s submitted to a massive Beowulf cluster of\n"
+		        "overclocked 486s. Expect your answer next year somewhere around this time. :-)\n", argv[3] );
+	}
+	else if( strcmp( argv[2], "chkhash" ) == 0 )
+	{
+		int st = md5_verify_password( argv[4], argv[3] );
+		
+		printf( "Hash %s given password.\n", st == 0 ? "matches" : "does not match" );
+		
+		return st;
+	}
+	
+	return 0;
+}
+
 static void sighandler( int signal )
 {
@@ -214,4 +279,2 @@
 	return( (double) time->tv_sec + (double) time->tv_usec / 1000000 );
 }
-
-
