diff -urN BitchX-clean/Makefile.in BitchXcns-1.0c19cns/Makefile.in
--- BitchX-clean/Makefile.in	Mon Mar  5 20:30:04 2001
+++ BitchXcns-1.0c19cns/Makefile.in	Fri Mar 29 07:36:37 2002
@@ -237,10 +237,10 @@
 	$(INSTALL) source/$(_VERSION_)$(EXEEXT) $(local_dir)/bin/$(VERSION)$(EXEEXT)
 	$(INSTALL) $(local_dir)/bin/$(VERSION)$(EXEEXT) $(local_dir)/bin/$(_VERSION_)$(EXEEXT)
 	$(INSTALL) source/scr-bx$(EXEEXT) $(local_dir)/bin/scr-bx$(EXEEXT)
-	$(INSTALL_DATA) $(top_srcdir)/BitchX.help $(DEFAULT_CTOOLZ_DIR)/$(DEFAULT_BITCHX_HELP_FILE)
-	$(INSTALL_DATA) $(top_srcdir)/BitchX.ircnames $(DEFAULT_CTOOLZ_DIR)/$(DEFAULT_BITCHX_IRCNAME_FILE)
-	$(INSTALL_DATA) $(top_srcdir)/BitchX.quit $(DEFAULT_CTOOLZ_DIR)/$(DEFAULT_BITCHX_QUIT_FILE)
-	$(INSTALL_DATA) $(top_srcdir)/BitchX.reasons $(DEFAULT_CTOOLZ_DIR)/$(DEFAULT_BITCHX_KICK_FILE)
+	$(INSTALL_DATA) $(top_srcdir)/BitchX.help $(local_dir)/.BitchX/$(DEFAULT_BITCHX_HELP_FILE)
+	$(INSTALL_DATA) $(top_srcdir)/BitchX.ircnames $(local_dir)/.BitchX/$(DEFAULT_BITCHX_IRCNAME_FILE)
+	$(INSTALL_DATA) $(top_srcdir)/BitchX.quit $(local_dir)/.BitchX/$(DEFAULT_BITCHX_QUIT_FILE)
+	$(INSTALL_DATA) $(top_srcdir)/BitchX.reasons $(local_dir)/.BitchX/$(DEFAULT_BITCHX_KICK_FILE)
 
 wserv: .config.h $(srcdir)/source/wserv.c $(srcdir)/source/term.c $(srcdir)/Makefile
 	cd source \
diff -urN BitchX-clean/README.CNSirc BitchXcns-1.0c19cns/README.CNSirc
--- BitchX-clean/README.CNSirc	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/README.CNSirc	Fri Mar 29 07:36:37 2002
@@ -0,0 +1,219 @@
+CNSirc, the come back (final version ? :-)
+we,
+     _____ _   _  _____    ____  __ _ _   _ _ _______ _    _ _ _   _  _____ 
+    / ____| \ | |/ ____|  / /  \/  (_) \ | (_)__   __| |  | (_) \ | |/ ____|
+   | |    |  \| | (___   / /| \  / |_|  \| |_   | |  | |__| |_|  \| | (___  
+   | |    | . ` |\___ \ / / | |\/| | | . ` | |  | |  |  __  | | . ` |\___ \ 
+   | |____| |\  |____) / /  | |  | | | |\  | |  | |  | |  | | | |\  |____) |
+    \_____|_| \_|_____/_/   |_|  |_|_|_| \_|_|  |_|  |_|  |_|_|_| \_|_____/ 
+                                                                            
+present:
+
+                             with their fans
+                          a new more secure tool
+                             with more colors
+                           high definition video
+                         no more VHS, now use DVD
+                      the *BEST* irc client for ever
+                                we named:
+
+           ____ _   _ ____  _            ____ _____  _    ____  ____         
+  __/\__  / ___| \ | / ___|(_)_ __ ___  / ___|_   _|/ \  |  _ \/ ___|  __/\__
+  \    / | |   |  \| \___ \| | '__/ __| \___ \ | | / _ \ | |_) \___ \  \    /
+  /_  _\ | |___| |\  |___) | | | | (__   ___) || |/ ___ \|  _ < ___) | /_  _\
+    \/    \____|_| \_|____/|_|_|  \___| |____/ |_/_/   \_\_| \_\____/    \/  
+                                                                             
+	(and i still love pr0n stars so much, but now i prefer my irc client :-))
+
+PRIVATE DON'T DISTRIBUTE !!!
+        PRIVATE DON'T DISTRIBUTE !!!
+
+---[ email adress:         cns@minithins.net
+---[ irc channel:          #minithins on any Undernet servers
+---[ website adress:       http://www.minithins.net/
+---[ get last release:     http://www.minithins.net/private/
+---[ no private access:    ask on #minithins
+
+VERSION: CNSirc-1.2.0
+
+RELEASES NOTES:
+
+My IRC client, CNSirc, permits channels and private messages encryption.
+I use RSA and twofish algorithms, using OpenSSL and some code proposed for new
+AES 2 years ago.
+	CNSirc was created to secure IRC communications; unlike ircs servers, the
+data is not uncrypted by the server; so only clients can see real traffic.
+	CNSirc is a private tool. Don't distribute it if you're not allowed to do 
+it. By the way, only my friends 'll get it. If you give it, i'll change the 
+code and make it unusable by you. That's the way i want it to be. So fuck off.
+
+HOW TO INSTALL:
+
+	* Install shared OpenSSL libs:
+Get latest openssl package; and configure it:
+./Configure --prefix=/usr shared linux-elf
+
+	* For CNSirc, just gmake && gmake && gmake install (or install_local).
+
+
+FIRST USE:
+
+	* First time, you need to do one thing: create your own RSA keys.
+	You only need to do that one time; it ll create a file key in
+	~/.BitchX/CNSkeys, and after you don't need anymore to create keys.
+	To do that, just use /genmykey, and save it with /savekey
+
+
+HOW TO USE:
+
+	* first use:
+		/genmykey and /savekey <-- just for generate your uniq RSA key
+
+	* after, normal use:
+		/pubkey <-- to share your public RSA key (to chat or recieve keys)
+		/genkey <-- generate a channel key for crypting
+		/sendkey <nick> <channel><-- to send channel key
+
+
+COMMANDS:
+
+	* basic commands
+		/pubkeycns [target]
+		or /pk or /cpubkey
+			Send your RSA public key to a target (nick or channel)
+		
+		/sendkeycns [channel] [nick]
+		or /sk or /csendkey
+			Send a channel key to a target (nick)
+
+		/genkeycns [target]
+		or /gk or /cgenkey
+			Create a new channel key 
+
+
+	* remote commands
+		/getrsakey [nick]
+			Ask for someone's RSA key
+
+		/getrsakey [nick] [channel]
+			Ask channel's key to someone
+
+
+	* clear message functions
+		/cm <message>
+			Clear /msg to current channel
+
+		/cme <message>
+			Clear /me to currnet channel
+
+		/cmsg [channel] <message>
+			Clear /msg to channel 
+
+		/ctoggle [channel]
+			Toggle crypting channel (on/off)		
+
+
+	* remove functions
+		/clearkey [target]
+			Remove RSA/Channel key
+
+		/clearrsakey [nick]
+			Remove RSA key
+
+		/clearchankey
+			Remove Channel key
+
+		/clearnick
+			Remove a nick (not a RSA key if there is another key)
+
+
+	* list keys
+		/listrsa
+			List Rsa keys.
+
+		/listchan
+			List channel keys.
+
+		/listnick
+			List all nicks.
+
+
+	* key administration
+		/genmykey
+			create your keys.
+
+		/savemykey
+			save your keys.
+
+		/freemykey
+			remove my keys from memory.
+
+		/loadkey
+			you can reload my keys from memory.
+
+		/keyinfo
+			gives some info on your keys
+
+
+	* misc functions
+		/vers
+			print version
+
+		/testkey
+			test your RSA key
+
+		/testrsacrypt
+			test RSA crypting
+
+		/testcrypt
+			test twofish encryption
+			 
+
+SOME USING:
+
+  ---------------------------------------------------------------------------
+
+ùíù user [~user@lives.in.minithins.net] has joined #mychannel
+ùíù ServerMode/#mychannel [+nt] by kiev.minithins.net
+ùíù [Users(#mychannel:1)] 
+[@user      ] 
+ùíù CNSirc: Join to #mychannel was synched in 0.006 secs!!
+ùíù mode/#mychannel [+nt] by user
+<user> ho ! I'm alone ! So i'll generate a key to crypt this channel !
+ùíù CNSirc: Commands:
+ùíù GENKEY
+ùíù [*] #mychannel is now crypted ... (key crc: D9478823)
+(user) wow it's cool !
+ùíù friend [~friend@lives.in.minithins.net] has joined #mychannel
+<friend> hello !
+<friend> I'm not alone I'll send my public key and i'll wait that 'user' give
+          me channel key !
+ùíù [*] Got friend's public key (crc is F6E200FE, len is 256)
+<friend> <CNSirc>TMfdp+vntZAhTEzrTETBFmhXi3eQ+V9D0ON4rg3qpyPdUL+LKk2Pg2aWjIilEx
+          J1R8kqN5q7/le+gJSEg00h/WZVIcjEB5Faj7F2LZc4bllDxTYtqmg9HcTxKKVuIjNV1vE
+          Vl2PBvP5e1EFd4ozKoMwBfEhPqvpChxGyOv8famea
+
+(at this moment friend just used /pubkey)
+
+(now, user only has to press /sendkey)
+ùíù [*] #mychannel's key sent to friend
+
+(on friend screen:)
+ùíù [*] Recieved key for #mychannel. 
+(friend) hello !
+
+  ---------------------------------------------------------------------------
+
+NOTES:
+
+--- main things ---
+
+    * release 1.1.1 version
+    * write RFC file.
+
+--- second things ---
+
+    * more encryption schematics
+        (pubkey: dsa; normal: blowfish, rc6, rijndael, mars)
+
+end of file.
diff -urN BitchX-clean/RFC.CNSirc BitchXcns-1.0c19cns/RFC.CNSirc
--- BitchX-clean/RFC.CNSirc	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/RFC.CNSirc	Fri Mar 29 07:36:37 2002
@@ -0,0 +1,59 @@
+CNSirc PROTOCOL
+
+- privates via RSA -
+paquets cryptés par paquets de 128
+crypt_method = 1;
+
+clée publique dans clée privée
+cle->n et cle->e (cle->e toujours = à 65537, 0x10001)
+crypt_method = 2;
+
+- public via twofish -
+clé de 32 octets
+paquets cryptés par paquets de 16
+
+* TODO:
+* procedure to check if rsa key sent is correct
+* procedure to check if rsa key already is not in someone other rsa key.
+
+
+/*****************************************************************************/
+
+
+struct st_nick_crypted
+{
+    struct st_nick_crypted *next;
+    char    *nick;
+    RSA     *hispubkey;
+    time_t  modified; 
+    int     opt;
+} *nick_head = NULL;
+
+struct st_chan_crypted
+{
+    struct st_chan_crypted *next;
+    char   *chan;
+    char   *chankey;
+    time_t modified;
+    int    opt;
+} *chan_head = NULL;
+
+struct st_msg_header
+{   
+    unsigned short un_len;
+    unsigned short cr_len;
+    unsigned long  crc32;
+    char           crypt_method; 
+	// 0 for none (clear), 
+	// 1 for RSA, 2 for Twofish
+    char           opt;
+	unsigned short padding;
+	// padding 'll be 7337
+	unsigned char  text;
+};
+
+sizeof(struct st_msg_header) == 12.
+
+
+
+
diff -urN BitchX-clean/configure BitchXcns-1.0c19cns/configure
--- BitchX-clean/configure	Sun Mar 24 10:30:49 2002
+++ BitchXcns-1.0c19cns/configure	Fri Mar 29 07:50:14 2002
@@ -763,6 +763,9 @@
   cat <<_ACEOF
 \`configure' configures this package to adapt to many kinds of systems.
 
+CNSirc* by CNS/Minithins
+As CNSirc standard edition, you need OpenSSL (with shared objects)
+
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 To assign environment variables (e.g., CC, CFLAGS...), specify them as
@@ -865,7 +868,6 @@
                           Prefix where AUDIOFILE is installed (optional)
   --with-audiofile-exec-prefix=PFX
                           Exec prefix where AUDIOFILE is installed (optional)
-  --with-ssl              Enable SSL support
   --with-tgetent          Use tgetent (termcap) instead of setupterm (ncurses)
   --with-tcl              Enable Tcl support
   --with-maildir=PATH     Enable QMAIL support
@@ -1254,8 +1256,17 @@
 _ACEOF
 
 
-echo Welcome to the "$VERSION" configuration
+echo "     _____ _   _  _____    ____  __ _ _   _ _ _______ _    _ _ _   _  _____ "
+echo "    / ____| \ | |/ ____|  / /  \/  (_) \ | (_)__   __| |  | (_) \ | |/ ____|"
+echo "   | |    |  \| | (___   / /| \  / |_|  \| |_   | |  | |__| |_|  \| | (___  "
+echo "   | |    | . \` |\___ \ / / | |\/| | | . \` | |  | |  |  __  | | . \` |\___ \ "
+echo "   | |____| |\  |____) / /  | |  | | | |\  | |  | |  | |  | | | |\  |____) |"
+echo "    \_____|_| \_|_____/_/   |_|  |_|_|_| \_|_|  |_|  |_|  |_|_|_| \_|_____/ "
 echo
+  
+echo "Welcome to the "$VERSION" configuration"
+echo "Be sure you have OpenSSL (shared objects format requiered)"
+
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -9009,8 +9020,9 @@
 echo $ECHO_N "checking whether to enable SSL support... $ECHO_C" >&6
 
 # Check whether --with-ssl or --without-ssl was given.
-if test "${with_ssl+set}" = set; then
-  withval="$with_ssl"
+#if test "${with_ssl+set}" = set; then
+#  withval="$with_ssl"
+ withval="yes"
    case "$withval" in
     yes)
       echo "$as_me:$LINENO: result: yes" >&5
@@ -9086,21 +9098,24 @@
 
 else
   { { echo "$as_me:$LINENO: error: Could not find OpenSSL." >&5
-echo "$as_me: error: Could not find OpenSSL." >&2;}
+echo "$as_me: error: Could not find OpenSSL." >&2;
+echo "$as_me: README.CNSirc told me to compile it and install it." >&2
+echo "$as_me: Configure OpenSSL: ./Configure --prefix=/usr shared linux-elf" >&2
+}
    { (exit 1); exit 1; }; }
 fi
 
       ;;
-    no)
-      echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-      ;;
+#    no)
+#      echo "$as_me:$LINENO: result: no" >&5
+#echo "${ECHO_T}no" >&6
+#      ;;
   esac
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+#else
+#  echo "$as_me:$LINENO: result: no" >&5
+#echo "${ECHO_T}no" >&6
 
-fi;
+#fi;
 
 if test -n "$gtk" -o -n "$pm" -o -n "$win32"; then
 
@@ -16042,10 +16057,16 @@
 
 
 echo
-echo BitchX \(c\) 1996-2002 Colten Edwards
+echo BitchX \(c\) 1996-2001 Colten Edwards
+echo BitchX 2001-2002 by CNS/Minithins
 echo ----------------------------------------------------------
 echo
+echo CNSirc by CNS \/ Minithins - !!! PRIVATE !!!
+echo VERSION \"$VERSION\"  - DON\'T DISTRIBUTE !!
+echo
+echo BitchX use notification disabled
+echo
 echo The configuration script has finished. You should look through
 echo \"include/config.h\" and make any changes you would like to make.
 echo
-echo Now type \"$MAKE\" to compile BitchX.
+echo Now type \"$MAKE\" to compile CNSirc. 
diff -urN BitchX-clean/include/cfunctions.h BitchXcns-1.0c19cns/include/cfunctions.h
--- BitchX-clean/include/cfunctions.h	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/include/cfunctions.h	Fri Mar 29 07:36:37 2002
@@ -0,0 +1,165 @@
+/*
+ * Specific CNSirc functions header
+ *
+ *
+ */
+
+#ifndef __cns_functions_h_
+#define __cns_functions_h_
+
+#define CNS_VERSION "1.4.0beta"
+
+	enum CRYPTO_TYPES
+	{
+		NO_CRYPT,
+		RSA_CRYPT,
+		TWOFISH_CRYPT,
+		PLUS_ONE_CRYPT_NUMBERS
+	}; // may be more later ? :-)
+
+	struct st_a_nick
+	{
+		struct st_a_nick *next;
+		char             *nick;
+	};
+
+	struct st_nick_crypted
+	{
+		struct st_nick_crypted 	*next;
+		struct st_a_nick		*nick_list;
+		RSA						*hispubkey;
+		unsigned int 			opt;
+		unsigned char 			crypt_typ;
+	};
+
+	struct st_chan_crypted
+	{
+		struct st_chan_crypted *next;
+		unsigned char 	*chan;
+		unsigned char 	*chankey;
+		unsigned int	opt;
+		unsigned char	crypt_typ;
+	};
+
+	struct st_msg_header
+	{   
+		unsigned short un_len;
+		unsigned short cr_len;
+		unsigned long  crc32;
+		char           crypt_method;
+		char           opt;
+		unsigned short padding;
+		unsigned char  *text;
+	};
+
+	typedef unsigned char   u1byte;
+	typedef unsigned short  u2byte;
+	typedef unsigned long   u4byte;
+
+	typedef signed char     s1byte;
+	typedef signed short    s2byte;
+	typedef signed long     s4byte;
+
+	char **cipher_name_mars(void);
+	u4byte *set_key_mars(const u4byte in_key[], const u4byte key_len);
+	void encrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+	void decrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+
+	char **cipher_name_twofish(void);
+	u4byte *set_key_twofish(const u4byte in_key[], const u4byte key_len);
+	void encrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+	void decrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+	
+	int get_from_codec(char a);
+	unsigned long my_cksum (unsigned char *buf, int len);
+	void c_say (char *display, const char *, ...);
+	unsigned char *cns_generate_channel_key();
+
+	char *encode_rsa_key(unsigned char *rsapubkey);
+	char *decode_rsa_key(unsigned char *rsapubkey);
+
+	// keys functions
+	void cmd_generate_key (char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_free_my_key (char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_load_my_key (char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_save_my_key (char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_test_my_key (char *cmd, char *args, char *subargs, char *helparg);
+
+	void cmd_key_info (char *cmd, char *args, char *subargs, char *helparg);
+
+	// misc functions
+	void cmd_version (char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_test_twofish (char *cmd, char *args, char *subargs, char *helparg);
+
+	// IO functions
+
+	void cmd_send_pubkey (char *cmd, char *args, char *subargs, char *helparg);
+	int check_is_rsa_key (char *ptr);
+	void get_rsa_key (char *from, char *to, char *ptr);
+
+	RSA* get_rsa_key_from_nick (char *nick); 
+	void add_rsa_key (char *nick, unsigned char *pubkey);
+	void clear_rsa_key (char *nick);
+	void cmd_clear_rsa_key(char *cmd, char *args, char *subargs, char *helparg);
+	void cmd_rsa_list (char *cmd, char *args, char *subargs, char *helparg); 
+
+	// to code:
+	void cmd_chan_list (char *cmd, char *args, char *subargs, char *helparg);
+	unsigned char *get_pass_from_chan (char *chan);
+
+	void cmd_test_rsa_crypt (char *cmd, char *args, char *subargs, char *helparg);
+
+	unsigned char *normal_2_irc (unsigned char *texte, int len);
+	unsigned char *irc_2_normal (unsigned char *texte);
+	unsigned char *form_normal_irc
+		(unsigned char *texte, short cr_len, short un_len, int typ);
+	struct st_msg_header *form_irc_normal (unsigned char *texte);
+	unsigned char *cns_crypt_RSA (unsigned char *phrase, RSA *key, int p_len);
+	unsigned char *cns_decrypt_RSA (unsigned char *phrase);
+
+	int is_sed_crypted (unsigned char *texte);
+	struct st_msg_header *get_st (unsigned char *texte);
+	int is_correct_crypt (unsigned char *texte);
+	int is_cnsirc_crypted(unsigned char *target, unsigned char *command);
+	int is_have_to_send_clear_text (char *cmd);
+
+	unsigned char *get_pass_from_chan (char *chan);
+
+	void cmd_gen_chan_key (char *cmd, char *args, char *subargs, char *helparg);
+
+void cmd_clear_chan_key (char *cmd, char *args, char *subargs, char *helparg);
+void cmd_clear_key (char *cmd, char *args, char *subargs, char *helparg);
+void cmd_list_all_nick (char *cmd, char *args, char *subargs, char *helparg);
+unsigned char *cns_decrypt_twofish (unsigned char *phrase, unsigned char *key);
+unsigned char *cns_crypt_twofish (unsigned char *phrase, unsigned char *key);
+void cmd_send_chan_key (char *cmd, char *args, char *subargs, char *helparg);
+int recieve_chan_key (char *phrase, int p_len);
+struct st_chan_crypted *add_chan_key (char *channel, unsigned char *chankey);
+void cmd_clear_text (char *cmd, char *args, char *subargs, char *helparg);
+
+void cmd_clear_nick (char *cmd, char *args, char *subargs, char *helparg);
+void c_rename_nick (char *from_nick, char *to_nick);
+void clear_nick (char *nick);
+void cmd_ctoggle (char *cmd, char *args, char *subargs, char *helparg);
+
+int is_crypted_by_opt (unsigned char *target);
+
+void cmd_require_key (char *cmd, char *args, char *subargs, char *helparg);
+void get_ctcp_cnscmd (char *from, char *to, char *message);
+int is_trusted_nick (char *nick);
+void cmd_trust (char *cmd, char *args, char *subargs, char *helparg);
+void cmd_untrust (char *cmd, char *args, char *subargs, char *helparg);
+
+void cmd_require_rsa_key
+	(char *cmd, char *args, char *subargs, char *helparg);
+
+void cmd_greet (char *cmd, char *args, char *subargs, char *helparg);
+
+void clear_all_keys();
+void cmd_key_save (char *cmd, char *args, char *subargs, char *helparg);
+void cmd_key_load (char *cmd, char *args, char *subargs, char *helparg);
+
+void load_private_file();
+void save_private_file();
+
+#endif
diff -urN BitchX-clean/include/color.h BitchXcns-1.0c19cns/include/color.h
--- BitchX-clean/include/color.h	Mon Mar  5 20:38:48 2001
+++ BitchXcns-1.0c19cns/include/color.h	Fri Mar 29 07:36:37 2002
@@ -188,6 +188,21 @@
 #define DEFAULT_FORMAT_SEND_NOTICE_FSET "%K[%rnotice%K(%R$1%K)] %n$3-"
 #define DEFAULT_FORMAT_SEND_PUBLIC_FSET "%p<%n$2%p>%n $3-"
 #define DEFAULT_FORMAT_SEND_PUBLIC_OTHER_FSET "%p<%n$2%K:%n$1%p>%n $3-"
+
+/* Done for CNSirc */
+#define DEFAULT_FORMAT_C_PUBLIC_FSET			 "%W(%n$1%W)%n $3-"
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_FSET        "%W(%n%K$1%n%W)%n $3-"
+#define DEFAULT_FORMAT_C_PUBLIC_OTHER_FSET       "%K(%n$1%K/%n$2%K)%n $3-"
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_OTHER_FSET  "%K(%n%W$1%n%K/%n$2%K)%n $3-"
+
+#define DEFAULT_FORMAT_C_MSG_FSET                "%K[%W$1%K]%n%K(%n$2%K)%n $4-"
+#define DEFAULT_FORMAT_C_SEND_MSG_FSET           "%K[%nmsg%K](%W$2%K)%n $3-"
+
+#define DEFAULT_FORMAT_C_NOTICE_FSET             "%K-%W$1%K(%n$2%K)-%n $4-" 
+#define DEFAULT_FORMAT_C_SEND_NOTICE_FSET        "%K[%nnotice%K](%W$2%K)%n $3-"
+#define DEFAULT_FORMAT_C_PUBLIC_NOTICE_FSET      "%K-%W$1%K:$2-%n $4-" 
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_NOTICE_FSET "%K-%W$1%K($2)-%n $3-"
+
 /* Not in Hades*/
 #define DEFAULT_FORMAT_SEND_AWAY_FSET "[Away ($strftime($1 %a %b %d %I:%M%p %Z))] [$tdiff2(${time() - u})] [BX-MsgLog $2]"
 #define DEFAULT_FORMAT_SEND_CTCP_FSET "%K[%rctcp%K(%R$1%K)] %n$2"
@@ -574,6 +589,20 @@
 #define DEFAULT_FORMAT_PUBLIC_OTHER_FSET ansi?"%@%b<%n$1%K:%n$2%b>%n $3-":"%@<$1:$2> $3-"
 #define DEFAULT_FORMAT_PUBLIC_OTHER_AR_FSET ansi?"%@%b<%Y$1%K:%n$2%b>%n $3-":"%@<$1:$2> $3-"
 
+/* Done for CNSirc */
+#define DEFAULT_FORMAT_C_PUBLIC_FSET             "%@%W(%n$1%W)%n $3-"
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_FSET        "%@%W(%n%K$1%n%W)%n $3-"
+#define DEFAULT_FORMAT_C_PUBLIC_OTHER_FSET       "%@%K(%n$1%K/%n$2%K)%n $3-"
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_OTHER_FSET  "%@%K(%n%W$1%n%K/%n$2%K)%n $3-"
+
+#define DEFAULT_FORMAT_C_MSG_FSET               "%@%K[%W$1%K]%n%K(%n$2%K)%n $4-"
+#define DEFAULT_FORMAT_C_SEND_MSG_FSET          "%@%K[%nmsg%K](%W$2%K)%n $3-"
+
+#define DEFAULT_FORMAT_C_NOTICE_FSET            "%@%K-%W$1%K(%n$2%K)-%n $4-"
+#define DEFAULT_FORMAT_C_SEND_NOTICE_FSET       "%@%K[%nnotice%K](%W$2%K)%n $3-"
+#define DEFAULT_FORMAT_C_PUBLIC_NOTICE_FSET      "%@%K-%W$1%K:$2-%n $4-"
+#define DEFAULT_FORMAT_C_SEND_PUBLIC_NOTICE_FSET "%@%K-%W$1%K($2)-%n $3-"
+
 #ifdef ONLY_STD_CHARS
 #define DEFAULT_FORMAT_SEND_ACTION_FSET "%K* %W$1 %n$3-"
 #define DEFAULT_FORMAT_SEND_ACTION_OTHER_FSET "%K* %n-> %W$1%n/%c$2 %n$3-"
@@ -717,8 +746,8 @@
 	
 #define DEFAULT_FORMAT_NICK_MSG_FSET "$0 $1 $2-"
 
-#define DEFAULT_FORMAT_NICK_COMP_FSET "$0\002:\002$1-"
-#define DEFAULT_FORMAT_NICK_AUTO_FSET "$0\002:\002$1-"
+#define DEFAULT_FORMAT_NICK_COMP_FSET "$0:$1-"
+#define DEFAULT_FORMAT_NICK_AUTO_FSET "$0:$1-"
 
 #define DEFAULT_FORMAT_STATUS_FSET "%4%W$0-"
 #define DEFAULT_FORMAT_STATUS1_FSET "%4%W$0-"
diff -urN BitchX-clean/include/config.h BitchXcns-1.0c19cns/include/config.h
--- BitchX-clean/include/config.h	Sun Mar 24 10:31:04 2002
+++ BitchXcns-1.0c19cns/include/config.h	Fri Mar 29 07:44:58 2002
@@ -195,7 +195,7 @@
  * we define the default network type for server groups. Do not just
  * undefine this.
  */
- #define DEFAULT_NETWORK "efnet"
+#define DEFAULT_NETWORK "efnet"
 
 /*
  * Below are the IRCII variable defaults.  For boolean variables, use 1 for
@@ -218,7 +218,7 @@
  * mode compressor to the client. It reduces the duplicate modes that
  * might occur on a channel.. it's explained in names.c much better.
  */
- #define COMPRESS_MODES
+#define COMPRESS_MODES
 
 
 /*
@@ -373,12 +373,17 @@
 #define IRCRC_NAME "/.ircrc"
 #endif
 
+#define DEFAULT_DEFAULT_ADDED_LETTER "`"
+#define DEFAULT_ACT_AS_KEY_SERV OFF
+#define DEFAULT_SHOW_RSA_KEY OFF
+#define DEFAULT_IGNORE_REMOTE ON
+#define DEFAULT_SHOW_ALL_CNSIRC_MESSAGES ON
 #define DEFAULT_PING_TYPE 1
 #define DEFAULT_MSGLOG ON
 #define DEFAULT_AUTO_NSLOOKUP OFF
 #define DEFAULT_ALT_CHARSET ON
-#define DEFAULT_FLOOD_KICK ON
-#define DEFAULT_FLOOD_PROTECTION ON
+#define DEFAULT_FLOOD_KICK OFF
+#define DEFAULT_FLOOD_PROTECTION OFF
 #define DEFAULT_CTCP_FLOOD_PROTECTION ON
 #define DEFAULT_MAX_AUTOGET_SIZE 2000000
 #define DEFAULT_LLOOK_DELAY 120
@@ -419,7 +424,7 @@
 #define DEFAULT_INVERSE_VIDEO ON
 #define DEFAULT_LASTLOG 1000
 #define DEFAULT_LOG OFF
-#define DEFAULT_MAIL 2
+#define DEFAULT_MAIL 0 
 #define DEFAULT_NO_CTCP_FLOOD ON
 #define DEFAULT_NOTIFY_HANDLER "QUIET"
 #define DEFAULT_NOTIFY_INTERVAL 60
@@ -477,7 +482,7 @@
 #define DEFAULT_TAB_MAX 8
 #define DEFAULT_TIMESTAMP OFF
 #define DEFAULT_TIMESTAMP_AWAYLOG_HOURLY ON
-#define DEFAULT_TIMESTAMP_STR "%I:%M%p "
+#define DEFAULT_TIMESTAMP_STR "[%I:%M%P] "
 #define DEFAULT_UNDERLINE_VIDEO ON
 #define DEFAULT_VERBOSE_CTCP ON
 #define DEFAULT_DISPLAY_ANSI ON
@@ -494,10 +499,10 @@
 #define DEFAULT_AINV 0
 #define DEFAULT_ANNOY_KICK OFF
 #define DEFAULT_AOP_VAR OFF
-#define DEFAULT_AUTO_AWAY ON
+#define DEFAULT_AUTO_AWAY OFF
 #define DEFAULT_KICK_OPS ON
 #define DEFAULT_AUTO_REJOIN ON
-#define DEFAULT_DEOPFLOOD ON
+#define DEFAULT_DEOPFLOOD OFF
 #if defined(__EMXPM__) || defined(WIN32)
 #define DEFAULT_CODEPAGE 437
 #endif
@@ -508,16 +513,16 @@
 #define DEFAULT_DEOP_ON_KICKFLOOD 3
 #define DEFAULT_KICK_IF_BANNED OFF
 #define DEFAULT_HACKING 0  /* 0 1 2 */
-#define DEFAULT_JOINFLOOD ON
+#define DEFAULT_JOINFLOOD OFF
 #define DEFAULT_JOINFLOOD_TIME 50
-#define DEFAULT_KICKFLOOD ON
+#define DEFAULT_KICKFLOOD OFF
 #define DEFAULT_KICKFLOOD_TIME 30
 #define DEFAULT_KICK_ON_DEOPFLOOD 3
 #define DEFAULT_KICK_ON_JOINFLOOD 4
 #define DEFAULT_KICK_ON_KICKFLOOD 4
 #define DEFAULT_KICK_ON_NICKFLOOD 3
 #define DEFAULT_KICK_ON_PUBFLOOD 30
-#define DEFAULT_NICKFLOOD ON
+#define DEFAULT_NICKFLOOD OFF
 #define DEFAULT_NICKFLOOD_TIME 30
 #ifdef __EMXPM__
 #define DEFAULT_NICKLIST 10
@@ -598,7 +603,7 @@
 #define DEFAULT_HIGHLIGHT_CHAR "INVERSE"
 #define DEFAULT_LASTLOG_LEVEL "ALL"
 #define DEFAULT_MSGLOG_LEVEL "MSGS NOTICES SEND_MSG"
-#define DEFAULT_LOGFILE "IrcLog"
+#define DEFAULT_LOGFILE "~/.IrcLog"
 #define DEFAULT_SHELL "/bin/sh"
 #define DEFAULT_SHELL_FLAGS "-c"
 #define DEFAULT_USERINFO ""
diff -urN BitchX-clean/include/cset.h BitchXcns-1.0c19cns/include/cset.h
--- BitchX-clean/include/cset.h	Mon May  7 10:41:16 2001
+++ BitchXcns-1.0c19cns/include/cset.h	Fri Mar 29 07:36:37 2002
@@ -144,6 +144,17 @@
 FORMAT_BOT_HEADER_FSET,
 FORMAT_BWALL_FSET,
 
+FORMAT_C_MSG_FSET,
+FORMAT_C_NOTICE_FSET,
+FORMAT_C_PUBLIC_FSET,
+FORMAT_C_PUBLIC_NOTICE_FSET,
+FORMAT_C_PUBLIC_OTHER_FSET,
+FORMAT_C_SEND_MSG_FSET,
+FORMAT_C_SEND_NOTICE_FSET,
+FORMAT_C_SEND_PUBLIC_FSET,
+FORMAT_C_SEND_PUBLIC_NOTICE_FSET,
+FORMAT_C_SEND_PUBLIC_OTHER_FSET,
+
 FORMAT_CHANNEL_SIGNOFF_FSET,
 
 FORMAT_COMPLETE_FSET,
diff -urN BitchX-clean/include/ctcp.h BitchXcns-1.0c19cns/include/ctcp.h
--- BitchX-clean/include/ctcp.h	Mon May  7 10:41:16 2001
+++ BitchXcns-1.0c19cns/include/ctcp.h	Fri Mar 29 07:36:37 2002
@@ -42,8 +42,10 @@
 #define CTCP_IDENT	19
 #define CTCP_UNBAN	20
 #define CTCP_BOTLINK	21
-#define CTCP_UPTIME	22
-#define CTCP_CUSTOM	23
+#define CTCP_UPTIME		22
+#define CTCP_C_ACTION   23
+#define CTCP_CNS_CMD    24
+#define CTCP_CUSTOM		25
 
 #define NUMBER_OF_CTCPS	CTCP_CUSTOM
 
diff -urN BitchX-clean/include/vars.h BitchXcns-1.0c19cns/include/vars.h
--- BitchX-clean/include/vars.h	Sun Mar 24 10:31:04 2002
+++ BitchXcns-1.0c19cns/include/vars.h	Fri Mar 29 07:36:37 2002
@@ -12,6 +12,7 @@
 /* indexes for the irc_variable array */
 
 enum VAR_TYPES {
+	ACT_AS_KEY_SERV ,
 	AINV_VAR,
 	ALTNICK_VAR,
 	ALT_CHARSET_VAR,
@@ -97,6 +98,7 @@
 	DCC_ULDIR_VAR,
 	DCC_USE_GATEWAY_ADDR_VAR,
 	DEBUG_VAR ,
+	DEFAULT_ADDED_LETTER_VAR,
 #if defined(__EMXPM__) || defined(WIN32)
 	DEFAULT_CODEPAGE_VAR,
 #endif
@@ -142,6 +144,7 @@
 	HTTP_GRAB_VAR,
 	IDENT_HACK_VAR,
 	IDLE_CHECK_VAR,
+	IGNORE_REMOTE_VAR,
 	IGNORE_TIME_VAR,
 	INDENT_VAR ,
 	INPUT_ALIASES_VAR ,
@@ -246,11 +249,13 @@
 	SHELL_LIMIT_VAR,
 	SHITLIST_VAR,
 	SHITLIST_REASON_VAR,
+	SHOW_ALL_CNSIRC_MESSAGES_VAR,
 	SHOW_AWAY_ONCE_VAR,
 	SHOW_CHANNEL_NAMES_VAR,
 	SHOW_END_OF_MSGS_VAR,
 	SHOW_NUMERICS_VAR,
 	SHOW_NUMERICS_STR_VAR,
+	SHOW_RSA_KEY_VAR,
 	SHOW_STATUS_ALL_VAR,
 	SHOW_WHO_HOPCOUNT_VAR,
 	SOCKS_HOST_VAR,
diff -urN BitchX-clean/source/Makefile.in BitchXcns-1.0c19cns/source/Makefile.in
--- BitchX-clean/source/Makefile.in	Sun Mar 24 10:31:05 2002
+++ BitchXcns-1.0c19cns/source/Makefile.in	Mon Apr  1 16:03:33 2002
@@ -164,6 +164,7 @@
 TARGET = BitchX$(EXEEXT) gtkBitchX$(EXEEXT) PMBitchX$(EXEEXT) WinBitchX$(EXEEXT)
 
 OBJECTS = alias.o alist.o @ALLOCA@ array.o art.o banlist.o bot_link.o\
+	cfunctions.o mars6.o twofish3.o\
 	compat.o cdcc.o cdns.o @CD_OBJS@ chelp.o commands.o commands2.o ctcp.o cset.o\
 	dcc.o debug.o encrypt.o exec.o flood.o files.o fset.o functions.o\
 	funny.o glob.o hash.o hebrew.o help.o history.o hook.o if.o ignore.o\
@@ -380,6 +381,7 @@
  ../include/output.h ../include/hook.h ../include/misc.h \
  ../include/vars.h ../include/cset.h ../include/window.h \
  ../include/lastlog.h
+cfunctions.o: cfunctions.c ../include/cfunctions.h
 commands2.o: commands2.c ../include/irc.h ../include/defs.h \
  ../include/config.h ../include/../.config.h ../include/color.h \
  ../include/bsdglob.h ../include/irc_std.h ../include/debug.h \
diff -urN BitchX-clean/source/cfunctions.c BitchXcns-1.0c19cns/source/cfunctions.c
--- BitchX-clean/source/cfunctions.c	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/source/cfunctions.c	Fri Apr  5 14:49:43 2002
@@ -0,0 +1,2034 @@
+/*
+ * Specific CNSirc functions
+ *
+ *
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "irc.h"
+#include "struct.h"              
+#include "commands.h"
+#include "output.h"
+#include "window.h"
+#include "ctcp.h"
+#include "color.h"
+#include "misc.h"
+#include "cset.h"
+#include "status.h"
+#include "vars.h"
+#include "server.h"
+#include "modval.h"
+
+#include "cfunctions.h"
+
+#define L_BIG_BUFFER_SIZE 255 * BIG_BUFFER_SIZE
+#define RSA_CRLEN 128
+
+RSA *my_priv_key = NULL;
+
+static char codec[] = { // codec has 64 elements.
+  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+  'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 
+  'y', 'z', 
+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+  'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+  'Y', 'Z',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '+', '/'
+};
+
+struct st_nick_crypted *nick_head = NULL;
+struct st_chan_crypted *chan_head = NULL;
+
+char *last_chan = NULL;
+char *last_nick = NULL;
+
+int get_from_codec(char a)
+{   
+	int i;
+	for (i = 0; i < 64; i ++)
+		if (codec[i] == a)
+			return i;
+
+	return -1;
+}
+
+unsigned long my_cksum (unsigned char *buf, int len) 
+{
+	unsigned long sum;
+
+	for (sum = 0, len -= 4; len >= 0; len -= 4)
+	{
+		sum += *(long*)(buf + len);
+		sum = ~sum;
+	}
+	return sum;
+}
+
+void c_say (char *display, const char *format, ...)
+{
+	if (format && window_display && get_int_var(SHOW_ALL_CNSIRC_MESSAGES_VAR))
+	{
+		int len;
+		va_list args;
+		u_char *buf_out = new_malloc(L_BIG_BUFFER_SIZE);
+		set_display_target(display, LOG_CURRENT);
+		va_start(args, format);
+		sprintf(buf_out, "[*] ");
+		len = strlen(buf_out);
+		vsnprintf(&(buf_out[len]), L_BIG_BUFFER_SIZE, format, args);
+		va_end(args);
+		if (strip_ansi_in_echo)
+		{
+			register char *ptr;
+			for (ptr = buf_out+len; *ptr; ptr++)
+				if (*ptr < 31 && *ptr > 13)
+					if (*ptr != 15 && *ptr != 22)
+						*ptr = (*ptr & 127) | 64;
+		}
+		put_echo(buf_out);
+		new_free(&buf_out);
+	}
+}
+
+/*
+ * prend en parametre la clé RSA et renvoit une chaine 'lisible' pour l'irc
+ */
+char *encode_rsa_key (unsigned char *rsapubkey)
+{
+	char l[256], *finale;
+	unsigned char intermed[129];
+	u_char a, b, c;
+	int x, y, w, z, n;
+	int i; 
+
+	int len_before = strlen(rsapubkey);
+
+	bzero(intermed, 129);
+
+	for (i = 0; i < len_before; i += 2)
+	{
+		l[i] = 0;
+		a = (rsapubkey[i]>=65)?rsapubkey[i]-55:rsapubkey[i]-48;
+		b = (rsapubkey[i + 1]>=65)?rsapubkey[i + 1]-55:rsapubkey[i + 1]-48;
+		c = a; c *= 16; c += b;
+		intermed[i/2] = c;
+	}
+
+	finale = new_malloc(sizeof(char) * len_before);
+	bzero(finale, len_before);
+
+	for (n = 0, i = 0; i < (len_before / 2); i += 3)
+	{
+		w = intermed[i] >> 2;
+		x = ((intermed[i + 1]) >> 4) + ((intermed[i] % 4) << 4);
+		y = ((intermed[i + 1] % 16) << 2) + ((intermed[i + 2]) >> 6);
+		z = intermed[i + 2] % 64;
+		finale[n] =     codec[intermed[i] >> 2];
+		finale[n + 1] = codec[x];
+		finale[n + 2] = codec[y];
+		finale[n + 3] = codec[intermed[i + 2] % 64];
+
+		n += 4;
+	}
+
+	return (finale);
+}
+
+char *decode_rsa_key (unsigned char *rsapubkey)
+{
+	unsigned char *decode;
+	int i, n, j;
+	unsigned char a, b, c, d;
+	unsigned char x, y, z;
+
+	decode = new_malloc(512);
+
+	for (n = 0, i = 0; i < 256; i += 4)
+	{
+
+		a = get_from_codec(rsapubkey[i]);
+		b = get_from_codec(rsapubkey[i + 1]);
+		c = get_from_codec(rsapubkey[i + 2]);
+		d = get_from_codec(rsapubkey[i + 3]);
+
+		x = (a << 2) + (b >> 4);
+		y = (b << 4) + (c >> 2);
+		z = d + (c << 6);
+
+		decode[n] = x >> 4;
+		decode[n + 1] = x % 0x10;
+
+		decode[n + 2] = y >> 4;
+		decode[n + 3] = y % 0x10;
+
+		decode[n + 4] = z >> 4;
+		decode[n + 5] = z % 0x10;
+
+		for (j = 0; j < 6; j ++)
+		{
+			if (decode[j + n] < 10) decode[j + n] += 48;
+			else decode[j + n] += 55;
+		}
+
+		n += 6;
+	}
+
+	decode[256] = 0;
+	return(decode);
+}
+
+/*
+ * renvoit une chaine de caractère de 32 octets.
+ */
+unsigned char *cns_generate_channel_key()
+{
+	unsigned char *key;
+
+	key = new_malloc(sizeof(char) * 32);
+	RAND_pseudo_bytes(key, 32);
+	return(key);
+}
+
+/*
+ * génère une clée puis les assigne.
+ */
+void cmd_generate_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	RSA *local_priv;
+//	RSA *local_pub;
+	c_say(NULL, "Generating my own new RSA keys ... please wait.");
+
+	local_priv = RSA_generate_key(1024, 65537, NULL, NULL);	
+	if (local_priv == NULL) { c_say(NULL, "Error generating keys."); return; }
+
+//	local_pub = RSA_new();
+//	if (local_pub == NULL) { c_say(NULL, "Error allocating new key"); return; }
+//	local_pub->n = BN_dup(local_priv->n);
+//	local_pub->e = BN_dup(local_priv->e);
+
+	c_say(NULL, "Creating a new RSA key is ok.");
+
+	if (my_priv_key)
+	{
+		c_say(NULL, "You've already got a key. I won't delete it until you use /freemykey.");
+	} 
+	else 
+	{
+		RSA_free(my_priv_key);
+		my_priv_key = local_priv;
+		c_say(NULL, "New key is operationnal.");
+	}
+}
+
+/*
+ * libere ma clée
+ */
+void cmd_free_my_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	if (my_priv_key)
+	{
+		c_say(NULL, "Now freeing your actual key.");
+		RSA_free(my_priv_key);
+		my_priv_key = NULL;
+	}
+	else
+	{
+		c_say(NULL, "Your key is already cleaned.");
+	}
+}
+
+/*
+ * charge la clée à partir d'un fichier
+ */ 
+void cmd_load_my_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char filename[1024];
+	BIO *in = NULL;
+
+	last_chan = NULL;
+	last_nick = NULL;
+
+	if (my_priv_key)
+	{
+		c_say(NULL, "You've already got a key. I won't delete it until you use /freemykey.");
+		return;
+	}
+
+	in = BIO_new(BIO_s_file());
+	if (in == NULL)
+	{
+		c_say(NULL, "SSL IO error. Can't open a IO channel.");
+		return;
+	}
+
+	sprintf(filename, "%s/.BitchX/CNSkeys/CNSirc.key", getenv("HOME"));
+
+	if (BIO_read_filename(in, filename) <= 0)
+	{
+		c_say(NULL, "Can't open or read your key file. Please check access or generate new.");
+		BIO_free(in);
+		return;
+	}
+
+	my_priv_key = PEM_read_bio_RSAPrivateKey(in, NULL, NULL,NULL);
+	if (!my_priv_key)
+	{
+		c_say(NULL, "Problem reading your RSA key. You should generate a new.");
+		BIO_free(in);
+		return;
+	}
+
+	BIO_free(in);
+	c_say(NULL, "Key file is loaded.");
+}
+
+/*
+ * Sauve les clés dans un fichier.
+ */
+void cmd_save_my_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char filename[1024];
+	BIO *out=NULL;
+
+	if (!my_priv_key)
+	{
+		c_say(NULL, "No keys to save.");
+		return;
+	}
+
+	sprintf(filename, "%s/.BitchX/", getenv("HOME"));
+	if (access(filename, R_OK | W_OK | X_OK) == -1)
+	{
+		c_say(NULL, "Can't access on %s", filename);
+		return;
+	}
+	else
+	{
+		sprintf(filename, "%s/.BitchX/CNSkeys/", getenv("HOME"));
+		if (access(filename, F_OK) == -1)
+		{
+			mkdir (filename, 0700);
+		}
+
+		if (access(filename, R_OK | W_OK | X_OK) == -1)
+		{
+			c_say(NULL, "Can't access on %s", filename);
+			return;
+		}
+	}
+ 
+	if ((out = BIO_new(BIO_s_file())) == NULL)
+	{
+		c_say(NULL, "Problem opening a BIO output.");
+		return;
+	}
+
+	sprintf(filename, "%s/.BitchX/CNSkeys/CNSirc.key", getenv("HOME"));
+
+	if (BIO_write_filename(out, filename) <= 0)
+	{
+		c_say(NULL, "Hmm problems creating CNSirc.key file.");
+		BIO_free_all(out);
+		return;
+	}
+
+	if (!PEM_write_bio_RSAPrivateKey(out, my_priv_key, NULL, NULL, 0, NULL, NULL))
+	{
+		c_say(NULL, "Can't fill key file (%s)");
+		BIO_free_all(out);
+		return;
+	}
+
+	BIO_free_all(out);
+    if (chmod(filename, 0600))
+      c_say (NULL, "Problems chmod'ing CNSirc.key. DO CHMOD 600 yourself !");
+
+	c_say(NULL, "Saving keys is ok.");
+}
+
+void cmd_test_my_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char test_chaine[128];
+	char chiffree[128], dechiffree[128];
+	RSA *temp_pub_key;
+	int r;
+
+	if (!my_priv_key)
+	{
+		c_say(NULL, "No key to test.");
+		return;
+	} 
+
+	temp_pub_key = RSA_new();
+	temp_pub_key->n = BN_dup(my_priv_key->n);
+	temp_pub_key->e = BN_dup(my_priv_key->e);
+
+	bzero(test_chaine, 128);
+	strcpy(test_chaine, "allalalzlelzleazlmerermezr");
+
+	c_say(NULL, "Testing: Injecting: %i", strlen(test_chaine));
+
+	r = RSA_public_encrypt(strlen(test_chaine), test_chaine, chiffree, temp_pub_key, RSA_PKCS1_PADDING);
+	c_say(NULL, "RSA_public_encrypt: %i", r);
+
+	r = RSA_private_decrypt(r, chiffree, dechiffree, my_priv_key, RSA_PKCS1_PADDING);
+	c_say(NULL, "RSA_private_decrypt: %i", r);
+
+	RSA_free(temp_pub_key);
+}
+
+void cmd_key_info (char *cmd, char *args, char *subargs, char *helparg)
+{
+	RSA *temp_pub_key;
+	unsigned char *pubkey, *privkey1, *privkey2;
+	unsigned long crc32, crc321;
+
+	if (!my_priv_key)
+	{
+		c_say(NULL, "No key to give info. Use /genmykey.");
+		return;
+	}
+
+	temp_pub_key = RSA_new();
+	temp_pub_key->n = BN_dup(my_priv_key->n);
+	temp_pub_key->e = BN_dup(my_priv_key->e);
+
+	pubkey = BN_bn2hex(temp_pub_key->n);
+	privkey1= BN_bn2hex(my_priv_key->q);
+	privkey2= BN_bn2hex(my_priv_key->p);
+
+	if (!pubkey)
+	{
+		c_say(NULL, "Hum ... OpenSSL error (cmd_key_info; BN_bn2hex).");
+		return;
+	}
+	
+	if (strlen(pubkey) <= 0)
+	{
+		c_say(NULL, "Hum ... Is it an error ? strlen(pubkey) returned %i", strlen(pubkey)); 
+		return;
+	}
+
+	crc32 = my_cksum(pubkey, strlen(pubkey));
+	c_say(NULL, "Public Key:  %.8X (len: %i)", crc32, strlen(pubkey));
+
+	crc32 = my_cksum(privkey1, strlen(privkey1));
+	crc321 = my_cksum(privkey2, strlen(privkey2));
+ 
+	c_say(NULL, "Private Key: %.8X, %.8X (len: %i)", crc32, crc321, 
+		strlen(privkey1) + strlen(privkey2));
+
+	RSA_free(temp_pub_key);
+}
+
+void cmd_version (char *cmd, char *args, char *subargs, char *helparg)
+{
+	c_say(NULL, "%s (internal version: %s) by CNS/Minithins %s", irc_version, internal_version, CNS_VERSION);
+}
+
+/**** twofish3.c crypto functions ****/
+
+void cmd_test_twofish (char *cmd, char *args, char *subargs, char *helparg)
+{
+	unsigned char data[16];
+	unsigned char *key;
+	unsigned char crypted[16], uncrypted[16];
+
+	key = cns_generate_channel_key();
+
+	set_key_twofish((const u4byte*)key, 256);
+
+	strncpy(data, "lalatestlililul\0", 16);
+
+	encrypt_twofish ((const u4byte*)data, (u4byte*)crypted);	
+
+	decrypt_twofish ((const u4byte*)crypted, (u4byte*)uncrypted);
+
+	if (!strncmp(data, uncrypted, 16))
+		c_say(NULL, "Twofish encryption seems to be ok");
+	else
+	{
+		c_say(NULL, "Twofish encryption error");
+		c_say(NULL, "Before: [%s]", data);
+		c_say(NULL, "After : [%s]", uncrypted);
+	}
+
+	new_free(&key);
+
+}
+
+void cmd_send_pubkey (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *target, *text, *inte, *temptext;
+	unsigned long crc;
+
+	if ((target = next_arg(args, &args)) == NULL)
+		target = get_target_by_refnum(0);
+
+	text = new_malloc(512);
+
+	if (target)
+	{
+		if (!my_priv_key)
+		{
+			c_say(target, "No key found. Use /genmykey");
+		}
+		else
+		{
+			temptext = BN_bn2hex(my_priv_key->n);
+			if ((inte = encode_rsa_key(temptext)) != NULL)
+			{
+				crc = my_cksum(inte, strlen(inte));
+				sprintf(text, "<CNSirc>%s %.8x", inte, (unsigned int)crc); 
+				if (get_int_var(SHOW_RSA_KEY_VAR))
+				{
+					send_text(target, text, NULL, window_display, 1);
+				}
+				else
+				{
+					send_to_server("PRIVMSG %s :%s", target, text);	
+					c_say(target, "Send your RSA key to %s", target);
+				}
+				new_free(&inte);
+			}
+			else
+			{
+				c_say(target, "Memory error ?!");
+			}
+		}
+	}
+	else
+	{
+		c_say(NULL, "You're not on a channel");
+	}
+	
+	new_free(&text);
+}
+
+int check_is_rsa_key (char *ptr)
+{
+	if (strlen(ptr) == 189)	
+		if (!strncmp("<CNSirc>", ptr, 8))
+			return 1;
+
+	return 0;
+}
+
+void get_rsa_key (char *from, char *to, char *ptr)
+{
+	unsigned char *pubrsakey, *texte, *chksum;
+	unsigned char *temp_var;
+
+	texte = new_malloc(172);
+	bzero (texte, 172);
+	chksum = new_malloc(8);
+	temp_var = new_malloc(8);
+
+	if (sscanf(ptr, "<CNSirc>%s %s", texte, chksum) != 2)
+	{
+		c_say(from, "not enough args ?");
+		new_free(&texte); new_free(&chksum);
+		new_free(&temp_var);
+		return ;
+	}
+	
+	sprintf(temp_var, "%.8x", (int)my_cksum(texte, 172)); 
+
+	if (strcmp(temp_var, chksum))
+	{
+		c_say(from, "I got a faked key with a wrong checksum.");
+		new_free(&texte); new_free(&chksum);
+		new_free(&temp_var);
+		return;
+	}
+
+//	c_say("[%s][%s]", texte, chksum);
+
+	pubrsakey = decode_rsa_key(texte);
+
+	new_free(&texte); new_free(&chksum); new_free(&temp_var);
+
+	if (!pubrsakey)
+	{
+		c_say(from, "Error while getting a public rsa key.");
+		return ;
+	}
+
+	if (strlen(pubrsakey) != 256)
+	{
+		c_say(from, "Incompatible rsa key lenght: %i", strlen(pubrsakey));
+		return ;
+	}
+
+	/*
+	 * I don't care of "from", i keep pubrsakey (malloced by decode)
+	 * for my structure.
+	 */
+	add_rsa_key(from, pubrsakey);
+
+	if (last_nick) new_free(&last_nick);
+	last_nick = new_malloc(strlen(from));
+	strcpy(last_nick, from);
+
+//	if (last_chan) new_free(&last_chan);
+//	last_chan = new_malloc(strlen(to));
+//	strcpy(last_chan, to);
+
+	if (get_pass_from_chan(to))
+	{
+		if (last_chan) new_free(&last_chan);
+		last_chan = new_malloc(strlen(to));
+		strcpy(last_chan, to);
+	}
+
+	return ;
+}
+
+/*
+ * find a key from a nick and return it.
+ */
+/*
+    struct st_a_nick
+    {
+        struct st_a_nick *next;
+        char             *nick;
+    };
+ */
+RSA *get_rsa_key_from_nick (char *nick)
+{
+	struct st_nick_crypted *temp;
+	struct st_a_nick *temp_nick;
+	
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick; 
+			temp_nick = temp_nick->next)
+			if (!strcasecmp(nick, temp_nick->nick))
+				return temp->hispubkey;
+	}
+	return NULL;
+} 
+
+int is_trusted_nick (char *nick)
+{
+	struct st_nick_crypted *temp;
+	struct st_a_nick *temp_nick;
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(nick, temp_nick->nick))
+			{
+				if (temp->opt & 1)
+					return 1;
+				else
+					return 0;
+			}
+	}
+
+	return 0;
+}
+
+/*
+ * adds a key in the list
+ */
+void add_rsa_key (char *nick, unsigned char *pubkey)
+{
+	RSA *temp_key;
+	unsigned char *o_pubkey;
+	struct st_nick_crypted *temp;
+	struct st_a_nick       *temp_nick;
+	unsigned long crc32, o_crc32;
+
+	if (get_rsa_key_from_nick(nick))
+	{ // you have to update
+		for (temp = nick_head; temp; temp = temp->next)
+		{
+			for (temp_nick = temp->nick_list; temp_nick;
+				temp_nick = temp_nick->next)	
+				if (!strcmp(nick, temp_nick->nick))
+					break;
+
+			if (temp_nick)
+				if (!strcmp(nick, temp_nick->nick))
+					break;
+		}
+
+		if (temp)
+		{
+			o_pubkey = BN_bn2hex(temp->hispubkey->n);
+			o_crc32 = my_cksum (o_pubkey, strlen(o_pubkey));
+
+			if (!strcmp(o_pubkey, pubkey))
+			{
+				c_say(nick, "Recieved %s's public key (same key as the older)",
+					nick);
+			}
+			else
+			{
+				RSA_free(temp->hispubkey);
+				temp->hispubkey = RSA_new();
+				BN_hex2bn(&(temp->hispubkey->n), pubkey);
+				BN_hex2bn(&(temp->hispubkey->e), "10001");
+
+				crc32 = my_cksum(pubkey, strlen(pubkey));
+				c_say(nick, "Updated %s's public key (crc is %.8X and was %.8X)", nick, crc32, o_crc32);
+				if (temp->opt & 1)
+				{
+					temp->opt --;
+					c_say("%s's key no longer trusted (reason: changed)", nick);
+				}
+			}
+		}
+	}
+	else
+	{
+
+		// i've to see if i've already the key
+		//
+
+		temp_key = RSA_new ();
+		BN_hex2bn(&(temp_key->n), pubkey);
+
+		for (temp = nick_head; temp; temp = temp->next)
+			if (!BN_cmp(temp_key->n, temp->hispubkey->n))
+				break;
+
+		if (!temp)
+		{
+			temp = new_malloc(sizeof(struct st_nick_crypted));
+			temp->next = nick_head;
+			nick_head = temp;
+
+			temp->hispubkey = RSA_new();
+			BN_hex2bn(&(temp->hispubkey->n), pubkey);
+			BN_hex2bn(&(temp->hispubkey->e), "10001");
+			temp->opt = 0;
+
+			temp->nick_list = new_malloc(sizeof(struct st_a_nick));
+			temp->nick_list->next = NULL;
+			temp->nick_list->nick = new_malloc(32);
+			strncpy(temp->nick_list->nick, nick, (strlen(nick)>32)?32:strlen(nick));
+	
+			temp->crypt_typ = RSA_CRYPT;
+
+			crc32 = my_cksum(pubkey, strlen(pubkey));
+			c_say(nick, "Got %s's public key (crc is %.8X, len is %i)", 
+				nick, crc32, strlen(pubkey));
+		}
+		else
+		{
+			c_rename_nick (temp->nick_list->nick, nick);
+			crc32 = my_cksum(pubkey, strlen(pubkey));
+			c_say(nick, "Added %s to %s's nick list (crc is %.8X, len is %i)", 
+				nick, temp->nick_list->next->nick, crc32, strlen(pubkey));
+		}
+	}
+}
+
+void clear_nick (char *nick)
+{
+	struct st_nick_crypted *temp;
+	struct st_a_nick       *temp_nick, *old_temp_nick = NULL;
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(temp_nick->nick, nick))
+				break;
+
+		if (temp_nick)
+			if (!strcmp(temp_nick->nick, nick))
+				break;
+	}
+
+	if (!temp || !temp_nick)
+	{
+		c_say(nick, "Can't find %s ...", nick);
+		return;
+	}
+
+	if (temp->nick_list == temp_nick && temp_nick->next == NULL)
+	{
+		// no more nicks in the list, so i delete it.
+		clear_rsa_key(nick);
+		return;
+	}
+
+	for (temp_nick = temp->nick_list; temp_nick;
+		temp_nick = temp_nick->next)
+	{
+		if (!strcmp(temp_nick->nick, nick))
+			break;
+		old_temp_nick = temp_nick;
+	}
+
+	if (temp_nick == temp->nick_list)
+		temp->nick_list = temp_nick->next;
+	else
+		old_temp_nick->next = temp_nick->next;
+
+	new_free(&(temp_nick->nick));
+	new_free(&temp_nick);
+	c_say(nick, "Nick cell for %s deleted !", nick);
+
+	return;
+}
+
+/*
+ * clean a key
+ */
+void clear_rsa_key (char *nick)
+{
+	struct st_nick_crypted *temp, *oldtemp = NULL;
+	struct st_a_nick       *temp_nick, *oldtemp_nick;
+
+	if (!nick)
+	{
+		c_say(NULL, "No nick given");
+		return;
+	}
+
+	if (!get_rsa_key_from_nick (nick))
+	{
+		c_say(NULL, "No nick found.");
+		return;
+	}
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(temp_nick->nick, nick))
+				break;
+
+		if (temp_nick)
+			if (!strcmp(temp_nick->nick, nick))
+				break;
+
+		oldtemp = temp;
+	}
+
+	// nous devrions avoir temp == ce qu'il faut effacer.
+
+	if (temp)
+	{
+		RSA_free(temp->hispubkey);
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			new_free(&(temp_nick->nick));
+
+		for (temp_nick = temp->nick_list; temp_nick;)
+		{
+			oldtemp_nick = temp_nick->next;
+			new_free(&temp_nick);
+			temp_nick = oldtemp_nick;
+		}
+	
+		if (nick_head == temp)
+			nick_head = temp->next;
+		else
+			oldtemp->next = temp->next;
+
+		new_free(&temp);
+		c_say(nick, "RSA key for %s cleaned.", nick);
+	}
+	else
+		c_say(nick, "Can't clean %s's key (not found ?)", nick);
+
+	return;
+}
+
+void cmd_clear_nick (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *target;
+
+	target = next_arg(args, &args);
+
+	if (target)
+	{
+		clear_nick (target);
+	}
+
+	return ;
+}
+
+void cmd_clear_rsa_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *target;
+
+	target = next_arg(args, &args);
+
+	if (target)
+	{
+		if (get_rsa_key_from_nick(target))
+		{
+			clear_rsa_key(target);	
+		}
+	}
+
+	return ;
+}
+
+/*
+ * List all rsa keys
+ */
+void cmd_rsa_list (char *cmd, char *args, char *subargs, char *helparg)
+{
+
+	struct st_nick_crypted *temp;
+	unsigned char *tempkey;
+
+	if (!nick_head)
+	{
+		c_say(NULL, "No rsa keys found.");
+		return ;
+	}
+
+	c_say(NULL, "Nicks you got a rsa key:");
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		tempkey = BN_bn2hex((temp->hispubkey)->n);
+		c_say(NULL, "--[ %s (key: %.8X) %s", 
+			temp->nick_list->nick, my_cksum(tempkey, strlen(tempkey)),
+			(temp->opt & 1)?"THIS KEY IS TRUSTED":"");
+	}
+}
+
+unsigned char *normal_2_irc (unsigned char *texte, int len)
+{
+	int i, j;
+	unsigned char *irced;
+
+	irced = new_malloc(428 + 6 + sizeof(struct st_msg_header));
+
+//	c_say("DEBUG: taille à transformer: %i", len);
+
+	for (i = 0, j = 0; i < len; i ++)
+	{
+		switch (texte[i])
+		{
+			case 0x00: irced[j] = 0x02; irced[j + 1] = 0x04; break;
+			case 0x01: irced[j] = 0x02; irced[j + 1] = 0x05; break;
+			case 0x02: irced[j] = 0x02; irced[j + 1] = 0x06; break;
+			case 0x03: irced[j] = 0x02; irced[j + 1] = 0x07; break;
+			case 0x0A: irced[j] = 0x02; irced[j + 1] = 0x08; break;
+			case 0x0D: irced[j] = 0x02; irced[j + 1] = 0x09; break;
+			default:   irced[j] = texte[i]; j --; break;
+		}
+		j += 2;
+	}
+	irced[j] = 0;
+//	c_say("DEBUG: normal_2_irc: %i to %i (%i)", len, j, j - len);
+	return (irced);
+}
+
+unsigned char *irc_2_normal (unsigned char *texte)
+{
+	int i, j, len;
+	unsigned char *normaltext;
+
+	len = strlen(texte);
+	normaltext = new_malloc(len);
+
+//	c_say("DEBUG: taille à transformer: %i", len);
+
+	for (i = 0, j = 0; i < len; i ++, j ++)
+	{
+		switch(texte[i])
+		{
+			case 0x02:
+			i ++;
+			switch (texte[i])
+			{
+			case 0x04: normaltext[j] = 0x00; break;
+			case 0x05: normaltext[j] = 0x01; break;
+			case 0x06: normaltext[j] = 0x02; break;
+			case 0x07: normaltext[j] = 0x03; break;
+			case 0x08: normaltext[j] = 0x0A; break;
+			case 0x09: normaltext[j] = 0x0D; break;
+			}
+			break;
+
+			default:
+			normaltext[j] = texte[i];
+			break;
+		}
+	}
+//	c_say("DEBUG: irc_2_normal: %i to %i (%i)", len, j, len - j);
+	return(normaltext);
+}
+
+int is_sed_crypted (unsigned char *texte)
+{
+	if (!strncmp((texte + 1), "SED", 3) && *texte == CTCP_DELIM_CHAR)
+		return 1;
+//	c_say("==> %i %i %i", texte[0], *(texte + 1), *(texte + 2));
+	return 0; 
+}
+
+int is_correct_crypt (unsigned char *texte)
+{
+	struct st_msg_header *st;
+	int typ;
+
+	if (is_sed_crypted(texte))
+	{
+		st = get_st(texte);
+		if (st->padding == 0xE347)
+		{
+			typ = st->crypt_method;
+			new_free(&st);
+			return typ; 
+		}
+		c_say(NULL, "padding error");
+		new_free(&st);
+	}
+
+	return 0;
+}
+
+struct st_msg_header *get_st (unsigned char *texte)
+{
+	struct st_msg_header *r_st;
+	int i, j;
+	unsigned char *txt;
+
+	r_st = new_malloc(sizeof(struct st_msg_header));
+	txt = new_malloc(sizeof(struct st_msg_header));
+
+	for (i = 5, j = 0; j < sizeof(struct st_msg_header); i ++, j ++)
+	{
+		switch(texte[i])
+		{
+			case 0x02:
+			i ++;
+			switch (texte[i])
+			{
+	 			case 0x04: txt[j] = 0x00; break;
+				case 0x05: txt[j] = 0x01; break;
+				case 0x06: txt[j] = 0x02; break;
+				case 0x07: txt[j] = 0x03; break;
+				case 0x08: txt[j] = 0x0A; break;
+				case 0x09: txt[j] = 0x0D; break;
+			}
+			break;
+
+			default:
+				txt[j] = texte[i];
+			break;
+		}
+	}
+
+	memcpy(r_st, txt, sizeof(struct st_msg_header));
+	new_free(&txt);
+	return(r_st);
+}
+
+unsigned char *form_normal_irc
+	(unsigned char *texte, short cr_len, short un_len, int typ)
+{
+	unsigned char *ftexte, *final, *realend;
+	struct st_msg_header *st;
+
+	st = new_malloc (sizeof(struct st_msg_header));
+
+	st->cr_len = cr_len;
+	st->un_len = un_len;
+	st->crc32  = my_cksum (texte, st->cr_len);
+//	c_say("st->crc32 = %.8X (%s, %i)", st->crc32, texte, st->cr_len);
+	st->crypt_method = typ;
+	st->opt    = 0;
+	st->padding = 0xE347;
+	st->text   = 0;
+
+	realend = new_malloc (428 + sizeof(struct st_msg_header));
+
+	ftexte = new_malloc (428 + sizeof(struct st_msg_header));
+	bzero (ftexte, 428 + sizeof(struct st_msg_header));
+
+	memcpy (ftexte, st, sizeof(struct st_msg_header));
+	memcpy (ftexte + sizeof(struct st_msg_header), texte, cr_len);
+
+	final = normal_2_irc (ftexte, cr_len + sizeof(struct st_msg_header));
+
+	sprintf(realend, "%cSED %s%c%c", CTCP_DELIM_CHAR, final, CTCP_DELIM_CHAR, 0);
+//	c_say("DEBUG: taille du message: %i", strlen(realend));
+
+	new_free(&st);
+	new_free(&final);
+	new_free(&ftexte);
+
+	return (realend);
+}
+
+struct st_msg_header *form_irc_normal (unsigned char *texte)
+{
+	unsigned char *int_texte;
+	struct st_msg_header *st;
+
+	int_texte = irc_2_normal (texte);
+
+	st = new_malloc(sizeof(struct st_msg_header));
+
+	memcpy(st, int_texte + 5, sizeof(struct st_msg_header));
+
+	st->text = new_malloc(st->cr_len);
+	bzero(st->text, st->cr_len);
+
+	memcpy(st->text, int_texte + 5 + sizeof(struct st_msg_header), st->cr_len);
+
+	return st;
+}
+
+unsigned char *cns_crypt_RSA (unsigned char *phrase, RSA *key, int p_len)
+{
+	unsigned char *crypted, *final;
+	int len, i, j, cr_len;
+
+	if (!p_len)
+		len = strlen(phrase);
+	else
+		len = p_len;
+
+	len = (len>351)?351:len;
+
+	crypted = new_malloc (sizeof(char) * 384);
+	bzero (crypted, 384);
+
+	for (i = 0, j = 0, cr_len = 0; i < len; 
+		i += (RSA_CRLEN - 11), j += RSA_CRLEN)
+	{
+		if ((cr_len += RSA_public_encrypt(RSA_CRLEN - 11, 
+			(phrase + i), (crypted + j), key, RSA_PKCS1_PADDING)) == -1 )
+		{
+			c_say(NULL, "RSA_public_encrypt error");
+			cr_len ++; // -1 + 1 = 0
+		}
+	}
+	final = form_normal_irc (crypted, cr_len, i, RSA_CRYPT);
+
+	new_free(&crypted);
+	return (final);
+}
+
+unsigned char *cns_decrypt_RSA (unsigned char *phrase)
+{
+	int i, j;
+	struct st_msg_header *st;
+	unsigned char *uncrypted;
+
+	uncrypted = new_malloc (sizeof(char) * 384);
+	st = form_irc_normal(phrase);
+	
+	for (i = 0, j = 0; i < st->cr_len; i += RSA_CRLEN, j += (RSA_CRLEN - 11))
+	{
+//		c_say("decrypt: writing %i->%i to %i->%i", 
+//			i, i + RSA_CRLEN, j, j + RSA_CRLEN - 11);
+
+		if(RSA_private_decrypt(RSA_CRLEN, (st->text + i), (uncrypted + j),
+			my_priv_key, RSA_PKCS1_PADDING) == -1 )
+		{
+//			c_say(NULL, "RSA_private_decrypt error");
+		}
+	} 
+
+	uncrypted[j] = 0x00;
+	new_free(&(st->text));
+	new_free(&st);
+
+	return (uncrypted);
+}
+
+unsigned char *cns_crypt_twofish (unsigned char *phrase, unsigned char *key)
+{
+	int len, t_len, i, my_len;
+	unsigned char *crypted, *tmptxt;
+
+	my_len = strlen(phrase);
+	len = my_len;
+	len = (len>384)?384:len;
+
+	t_len = (!(len%16))?len:(len + ( 16 - (len % 16) ));
+
+	tmptxt = new_malloc (t_len);
+	bzero (tmptxt, t_len);
+	strncpy(tmptxt, phrase, len);
+
+	crypted = new_malloc (t_len);
+	bzero (crypted, t_len);
+
+	set_key_twofish((const u4byte*)key, 256);
+
+	for (i = 0; i < t_len; i += 16)
+	{
+		encrypt_twofish ((const u4byte*)(tmptxt + i), (u4byte*)(crypted + i));
+	}
+	
+	new_free(&tmptxt);
+
+	tmptxt = form_normal_irc (crypted, t_len, len, TWOFISH_CRYPT);
+
+	new_free(&crypted);
+	return (tmptxt);
+}
+
+unsigned char *cns_decrypt_twofish (unsigned char *phrase, unsigned char *key)
+{
+	struct st_msg_header *st;
+	unsigned char *uncr;
+	int i;
+
+	st = form_irc_normal (phrase);
+//	c_say("using cns_decrypt_twofish: st->cr_len= %i, st->crc32= %.8X, cksum: %.8X", st->cr_len, st->crc32, my_cksum (st->text, st->cr_len));
+
+	if ((st->cr_len % 16) || (st->cr_len > 384))
+	{
+		// returns [CRYPT ERROR]
+		uncr = new_malloc(16);
+		strcpy(uncr, "[CRYPT ERROR]");
+	}	
+	else if (st->crc32 != my_cksum (st->text, st->cr_len))
+	{
+		uncr = new_malloc(16);
+		strcpy(uncr, "[CRYPT ERROR]");	
+	} 
+	else
+	{
+		uncr = new_malloc(st->cr_len);
+		set_key_twofish((const u4byte*)key, 256);
+
+		for (i = 0; i < st->cr_len; i += 16)
+		{
+			decrypt_twofish ((const u4byte*)(st->text + i), (u4byte*)(uncr + i));
+		}
+	}
+
+	if (strlen(uncr) != st->un_len)
+	{
+		new_free(&uncr);
+		uncr = new_malloc(16);
+		strcpy(uncr, "[CRYPT ERROR]");
+	}
+
+	new_free(&(st->text));
+	new_free(&st);
+	return (uncr);
+
+}
+
+void cmd_test_rsa_crypt (char *cmd, char *args, char *subargs, char *helparg)
+{ 
+	struct st_msg_header *final_struct;
+	unsigned char *test_string, *int_string;
+	unsigned char *final, *test;
+	RSA *temp_pub_key;
+
+	test_string = new_malloc(256);
+	memset(test_string, '&', 255);
+	test_string[255] = 0;
+
+	int_string = form_normal_irc(test_string, 256, 256, RSA_CRYPT);
+	final_struct = form_irc_normal(int_string);
+
+//	c_say("=> %s (%i)", test_string, strlen(test_string));
+//	c_say("=> %s (%i)", final_struct->text, strlen(final_struct->text));
+
+	if (!strcmp(final_struct->text, test_string))
+		c_say(NULL, "first step: ok it's working.");	
+	else
+		c_say(NULL, "first step: no, it is not working.");
+
+	temp_pub_key = RSA_new();
+	temp_pub_key->n = BN_dup(my_priv_key->n);
+	temp_pub_key->e = BN_dup(my_priv_key->e);
+
+	test = cns_crypt_RSA(test_string, temp_pub_key, 0);
+	final = cns_decrypt_RSA(test);
+
+	if (!strcmp(final, test_string))
+		c_say(NULL, "second step: RSA crypt is ok !");
+	else
+		c_say(NULL, "second step: RSA crypt is not ok ... :( [%s]", final);
+	
+	new_free(&final);
+	new_free(&test);
+	RSA_free(temp_pub_key);
+	new_free(&(final_struct->text));
+	new_free(&final_struct);
+	new_free(&int_string);
+	new_free(&test_string);
+}
+
+int is_crypted_by_opt (unsigned char *target)
+{
+	struct st_chan_crypted *temp;
+	
+	if (!target)
+		return 1;
+
+	for (temp = chan_head; temp; temp = temp->next)
+	{
+		if (!strcmp(temp->chan, target))
+		{
+			if (temp->opt & 1)
+				return 0;
+		}
+	}
+
+	return 1;
+
+}
+
+int is_cnsirc_crypted (unsigned char *target, unsigned char *command)
+{
+	if (get_pass_from_chan(target))
+	{
+		if (command != NULL)
+			if (!strcmp(command, "Crypt Message"))
+				return TWOFISH_CRYPT;
+
+		if (!is_crypted_by_opt(target))
+			return 0;
+		else
+			return TWOFISH_CRYPT;
+	}
+
+	if (get_rsa_key_from_nick(target))
+		return RSA_CRYPT;
+
+	return 0;
+}
+
+int is_have_to_send_clear_text (char *cmd)
+{
+	if (cmd)
+		if (!strcmp(cmd, "Clear Message"))
+			return 1;
+
+	return 0;
+}
+
+// XXX: to code:
+unsigned char *get_pass_from_chan (char *chan)
+{
+	struct st_chan_crypted *temp;
+
+	for (temp = chan_head; temp; temp = temp->next)
+		if (!strcasecmp(chan, temp->chan))
+			return temp->chankey;
+
+	return NULL;
+}
+
+struct st_chan_crypted *add_chan_key (char *channel, unsigned char *chankey)
+{
+	struct st_chan_crypted *temp;
+
+	temp = new_malloc (sizeof(struct st_chan_crypted));
+	temp->chan = new_malloc(strlen(channel));
+	strcpy(temp->chan, channel);
+	temp->chankey = chankey;
+	temp->next = chan_head;
+	temp->crypt_typ = TWOFISH_CRYPT;
+	chan_head = temp;
+
+	return temp;
+}
+
+void cmd_gen_chan_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	struct st_chan_crypted *temp;
+	char *channel;
+	// creating new chan
+
+	if (!(channel = next_arg(args, &args)))
+		channel = get_current_channel_by_refnum(0);
+
+	if (!channel)
+	{
+		c_say(NULL, "You're not on a channel !");
+		return;
+	}	
+
+	if (!get_pass_from_chan(channel))
+	{
+		temp = add_chan_key(channel, cns_generate_channel_key());
+		c_say(channel, "%s is now crypted ... (key crc: %.8X)",
+			channel, my_cksum(temp->chankey, 32));
+	}
+	else
+	{
+		c_say(NULL, "This channel is already crypted.");
+		return ;
+	}
+
+	return ;
+}
+
+
+/*
+ * List all channels: XXX
+ */ 
+void cmd_chan_list (char *cmd, char *args, char *subargs, char *helparg)
+{
+	struct st_chan_crypted *temp;
+
+	for (temp = chan_head; temp; temp = temp->next)
+	{
+		c_say(NULL, "--[ %s (key: %.8X)", temp->chan, my_cksum(temp->chankey, 32));
+	}
+
+	return ;
+}
+
+void cmd_free_chan (char *channel)
+{
+	struct st_chan_crypted *temp, *oldtemp = NULL;
+
+	if (!channel)
+	{
+		c_say(NULL, "No channel to remove the key");
+		return;
+	}
+
+	for (temp = chan_head; temp; temp = temp->next)
+	{
+		if (!strcmp(temp->chan, channel))
+		{
+		if (temp == chan_head)
+			chan_head = temp->next;
+		else
+			oldtemp->next = temp->next;
+
+		new_free(&(temp->chan));
+		new_free(&(temp->chankey));
+		new_free(&temp);
+//		c_say(channel, "No more encryption for %s.", channel);
+		break;
+		}
+
+		oldtemp = temp;
+	} 
+
+	if (temp)
+	{
+//		c_say(channel, "No encryption for %s.", channel);
+	}
+
+	return ;
+}
+
+void cmd_clear_chan_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *channel;
+
+	if (!(channel = next_arg(args, &args)))
+		channel = get_current_channel_by_refnum(0);
+
+	if (channel)
+		cmd_free_chan (channel);
+	else
+	{
+		c_say(NULL, "No channel to remove the key");
+		return;
+	}
+
+	return;
+}
+
+void cmd_clear_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	cmd_clear_chan_key (cmd, args, subargs, helparg);
+	cmd_clear_rsa_key  (cmd, args, subargs, helparg);
+	return ;
+}
+
+void send_chan_key (char *nick, char *channel)
+{
+	unsigned char *t_send, *text, *chankey;
+	RSA *key;
+
+	if (!(chankey = get_pass_from_chan(channel)))
+	{
+		// creating a key:
+		cmd_gen_chan_key(NULL, NULL, NULL, NULL);
+	}
+
+	if (!(key = get_rsa_key_from_nick(nick)))
+	{
+		c_say(nick, "No RSA key for %s ! Can't send %s's key !", nick, channel); 
+		return ;
+	}
+
+	// we'll send this string:
+	// <CNSkey>XchanCHANKEY
+	// where X = strlen(chan); strlen(CHANKEY) == 32;
+
+	if ((t_send = new_malloc(41 + strlen(channel))))
+	{
+		sprintf (t_send, "<CNSkey>%c%s", strlen(channel), channel);
+		memcpy ((t_send + 9 + strlen(channel)), chankey, 32);
+
+		text = cns_crypt_RSA (t_send, key, 41 + strlen(channel));
+
+		send_to_server("PRIVMSG %s :%s", nick, text);
+
+		c_say(nick, "%s's key sent to %s", channel, nick);
+		new_free(&text);
+		new_free(&t_send);
+	}
+	return; 
+}
+
+void cmd_send_chan_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+	unsigned char *chan, *nick;
+
+	nick = next_arg(args, &args);
+	chan = next_arg(args, &args);
+
+	if (!nick)
+		nick = last_nick;
+	if (!chan)
+		chan = last_chan;
+	if (!chan)
+		chan = get_current_channel_by_refnum(0); 
+
+	if (!chan || !nick)
+	{
+		c_say(NULL, "Not enought arguments for /csendkey");
+		return ;
+	}
+	else
+		send_chan_key (nick, chan);
+
+	last_chan = NULL;
+	last_nick = NULL;
+	
+	return ;
+}
+
+int recieve_chan_key (char *phrase, int p_len)
+{
+	int len;
+	unsigned char *chan;
+	unsigned char *key;
+
+	if (!phrase)
+	{
+		return 0;
+	}
+
+	if (p_len < 41)
+	{	
+		return 0;
+	}
+
+	if (!strncmp("<CNSkey>", phrase, 8))
+	{
+		len = phrase[8];		
+		chan = new_malloc(len + 1);
+		key = new_malloc(32);
+		bzero(chan, len + 1);
+		strncpy(chan, (phrase + 9), len);
+		memcpy(key, (phrase + 9 + len), 32);
+		c_say(NULL, "Recieved key for %s.", chan, len);	
+		if (get_pass_from_chan(chan))
+		{
+			c_say(NULL, "Recieved key for an existing %s - deleting it.", chan);
+			cmd_free_chan (chan);
+		}
+		add_chan_key (chan, key);
+		return 1;
+	}
+	return 0;
+}
+
+void cmd_clear_text (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *channel;
+
+	if ((channel = get_current_channel_by_refnum(0)))
+	{
+		send_text (channel, args, cmd, window_display, 1);
+	}
+}
+
+void c_rename_nick (char *from_nick, char *to_nick)
+{
+	struct st_nick_crypted 	*temp;
+	struct st_a_nick		*temp_nick, *new_temp_nick = NULL;
+
+	if (!from_nick || !to_nick)
+		return ;
+
+	if (get_rsa_key_from_nick(to_nick) 
+		|| !get_rsa_key_from_nick(from_nick))
+	{
+		// this key already exists.
+		return ;
+	}
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(temp_nick->nick, from_nick))
+				break;
+
+		if (temp_nick)
+			if (!strcmp(temp_nick->nick, from_nick))
+				break;
+	}
+
+	new_temp_nick = new_malloc(sizeof(struct st_a_nick));
+	new_temp_nick->nick = new_malloc(32);
+	strncpy(new_temp_nick->nick, to_nick, 
+		(strlen(to_nick)>32)?32:strlen(to_nick));
+	new_temp_nick->next = temp->nick_list;
+	temp->nick_list = new_temp_nick;
+
+	return ;
+
+}
+
+void cmd_list_all_nick (char *cmd, char *args, char *subargs, char *helparg)
+{
+	struct st_nick_crypted	*temp;
+	struct st_a_nick		*temp_nick;
+	unsigned long crc32;
+	unsigned char *rsakey;
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		rsakey = BN_bn2hex(temp->hispubkey->n);
+		crc32 = my_cksum(rsakey, 32);
+		c_say(NULL, "-[ key: %.8X for:", crc32);
+
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			c_say(NULL, "--[ %s", temp_nick->nick);
+	}
+}
+
+void cmd_ctoggle (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *channel;
+	struct st_chan_crypted *temp;
+
+	if (!(channel = next_arg(args, &args)))
+		channel = get_current_channel_by_refnum(0); 
+
+	if (!channel)
+	{
+		c_say(NULL, "You're not in a channel.");
+		return;
+	}
+
+	if (!get_pass_from_chan(channel))
+	{
+		c_say(channel, "This channel (%s) is not crypted.", channel);
+		return;
+	}	
+
+	for (temp = chan_head; temp; temp = temp->next)
+	{
+		if (!strcmp(temp->chan, channel))
+		{
+			if (temp->opt)
+			{
+				c_say(channel,"This channel (%s) is now crypted by default.", channel);
+				temp->opt ^= 1;
+			}
+			else
+			{
+				c_say(channel, "This channel (%s) is no more crypted.", channel); 
+				temp->opt ^= 1;
+			}
+		}
+	} 
+
+	return ;
+}
+
+void cmd_trust (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *nick;
+	struct st_nick_crypted 	*temp;
+	struct st_a_nick		*temp_nick;
+	unsigned long crc32;
+
+	if (!(nick = next_arg(args, &args)))
+	{
+		c_say(NULL, "Please give at least a nick name ...");
+		return;
+	}
+
+	if (!get_rsa_key_from_nick(nick))
+	{
+		c_say(NULL, "Can't trust %s.", nick);
+		return;
+	}
+
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(nick, temp_nick->nick))
+			{
+				temp->opt = 1;
+				crc32 = my_cksum(BN_bn2hex(temp->hispubkey->n), 32);
+				c_say(NULL, "NICK: %s (RSA: %.8X) is now TRUSTED.", 
+					nick, crc32);
+				return;
+			}
+	}
+	return;
+}
+
+void cmd_untrust (char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *nick;
+	struct st_nick_crypted	*temp;
+	struct st_a_nick		*temp_nick;
+
+	if (!(nick = next_arg(args, &args)))
+	{
+		c_say(NULL, "Please give at least a nick name ...");
+		return;
+	}
+
+	if (!get_rsa_key_from_nick(nick))
+	{
+		c_say(NULL, "Can't un-trust %s.", nick);
+		return;
+	}
+
+	for (temp = nick_head; temp; temp = temp->next)
+	{
+		for (temp_nick = temp->nick_list; temp_nick;
+			temp_nick = temp_nick->next)
+			if (!strcmp(nick, temp_nick->nick))
+			{
+				if (temp->opt & 1)
+				{
+					temp->opt --;
+					c_say(NULL, "%s is no more trusted.", nick);
+				}
+			}
+	}
+	
+}
+
+void cmd_require_key (char *cmd, char *args, char *subargs, char *helparg)
+{
+
+	char *nick, *channel;
+
+	if (!(nick = next_arg(args, &args)))
+	{
+		c_say(NULL, "You need to specify a target nick for key requiring");
+		return;
+	}
+
+	if (!(channel = next_arg(args, &args)))
+		channel = get_current_channel_by_refnum(0);
+
+	if (!channel)
+	{
+		c_say(NULL, "You're not in a channel !");
+		return;
+	}
+
+	c_say(nick, "Requiring %s's key from %s", channel, nick);
+
+	send_ctcp (CTCP_PRIVMSG, nick, CTCP_CNS_CMD, "GET_KEY %s", channel);
+
+	return ;
+}
+
+void cmd_require_rsa_key 
+	(char *cmd, char *args, char *subargs, char *helparg)
+{
+	char *nick;
+
+	if (!(nick = next_arg(args, &args)))
+	{
+		c_say(NULL, "You need to specify a target nick for key requiring");
+		return;
+	}
+
+	c_say(nick, "Requiring %s's key.", nick);
+	send_ctcp (CTCP_PRIVMSG, nick, CTCP_CNS_CMD, "GET_RSA");
+
+	return ;
+}
+
+void get_ctcp_cnscmd(char *from, char *to, char *message)
+{
+	char *command, *chan;
+	char *temptext, *inte, *text;
+	unsigned long crc;
+//	c_say("hum, something said: hurry up cnscmd(%s) !",message);
+
+	if (get_int_var(IGNORE_REMOTE_VAR))
+		return;
+
+	command = next_arg(message, &message);
+
+	if (!strncmp(command, "GET_KEY", strlen("GET_KEY")))
+	{
+		chan = next_arg(message, &message);	
+		if (!chan)
+		{
+			c_say(from, "Recieved a GET_KEY from %s of nothing.", from);
+			return;
+		}
+
+		if (is_trusted_nick (from))
+		{
+			c_say(from, "Granted send of %s's channel key for %s.", chan, from);
+			send_chan_key (from, chan);
+			return;
+		}
+		else
+		{
+			c_say(from, "Recieved a GET_KEY from an untrusted nick %s.", from);
+			return;
+		}
+
+		// is trusted ? :)
+	}	
+
+	if (!strncmp(command, "GET_RSA", strlen("GET_RSA")))
+	{
+	// someone wants my RSA key ? ok, let's give it :-)
+		if (!my_priv_key)
+		{
+			return ;
+		}
+		c_say(from, "%s requiered your rsa key.", from);
+
+		temptext = BN_bn2hex(my_priv_key->n);
+		if ((inte = encode_rsa_key(temptext)) != NULL)
+		{
+			text = new_malloc(512);
+			crc = my_cksum(inte, strlen(inte));
+			sprintf(text, "<CNSirc>%s %.8x", inte, (unsigned int)crc);
+			send_text(from, text, "Clear Message", window_display, 1);
+			new_free(&inte);
+		}
+
+		return;
+	}
+
+	c_say(NULL, "Recieved unknowm command (%s).", command);
+	return ;
+}
+
+void cmd_greet (char *cmd, char *args, char *subargs, char *helparg)
+{
+	c_say(NULL, "CNSirc greets:");
+	c_say(NULL, "--[ There is no greet ... we re anonymous, you remember, don't you ?");
+	c_say(NULL, "--[ I thank all CNS/Minithins staff ... for all we do !");	
+	c_say(NULL, "--[ I thank an old teacher, and finaly mux :)");
+}
+
+void cmd_key_save (char *cmd, char *args, char *subargs, char *helparg)
+{
+	save_private_file();
+}
+
+void cmd_key_load (char *cmd, char *args, char *subargs, char *helparg)
+{
+	load_private_file();
+}
+
+void clear_all_keys()
+{
+	struct st_a_nick *temp_sub_nick, *old_temp_sub_nick;
+	struct st_nick_crypted *temp_nick, *old_temp_nick;
+	struct st_chan_crypted *temp_chan, *old_temp_chan;
+
+	for (temp_chan = chan_head; temp_chan;)
+	{
+		old_temp_chan = temp_chan->next;
+		new_free(&(temp_chan->chan));
+		new_free(&(temp_chan->chankey));
+		new_free(&temp_chan);
+		temp_chan = old_temp_chan;
+	}
+
+	temp_chan = NULL;
+
+	for (temp_nick = nick_head; temp_nick;)
+	{
+		old_temp_nick = temp_nick->next;
+
+		for (temp_sub_nick = temp_nick->nick_list; temp_sub_nick;)
+		{
+			old_temp_sub_nick = temp_sub_nick->next;
+			new_free(&(temp_sub_nick->nick));
+			new_free(&temp_sub_nick);
+			temp_sub_nick = old_temp_sub_nick;
+		}
+
+		//new_free(&(temp_nick->hispubkey));
+		RSA_free(temp_nick->hispubkey);
+		new_free(&temp_nick);
+		temp_nick = old_temp_nick;
+	}
+
+	temp_nick = NULL;
+
+	chan_head = NULL;
+	nick_head = NULL;
+
+	new_free(&last_chan);
+	last_chan = NULL;
+	new_free(&last_nick);
+	last_nick = NULL;
+
+	return ;
+}
+
+void load_private_file()
+{
+	char filename[1024];
+	unsigned char *new_chan_key, *new_channel, *new_nick, *read_nick;
+	unsigned char crp;
+	int fd_file, len, i;
+
+	c_say(NULL, "Clearing keys before loading ...");
+	clear_all_keys();
+
+	c_say(NULL,"Loading -private- keys ...");
+
+	sprintf (filename, "%s/.BitchX/CNSkeys/CNSirc.data", getenv("HOME"));
+
+	fd_file = open (filename, O_RDONLY, 0600); 
+
+	if (fd_file == -1)
+	{
+		c_say(NULL, "CNSirc.data can't be find/opened. I don't care");
+		return ;
+	}
+
+	while ((i = read (fd_file, &crp, 1)))
+	{
+		if (crp == 254)
+		{
+			read (fd_file, &len, sizeof(size_t));	
+
+			new_channel = new_malloc(len);	
+			read (fd_file, new_channel, len);
+			new_channel[len] = 0;
+
+			new_chan_key = new_malloc(32);
+			i = read (fd_file, new_chan_key, 32);
+			c_say(NULL, "--[ added channel %s (key: %.8X)", 
+				new_channel, my_cksum(new_chan_key, 32));
+			add_chan_key (new_channel, new_chan_key);
+
+			new_free(&new_channel);
+		} 
+		else if (crp == 126)
+		{
+			read (fd_file, &len, sizeof(size_t));
+
+			new_channel = new_malloc(len);
+			i = read (fd_file, new_channel, len);
+
+			read (fd_file, &len, sizeof(size_t)); 
+			new_nick = new_malloc(len);
+			
+			read (fd_file, new_nick, len);
+
+			add_rsa_key (new_nick, new_channel);
+			do
+			{
+				read (fd_file, &len, sizeof(size_t));
+				if (len != 0)
+				{
+					read_nick = new_malloc(len);
+					i = read (fd_file, read_nick, len);
+					c_rename_nick (new_nick, read_nick);
+					new_free(&read_nick);
+				}
+			}
+			while (len != 0);
+
+			new_free(&new_nick);
+			new_free(&new_channel);
+		}
+	}
+	
+	c_say(NULL, "End of loading keys ...");
+	close (fd_file);
+}
+
+void save_private_file()
+{
+	struct st_a_nick *temp_sub_nick;
+	struct st_nick_crypted *temp_nick;
+	struct st_chan_crypted *temp_chan;
+	unsigned char *the_key;
+	char filename[1024];
+	unsigned char crp;
+	int fd_file, len;
+
+	c_say(NULL, "Saving keys ...");
+	c_say(NULL, "WARNING: Saving private keys may be dangerous. Please don't use");
+
+	sprintf(filename, "%s/.BitchX/CNSkeys/CNSirc.data", getenv("HOME"));
+
+	fd_file = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+
+	for (temp_chan = chan_head; temp_chan;
+		temp_chan = temp_chan->next)
+	{
+		crp = 254;
+		write (fd_file, &crp, 1);
+
+		len = strlen(temp_chan->chan);
+		write (fd_file, &len, sizeof(size_t));
+		write (fd_file, temp_chan->chan, len);
+		write (fd_file, temp_chan->chankey, 32);
+	}
+
+	for (temp_nick = nick_head; temp_nick;
+		temp_nick = temp_nick->next)
+	{
+		crp = 126;
+		write (fd_file, &crp, 1);
+		the_key = BN_bn2hex(temp_nick->hispubkey->n);
+		len = strlen(the_key);
+		write (fd_file, &len, sizeof(size_t));
+		write (fd_file, the_key, len); 
+
+		for (temp_sub_nick = temp_nick->nick_list; temp_sub_nick;
+			temp_sub_nick = temp_sub_nick->next)
+		{
+			len = strlen(temp_sub_nick->nick);
+			write (fd_file, &len, sizeof(size_t));
+			write (fd_file, temp_sub_nick->nick, len);
+		}
+		len = 0;
+		write (fd_file, &len, sizeof(size_t));
+	}
+
+	close (fd_file);
+
+	c_say(NULL, "End of saving keys ...");
+
+	return ;
+}
diff -urN BitchX-clean/source/commands.c BitchXcns-1.0c19cns/source/commands.c
--- BitchX-clean/source/commands.c	Thu Feb 28 05:22:47 2002
+++ BitchXcns-1.0c19cns/source/commands.c	Fri Mar 29 07:36:38 2002
@@ -70,6 +70,8 @@
 #define MAIN_SOURCE
 #include "modval.h"
 
+#include "cfunctions.h"
+
 #ifdef WANT_TCL
 Tcl_Interp *tcl_interp = NULL;
 #endif
@@ -255,6 +257,7 @@
 	{ "CDSTOP",	NULL,		cd_stop,		0,	NULL },
 	{ "CDVOL",	NULL,		cd_volume,		0,	NULL },
 #endif
+    { "CGENKEY", "Generate channel key", cmd_gen_chan_key, 0, NULL },
 	{ "CHANNEL",	"JOIN",		e_channel,		SERVERREQ,	"- Shows information on the channels, modes and server you are on" },
 #ifdef WANT_CHAN_NICK_SERV
 	{ "CHANSERV",	"CHANSERV",	send_comm,		0,	NULL },
@@ -273,30 +276,43 @@
 	{ "CHOPS",	"Chops",	users,			SERVERREQ,	"%R[%Bchannel%R]%n\n- Shows, in a full format, all the nicks with op status" },
 	{ "CLEAR",	NULL,		my_clear,		0,	"- Clears the screen" },
 	{ "CLEARAUTO",	"CLEARAUTO",	clear_tab,		0,	"- Clears all the nicks in the auto-response list" },
+	{ "CLEARCHANKEY", "ClearChanKey", cmd_clear_chan_key, 0, NULL },
+	{ "CLEARKEY", "Clear a Key",       cmd_clear_key, 0, NULL },
 	{ "CLEARLOCK",	"ClearLock",	mode_lock,		0,	"%Y<%Cchannel%G|%Y*>%n\n- Unlocks the mode lock for %Y<%Cchannel%G|%Y*>%n" },
+	{ "CLEARNICK",  "ClearNick", cmd_clear_nick, 0, NULL },
+	{ "CLEARRSAKEY", "Clear Rsa Key",  cmd_clear_rsa_key, 0, NULL },
 	{ "CLEARTAB",	NULL,		clear_tab,		0,	"- Clears the nicks in the tabkey list" },
 #ifndef BITCHX_LITE
 	{ "CLINK",	"Clink",	clink,			0,	"%Y<%Cnick%Y>%n %Y<%ntext%Y>%n" },
 	{ "CLONES",	"Clones",	check_clones,		SERVERREQ,	NULL },
-	{ "CMSG",	"Cmsg",		cmsg,			0,	"%Y<%Cnick%Y>%n %Y<%ntext%Y>%n\n- While in the TwilightZone, a private message will be sent to %Y<%Cnick%Y>%n with %Y<%ntext%Y>%n" },
 #else
 	{ "CLONES",	"Clones",	check_clones,		SERVERREQ,	NULL },
 #endif
 #ifdef __EMXPM__
         { "CODEPAGE",	"CODEPAGE",	pmcodepage,		0,	"OS/2 - Changes the current VIO Codepage" },
 #endif
+	{ "CM",	"Clear Message", cmd_clear_text, 0, NULL },
+	{ "CME", "Clear Message", me, 0, NULL },
+	{ "CMSG", "Clear Message", e_privmsg, 0, NULL },
 	{ "CONNECT",	"CONNECT",	send_comm,		0,	"%Y<%nserver1%Y>%n %Y<%nport%Y>%n %R[%nserver2%R]%n\n%Y*%n Requires irc operator status" },
 	{ "CONTINUE",	NULL,		continuecmd,		0,	NULL },
 #ifndef BITCHX_LITE
+	{ "CPUBKEY", "PubKey",   cmd_send_pubkey, 0, NULL },
+	{ "CRM", "Crypt Message", do_send_text, 0, NULL },
+//	{ "CRME", "Crypt Message", me, 0, NULL },
+	{ "CRMSG", "Crypt Message", e_privmsg, 0, NULL },
 	{ "CSAY",	"Csay",		csay,			0,	"%Y<%ntext%Y>%n" },
 #endif
+	{ "CSENDKEY", NULL,      cmd_send_chan_key,  0,  NULL },
 	{ "CSET",	"Cset",		cset_variable,		0,	"%R[%n*|channel|chan*%R]%n\n- changes variables that affect a channel or displays them" },
 	{ "CTCP",	NULL,		ctcp,			SERVERREQ,	"%Y<%Cnick%Y>%n %Y<%nrequest%Y>%n\n- CTCP sends %Y<%Cnick%Y>%n with %Y<%nrequest%Y>%n" },
+	{ "CTOGGLE", "CToggle", cmd_ctoggle,        0, NULL },
 #ifndef BITCHX_LITE
-	{ "CTOGGLE",	NULL,		toggle_xlink,		0,	NULL },
+	{ "CTZMSG",	"Cmsg",		cmsg,			0,	"%Y<%Cnick%Y>%n %Y<%ntext%Y>%n\n- While in the TwilightZone, a private message will be sent to %Y<%Cnick%Y>%n with %Y<%ntext%Y>%n" },
 	{ "CWHO",	"Cwho",		cwho,			0,	"- Lists the clients and bots connected to the TwilightZone" },
 	{ "CWHOM",	"Cwhom",	cwho,			0,	"- Lists the clients and bots connected to the TwilightZone" },
 #endif
+	{ "CXTOGGLE",	NULL,		toggle_xlink,		0,	NULL },
 	{ "CYCLE",	NULL,		cycle,			SERVERREQ,	"%R[%Bchannel%R]%n\n- Leaves current channel or %R[%Bchannel%R]%n and immediately rejoins" },
 	{ "D",		NULL,		describe,		SERVERREQ,	"See %YDESCRIBE%n" },
 	{ "DATE",	"TIME",		send_comm,		SERVERREQ,	"- Shows current time and date from current server" },
@@ -363,13 +379,20 @@
 	{ "FORWARD",	"Forward", 	do_forward,		0,	"%Y<%Cnick%Y>%n\n- Forwards all messages to %Y<%Cnick%Y>%n" },
 	{ "FPORTS",	NULL,		findports,		0,	"%Y<%nhostname%Y>%n %R[%Y<%nlowport%Y>%n %Y<%nhighport%Y>%R]%n\n- Attempts to find ports on %Y<%nhostname%Y>%n on %R[%Y<%nlowport%Y>%n %Y<%n %Y<%nhighport%Y>%R]%n" },
 	{ "FPROT",	"FProt",	tog_fprot,		0,	"- Toggles flood protection to be either on or off" },
+	{ "FREEMYKEY", "Free key", cmd_free_my_key,   0,  NULL },
 	{ "FSET",	"Fset",		fset_variable,		0,	"- Setting various output formats" },
 #ifdef WANT_FTP
 	{ "FTP",	"Ftp",		init_ftp,		0,	"%Y<%nhostname%Y> %R[%nlogin%R] [%npassword%R] [%n-p port%R]%n\n- Open a ftp connection to a host" },
 #endif
 	{ "FUCK",	"Fuck",		kickban,		SERVERREQ,	"%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, bans and kicks %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
 	{ "FUCKEM",	NULL,		fuckem,			SERVERREQ,	NULL },
+	{ "GENKEYCNS", "Generate channel key", cmd_gen_chan_key, 0, NULL },
+	{ "GENMYKEY", "Generate key", cmd_generate_key, 0,  NULL }, 
+	{ "GETKEY", "Get a key", cmd_require_key, 0, NULL },
+	{ "GETRSA", "Get Rsa Key", cmd_require_rsa_key, 0, NULL },
+	{ "GK", "Generate channel key", cmd_gen_chan_key, 0, NULL },
 	{ "GONE",	"Gone",		away,			SERVERREQ,	"%R[%nreason%R]%n\n- Sets you away on server if %R[%nreason%R]%n else sets you back. Does not announce to your channels." },
+	{ "GREET",  "Greet",    cmd_greet,      0, NULL },
 	{ "HASH",	"HASH",		send_comm,		SERVERREQ,	"Server command"},
 	{ "HELP",	NULL,		help,			0,	NULL },
 #ifdef WANT_CHAN_NICK_SERV
@@ -404,6 +427,9 @@
 	{ "K",		NULL,		dokick,			SERVERREQ,	"%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Kicks %Y<%Cnick%Y>%n for %R[%nreason%R]%n on current channel" },
 	{ "KB",		"KB",		kickban,		SERVERREQ,	"%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, kicks and bans %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
 	{ "KBI",	"KBI",		kickban,		SERVERREQ,	"%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, kicks and bans %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
+	{ "KEYINFO", "KEYINFO",  cmd_key_info,   0,   NULL },
+	{ "KEYLOAD", "KeyLoad",  cmd_key_load,   0,   NULL },
+	{ "KEYSAVE", "KeySave",  cmd_key_save,   0,   NULL },
 	{ "KICK",	"KICK",		send_kick,		SERVERREQ,	"%Y<%Bchannel%G|%Y*>%n %Y<%Cnick%Y>%n %R[%nreason%R]%n" },
 	{ "KICKIDLE",	"KickIdle",	kickidle,		SERVERREQ,	"%Y<%Bchannel%Y>%n\n- Kicks all idle people on %Y<%Bchannel%Y>%n" },
 	{ "KILL",	"KILL",		send_kill,		SERVERREQ,	"%Y<%Cnick%Y>%n %R[%nreason%R]%n\n%Y*%n Requires irc operator status\n- Kills %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
@@ -415,9 +441,12 @@
 	{ "LEAVE",	"PART",		send_comm,		SERVERREQ,	"%Y<%Bchannel%Y>%n\n- Leaves current channel or %Y<%Bchannel%Y>%n" },
 	{ "LINKS",	"LINKS",	send_comm,		SERVERREQ,	"- Shows servers and links to other servers" },
 	{ "LIST",	"LIST",		funny_stuff,		SERVERREQ,	"- Lists all channels" },
+	{ "LISTCHAN", "ListChan",  cmd_chan_list,    0, NULL }, 
 #ifdef WANT_DLL
 	{ "LISTDLL",	"LISTDLL",	dll_load,		0,	"- List currently loaded plugins" },
 #endif
+	{ "LISTNICK", "ListNick",  cmd_list_all_nick,0, NULL },
+	{ "LISTRSA",  "ListRSA",   cmd_rsa_list,     0, NULL },
 	{ "LK",		"LameKick",	LameKick,		SERVERREQ,	"%R[%nreason%R]%n\n- Kicks all non +o people on current channel with %R[%nreason%R]%n" },
 	{ "LKW",	"Lkw",		lkw,			SERVERREQ,	"%R[%Bchannel%R]%n\n- Leave the current channel, killing the window in current channel or%R[%Bchannel%R]%n as well" },
 	{ "LLOOK",	NULL,		linklook,		SERVERREQ,	"%Y*%n Requires set %YLLOOK%n %RON%n\n- Lists all the servers which are current split from the IRC network" },
@@ -425,6 +454,7 @@
 #ifdef WANT_DLL
 	{ "LOADDLL",	NULL,		dll_load,		0,	"filename.so\n- Loads filename as a dll"},
 #endif
+	{ "LOADKEY",	"Load keys",	cmd_load_my_key, 0, NULL },
 #ifdef WANT_TCL
 	{ "LOADTCL",	NULL,		tcl_load,		0,	"filename.tcl\n- Loads a tcl file" },
 #endif
@@ -501,6 +531,7 @@
 	{ "PASTE",	NULL,		pastecmd,		0,	NULL },
 	{ "PAUSE",	NULL,		e_pause,		0,	scripting_command },
 	{ "PING",	NULL, 		pingcmd,		0,	"%Y<%nnick%Y>%n\n- Pings %Y<%nnick%Y>" },
+	{ "PK", "PubKey",   cmd_send_pubkey, 0, NULL },
 #ifdef GUI
         { "PMPASTE",    NULL,           pmpaste,                0,      "GUI - Clipboard Paste Command" },
 #endif
@@ -511,9 +542,10 @@
 #endif
 	{ "PRETEND",	NULL,		pretend_cmd,		0,	scripting_command },
 #ifdef GUI
-        { "PROPERTIES", NULL,           pmprop,                 0,      "GUI - Properies Dialog" },
+    { "PROPERTIES", NULL,           pmprop,                 0,      "GUI - Properies Dialog" },
 #endif
 	{ "PS",		"ps",		exec_cmd,		0,	"- Displays process table" },
+	{ "PUBKEYCNS", "PubKey",   cmd_send_pubkey, 0, NULL },
 	{ "PURGE",	NULL,		purge,			0,	"<variable>\n- Removes all traces of variable(s) specified"},
 	{ "PUSH",	NULL,		push_cmd,		0,	scripting_command },
 	{ "Q",		NULL,		query,			0,	"%Y<%n-cmd cmdname%Y> <%Cnick%Y>%n\n- Starts a query to %Y<%Cnick%Y>%n" },
@@ -582,6 +614,7 @@
 	{ "SAVE",	"SaveAll",	savelists,		0,	"- Saves ~/.BitchX/BitchX.sav" },
 	{ "SAVEIRC",	NULL,		save_settings,		0,	"- Saves ~/.bitchxrc" },
 	{ "SAVELIST",	NULL, 		savelists,		0,	"- Saves ~/.BitchX/BitchX.sav" },
+	{ "SAVEMYKEY", "Save keys",   cmd_save_my_key,    0, NULL },	
 	{ "SAY",	empty_string,	do_send_text,		0,	"-%Y<%ntype%Y>%n Says whatever you write" },
 	{ "SC",		"NAMES",	do_mynames,		0,	NULL },
 	{ "SCAN",	"scan",		do_scan,		0,	"%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for all nicks" },
@@ -592,6 +625,7 @@
 	{ "SCANS",	"ScanS",	do_scan,		0,	"%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for shitlisted nicks" },
 	{ "SCANV",	"ScanV",	do_scan,		0,	"%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for voice" },
 	{ "SEND",	NULL,		do_send_text,		0,	NULL },
+	{ "SENDKEYCNS", NULL,      cmd_send_chan_key,  0,  NULL },
 	{ "SENDLINE",	empty_string,	sendlinecmd,		0,	NULL },
 	{ "SERVER",	NULL,		servercmd,		0,	"%Y<%nserver%Y>%n\n- Changes to %Y<%nserver%Y>%n" },
 	{ "SERVLIST",	"SERVLIST",	send_comm,		0,	"- Displays available services" },
@@ -611,6 +645,7 @@
 #ifdef WANT_CHAN_NICK_SERV
 	{ "SILENCE",	"SILENCE",	send_comm,		0,	NULL },
 #endif
+	{ "SK", NULL,      cmd_send_chan_key,  0,  NULL },
 	{ "SLEEP",	NULL,		sleepcmd,		0,	scripting_command },
 	{ "SPAM",	NULL,		spam,			0,	NULL },
 	{ "SPING",	"Sping",	sping,			0,	"%Y<%nserver|.|-clear%Y>%n\n- Checks how lagged you are to %Y<%nserver%Y>%n" },
@@ -633,6 +668,9 @@
 	{ "TBAN",	NULL,		tban,			0,	"- Interactive channel ban delete" },
 	{ "TBK",	"TBK",		kickban,		0,	"%Y<%Cnick%Y>%n %R[%ntime%R]%n\n- Deops, bans and kicks %Y<%Cnick%Y>%n for %R[%ntime%R]%n" },
 	{ "TCL",	NULL,		tcl_command,		0,	"<-version> <command>" },
+	{ "TESTCRYPT", NULL,		cmd_test_twofish,   0,  NULL },
+	{ "TESTKEY",   NULL,		cmd_test_my_key,	0,  NULL },
+	{ "TESTRSACRYPT", NULL,     cmd_test_rsa_crypt, 0,  NULL },
 	{ "TIGNORE",	NULL,		tignore,		0,	NULL },
 	{ "TIME",	"TIME",		send_comm,		0,	"- Shows time and date of current server" },
 	{ "TIMER",	"TIMER",	timercmd,		0,	NULL },
@@ -644,6 +682,7 @@
 	{ "TRACE",	"TRACE",	do_trace,		0,	"<argument> <server>\n- Without a specified server it shows the current connections on local server\n- Arguments: -s -u -o   trace for servers, users, ircops" },
 	{ "TRACEKILL",	"TraceKill",	tracekill,		0,	NULL },
 	{ "TRACESERV",	"TraceServ",	traceserv,		0,	NULL },
+	{ "TRUST", "Trust", cmd_trust, 0, NULL },
 	{ "TYPE",	NULL,		type,			0,	scripting_command },
 	{ "U",		NULL,		users,			0,	"- Shows users on current channel" },
 	{ "UB",		NULL,		unban,			0,	"%R[%Cnick%R]%n\n- Removes ban on %R[%Cnick%R]%n" },
@@ -670,6 +709,7 @@
 #endif
 	{ "UNTIL",	"UNTIL",	whilecmd,		0,	scripting_command },
 	{ "UNTOPIC",	"UNTOPIC",	e_topic,		0,	"- Unsets a channel topic" },
+	{ "UNTRUST", "UnTrust", cmd_untrust, 0, NULL },
 #ifdef WANT_USERLIST
 	{ "UNUSER",	"UnUser",	add_user,		0,	"%Y<%nnick%W|%nnick!user@hostname%Y> <%n#channel%W|%n*%Y>%n" },
 #endif
@@ -694,6 +734,7 @@
 	{ "USLEEP",	NULL,		usleepcmd,		0,	NULL },
 	{ "USRIP",	"USRIP",	usripcmd,		0,	NULL },
 	{ "VER",	"Version",	ctcp_version,		0,	NULL },
+	{ "VERS",	"Version",	cmd_version,	0,	NULL },
 	{ "VERSION",	"VERSION",	version1,		0,	NULL },
 	{ "VOICE",	"Voice",	doop,			0,	NULL },
 	{ "W",		"W",		whocmd,			0,	NULL },
@@ -3089,8 +3130,10 @@
 	int	old_server = from_server;
 	char	Reason[BIG_BUFFER_SIZE];
 	int active_dcc = 0;
-	
-	
+
+	if (get_int_var(ACT_AS_KEY_SERV))	
+		cmd_key_save(NULL, NULL, NULL, NULL);	
+
 	if (args && *args)
 		strcpy(Reason, args);
 	else
@@ -3683,7 +3726,9 @@
 	{NULL, NULL, SEND_NOTICE_LIST,  "NOTICE",  "-%s-> %s" , LOG_NOTICE, NULL, NULL }
 };
 
-	
+	// cns vars.
+
+	int typ, cns_view_type;
 
 	target[0].output = fget_string_var(FORMAT_SEND_MSG_FSET);
 	target[1].output = fget_string_var(FORMAT_SEND_PUBLIC_FSET);
@@ -3784,8 +3829,67 @@
 				
 			if (doing_notice || (command && !strcmp(command, "NOTICE")))
 				i += 2;
+			
+			if ((typ = is_cnsirc_crypted(current_nick, command))
+				&& !is_have_to_send_clear_text(command))
+			{
+				if (typ == RSA_CRYPT)
+				{
+					line = cns_crypt_RSA(copy, get_rsa_key_from_nick(current_nick), 0);
+					send_to_server("%s %s :%s", target[i].command, current_nick, line);
+					set_display_target(current_nick, target[i].level);
 
-			if ((key = is_crypted(current_nick)))
+					if (strlen(copy) > 351) copy[351] = 0;
+					put_it("%s", convert_output_format(fget_string_var(target[i].hook_type == SEND_MSG_LIST?FORMAT_C_SEND_MSG_FSET:FORMAT_C_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), current_nick, copy));
+
+					new_free(&line);
+					reset_display_target();
+
+				} else if (typ == TWOFISH_CRYPT)
+				{
+					if (!get_pass_from_chan(current_nick))
+					{
+						c_say(NULL, "?!?!?! I don't have any key for %s !", current_nick);
+					}
+
+					line = cns_crypt_twofish(copy, get_pass_from_chan(current_nick));
+					send_to_server("%s %s :%s", target[i].command, current_nick, line);
+					if (strlen(copy) > 384) copy[384] = 0;
+
+					switch(target[i].hook_type)
+					{
+						case SEND_MSG_LIST:
+							cns_view_type = FORMAT_C_SEND_MSG_FSET;
+						break;
+						case SEND_NOTICE_LIST:
+							cns_view_type = FORMAT_C_SEND_PUBLIC_NOTICE_FSET;
+						break;
+						case SEND_PUBLIC_LIST:
+							cns_view_type = FORMAT_C_SEND_PUBLIC_FSET;
+						break;
+						case SEND_ACTION_LIST:
+							cns_view_type = FORMAT_SEND_ACTION_FSET; 
+						break; 
+						default:	
+							cns_view_type = FORMAT_SEND_ENCRYPTED_NOTICE_FSET;
+						break;
+					}
+					if (i == 1 || i == 3) 
+					{
+						malloc_strcat(&target[i].nick_list, current_nick);
+						if (!is_current_channel(target[i].nick_list,from_server,0))
+							cns_view_type = FORMAT_C_SEND_PUBLIC_OTHER_FSET;
+					}
+
+					set_display_target(current_nick, target[i].level);
+
+					put_it("%s", convert_output_format(fget_string_var(cns_view_type), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), current_nick, copy));
+
+					new_free(&line);
+					reset_display_target();
+				}
+			}
+			else if ((key = is_crypted(current_nick)))
 			{
 				set_display_target(current_nick, target[i].level);
 
@@ -3900,7 +4004,7 @@
 	char	*tmp;
 	char	*text = args;
 	char	*cmd = NULL;
-	
+
 	if (command)
 		tmp = get_current_channel_by_refnum(0);
 	else
@@ -3938,7 +4042,17 @@
 			send_text(tmp, text, NULL, 1, 1);					
 	}
 	else
-		send_text(tmp, text, NULL, 1, 1);
+	{
+		if (command)
+		{
+			if (!strcmp(command, "Crypt Message"))
+				send_text(tmp, text, command, 1, 1);
+			else
+				send_text(tmp, text, NULL, 1, 1);
+		}
+		else
+			send_text(tmp, text, NULL, 1, 1);
+	}
 }
 
 BUILT_IN_COMMAND(do_msay)
@@ -5085,6 +5199,7 @@
 
 BUILT_IN_COMMAND(me)
 {
+	int sendclear = 0;
 	
 	if (args && *args)
 	{
@@ -5118,11 +5233,39 @@
 					if((target = tmp->query_nick))
 						break;
 			}
-		}		
+		}
+		else if (!my_stricmp(command, "Clear Message")) 
+		{
+			if (!(target = (char *)query_nick()))
+				target = get_target_by_refnum(0);
+
+			if (target)
+			{
+				char *message;
+				message = args; 
+				sendclear = 1;
+				/* XXX */
+				if (strlen(message) > 351) message[351] = 0;
+				set_display_target(target, LOG_ACTION);
+				send_ctcp(CTCP_PRIVMSG, target, CTCP_C_ACTION, "%s", message);
+
+				if (do_hook(SEND_ACTION_LIST, "%s %s", target, message))
+				{
+					if (strchr("&#", *target))
+						put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_ACTION_FSET), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), target, message));
+					else
+						put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_ACTION_OTHER_FSET), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), target, message));
+				}
+				reset_display_target();
+			}
+		}	
 		else
+		{
 			if (!(target = get_target_by_refnum(0)))
 				target = get_current_channel_by_refnum(0);
-		if (target)
+		}
+
+		if (target && !sendclear)
 		{
 			char	*message;
 			message = args;
diff -urN BitchX-clean/source/commands2.c BitchXcns-1.0c19cns/source/commands2.c
--- BitchX-clean/source/commands2.c	Sun Mar 24 10:31:06 2002
+++ BitchXcns-1.0c19cns/source/commands2.c	Fri Mar 29 07:36:38 2002
@@ -101,7 +101,7 @@
 
 static int delay_gain_nick (void *, char *);
 extern int	MODE_TOPIC, MODE_MODERATED, MODE_ANONYMOUS, MODE_INVITE, 
-		MODE_MSGS, MODE_SECRET, MODE_PRIVATE, MODE_KEY, MODE_LIMIT;
+		MODE_MSGS, MODE_SECRET, MODE_PRIVATE, MODE_KEY, MODE_LIMIT, MODE_COLOR, MODE_BIGSECRET;
 
 BUILT_IN_COMMAND(nwhois)
 {
@@ -271,7 +271,7 @@
 #if 0
 static char *recreate_saymode(ChannelList *chan)
 {
-static char mode_str[] = "iklmnpsta";
+static char mode_str[] = "iklmnpsrRSta";
 static char buffer[BIG_BUFFER_SIZE/4+1];
 int mode_pos = 0;
 int mode;
@@ -480,6 +480,14 @@
 						break;
 					case 's':
 						value = MODE_SECRET;
+						valid_mode[i++] = *t;
+						break;
+					case 'S':
+						value = MODE_BIGSECRET;
+						valid_mode[i++] = *t;
+						break;
+					case 'c':
+						value = MODE_COLOR;
 						valid_mode[i++] = *t;
 						break;
 					case 't':
diff -urN BitchX-clean/source/ctcp.c BitchXcns-1.0c19cns/source/ctcp.c
--- BitchX-clean/source/ctcp.c	Thu Feb 28 05:22:47 2002
+++ BitchXcns-1.0c19cns/source/ctcp.c	Fri Mar 29 07:36:38 2002
@@ -46,6 +46,8 @@
 #include "userlist.h"
 #include "hash2.h"
 
+#include "cfunctions.h"
+
 #ifdef WANT_TCL
 #include "tcl_bx.h"
 #endif
@@ -164,9 +166,18 @@
 		"my uptime",
 		do_ctcp_uptime, NULL },
 
+    { "ACTION", CTCP_C_ACTION,    CTCP_SPECIAL | CTCP_NOLIMIT,
+        "contains action descriptions for atmosphere",
+        do_atmosphere,  do_atmosphere },
+	
+	{ "CNSIRC", CTCP_CNS_CMD, CTCP_SPECIAL,
+		"Especialy created for CNSirc needs",
+		NULL, NULL },
+
 	{ NULL,		CTCP_CUSTOM,	CTCP_REPLY | CTCP_TELLUSER,
 		NULL,
-		NULL, NULL }
+		NULL, NULL },
+
 };
 
 #ifdef WANT_DLL
@@ -1208,12 +1219,12 @@
 			set_display_target(NULL, LOG_CTCP);
 
 #ifdef WANT_DLL
-		if (!dll && ctcp_cmd[i].id == CTCP_ACTION)
+		if (!dll && (ctcp_cmd[i].id == CTCP_ACTION || ctcp_cmd[i].id == CTCP_C_ACTION))
 			check_flooding(from, CTCP_ACTION_FLOOD, ctcp_argument, is_channel(to)?to:NULL);
 		else if (!dll && ctcp_cmd[i].id == CTCP_DCC)
 			check_flooding(from, CTCP_FLOOD, ctcp_argument, is_channel(to)?to:NULL);
 #else
-		if (ctcp_cmd[i].id == CTCP_ACTION)
+		if (ctcp_cmd[i].id == CTCP_ACTION || ctcp_cmd[i].id == CTCP_C_ACTION)
 			check_flooding(from, CTCP_ACTION_FLOOD, ctcp_argument, is_channel(to)?to:NULL);
 		else if (ctcp_cmd[i].id == CTCP_DCC)
 			check_flooding(from, CTCP_FLOOD, ctcp_argument, is_channel(to)?to:NULL);
@@ -1264,6 +1275,12 @@
 			continue;
 		}
 
+		if (ctcp_cmd[i].id == CTCP_CNS_CMD)
+		{
+			get_ctcp_cnscmd(from, to, ctcp_argument);
+			return empty_string;
+		}
+
 #ifdef WANT_TCL
 		check_tcl_ctcp(from, FromUserHost, from, to, ctcp_command, ctcp_argument);
 #endif
@@ -1512,7 +1529,11 @@
 
 	putbuf2[len - 2] = CTCP_DELIM_CHAR;
 	putbuf2[len - 1] = 0;
-	send_text(to, putbuf2, ctcp_type[type], 0, 0);
+
+	if (datatag != CTCP_C_ACTION)
+		send_text(to, putbuf2, ctcp_type[type], 0, 0);
+	else
+		send_text(to, putbuf2, "Clear Message", 0, 0);
 }
 
 
diff -urN BitchX-clean/source/fset.c BitchXcns-1.0c19cns/source/fset.c
--- BitchX-clean/source/fset.c	Thu Feb 28 05:22:48 2002
+++ BitchXcns-1.0c19cns/source/fset.c	Fri Mar 29 07:36:38 2002
@@ -46,6 +46,17 @@
 	{ "BOT_HEADER",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
 	{ "BWALL",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
 
+    { "C_MSG",                0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+	{ "C_NOTICE",             0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+    { "C_PUBLIC",             0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+	{ "C_PUBLIC_NOTICE",      0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+    { "C_PUBLIC_OTHER",       0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+    { "C_SEND_MSG",           0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+	{ "C_SEND_NOTICE",        0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+    { "C_SEND_PUBLIC",        0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+	{ "C_SEND_PUBLIC_NOTICE", 0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+    { "C_SEND_PUBLIC_OTHER",  0,STR_TYPE_VAR, 0, NULL, NULL, 0, 0},
+
 	{ "CHANNEL_SIGNOFF",	0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
 	
 	{ "COMPLETE",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
@@ -259,6 +270,7 @@
 	{ "WIDELIST",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
 	{ "WINDOW_SET",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
 	{ "XTERM_TITLE",		0,STR_TYPE_VAR,	0, NULL, NULL, 0, 0},
+
 	{ NULL,				0, 0,		0, NULL, NULL, 0, 0}
 };
 
@@ -572,6 +584,18 @@
 	fset_string_var(FORMAT_BOT_FOOTER_FSET, DEFAULT_FORMAT_BOT_FOOTER_FSET);
 	fset_string_var(FORMAT_BOT_FSET, DEFAULT_FORMAT_BOT_FSET);
 	fset_string_var(FORMAT_BWALL_FSET, DEFAULT_FORMAT_BWALL_FSET);
+
+	fset_string_var(FORMAT_C_MSG_FSET, DEFAULT_FORMAT_C_MSG_FSET);
+	fset_string_var(FORMAT_C_NOTICE_FSET, DEFAULT_FORMAT_C_NOTICE_FSET);
+	fset_string_var(FORMAT_C_PUBLIC_FSET, DEFAULT_FORMAT_C_PUBLIC_FSET);
+	fset_string_var(FORMAT_C_PUBLIC_NOTICE_FSET, DEFAULT_FORMAT_C_PUBLIC_NOTICE_FSET);
+	fset_string_var(FORMAT_C_PUBLIC_OTHER_FSET, DEFAULT_FORMAT_C_PUBLIC_OTHER_FSET);
+	fset_string_var(FORMAT_C_SEND_MSG_FSET, DEFAULT_FORMAT_C_SEND_MSG_FSET);
+	fset_string_var(FORMAT_C_SEND_NOTICE_FSET, DEFAULT_FORMAT_C_SEND_NOTICE_FSET);
+	fset_string_var(FORMAT_C_SEND_PUBLIC_FSET, DEFAULT_FORMAT_C_SEND_PUBLIC_FSET);
+	fset_string_var(FORMAT_C_SEND_PUBLIC_NOTICE_FSET, DEFAULT_FORMAT_C_SEND_PUBLIC_NOTICE_FSET);
+	fset_string_var(FORMAT_C_SEND_PUBLIC_OTHER_FSET, DEFAULT_FORMAT_C_SEND_PUBLIC_OTHER_FSET);
+
 	fset_string_var(FORMAT_CHANNEL_SIGNOFF_FSET, DEFAULT_FORMAT_CHANNEL_SIGNOFF_FSET);
 	fset_string_var(FORMAT_CONNECT_FSET, DEFAULT_FORMAT_CONNECT_FSET);
 	fset_string_var(FORMAT_COMPLETE_FSET, DEFAULT_FORMAT_COMPLETE_FSET);
diff -urN BitchX-clean/source/irc.c BitchXcns-1.0c19cns/source/irc.c
--- BitchX-clean/source/irc.c	Mon Mar 25 21:52:56 2002
+++ BitchXcns-1.0c19cns/source/irc.c	Fri Mar 29 08:04:20 2002
@@ -54,6 +54,7 @@
 #include "cdns.h"
 #include "tcl_bx.h"
 #include "ssl.h"
+#include "cfunctions.h"
 #include <pwd.h>
 #define MAIN_SOURCE
 #include "modval.h"
@@ -63,7 +64,7 @@
 #endif
 
 #ifndef VERSION
-	const char irc_version[] = "BitchX-1.0c19";
+	const char irc_version[] = "BitchX-1.0c19cns";
 #else
 	const char irc_version[] = VERSION;
 #endif
@@ -1664,6 +1665,17 @@
 #ifdef GUI
 	gui_font_init();
 #endif
+
+    {   /* here we start CNSirc */
+      c_say(NULL, "CNSirc %s is LOADED $@#*#@#@#!!!", CNS_VERSION);
+      c_say(NULL, "Hello ! You re using %s-%s ... Enjoy !! :-)", irc_version, internal_version);
+      c_say(NULL, "Internal version: %s", internal_version);
+      c_say(NULL, "Read README.CNSirc if you need any information");
+      cmd_load_my_key(NULL, NULL, NULL, NULL);
+      if (get_int_var(ACT_AS_KEY_SERV))
+        load_private_file();
+    }
+
 
 	reinit_autoresponse(current_window, NULL, 0);
 	if (auto_connect)
diff -urN BitchX-clean/source/mars6.c BitchXcns-1.0c19cns/source/mars6.c
--- BitchX-clean/source/mars6.c	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/source/mars6.c	Fri Mar 29 07:36:38 2002
@@ -0,0 +1,547 @@
+/* This is an independent implementation of the MARS encryption 	*/
+/* algorithm designed by a team at IBM as a candidate for the US	*/
+/* NIST Advanced Encryption Standard (AES) effort. The algorithm	*/
+/* is subject to Patent action by IBM, who intend to offer royalty	*/
+/* free use if a Patent is granted. 								*/
+/*																	*/
+/* Copyright in this implementation is held by Dr B R Gladman but	*/
+/* I hereby give permission for its free direct or derivative use	*/
+/* subject to acknowledgment of its origin and compliance with any	*/
+/* constraints that IBM place on the use of the MARS algorithm. 	*/
+/*																	*/
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 4th October 1998	*/
+/*																	*/
+/* Timing data:
+
+Algorithm: mars (mars6.c)
+128 bit key:
+Key Setup:    4329 cycles
+Encrypt:       383 cycles =    66.8 mbits/sec
+Decrypt:       374 cycles =    68.4 mbits/sec
+Mean:          379 cycles =    67.6 mbits/sec
+192 bit key:
+Key Setup:    4414 cycles
+Encrypt:       379 cycles =    67.5 mbits/sec
+Decrypt:       382 cycles =    67.0 mbits/sec
+Mean:          381 cycles =    67.3 mbits/sec
+256 bit key:
+Key Setup:    4351 cycles
+Encrypt:       387 cycles =    66.2 mbits/sec
+Decrypt:       367 cycles =    69.8 mbits/sec
+Mean:          377 cycles =    68.0 mbits/sec
+*/
+
+/*****************************************************************************/
+
+/* 1. Standard types for AES cryptography source code               */
+
+typedef unsigned char   u1byte; /* an 8 bit unsigned character type */
+typedef unsigned short  u2byte; /* a 16 bit unsigned integer type   */
+typedef unsigned long   u4byte; /* a 32 bit unsigned integer type   */
+
+typedef signed char     s1byte; /* an 8 bit signed character type   */
+typedef signed short    s2byte; /* a 16 bit signed integer type     */
+typedef signed long     s4byte; /* a 32 bit signed integer type     */
+
+/* 2. Standard interface for AES cryptographic routines             */
+
+/* These are all based on 32 bit unsigned values and may therefore  */
+/* require endian conversions                                       */
+
+#ifdef  __cplusplus
+
+extern "C"
+{
+    char **cipher_name(void);
+    u4byte *set_key_mars(const u4byte in_key[], const u4byte key_len);
+    void encrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+    void decrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+};
+
+#else
+
+char **cipher_name(void);
+u4byte *set_key_mars(const u4byte in_key[], const u4byte key_len);
+void encrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+void decrypt_mars(const u4byte in_blk[4], u4byte out_blk[4]);
+
+#endif
+
+/* 3. Basic macros for speeding up generic operations               */
+
+/* Circular rotate of 32 bit values                                 */
+
+#ifndef _MSC_VER
+
+#define rotr(x,n)   (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+#define rotl(x,n)   (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+
+#else
+
+#include <stdlib.h>
+
+#pragma intrinsic(_lrotr,_lrotl)
+#define rotr(x,n)   _lrotr(x,n)
+#define rotl(x,n)   _lrotl(x,n)
+
+#endif
+
+/* Invert byte order in a 32 bit variable                           */
+
+#define bswap(x)    (rotl(x, 8) & 0x00ff00ff | rotr(x, 8) & 0xff00ff00)
+
+/* Extract byte from a 32 bit quantity (little endian notation)     */ 
+
+#define byte(x,n)   ((u1byte)((x) >> (8 * n)))
+
+/* For inverting byte order in input/output 32 bit words if needed  */
+
+#ifdef  BYTE_SWAP
+#define io_swap(x)  bswap(x)
+#else
+#define io_swap(x)  (x)
+#endif
+
+/* For inverting the byte order of input/output blocks if needed    */
+
+#ifdef  WORD_SWAP
+
+#define get_block(x)                            \
+    ((u4byte*)(x))[0] = io_swap(in_blk[3]);     \
+    ((u4byte*)(x))[1] = io_swap(in_blk[2]);     \
+    ((u4byte*)(x))[2] = io_swap(in_blk[1]);     \
+    ((u4byte*)(x))[3] = io_swap(in_blk[0])
+
+#define put_block(x)                            \
+    out_blk[3] = io_swap(((u4byte*)(x))[0]);    \
+    out_blk[2] = io_swap(((u4byte*)(x))[1]);    \
+    out_blk[1] = io_swap(((u4byte*)(x))[2]);    \
+    out_blk[0] = io_swap(((u4byte*)(x))[3])
+
+#define get_key(x,len)                          \
+    ((u4byte*)(x))[4] = ((u4byte*)(x))[5] =     \
+    ((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0;  \
+    switch((((len) + 63) / 64)) {               \
+    case 2:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[0]);     \
+    break;                                      \
+    case 3:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[5]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[4] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[0]);     \
+    break;                                      \
+    case 4:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[7]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[6]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[5]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[4] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[6] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[7] = io_swap(in_key[0]);     \
+    }
+
+#else
+
+#define get_block(x)                            \
+    ((u4byte*)(x))[0] = io_swap(in_blk[0]);     \
+    ((u4byte*)(x))[1] = io_swap(in_blk[1]);     \
+    ((u4byte*)(x))[2] = io_swap(in_blk[2]);     \
+    ((u4byte*)(x))[3] = io_swap(in_blk[3])
+
+#define put_block(x)                            \
+    out_blk[0] = io_swap(((u4byte*)(x))[0]);    \
+    out_blk[1] = io_swap(((u4byte*)(x))[1]);    \
+    out_blk[2] = io_swap(((u4byte*)(x))[2]);    \
+    out_blk[3] = io_swap(((u4byte*)(x))[3])
+
+#define get_key(x,len)                          \
+    ((u4byte*)(x))[4] = ((u4byte*)(x))[5] =     \
+    ((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0;  \
+    switch((((len) + 63) / 64)) {               \
+    case 4:                                     \
+    ((u4byte*)(x))[6] = io_swap(in_key[6]);     \
+    ((u4byte*)(x))[7] = io_swap(in_key[7]);     \
+    case 3:                                     \
+    ((u4byte*)(x))[4] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[5]);     \
+    case 2:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[0]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[3]);     \
+    }
+
+#endif
+
+#ifdef  BLOCK_SWAP
+#define BYTE_SWAP
+#define WORD_SWAP
+#endif
+
+/*****************************************************************************/
+
+static char *alg_name[] = { "mars", "mars6.c" };
+
+char **cipher_name_mars()
+{
+	return alg_name;
+}
+
+static u4byte s_box[] = 
+{
+	0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, /* 0x000	*/
+	0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93, 
+	0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d, 
+	0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4, 
+	0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, /* 0x010	*/
+	0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac, 
+	0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4, 
+	0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26, 
+	0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, /* 0x020	*/
+	0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086, 
+	0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c, 
+	0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253, 
+	0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, /* 0x030	*/
+	0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e, 
+	0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b, 
+	0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a, 
+	0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, /* 0x040	*/
+	0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb, 
+	0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958, 
+	0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215, 
+	0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, /* 0x050	*/
+	0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c, 
+	0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462, 
+	0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44, 
+	0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, /* 0x060	*/
+	0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df, 
+	0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8, 
+	0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae, 
+	0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, /* 0x070	*/ 
+	0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365, 
+	0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3, 
+	0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55, 
+	0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, /* 0x080	*/
+	0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7, 
+	0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8, 
+	0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063, 
+	0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, /* 0x090	*/
+	0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371, 
+	0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6, 
+	0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b, 
+	0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, /* 0x0a0	*/
+	0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1, 
+	0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd, 
+	0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294, 
+	0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, /* 0x0b0	*/
+	0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98, 
+	0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f, 
+	0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d, 
+	0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, /* 0x0c0	*/
+	0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48,
+	0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149, 
+	0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9, 
+	0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, /* 0x0d0	*/ 
+	0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e,
+	0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3, 
+	0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52, 
+	0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, /* 0x0e0	*/ 
+	0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f,
+	0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59, 
+	0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8, 
+	0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, /* 0x0f0	*/ 
+	0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca, 
+	0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3, 
+	0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030,
+
+	0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, /* 0x100	*/
+	0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734, 
+	0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, 
+	0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03, 
+	0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, /* 0x110	*/ 
+	0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3, 
+	0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf, 
+	0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568, 
+	0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, /* 0x120	*/
+	0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10, 
+	0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce,
+	0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047, 
+	0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, /* 0x130	*/
+	0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158, 
+	0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969, 
+	0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f, 
+	0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, /* 0x140	*/
+	0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05, 
+	0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3, 
+	0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33, 
+	0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, /* 0x150	*/
+	0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd, 
+	0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e,
+	0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246, 
+	0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, /* 0x160	*/
+	0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e, 
+	0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2, 
+	0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b, 
+	0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, /* 0x170	*/
+	0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba, 
+	0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c, 
+	0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5, 
+	0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, /* 0x180	*/
+	0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47, 
+	0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54, 
+	0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72, 
+	0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, /* 0x190	*/
+	0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6, 
+	0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9, 
+	0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68, 
+	0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, /* 0x1a0	*/
+	0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f,
+	0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4, 
+	0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7, 
+	0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, /* 0x1b0	*/ 
+	0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038, 
+	0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c, 
+	0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53, 
+	0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, /* 0x1c0	*/
+	0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336, 
+	0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235, 
+	0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185, 
+	0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, /* 0x1d0	*/
+	0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558, 
+	0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830, 
+	0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85, 
+	0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, /* 0x1e0	*/
+	0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6, 
+	0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319, 
+	0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469, 
+	0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, /* 0x1f0	*/
+	0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b, 
+	0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0, 
+	0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee
+};
+
+static u4byte vk[47] =
+{ 
+	0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, 0x7dff9be3, 0xd4268361,
+	0xc96da1d4
+};
+
+static u4byte	l_key[40];
+
+#define f_mix(a,b,c,d)					\
+		r = rotr(a, 8); 				\
+		b ^= s_box[a & 255];			\
+		b += s_box[(r & 255) + 256];	\
+		r = rotr(a, 16);				\
+		a  = rotr(a, 24);				\
+		c += s_box[r & 255];			\
+		d ^= s_box[(a & 255) + 256]
+
+#define b_mix(a,b,c,d)					\
+		r = rotl(a, 8); 				\
+		b ^= s_box[(a & 255) + 256];	\
+		c -= s_box[r & 255];			\
+		r = rotl(a, 16);				\
+		a  = rotl(a, 24);				\
+		d -= s_box[(r & 255) + 256];	\
+		d ^= s_box[a & 255]
+
+#define f_ktr(a,b,c,d,i)	\
+	m = a + l_key[i];		\
+	a = rotl(a, 13);		\
+	r = a * l_key[i + 1];	\
+	l = s_box[m & 511]; 	\
+	r = rotl(r, 5); 		\
+	l ^= r; 				\
+	c += rotl(m, r);		\
+	r = rotl(r, 5); 		\
+	l ^= r; 				\
+	d ^= r; 				\
+	b += rotl(l, r)
+
+#define r_ktr(a,b,c,d,i)	\
+	r = a * l_key[i + 1];	\
+	a = rotr(a, 13);		\
+	m = a + l_key[i];		\
+	l = s_box[m & 511]; 	\
+	r = rotl(r, 5); 		\
+	l ^= r; 				\
+	c -= rotl(m, r);		\
+	r = rotl(r, 5); 		\
+	l ^= r; 				\
+	d ^= r; 				\
+	b -= rotl(l, r)
+
+/* For a 32 bit word (x) generate a mask (m) such that a bit in */
+/* m is set to 1 if and only if the corresponding bit in x is:	*/
+/*																*/
+/* 1. in a sequence of 10 or more adjacent '0' bits 			*/
+/* 2. in a sequence of 10 or more adjacent '1' bits 			*/
+/* 3. but is not either endpoint of such a sequence unless such */
+/*	  an endpoint is at the top bit (bit 31) of a word and is	*/
+/*	  in a sequence of '0' bits.								*/
+/*																*/
+/* The only situation in which a sequence endpoint is included	*/
+/* in the mask is hence when the endpoint is at bit 31 and is	*/
+/* the endpoint of a sequence of '0' bits. My thanks go to Shai */
+/* Halevi of IBM for the neat trick (which I missed) of finding */
+/* the '0' and '1' sequences at the same time.					*/
+
+u4byte gen_mask(u4byte x)
+{	u4byte	m;
+
+	/* if m{bn} stands for bit number bn of m, set m{bn} = 1 if */
+	/* x{bn} == x{bn+1} for 0 <= bn <= 30.	That is, set a bit	*/
+	/* in m if the corresponding bit and the next higher bit in */
+	/* x are equal in value (set m{31} = 0).					*/
+
+	m = (~x ^ (x >> 1)) & 0x7fffffff;
+
+	/* Sequences of 9 '1' bits in m now correspond to sequences */
+	/* of 10 '0's or 10 '1' bits in x.	Shift and 'and' bits in */
+	/* m to find sequences of 9 or more '1' bits.	As a result */
+	/* bits in m are set if they are at the bottom of sequences */
+	/* of 10 adjacent '0's or 10 adjacent '1's in x.			*/
+
+	m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6); 
+	
+	if(!m)	/* return if mask is empty - no key fixing needed	*/
+			/* is this early return worthwhile?	    			*/
+		return 0;
+	
+	/* We need the internal bits in each continuous sequence of */
+	/* matching bits (that is the bits less the two endpoints). */
+	/* We thus propagate each set bit into the 8 internal bits	*/
+	/* that it represents, starting 1 left and finsihing 8 left */
+	/* of its position. 										*/
+
+	m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);
+
+	/* m is now correct except for the odd behaviour of bit 31, */
+	/* that is, it will be set if it is in a sequence of 10 or	*/
+	/* more '0's and clear otherwise.							*/
+
+	m |= (m << 1) & ~x & 0x80000000;
+
+	return m & 0xfffffffc;
+};
+
+u4byte *set_key_mars(const u4byte in_key[], const u4byte key_len)
+{	u4byte	i, j, m, u, w, *t = vk + 7;
+
+	m = key_len / 32 - 1;
+
+	for(i = j = 0; i < 39; ++i)
+	{
+	  u = t[i - 7] ^ t[i - 2]; t[i] = rotl(u, 3) ^ in_key[j] ^ i;
+	  j = (j == m ? 0 : j + 1);
+	}
+
+	t[39] = key_len / 32;
+
+	for(j = 0; j < 7; ++j)
+	{
+		 for(i = 1; i < 40; ++i)
+		 {
+			u = t[i] + s_box[t[i - 1] & 511]; t[i] = rotl(u, 9);
+		}
+
+		u = t[0] + s_box[t[39] & 511]; t[0] = rotl(u, 9);
+	}
+
+	for(i = j = 0; i < 40; ++i)
+	{
+		l_key[j] = t[i];
+
+		j = (j < 33 ? j + 7 : j - 33);
+	}
+
+	for(i = 5; i < 37; i += 2)
+	{
+		w = l_key[i] | 3;
+
+		if((m = gen_mask(w)))
+		{
+			u = s_box[265 + (l_key[i] & 3)]; j = l_key[i + 3] & 31;
+			
+			w ^= (rotl(u, j) & m);
+		}
+
+		l_key[i] = w;
+	}
+
+	return l_key;
+};
+
+void encrypt_mars(const u4byte in_blk[4], u4byte out_blk[4])
+{	u4byte	a, b, c, d, l, m, r;
+
+	a = in_blk[0] + l_key[0]; b = in_blk[1] + l_key[1];
+	c = in_blk[2] + l_key[2]; d = in_blk[3] + l_key[3];
+
+	f_mix(a,b,c,d); a += d;
+	f_mix(b,c,d,a); b += c;
+	f_mix(c,d,a,b);
+	f_mix(d,a,b,c);
+	f_mix(a,b,c,d); a += d;
+	f_mix(b,c,d,a); b += c;
+	f_mix(c,d,a,b);
+	f_mix(d,a,b,c);
+
+	f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10); 
+	f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18); 
+	f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26); 
+	f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34); 
+
+	b_mix(a,b,c,d);
+	b_mix(b,c,d,a); c -= b;
+	b_mix(c,d,a,b); d -= a;
+	b_mix(d,a,b,c);
+	b_mix(a,b,c,d);
+	b_mix(b,c,d,a); c -= b;
+	b_mix(c,d,a,b); d -= a;
+	b_mix(d,a,b,c);
+
+	out_blk[0] = a - l_key[36]; out_blk[1] = b - l_key[37];
+	out_blk[2] = c - l_key[38]; out_blk[3] = d - l_key[39];
+};
+
+void decrypt_mars(const u4byte in_blk[4], u4byte out_blk[4])
+{	u4byte	a, b, c, d, l, m, r;
+
+	d = in_blk[0] + l_key[36]; c = in_blk[1] + l_key[37];
+	b = in_blk[2] + l_key[38]; a = in_blk[3] + l_key[39];
+
+	f_mix(a,b,c,d); a += d;
+	f_mix(b,c,d,a); b += c;
+	f_mix(c,d,a,b);
+	f_mix(d,a,b,c);
+	f_mix(a,b,c,d); a += d;
+	f_mix(b,c,d,a); b += c;
+	f_mix(c,d,a,b);
+	f_mix(d,a,b,c);
+
+	r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28);
+	r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20);
+	r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12);
+	r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4);
+
+	b_mix(a,b,c,d);
+	b_mix(b,c,d,a); c -= b;
+	b_mix(c,d,a,b); d -= a;
+	b_mix(d,a,b,c);
+	b_mix(a,b,c,d);
+	b_mix(b,c,d,a); c -= b;
+	b_mix(c,d,a,b); d -= a;
+	b_mix(d,a,b,c);
+
+	out_blk[0] = d - l_key[0]; out_blk[1] = c - l_key[1];
+	out_blk[2] = b - l_key[2]; out_blk[3] = a - l_key[3];
+}
diff -urN BitchX-clean/source/names.c BitchXcns-1.0c19cns/source/names.c
--- BitchX-clean/source/names.c	Mon Mar 25 21:47:30 2002
+++ BitchXcns-1.0c19cns/source/names.c	Fri Mar 29 07:36:38 2002
@@ -44,6 +44,8 @@
 #define MAIN_SOURCE
 #include "modval.h"
 
+#include "cfunctions.h"
+
 extern AJoinList *ajoin_list;
 
 
@@ -56,12 +58,13 @@
 static	int	decifer_mode (char *, char *, ChannelList **, unsigned long *, char *, char *, char **);
 	void	BX_clear_bans (ChannelList *);
 
-static	char	mode_str[] = "aciklmnprstzR";
+static	char	mode_str[] = "aciklmnprstzRS";
 	char	new_channel_format[BIG_BUFFER_SIZE];
 	
   
-const int	MODE_ANONYMOUS	= 1 << 0;	/* av2.9 */
-const int	MODE_C		= 1 << 1;	/* erf/TS4 */
+const int	MODE_ANONYMOUS	= 1 << 0;	/* Rv2.9 */
+/* 1998 code never include in hybrid it seems ... contact me if one day it is. */
+// const int	MODE_C		= 1 << 1;	/* erf/TS4 */
 const int 	MODE_INVITE 	= 1 << 2;	/* RFC */
 const int 	MODE_KEY    	= 1 << 3;	/* RFC */
 const int	MODE_LIMIT	= 1 << 4;	/* RFC */
@@ -73,6 +76,10 @@
 const int	MODE_TOPIC	= 1 << 10;	/* RFC */
 const int       MODE_Z          = 1 << 11;      /* erf/TS4 */
 const int       MODE_RESTRICTED = 1 << 12;      /* Dalnet */
+const int      MODE_BIGSECRET = 1 << 13;       /* ircs.link-net.org */
+const int      MODE_COLOR = 1 << 1;   /* bahamut +c mode (avoid colors) */
+
+
 
 
 
@@ -923,6 +930,12 @@
 		case 'R':
 			value = MODE_RESTRICTED;
 			break;
+		case 'S':
+			value = MODE_BIGSECRET;
+			break;
+		case 'c':
+			value = MODE_COLOR;
+			break;
 		case 'z':
 			value = MODE_Z;
 			break;
@@ -985,6 +998,7 @@
 			}
 			break;
 		}			
+/*
 		case 'c':
 			value = MODE_C;
 			if (add)
@@ -996,6 +1010,7 @@
 			}
 			else
 				new_free(&(*channel)->chanpass);
+*/
 			break;
 		case 'k':
 			value = MODE_KEY;
@@ -1357,8 +1372,36 @@
 	register ChannelList *chan;
 	register NickList *tmp;
 	int t = 0;
-		
-	
+    Window *seq;
+    int isend=0;
+
+	while(isend++ < 2)
+	{
+		seq=(isend==2) ? current_window : invisible_list;
+ 
+		if(seq)
+		{
+			while(seq->prev != NULL)
+			seq=seq->prev;
+        
+			while(seq != NULL)
+			{
+
+			if(seq->query_nick != NULL)
+				if(!strcmp(seq->query_nick,old_nick))
+				{
+					malloc_strcpy(&seq->query_nick, new_nick);
+#ifdef GUI
+					xterm_settitle();
+#endif
+					update_window_status(seq,0);
+				}
+			seq=seq->next;
+			}
+		}
+	}	
+
+	c_rename_nick(old_nick, new_nick);		
 	for (chan = get_server_channels(server); chan; chan = chan->next)
 	{
 		if ((chan->server == server))
diff -urN BitchX-clean/source/notice.c BitchXcns-1.0c19cns/source/notice.c
--- BitchX-clean/source/notice.c	Thu Feb 28 05:22:50 2002
+++ BitchXcns-1.0c19cns/source/notice.c	Fri Mar 29 07:36:38 2002
@@ -40,6 +40,8 @@
 #define MAIN_SOURCE
 #include "modval.h"
 
+#include "cfunctions.h"
+
 extern	char	*FromUserHost;
 static	void	parse_server_notice (char *, char *);
 int	doing_notice = 0;
@@ -680,6 +682,8 @@
 	ChannelList *tmpc = NULL;
 	char *newline = NULL;
 
+	int typ, len;
+	unsigned char *crp, *key;
 		
 	PasteArgs(Args, 1);
 	to = Args[0];
@@ -698,8 +702,6 @@
 		return;
 	}
 
-
-	
 	if (is_channel(to))
 	{
 		target = to;
@@ -724,14 +726,42 @@
 	if (!check_flooding(from, NOTICE_FLOOD, line, NULL))
 		goto notice_cleanup;
 
-	if (!strchr(from, '.'))
+	/* cns CNS XXX Cns */
+	if ((typ = is_correct_crypt(line)))
 	{
-		notify_mark(from, FromUserHost, 1, 0);
-		line = do_notice_ctcp(from, to, line);
-		if (!*line)
+		switch(typ)
+		{
+		case RSA_CRYPT:
+			len = strlen(line);
+			crp = cns_decrypt_RSA(line);
+			if (!strlen(crp))
+			{
+				c_say(from, "No data or error in message from %s.", from);
+			}
+			put_it("%s",convert_output_format(fget_string_var(FORMAT_C_NOTICE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, to, crp));
+			new_free(&crp);
 			goto notice_cleanup;
-	}
-		
+		break;
+		case TWOFISH_CRYPT:
+			if ((key = get_pass_from_chan(to)))
+			{
+				crp = cns_decrypt_twofish(line, key);
+				put_it("%s",convert_output_format(fget_string_var(FORMAT_C_PUBLIC_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, crp));
+				new_free(&crp);
+				goto notice_cleanup;
+			}
+		break;
+		}
+	} 
+
+    if (!strchr(from, '.'))
+    {
+        notify_mark(from, FromUserHost, 1, 0);
+        line = do_notice_ctcp(from, to, line);
+        if (!*line)
+            goto notice_cleanup;
+    }
+
 	if (sed && !do_hook(ENCRYPTED_NOTICE_LIST, "%s %s %s", from, to, line))
 	{
 #if 0
diff -urN BitchX-clean/source/parse.c BitchXcns-1.0c19cns/source/parse.c
--- BitchX-clean/source/parse.c	Sun Mar 24 10:31:07 2002
+++ BitchXcns-1.0c19cns/source/parse.c	Fri Mar 29 07:36:38 2002
@@ -54,6 +54,7 @@
 #define MAIN_SOURCE
 #include "modval.h"
 
+#include "cfunctions.h"
 
 #define STRING_CHANNEL '+'
 #define MULTI_CHANNEL '#'
@@ -457,7 +458,10 @@
 	ChannelList *channel = NULL;
 	NickList *tmpnick = NULL;
 	
+	// cnsirc vars:
 
+	int typ, cns_type_view, len;
+	unsigned char *key, *crp;
 	
 	if (!from)
 		return;
@@ -468,12 +472,25 @@
 		{ fake(); return; }
 	doing_privmsg = 1;
 
-	ptr = do_ctcp(from, to, ptr);
-	if (!ptr || !*ptr)
+	/* CNSirc: Is it a key ? */
+	if (check_is_rsa_key(ptr))
 	{
-		doing_privmsg = 0;
-		return;
-	} 
+		get_rsa_key(from, to, ptr);
+		if (!get_int_var(SHOW_RSA_KEY_VAR))
+			return ; 	
+	}
+
+	typ = is_correct_crypt(ptr);
+	if (!typ 
+		|| (typ != RSA_CRYPT && !get_pass_from_chan(to)))
+	{
+		ptr = do_ctcp(from, to, ptr);
+		if (!ptr || !*ptr)
+		{
+			doing_privmsg = 0;
+			return;
+		} 
+	}
 	
 	if (is_channel(to) && im_on_channel(to, from_server))
 	{
@@ -577,6 +594,93 @@
 	else
 		no_flood = check_flooding(from, flood_type, ptr, NULL);
 
+	if ((typ = is_correct_crypt(ptr)))
+	{
+		switch(typ)
+		{
+			case RSA_CRYPT:
+				len = strlen(ptr);
+				crp = cns_decrypt_RSA(ptr);
+
+				if (!strlen(crp))
+				{
+					c_say(from, "No data or error in message from %s.", from);
+				}
+
+				if (recieve_chan_key(crp, len))
+					return;
+
+				crp = do_ctcp(from, to, crp); if (!crp || !*crp) { return; }
+
+				if (check_is_rsa_key(crp))
+				{
+					get_rsa_key(from, to, crp);
+					if (!get_int_var(SHOW_RSA_KEY_VAR))
+					{
+						new_free(&crp);
+						return ;
+					}
+				}
+
+				if (do_hook(list_type, "%s %s", from, crp))
+				{
+					set_display_target(from, LOG_MSG);
+					logmsg(LOG_MSG, from,  0,"%s %s", FromUserHost, ptr);
+					put_it("%s",convert_output_format(fget_string_var(FORMAT_C_MSG_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, to, crp));
+				}
+				new_free(&crp);
+				return;
+			break;
+			case TWOFISH_CRYPT:
+				switch(list_type)
+				{
+					case MSG_LIST:
+					case MSG_GROUP_LIST:
+						cns_type_view = FORMAT_C_MSG_FSET;
+					break;
+
+					case PUBLIC_LIST:
+					case PUBLIC_MSG_LIST:
+						cns_type_view = FORMAT_C_PUBLIC_FSET;
+					break;
+	
+					case PUBLIC_OTHER_LIST:
+						cns_type_view = FORMAT_C_PUBLIC_OTHER_FSET;
+					break;
+					default:
+						cns_type_view = FORMAT_ENCRYPTED_PRIVMSG_FSET;
+					break;
+				}
+
+				if ((key = get_pass_from_chan(to)))
+					crp = cns_decrypt_twofish(ptr, key);
+
+				crp = do_ctcp(from, to, crp);
+				if (!crp || !*crp)
+				{
+					return ;
+				}
+
+				if (check_is_rsa_key(crp))
+				{
+					get_rsa_key(from, to, crp);
+					if (!get_int_var(SHOW_RSA_KEY_VAR))
+						return ;
+				}
+
+				if (do_hook(list_type, "%s %s %s", from, to, crp))
+				{
+					set_display_target(to, LOG_MSG);
+					logmsg(LOG_PUBLIC, from, 0,"%s %s", to, crp);
+					do_logchannel(LOG_PUBLIC, channel, "%s", convert_output_format(fget_string_var(FORMAT_ENCRYPTED_PRIVMSG_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, ptr));
+					put_it("%s",convert_output_format(fget_string_var(cns_type_view), "%s %s %s %s", update_clock(GET_TIME), from, to, crp));
+				}
+
+                new_free(&crp);
+			break;
+		}
+	}
+	else
 	if (sed == 1)
 	{
 		if (do_hook(ENCRYPTED_PRIVMSG_LIST,"%s %s %s",from, to, ptr))
diff -urN BitchX-clean/source/server.c BitchXcns-1.0c19cns/source/server.c
--- BitchX-clean/source/server.c	Mon Mar 25 06:21:24 2002
+++ BitchXcns-1.0c19cns/source/server.c	Fri Mar 29 07:36:38 2002
@@ -111,7 +111,8 @@
 	if (get_server_ssl(cs_index) && server_list[cs_index].ssl_fd)
 	{
 		say("Closing SSL connection");
-		SSL_shutdown(server_list[cs_index].ssl_fd);
+		if (server_list[cs_index].ssl_fd != NULL)
+			SSL_shutdown(server_list[cs_index].ssl_fd);
 	}
 #endif
 
@@ -153,7 +154,10 @@
 			snprintf(buffer, BIG_BUFFER_SIZE, "QUIT :%s\n", message);
 #ifdef HAVE_SSL
 			if (get_server_ssl(cs_index))
-				SSL_write(server_list[cs_index].ssl_fd, buffer, strlen(buffer));
+				if (server_list[cs_index].ssl_fd)
+					SSL_write(server_list[cs_index].ssl_fd, buffer, strlen(buffer));
+				else
+					send(server_list[cs_index].write, buffer, strlen(buffer), 0);
 			else
 #endif
 				send(server_list[cs_index].write, buffer, strlen(buffer), 0);
@@ -2806,6 +2810,7 @@
  */
 void BX_fudge_nickname (int servnum, int resend_only)
 {
+	char *n;
 	char l_nickname[BIG_BUFFER_SIZE + 1];
 	Server *s = &server_list[from_server];
 	if (resend_only)
@@ -2861,9 +2866,14 @@
 	/* 
 	 * Process of fudging a nickname:
 	 * If the nickname length is less then 9, add an underscore.
+	 * If the nickname length is less then 9, add what we want despotic #!@#!
 	 */
 	if (strlen(l_nickname) < 9)
-		strlcat(l_nickname, "_", NICKNAME_LEN);
+		if ((n = get_string_var(DEFAULT_ADDED_LETTER_VAR)))
+			strlcat(l_nickname, n, NICKNAME_LEN);
+		else
+			strlcat(l_nickname, "_", NICKNAME_LEN);
+
 
 	/* 
 	 * The nickname is 9 characters long. roll the nickname
diff -urN BitchX-clean/source/tcl_public.c BitchXcns-1.0c19cns/source/tcl_public.c
--- BitchX-clean/source/tcl_public.c	Thu Feb 28 05:22:51 2002
+++ BitchXcns-1.0c19cns/source/tcl_public.c	Fri Mar 29 07:36:38 2002
@@ -1566,4 +1566,3 @@
 
 
 #endif
- 
\ No newline at end of file
diff -urN BitchX-clean/source/twofish3.c BitchXcns-1.0c19cns/source/twofish3.c
--- BitchX-clean/source/twofish3.c	Thu Jan  1 01:00:00 1970
+++ BitchXcns-1.0c19cns/source/twofish3.c	Fri Mar 29 07:36:38 2002
@@ -0,0 +1,578 @@
+/* This is an independent implementation of the Twofish encryption  */
+/* algorithm designed by Bruce Schneier and colleagues and offered  */
+/* as a candidate algorithm for the US NIST Advanced Encryption     */
+/* Standard (AES) effort.                                           */
+/*                                                                  */
+/* Copyright in this implementation is held by Dr B R Gladman but   */
+/* I hereby give permission for its free direct or derivative use   */
+/* subject to acknowledgment of its origin.                         */
+/*                                                                  */
+/* My thanks to Niels Ferguson and the Twofish team for suggesting  */
+/* an additional optimisation for this code                         */ 
+/*                                                                  */
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 18th October 1998 */
+/*                                                                  */
+/* Timing data:
+
+Algorithm: twofish (twofish3.c)
+128 bit key:
+Key Setup:   16333 cycles
+Encrypt:       396 cycles =    64.6 mbits/sec
+Decrypt:       397 cycles =    64.5 mbits/sec
+Mean:          396 cycles =    64.6 mbits/sec
+192 bit key:
+Key Setup:   23378 cycles
+Encrypt:       396 cycles =    64.6 mbits/sec
+Decrypt:       398 cycles =    64.3 mbits/sec
+Mean:          397 cycles =    64.5 mbits/sec
+256 bit key:
+Key Setup:   24791 cycles
+Encrypt:       396 cycles =    64.6 mbits/sec
+Decrypt:       395 cycles =    64.8 mbits/sec
+Mean:          396 cycles =    64.7 mbits/sec
+
+
+*/
+
+/* 1. Standard types for AES cryptography source code               */
+
+typedef unsigned char   u1byte; /* an 8 bit unsigned character type */
+typedef unsigned short  u2byte; /* a 16 bit unsigned integer type   */
+typedef unsigned long   u4byte; /* a 32 bit unsigned integer type   */
+
+typedef signed char     s1byte; /* an 8 bit signed character type   */
+typedef signed short    s2byte; /* a 16 bit signed integer type     */
+typedef signed long     s4byte; /* a 32 bit signed integer type     */
+
+/* 2. Standard interface for AES cryptographic routines             */
+
+/* These are all based on 32 bit unsigned values and may therefore  */
+/* require endian conversions                                       */
+
+#ifdef  __cplusplus
+
+extern "C"
+{
+    char **cipher_name_twofish(void);
+    u4byte *set_key_twofish(const u4byte in_key[], const u4byte key_len);
+    void encrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+    void decrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+};
+
+#else
+
+char **cipher_name_twofish(void);
+u4byte *set_key_twofish(const u4byte in_key[], const u4byte key_len);
+void encrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+void decrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4]);
+
+#endif
+
+/* 3. Basic macros for speeding up generic operations               */
+
+/* Circular rotate of 32 bit values                                 */
+
+#ifndef _MSC_VER
+
+#define rotr(x,n)   (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+#define rotl(x,n)   (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+
+#else
+
+#include <stdlib.h>
+
+#pragma intrinsic(_lrotr,_lrotl)
+#define rotr(x,n)   _lrotr(x,n)
+#define rotl(x,n)   _lrotl(x,n)
+
+#endif
+
+/* Invert byte order in a 32 bit variable                           */
+
+#define bswap(x)    (rotl(x, 8) & 0x00ff00ff | rotr(x, 8) & 0xff00ff00)
+
+/* Extract byte from a 32 bit quantity (little endian notation)     */ 
+
+#define byte(x,n)   ((u1byte)((x) >> (8 * n)))
+
+/* For inverting byte order in input/output 32 bit words if needed  */
+
+#ifdef  BYTE_SWAP
+#define io_swap(x)  bswap(x)
+#else
+#define io_swap(x)  (x)
+#endif
+
+/* For inverting the byte order of input/output blocks if needed    */
+
+#ifdef  WORD_SWAP
+
+#define get_block(x)                            \
+    ((u4byte*)(x))[0] = io_swap(in_blk[3]);     \
+    ((u4byte*)(x))[1] = io_swap(in_blk[2]);     \
+    ((u4byte*)(x))[2] = io_swap(in_blk[1]);     \
+    ((u4byte*)(x))[3] = io_swap(in_blk[0])
+
+#define put_block(x)                            \
+    out_blk[3] = io_swap(((u4byte*)(x))[0]);    \
+    out_blk[2] = io_swap(((u4byte*)(x))[1]);    \
+    out_blk[1] = io_swap(((u4byte*)(x))[2]);    \
+    out_blk[0] = io_swap(((u4byte*)(x))[3])
+
+#define get_key(x,len)                          \
+    ((u4byte*)(x))[4] = ((u4byte*)(x))[5] =     \
+    ((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0;  \
+    switch((((len) + 63) / 64)) {               \
+    case 2:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[0]);     \
+    break;                                      \
+    case 3:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[5]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[4] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[0]);     \
+    break;                                      \
+    case 4:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[7]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[6]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[5]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[4] = io_swap(in_key[3]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[6] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[7] = io_swap(in_key[0]);     \
+    }
+
+#else
+
+#define get_block(x)                            \
+    ((u4byte*)(x))[0] = io_swap(in_blk[0]);     \
+    ((u4byte*)(x))[1] = io_swap(in_blk[1]);     \
+    ((u4byte*)(x))[2] = io_swap(in_blk[2]);     \
+    ((u4byte*)(x))[3] = io_swap(in_blk[3])
+
+#define put_block(x)                            \
+    out_blk[0] = io_swap(((u4byte*)(x))[0]);    \
+    out_blk[1] = io_swap(((u4byte*)(x))[1]);    \
+    out_blk[2] = io_swap(((u4byte*)(x))[2]);    \
+    out_blk[3] = io_swap(((u4byte*)(x))[3])
+
+#define get_key(x,len)                          \
+    ((u4byte*)(x))[4] = ((u4byte*)(x))[5] =     \
+    ((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0;  \
+    switch((((len) + 63) / 64)) {               \
+    case 4:                                     \
+    ((u4byte*)(x))[6] = io_swap(in_key[6]);     \
+    ((u4byte*)(x))[7] = io_swap(in_key[7]);     \
+    case 3:                                     \
+    ((u4byte*)(x))[4] = io_swap(in_key[4]);     \
+    ((u4byte*)(x))[5] = io_swap(in_key[5]);     \
+    case 2:                                     \
+    ((u4byte*)(x))[0] = io_swap(in_key[0]);     \
+    ((u4byte*)(x))[1] = io_swap(in_key[1]);     \
+    ((u4byte*)(x))[2] = io_swap(in_key[2]);     \
+    ((u4byte*)(x))[3] = io_swap(in_key[3]);     \
+    }
+
+#endif
+
+#ifdef  BLOCK_SWAP
+#define BYTE_SWAP
+#define WORD_SWAP
+#endif
+#define Q_TABLES
+#define M_TABLE
+#define MK_TABLE
+#define ONE_STEP
+
+static char *alg_name[] = { "twofish", "twofish3.c" };
+
+char **cipher_name_twofish()
+{
+    return alg_name;
+}
+
+u4byte  k_len;
+u4byte  l_key[40];
+u4byte  s_key[4];
+
+/* finite field arithmetic for GF(2**8) with the modular    */
+/* polynomial x**8 + x**6 + x**5 + x**3 + 1 (0x169)         */
+
+#define G_M 0x0169
+
+u1byte  tab_5b[4] = { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) };
+u1byte  tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 };
+
+#define ffm_01(x)    (x)
+#define ffm_5b(x)   ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3])
+#define ffm_ef(x)   ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3])
+
+u1byte ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
+u1byte ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 };
+
+u1byte qt0[2][16] = 
+{   { 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 },
+    { 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 }
+};
+
+u1byte qt1[2][16] =
+{   { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 }, 
+    { 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 }
+};
+
+u1byte qt2[2][16] = 
+{   { 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 },
+    { 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 }
+};
+
+u1byte qt3[2][16] = 
+{   { 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 },
+    { 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 }
+};
+ 
+u1byte  qp(const u4byte n, const u1byte x)
+{   u1byte  a0, a1, a2, a3, a4, b0, b1, b2, b3, b4;
+
+    a0 = x >> 4; b0 = x & 15;
+    a1 = a0 ^ b0; b1 = ror4[b0] ^ ashx[a0];
+    a2 = qt0[n][a1]; b2 = qt1[n][b1];
+    a3 = a2 ^ b2; b3 = ror4[b2] ^ ashx[a2];
+    a4 = qt2[n][a3]; b4 = qt3[n][b3];
+    return (b4 << 4) | a4;
+};
+
+#ifdef  Q_TABLES
+
+u4byte  qt_gen = 0;
+u1byte  q_tab[2][256];
+
+#define q(n,x)  q_tab[n][x]
+
+void gen_qtab(void)
+{   u4byte  i;
+
+    for(i = 0; i < 256; ++i)
+    {       
+        q(0,i) = qp(0, (u1byte)i);
+        q(1,i) = qp(1, (u1byte)i);
+    }
+};
+
+#else
+
+#define q(n,x)  qp(n, x)
+
+#endif
+
+#ifdef  M_TABLE
+
+u4byte  mt_gen = 0;
+u4byte  m_tab[4][256];
+
+void gen_mtab(void)
+{   u4byte  i, f01, f5b, fef;
+    
+    for(i = 0; i < 256; ++i)
+    {
+        f01 = q(1,i); f5b = ffm_5b(f01); fef = ffm_ef(f01);
+        m_tab[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
+        m_tab[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);
+
+        f01 = q(0,i); f5b = ffm_5b(f01); fef = ffm_ef(f01);
+        m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
+        m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
+    }
+};
+
+#define mds(n,x)    m_tab[n][x]
+
+#else
+
+#define fm_00   ffm_01
+#define fm_10   ffm_5b
+#define fm_20   ffm_ef
+#define fm_30   ffm_ef
+#define q_0(x)  q(1,x)
+
+#define fm_01   ffm_ef
+#define fm_11   ffm_ef
+#define fm_21   ffm_5b
+#define fm_31   ffm_01
+#define q_1(x)  q(0,x)
+
+#define fm_02   ffm_5b
+#define fm_12   ffm_ef
+#define fm_22   ffm_01
+#define fm_32   ffm_ef
+#define q_2(x)  q(1,x)
+
+#define fm_03   ffm_5b
+#define fm_13   ffm_01
+#define fm_23   ffm_ef
+#define fm_33   ffm_5b
+#define q_3(x)  q(0,x)
+
+#define f_0(n,x)    ((u4byte)fm_0##n(x))
+#define f_1(n,x)    ((u4byte)fm_1##n(x) << 8)
+#define f_2(n,x)    ((u4byte)fm_2##n(x) << 16)
+#define f_3(n,x)    ((u4byte)fm_3##n(x) << 24)
+
+#define mds(n,x)    f_0(n,q_##n(x)) ^ f_1(n,q_##n(x)) ^ f_2(n,q_##n(x)) ^ f_3(n,q_##n(x))
+
+#endif
+
+u4byte h_fun(const u4byte x, const u1byte key[])
+{   u1byte  b0, b1, b2, b3;
+
+    b0 = byte(x, 0); b1 = byte(x, 1); b2 = byte(x, 2); b3 = byte(x, 3);
+
+    switch(k_len)
+    {
+        case 4:
+            b0 = q(1,b0) ^ key[12];
+            b1 = q(0,b1) ^ key[13];
+            b2 = q(0,b2) ^ key[14];
+            b3 = q(1,b3) ^ key[15];
+        case 3: /* fall through */
+            b0 = q(1,b0) ^ key[ 8];
+            b1 = q(1,b1) ^ key[ 9];
+            b2 = q(0,b2) ^ key[10];
+            b3 = q(0,b3) ^ key[11];
+        case 2: /* fall through */
+            b0 = q(0,q(0,b0) ^ key[4]) ^ key[0];
+            b1 = q(0,q(1,b1) ^ key[5]) ^ key[1];
+            b2 = q(1,q(0,b2) ^ key[6]) ^ key[2];
+            b3 = q(1,q(1,b3) ^ key[7]) ^ key[3];
+    }
+
+#ifdef  M_TABLE
+
+    return  mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3);
+
+#else
+
+    b0 = q(1,b0); b1 = q(0,b1); b2 = q(1,b2); b3 = q(0,b3);
+
+    return (u4byte)(       b0  ^ ffm_ef(b1) ^ ffm_5b(b2) ^ ffm_5b(b3))       ^
+           (u4byte)(ffm_5b(b0) ^ ffm_ef(b1) ^ ffm_ef(b2) ^        b3 ) <<  8 ^
+           (u4byte)(ffm_ef(b0) ^ ffm_5b(b1) ^        b2  ^ ffm_ef(b3)) << 16 ^
+           (u4byte)(ffm_ef(b0) ^        b1  ^ ffm_ef(b2) ^ ffm_5b(b3)) << 24;
+#endif
+};
+
+#ifdef  MK_TABLE
+
+#ifdef  ONE_STEP
+u4byte  mk_tab[4][256];
+#else
+u1byte  sb[4][256];
+#endif
+
+void gen_mk_tab(u1byte key[])
+{   u1byte  b0, b1, b2, b3;
+    u4byte  i;
+
+    for(i = 0; i < 256; ++i)
+    {
+        b0 = b1 = b2 = b3 = i;
+
+        switch(k_len)
+        {
+            case 4:
+                b0 = q(1,b0) ^ key[12]; b1 = q(0,b1) ^ key[13];
+                b2 = q(0,b2) ^ key[14]; b3 = q(1,b3) ^ key[15];
+            case 3: /* fall through */
+                b0 = q(1,b0) ^ key[ 8]; b1 = q(1,b1) ^ key[ 9];
+                b2 = q(0,b2) ^ key[10]; b3 = q(0,b3) ^ key[11];
+            case 2: /* fall through */
+                b0 = q(0,q(0,b0) ^ key[4]) ^ key[0]; 
+                b1 = q(0,q(1,b1) ^ key[5]) ^ key[1]; 
+                b2 = q(1,q(0,b2) ^ key[6]) ^ key[2]; 
+                b3 = q(1,q(1,b3) ^ key[7]) ^ key[3];
+        }
+#ifdef ONE_STEP
+        mk_tab[0][i] = mds(0, b0);
+        mk_tab[1][i] = mds(1, b1);
+        mk_tab[2][i] = mds(2, b2);
+        mk_tab[3][i] = mds(3, b3);
+#else
+        sb[0][i] = b0;
+        sb[1][i] = b1;
+        sb[2][i] = b2;
+        sb[3][i] = b3;
+#endif
+    }
+};
+
+#  ifdef ONE_STEP
+#    define g0_fun(x)   mk_tab[0][byte(x,0)] ^ mk_tab[1][byte(x,1)] \
+                      ^ mk_tab[2][byte(x,2)] ^ mk_tab[3][byte(x,3)] 
+#    define g1_fun(x)   mk_tab[0][byte(x,3)] ^ mk_tab[1][byte(x,0)] \
+                      ^ mk_tab[2][byte(x,1)] ^ mk_tab[3][byte(x,2)] 
+#  else
+#    define g0_fun(x)   mds(0, sb[0][byte(x,0)]) ^ mds(1, sb[1][byte(x,1)]) \
+                      ^ mds(2, sb[2][byte(x,2)]) ^ mds(3, sb[3][byte(x,3)]) 
+#    define g1_fun(x)   mds(0, sb[0][byte(x,3)]) ^ mds(1, sb[1][byte(x,0)]) \
+                      ^ mds(2, sb[2][byte(x,1)]) ^ mds(3, sb[3][byte(x,2)]) 
+#  endif
+
+#else
+
+#define g0_fun(x)   h_fun(x,(u1byte*)s_key)
+#define g1_fun(x)   h_fun(rotl(x,8),(u1byte*)s_key)
+
+#endif
+
+/* The (12,8) Reed Soloman code has the generator polynomial
+
+  g(x) = x**4 + (a + 1/a) * x**3 + a * x**2 + (a + 1/a) * x + 1
+
+where the coefficients are in the finite field GF(2**8) with a
+modular polynomial a**8 + a**6 + a**3 + a**2 + 1. To generate the
+remainder we have to start with a 12th order polynomial with our
+eight input bytes as the coefficients of the 4th to 11th terms. 
+That is:
+
+  m[7] * x**11 + m[6] * x**10 ... + m[0] * x**4 + 0 * x**3 +... + 0
+  
+We then multiply the generator polynomial by m[7] * x**7 and subtract
+it - xor in GF(2**8) - from the above to eliminate the x**7 term (the 
+artihmetic on the coefficients is done in GF(2**8). We then multiply 
+the generator polynomial by x**6 * coeff(x**10) and use this to remove
+the x**10 term. We carry on in this way until the x**4 term is removed
+so that we are left with:
+
+  r[3] * x**3 + r[2] * x**2 + r[1] 8 x**1 + r[0]
+
+which give the resulting 4 bytes of the remainder. This is equivalent 
+to the matrix multiplication in the Twofish description but much faster 
+to implement.
+
+*/
+
+#define G_MOD   0x0000014d
+
+u4byte mds_rem(u4byte p0, u4byte p1)
+{   u4byte  i, t, u;
+
+    for(i = 0; i < 8; ++i)
+    {
+        t = p1 >> 24; 
+        
+        p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8;
+            
+        u = (t << 1) ^ (t & 0x80 ? G_MOD : 0); 
+
+        p1 ^= t ^ (u << 16);
+
+        u ^= (t >> 1) ^ (t & 0x01 ? G_MOD >> 1 : 0);
+
+        p1 ^= (u << 8) | (u << 24);
+    }
+
+    return p1;
+};
+
+/* initialise the key schedule from the user supplied key   */
+
+u4byte *set_key_twofish(const u4byte in_key[], const u4byte key_len)
+{   u4byte  i, a, b, me_key[4], mo_key[4];
+
+#ifdef Q_TABLES
+    if(!qt_gen)
+    {
+        gen_qtab(); qt_gen = 1;
+    }
+#endif
+
+#ifdef M_TABLE
+    if(!mt_gen)
+    {
+        gen_mtab(); mt_gen = 1;
+    }
+#endif
+
+    k_len = key_len / 64;   /* 2, 3 or 4 */
+
+    for(i = 0; i < k_len; ++i)
+    {
+        a = in_key[i + i];     me_key[i] = a;
+        b = in_key[i + i + 1]; mo_key[i] = b;
+        s_key[k_len - i - 1] = mds_rem(a, b);
+    }
+
+    for(i = 0; i < 40; i += 2)
+    {
+        a = 0x01010101 * i; b = a + 0x01010101;
+        a = h_fun(a, (u1byte*)me_key);
+        b = rotl(h_fun(b, (u1byte*)mo_key), 8);
+        l_key[i] = a + b;
+        l_key[i + 1] = rotl(a + 2 * b, 9);
+    }
+
+#ifdef MK_TABLE
+    gen_mk_tab((u1byte*)s_key);
+#endif
+
+    return l_key;
+};
+
+/* encrypt a block of text  */
+
+#define f_rnd(i)                                                    \
+    t0 = g0_fun(blk[0]); t1 = g1_fun(blk[1]);                       \
+    blk[2] = rotr(blk[2] ^ (t0 + t1 + l_key[4 * (i) + 8]), 1);      \
+    blk[3] = rotl(blk[3], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]);  \
+    t0 = g0_fun(blk[2]); t1 = g1_fun(blk[3]);                       \
+    blk[0] = rotr(blk[0] ^ (t0 + t1 + l_key[4 * (i) + 10]), 1);     \
+    blk[1] = rotl(blk[1], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 11])
+
+void encrypt_twofish(const u4byte in_blk[4], u4byte out_blk[])
+{   u4byte  t0, t1, blk[4];
+
+    blk[0] = in_blk[0] ^ l_key[0];
+    blk[1] = in_blk[1] ^ l_key[1];
+    blk[2] = in_blk[2] ^ l_key[2];
+    blk[3] = in_blk[3] ^ l_key[3];
+
+    f_rnd(0); f_rnd(1); f_rnd(2); f_rnd(3);
+    f_rnd(4); f_rnd(5); f_rnd(6); f_rnd(7);
+
+    out_blk[0] = blk[2] ^ l_key[4];
+    out_blk[1] = blk[3] ^ l_key[5];
+    out_blk[2] = blk[0] ^ l_key[6];
+    out_blk[3] = blk[1] ^ l_key[7]; 
+};
+
+/* decrypt a block of text  */
+
+#define i_rnd(i)                                                        \
+        t0 = g0_fun(blk[0]); t1 = g1_fun(blk[1]);                       \
+        blk[2] = rotl(blk[2], 1) ^ (t0 + t1 + l_key[4 * (i) + 10]);     \
+        blk[3] = rotr(blk[3] ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]), 1); \
+        t0 = g0_fun(blk[2]); t1 = g1_fun(blk[3]);                       \
+        blk[0] = rotl(blk[0], 1) ^ (t0 + t1 + l_key[4 * (i) +  8]);     \
+        blk[1] = rotr(blk[1] ^ (t0 + 2 * t1 + l_key[4 * (i) +  9]), 1)
+
+void decrypt_twofish(const u4byte in_blk[4], u4byte out_blk[4])
+{   u4byte  t0, t1, blk[4];
+
+    blk[0] = in_blk[0] ^ l_key[4];
+    blk[1] = in_blk[1] ^ l_key[5];
+    blk[2] = in_blk[2] ^ l_key[6];
+    blk[3] = in_blk[3] ^ l_key[7];
+
+    i_rnd(7); i_rnd(6); i_rnd(5); i_rnd(4);
+    i_rnd(3); i_rnd(2); i_rnd(1); i_rnd(0);
+
+    out_blk[0] = blk[2] ^ l_key[0];
+    out_blk[1] = blk[3] ^ l_key[1];
+    out_blk[2] = blk[0] ^ l_key[2];
+    out_blk[3] = blk[1] ^ l_key[3]; 
+};
diff -urN BitchX-clean/source/vars.c BitchXcns-1.0c19cns/source/vars.c
--- BitchX-clean/source/vars.c	Sun Mar 24 10:31:08 2002
+++ BitchXcns-1.0c19cns/source/vars.c	Fri Mar 29 07:49:24 2002
@@ -109,6 +109,7 @@
 
 static	IrcVariable irc_variable[] =
 {
+	{ "ACT_AS_KEY_SERV", 0, BOOL_TYPE_VAR, DEFAULT_ACT_AS_KEY_SERV, NULL, NULL, 0, 0 },
 	{ "AINV",0,			INT_TYPE_VAR,	DEFAULT_AINV, NULL, NULL, 0, VIF_BITCHX },
 	{ "ALTNICK",0,			STR_TYPE_VAR,	0, NULL, NULL, 0, VIF_BITCHX },
 	{ "ALT_CHARSET", 0,		BOOL_TYPE_VAR,	DEFAULT_ALT_CHARSET, NULL, NULL, 0, VIF_BITCHX },
@@ -199,6 +200,7 @@
 	{ "DCC_ULDIR",0,		STR_TYPE_VAR,	0, NULL, NULL, 0, VIF_BITCHX },
 	{ "DCC_USE_GATEWAY_ADDR",0,	BOOL_TYPE_VAR,	0, NULL, NULL, 0, VIF_BITCHX },
 	{ "DEBUG",0,			STR_TYPE_VAR,	0, NULL, debug_window, 0, 0 },
+	{ "DEFAULT_ADDED_LETTER", 0, STR_TYPE_VAR, 0, NULL, NULL, 0, 0 },
 #if defined(__EMXPM__) || defined(WIN32)
 	{ "DEFAULT_CODEPAGE",0,		INT_TYPE_VAR,	DEFAULT_CODEPAGE, NULL, NULL, 0, VIF_BITCHX },
 #endif
@@ -246,6 +248,7 @@
 	{ "HTTP_GRAB",0,		BOOL_TYPE_VAR,  DEFAULT_HTTP_GRAB, NULL, NULL, 0, VIF_BITCHX }, 
 	{ "IDENT_HACK",0,		STR_TYPE_VAR,	0, NULL, NULL, 0, VIF_BITCHX },
 	{ "IDLE_CHECK",0,		INT_TYPE_VAR,	120, NULL, NULL, 0, VIF_BITCHX },
+	{ "IGNORE_REMOTE", 0, BOOL_TYPE_VAR, DEFAULT_IGNORE_REMOTE, NULL, NULL, 0, 0 },
 	{ "IGNORE_TIME",0,		INT_TYPE_VAR,	DEFAULT_IGNORE_TIME, NULL, NULL, 0, VIF_BITCHX },
 	{ "INDENT",0,			BOOL_TYPE_VAR,	DEFAULT_INDENT, NULL, NULL, 0, 0 },
 	{ "INPUT_ALIASES",0,		BOOL_TYPE_VAR,	DEFAULT_INPUT_ALIASES, NULL, NULL, 0, 0 },
@@ -361,11 +364,13 @@
 	{ "SHELL_LIMIT",0,		INT_TYPE_VAR,	DEFAULT_SHELL_LIMIT, NULL, NULL, 0, VF_NODAEMON },
 	{ "SHITLIST",0,			BOOL_TYPE_VAR,  DEFAULT_SHITLIST, NULL, NULL, 0, VIF_BITCHX  },
 	{ "SHITLIST_REASON",0,		STR_TYPE_VAR,	0, NULL, NULL, 0, VIF_BITCHX  },
+	{ "SHOW_ALL_CNSIRC_MESSAGES", 0, BOOL_TYPE_VAR, DEFAULT_SHOW_ALL_CNSIRC_MESSAGES, NULL, NULL, 0, 0 },
 	{ "SHOW_AWAY_ONCE",0,		BOOL_TYPE_VAR,	DEFAULT_SHOW_AWAY_ONCE, NULL, NULL, 0, VIF_BITCHX },
 	{ "SHOW_CHANNEL_NAMES",0,	BOOL_TYPE_VAR,	DEFAULT_SHOW_CHANNEL_NAMES, NULL, NULL, 0, 0 },
 	{ "SHOW_END_OF_MSGS",0,		BOOL_TYPE_VAR,	DEFAULT_SHOW_END_OF_MSGS, NULL, NULL, 0, 0 },
 	{ "SHOW_NUMERICS",0,		BOOL_TYPE_VAR,	DEFAULT_SHOW_NUMERICS, NULL, NULL, 0, 0 },
 	{ "SHOW_NUMERICS_STR",0,	STR_TYPE_VAR,	0, NULL, set_numeric_string, 0, 0 },
+	{ "SHOW_RSA_KEY", 0,    BOOL_TYPE_VAR,  DEFAULT_SHOW_RSA_KEY, NULL, NULL, 0, 0 },
 	{ "SHOW_STATUS_ALL",0,		BOOL_TYPE_VAR,	DEFAULT_SHOW_STATUS_ALL, NULL, BX_update_all_status, 0, 0 },
 	{ "SHOW_WHO_HOPCOUNT",0, 	BOOL_TYPE_VAR,	DEFAULT_SHOW_WHO_HOPCOUNT, NULL, NULL, 0, 0 },
 	{ "SOCKS_HOST",0,		STR_TYPE_VAR,	0, NULL, set_use_socks, 0, VIF_BITCHX },
@@ -592,6 +597,7 @@
 	set_string_var(SHELL_VAR, DEFAULT_SHELL);
 	set_string_var(SHELL_FLAGS_VAR, DEFAULT_SHELL_FLAGS);
 #endif
+	set_string_var(DEFAULT_ADDED_LETTER_VAR, DEFAULT_DEFAULT_ADDED_LETTER);
 	set_string_var(CONTINUED_LINE_VAR, DEFAULT_CONTINUED_LINE);
 	set_string_var(INPUT_PROMPT_VAR, DEFAULT_INPUT_PROMPT);
 	set_string_var(HIGHLIGHT_CHAR_VAR, DEFAULT_HIGHLIGHT_CHAR);
