diff -uNrd cygnus-0.2.0/README.TSora cygnus-0.2.1+TSora/README.TSora
--- cygnus-0.2.0/README.TSora	Wed Dec 31 18:00:00 1969
+++ cygnus-0.2.1+TSora/README.TSora	Sun Apr 18 14:15:02 2004
@@ -0,0 +1,31 @@
+Cygnus 0.2.1 port for TSora IRCd's (ratbox/hybrid).
+
+All servers must add a shared{} block for the services so that AKILL works.
+
+For Hybrid 7.0:
+
+shared {
+  name = "services.network.tld";
+  kline = yes;
+  unkline = yes;
+};
+
+For ircd-ratbox:
+
+shared {
+  name = "services.networkd.tld";
+  type = kline, unkline;
+};
+
+Replacing the name for whatever you name your services server.
+
+If you run Hybrid 7, you MUST run the +demon patch, or AKILL's will never
+be removed.
+
+SnoopChan must be -n if the services are not joining it (like ircu).
+
+It will not forcefully take ops in the JoinChan.  If there are users in it,
+the services will join like normal users and will not be "server opped".
+
+SecuritySetting must be None on Hybrid 7 if you wish to access services when
+you are not /oper'd.
diff -uNrd cygnus-0.2.0/dist/cygnus.conf cygnus-0.2.1+TSora/dist/cygnus.conf
--- cygnus-0.2.0/dist/cygnus.conf	Fri Sep 13 12:03:17 2002
+++ cygnus-0.2.1+TSora/dist/cygnus.conf	Sun Apr 18 14:57:51 2004
@@ -40,12 +40,14 @@
 # this is not set properly, Cygnus will not work properly on your network.
 # If your IRCd is not listed below, you can try a similar IRCd, but there
 # are no gaurantees with any IRCds not listed.
-# There are 5 supported IRCds:
+# If you are running Hybrid 7 or ircd-ratbox use TSora.
+# There are 6 supported IRCds:
 #      DreamForge
 #      Prometheus
 #      Bahamut
 #      Unreal 3
 #      Unreal 3.2
+#      TSora
 # You must include any spaces shown above. For example:
 # IRCdType Unreal 3.2
 # This is required.
@@ -220,6 +222,12 @@
 
 #JoinChan #Services
 
+# Do you want to run your network in register only mode? If this is on,
+# users will be required to identify to a nickname to stay connected. They
+# will be temporarily AKilled if they do not identify in 60 seconds.
+
+#RegOnly
+
 # Do you want Cygnus to use the fake hostname assigned by Unreal? If this
 # is on, Cygnus will ignore a users real hostname and only use the fake one.
 # This option has no effect on IRCds other than Unreal.
@@ -269,7 +277,7 @@
 #     None      - Users can MSG Services any way they want.
 # Comment to disable.
 
-SecuritySetting Passwords
+SecuritySetting None
 
 # Delays: These allow you to specify how long a user must wait before
 # doing certain commands again. There are three delays:
diff -uNrd cygnus-0.2.0/doc/CHANGES cygnus-0.2.1+TSora/doc/CHANGES
--- cygnus-0.2.0/doc/CHANGES	Sat Apr  5 05:10:07 2003
+++ cygnus-0.2.1+TSora/doc/CHANGES	Fri Mar 26 21:03:35 2004
@@ -1,3 +1,22 @@
+Cygnus -- v0.2.1 - skold <skold@habber.net
+-----
+
+* Fixed NeverOp not working with linked nicks. - Reported by rakaur &
+  sycobuny
+* Fixed CS and NS register emails showing incorrect expire time for non
+  usage.
+* Fixed a null pointer crash caused by identifying from a non registered
+  nickname.
+* Users can no longer RECOVER a frozen nickname being held by NickServ.
+* Users can no longer IDENTIFY to a frozen nickname.
+* Fixed a crash resulting from frozen nicknames. - Reported by masrawy
+* Fixed a crash resulting from a server juped by services being squit.
+  - Reported by masrawy
+* Web DB is now updated after web.log is read. - Suggested by Domenic Datti
+* Fixed a bug in SET TOPIC that allowed any user to change a topic.
+  - Reported by rakaur & others
+* Users can no longer SET SUCCESSOR to a FROZEN nick. - Reported by oc5iD
+
 Cygnus -- v0.2.0 - skold <skold@habber.net>
 -----
 
diff -uNrd cygnus-0.2.0/doc/TODO cygnus-0.2.1+TSora/doc/TODO
--- cygnus-0.2.0/doc/TODO	Sat Apr  5 05:03:16 2003
+++ cygnus-0.2.1+TSora/doc/TODO	Thu Mar 11 03:37:04 2004
@@ -1,6 +1,12 @@
 These features and changes are planned for a future release. Feel free to
 provide diffs for any of these. In no particular order:
 
+* prevent sending of memos to frozen nicks, and prevent setting successor to frozen nicks
+
+* ns drop doesnt properly free successors
+
+* linked nicks in csop list?
+
 * csop/ircop level info in ns info. such as 'channels owned' 'memos stored', etc
 
 * akick is borked.
@@ -15,8 +21,6 @@
 * Add LogoImage conf option from OperStats
 
 * Drop any services nicknames on startup.
-
-* $EX token seems to be replaced with TempExpire instead of Expire
 
 * Allow CSOps to view channel and nickname access lists
 
diff -uNrd cygnus-0.2.0/inc/config.h cygnus-0.2.1+TSora/inc/config.h
--- cygnus-0.2.0/inc/config.h	Wed Aug 14 03:50:48 2002
+++ cygnus-0.2.1+TSora/inc/config.h	Sun Apr 18 14:16:36 2004
@@ -50,6 +50,7 @@
 #define BAHAMUT		3
 #define UNREAL3		4
 #define UNREAL3_2	5
+#define TSORA           6
 
 /* Do you want Cygnus to generate a core file if it crashes?
    I'd suggest you leave this option on. If you experience crashes,
diff -uNrd cygnus-0.2.0/inc/extern.h cygnus-0.2.1+TSora/inc/extern.h
--- cygnus-0.2.0/inc/extern.h	Thu Jan 30 06:49:03 2003
+++ cygnus-0.2.1+TSora/inc/extern.h	Thu Mar 11 03:37:03 2004
@@ -24,7 +24,7 @@
 E Boolean_T globalonakill_on, logupdates_on, age_on;
 E Boolean_T shareakills_on, sex_on, recoverkill_on;
 E Boolean_T name_on, location_on, privmsg_on, webint_on;
-E Boolean_T showmail_on, sendmail_on, email_on;
+E Boolean_T showmail_on, sendmail_on, email_on, regonly_on;
 E Boolean_T url_on, uin_on, memomail_on, securevop_on;
 E Boolean_T securesra_on, globalonauth_on, haveserv_on;
 E Boolean_T statglobal_on, noisyflood_on, sharesras_on;
@@ -213,6 +213,7 @@
 E void globalnoticer (User *u, char *buf);
 E void rootserv (User *u, char *buf);
 E int check_akill (const char *nick, const char *user, const char *host, const char *real);
+E AutoKill *add_akill (const char *setter, const char *mask, const char *reason, int realname, int expires);
 E void load_rs_dbase ();
 E void save_rs_dbase ();
 E void expire_akills ();
@@ -233,6 +234,7 @@
 E void cancel_user (User * u);
 E void release (NickInfo *ni, int from_timeout);
 E void collide (NickInfo *ni, int from_timeout, int recovered);
+E void regakill (User *u);
 E void expire_nicks ();
 E int islinked (const char *nick, NickInfo *ni);
 
diff -uNrd cygnus-0.2.0/inc/response.h cygnus-0.2.1+TSora/inc/response.h
--- cygnus-0.2.0/inc/response.h	Thu Dec  5 15:19:29 2002
+++ cygnus-0.2.1+TSora/inc/response.h	Thu Mar 11 03:37:03 2004
@@ -89,6 +89,7 @@
 #define RS_JUPED		"JUPEing \2%s\2 by request of \2%s\2."
 #define RS_AKILL_FORMAT		"Invalid %sAKill. The proper format is username@hostname"
 #define RS_AKILL_ADDED		"AKill on \2%s\2 successfully added."
+#define RS_AKILL_FAILED		"Failed to add AKill on \2%s\2. Please try again."
 #define RS_AKILL_ADDED_GLOBOP	"\2%s\2 %s%sAKilled \2%s\2: %s"
 #define RS_AKILL_LIST		"*** \2AKill List%s%s%s\2 ***"
 #define RS_AKILL_LIST_MATCH	"[%d] %s (%s (Expires: %s%s)) %s"
@@ -193,6 +194,7 @@
 #define NS_INFO_FLAGS		"Options      : %s"
 #define NS_INFO_END		"*** \2End of Info\2 ***"
 #define NS_KILLED_ENFORCEMENT	"NickName Enforcement"
+#define NS_KILLED_REGONLY	"You need a registered nickname to use this network"
 #define NS_ACCESS_ADDED		"\2%s\2 has been added to your \2ACCESS\2 list."
 #define NS_ACCESS_REMOVED	"\2%s\2 has been removed from your \2ACCESS\2 list."
 #define NS_ACCESS_LIST		"Listing \2ACCESS\2 entries for \2%s\2:"
@@ -203,8 +205,10 @@
 #define NS_NOT_HELD		"Nickname \2%s\2 is not being held."
 #define NS_RECOVERED		"Nickname \2%s\2 has been recovered."
 #define NS_NICK_OWNED		"Your nickname is owned by someone else. Please choose another."
+#define NS_REG_ONLY		"You need a registered nickname to use this network. Please identify for a nickname."
 #define NS_IDENTIFY		"If this is your nickname, type \2/%s%s%s%s IDENTIFY Password\2"
-#define NS_60_SECONDS		"You have \00260\002 seconds to comply or your nick will be changed."
+#define NS_TO_IDENTIFY		"To identify for a nickname, type \2/%s%s%s%s IDENTIFY Nickname Password\2"
+#define NS_60_SECONDS		"You have \00260\002 seconds to comply or %s"
 #define NS_40_SECONDS		"You have \00240\002 seconds to comply."
 #define NS_20_SECONDS		"You have \00220\002 seconds to comply. This is your last warning."
 #define NS_NICK_CHANGED		"You did not identify for this nickname, so your nickname has been changed."
diff -uNrd cygnus-0.2.0/inc/services.h cygnus-0.2.1+TSora/inc/services.h
--- cygnus-0.2.0/inc/services.h	Wed Sep  4 09:40:55 2002
+++ cygnus-0.2.1+TSora/inc/services.h	Fri Apr  2 16:03:58 2004
@@ -166,7 +166,7 @@
 #define CMODE_u		0x00400000	/* Auditorium		*/
 #define CMODE_z		0x00800000	/* Secure users only	*/
 #define CMODE_N		0x01000000	/* No nick changes	*/
-#define CMODE_L		0x02000000	/* Linked Channel	*/
+#define CMODE_L		0x02000000	/* Linked/Listed        */
 #define CMODE_A		0x04000000	/* Admin Only channel	*/
 #define CMODE_h		0x08000000	/* Half-Op		*/
 #define CMODE_a		0x10000000	/* Protected		*/
diff -uNrd cygnus-0.2.0/misc/makeconf cygnus-0.2.1+TSora/misc/makeconf
--- cygnus-0.2.0/misc/makeconf	Fri Sep 13 09:41:20 2002
+++ cygnus-0.2.1+TSora/misc/makeconf	Sun Apr 18 14:19:28 2004
@@ -174,6 +174,7 @@
 echo "    3) Bahamut"
 echo "    4) UnrealIRCd 3"
 echo "    5) UnrealIRCd 3.2"
+echo "    6) Hybrid 7/ircd-ratbox"
 while [ $ok -eq 0 ] ; do
         echo2 "[$IRCDTYPE] "
         if read INPUT ; then : ; else echo "" ; exit 1 ; fi
@@ -181,7 +182,7 @@
                 INPUT=$IRCDTYPE
         fi
         case $INPUT in
-                [1-5])
+                [1-6])
                         ok=1
                         ;;
                 *)
@@ -277,12 +278,14 @@
 # this is not set properly, Cygnus will not work properly on your network.
 # If your IRCd is not listed below, you can try a similar IRCd, but there
 # are no gaurantees with any IRCds not listed.
-# There are 5 supported IRCds:
+# If you are running Hybrid 7 or ircd-ratbox use TSora.
+# There are 6 supported IRCds:
 #      DreamForge
 #      Prometheus
 #      Bahamut
 #      Unreal 3
 #      Unreal 3.2
+#      TSora
 # You must include any spaces shown above. For example:
 # IRCdType Unreal 3.2
 # This is required.
@@ -311,6 +314,11 @@
 
 if [ "$IRCDTYPE" -eq "5" ] ; then cat <<_EOT_ >>cygnus.conf
 IRCdType Unreal 3.2
+_EOT_
+fi
+
+if [ "$IRCDTYPE" -eq "6" ] ; then cat <<_EOT_ >>cygnus.conf
+IRCdType TSora
 _EOT_
 fi
 
diff -uNrd cygnus-0.2.0/src/Makefile cygnus-0.2.1+TSora/src/Makefile
--- cygnus-0.2.0/src/Makefile	Sat Apr  5 05:09:44 2003
+++ cygnus-0.2.1+TSora/src/Makefile	Sun Apr 18 14:20:04 2004
@@ -2,7 +2,7 @@
 
 include ../Makefile.inc
 
-VERSION=0.2.0
+VERSION=0.2.1+TSora
 
 OBJS=main.o rootserv.o nickserv.o chanserv.o memoserv.o process.o socket.o function.o server.o conf.o timeout.o help.o
 
diff -uNrd cygnus-0.2.0/src/chanserv.c cygnus-0.2.1+TSora/src/chanserv.c
--- cygnus-0.2.0/src/chanserv.c	Sat Apr  5 03:46:44 2003
+++ cygnus-0.2.1+TSora/src/chanserv.c	Sun Apr 18 16:00:13 2004
@@ -1068,7 +1068,7 @@
 	id = 1;
 
     /* Allow SET TOPIC from users with topiclock access */
-    if (!stricmp (option, "TOPIC") && ci->topiclock <= ulev)
+    if (!stricmp (option, "TOPIC") && ci->topiclock && (ci->topiclock <= ulev))
 	stopic = 1;
 
     if (!id && !stopic)
@@ -1189,44 +1189,56 @@
 		    break;
 
 		case 'L':
-		    if (!(ircdtype == UNREAL3 || ircdtype == UNREAL3_2))
-			break;
-
-		    /* Only the channel founder can set +L. */
-		    if (u->idchancnt)
-			for (chans = u->idchans, i = 0; i < u->idchancnt; chans++, i++)
-			    if (!stricmp (*chans, ci->name))
-				id = 1;
-
-		    if (!id)
+			
+		    if ((ircdtype == UNREAL3 || ircdtype == UNREAL3_2))
 		    {
-			notice (s_ChanServ, u->nick, CS_IDENTIFY, ci->name, "MLock +L");
-			return;
-		    }
+			/* Only the channel founder can set +L. */
+		    	if (u->idchancnt)
+			    for (chans = u->idchans, i = 0; i < u->idchancnt; chans++, i++)
+			    	if (!stricmp (*chans, ci->name))
+				    id = 1;
 
-		    if (add)
-		    {
-			if (!(s = strtok (NULL, " ")))
+			if (!id)
 			{
-			    notice (s_ChanServ, u->nick, CS_MLOCK_NEED_PARAM, "channel", "+L");
-			    return;
-			}
+			    notice (s_ChanServ, u->nick, CS_IDENTIFY, ci->name, "MLock +L");
+		  	    return;
+		   	}
 
-			if (newlock_link)
-			    free (newlock_link);
+		    	if (add)
+		        {
+			    if (!(s = strtok (NULL, " ")))
+			    {
+			        notice (s_ChanServ, u->nick, CS_MLOCK_NEED_PARAM, "channel", "+L");
+			        return;
+			    }
 
-			newlock_link = sstrdup (s);
-			newlock_off &= ~CMODE_L;
+			    if (newlock_link)
+			        free (newlock_link);
+
+			    newlock_link = sstrdup (s);
+			    newlock_off &= ~CMODE_L;
+		        }
+		        else
+		        {
+			    if (newlock_link)
+			    {
+			        free (newlock_link);
+			        newlock_link = NULL;
+			    }
+
+			    newlock_off |= CMODE_L;
+		        }
+
+		        break;
 		    }
-		    else
+		    else if (ircdtype == BAHAMUT)
 		    {
-			if (newlock_link)
-			{
-			    free (newlock_link);
-			    newlock_link = NULL;
-			}
+			if (add)
+			   newlock_off &= ~CMODE_L;
+			else
+			   newlock_off |= CMODE_L;
 
-			newlock_off |= CMODE_L;
+			break;
 		    }
 
 		    break;
@@ -1258,7 +1270,8 @@
 	/* Registered channels are always +r. Add it to mlock on and remove it
 	   from mlock off.
 	 */
-	newlock_on |= CMODE_r, newlock_off &= ~CMODE_r;
+        if (ircdtype != TSORA)
+	    newlock_on |= CMODE_r, newlock_off &= ~CMODE_r;
 
 	/* Save it to ChanInfo. */
 	ci->mlock_on = newlock_on;
@@ -1401,6 +1414,13 @@
 	    return;
 	}
 
+	/* Check for the frozen flag */
+	if (hni->flags & NF_FROZEN)
+	{
+	    notice (s_ChanServ, u->nick, NS_NICK_FROZEN, hni->nick);
+	    return;
+	}
+
 	/* If theres already a successor, we have to do a bit of cleanup. */
 	if (ci->successor)
 	{
@@ -1655,8 +1675,13 @@
 	    strscpy (c->topic, "", TOPICLEN);
 	    strscpy (c->topicsetter, s_ChanServ, NICKLEN);
 	    c->topictime = ci->topictime = time (NULL);
-	    send_cmd (s_ChanServ, "%s %s %s %lu :", me.token ? ")" : "TOPIC", ci->name,
-		s_ChanServ, time (NULL));
+
+            if (ircdtype == TSORA)
+	        send_cmd (me.name, "%s %s %s %lu :", me.token ? ")" : "TOPIC", ci->name,
+		    s_ChanServ, time (NULL));
+            else
+                send_cmd (s_ChanServ, "%s %s %s %lu :", me.token ? ")" : "TOPIC", ci->name,
+                    s_ChanServ, time (NULL));
 
 	    notice (s_ChanServ, u->nick, RPL_REMOVED, "Your channel's \2TOPIC\2");
 	    return;
@@ -1671,8 +1696,13 @@
 		strscpy (c->topic, param, TOPICLEN);
 		strscpy (c->topicsetter, u->nick, NICKLEN);
 		c->topictime = ci->topictime = time (NULL);
-		send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name,
-		    u->nick, time (NULL), param);
+
+                if (ircdtype == TSORA)
+                    send_cmd (me.name, "%s %s %s %lu :", me.token ? ")" : "TOPIC", ci->name,
+                        s_ChanServ, time (NULL));
+                else
+                    send_cmd (s_ChanServ, "%s %s %s %lu :", me.token ? ")" : "TOPIC", ci->name,
+                        s_ChanServ, time (NULL));
 
 		notice (s_ChanServ, u->nick, RPL_ADDED, "Your channel's \2TOPIC\2", param);
 	    }
@@ -2417,7 +2447,7 @@
     /* LIST */
     if (!stricmp (option, "LIST"))
     {
-	if (ulev < VOP)
+	if ((ulev < VOP) && (!is_csop(u)))
 	{
 	    notice (s_ChanServ, u->nick, CS_ACCESS_DENIED, "VOP");
 	    return;
@@ -4488,7 +4518,7 @@
     free (ci);
 
     /* No longer registered. */
-    if (c && (c->mode & CMODE_r))
+    if (c && (c->mode & CMODE_r) && (ircdtype != TSORA))
     {
 	c->mode &= ~CMODE_r;
 	send_cmode (s_ChanServ, c->name, "-r");
@@ -5252,8 +5282,12 @@
 	strscpy (c->topicsetter, ci->topicsetter, NICKLEN);
 	c->topictime = ci->topictime;
 
-	send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name,
-	    ci->topicsetter, ci->topictime, ci->topic);
+        if (ircdtype == TSORA)
+	    send_cmd (me.name, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name,
+		ci->topicsetter, ci->topictime, ci->topic);
+        else
+  	    send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name,
+	        ci->topicsetter, ci->topictime, ci->topic);
     }
 
     /* Restore the channel modes. */
@@ -5280,7 +5314,7 @@
 
     if (!ci)
     {
-	if (c->mode & CMODE_r)
+	if ((c->mode & CMODE_r) && (ircdtype != TSORA))
 	{
 	    c->mode &= ~CMODE_r;
 	    send_cmode (s_ChanServ, c->name, "-r");
@@ -5292,7 +5326,10 @@
     if (debuglevel > 1)
 	debug ("check_modes(): %s", ci->name);
 
-    modes = ~c->mode & (ci->mlock_on | CMODE_r);
+    if (ircdtype == TSORA)
+        modes = ~c->mode & ci->mlock_on;
+    else
+        modes = ~c->mode & (ci->mlock_on | CMODE_r);
 
     end += snprintf (end, sizeof (newmodes) - (end - newmodes) - 2,
 	"+%s", flags_to_string (modes));
@@ -5471,7 +5508,10 @@
     c->topictime = now;
 
     /* Now change the topic. */
-    send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name, setter, now, topic);
+    if (ircdtype == TSORA)
+        send_cmd (me.name, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name, setter, now, topic);
+    else
+        send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", ci->name, setter, now, topic);
 }
 
 /* Return the user's access on the given channel. */
diff -uNrd cygnus-0.2.0/src/conf.c cygnus-0.2.1+TSora/src/conf.c
--- cygnus-0.2.0/src/conf.c	Sat Jan 18 17:33:03 2003
+++ cygnus-0.2.1+TSora/src/conf.c	Sun Apr 18 15:37:41 2004
@@ -23,7 +23,7 @@
 Boolean_T globalonakill_on = FALSE, logupdates_on = FALSE, age_on = FALSE;
 Boolean_T shareakills_on = FALSE, sex_on = FALSE, recoverkill_on = FALSE;
 Boolean_T name_on = FALSE, location_on = FALSE, privmsg_on = FALSE, webint_on = FALSE;
-Boolean_T showmail_on = FALSE, sendmail_on = FALSE, email_on = FALSE;
+Boolean_T showmail_on = FALSE, sendmail_on = FALSE, email_on = FALSE, regonly_on = FALSE;
 Boolean_T url_on = FALSE, uin_on = FALSE, memomail_on = FALSE, securevop_on = FALSE;
 Boolean_T securesra_on = FALSE, globalonauth_on = FALSE, haveserv_on = FALSE;
 Boolean_T statglobal_on = FALSE, noisyflood_on = FALSE, sharesras_on = FALSE;
@@ -1653,6 +1653,9 @@
 	    else if (stristr (s, "Unreal 3.2"))
 		ircdtype = UNREAL3_2;
 
+	    else if (stristr (s, "TSora"))
+		ircdtype = TSORA;
+
 	    else
 		fatal (0, "Config: Line %d: IRCdType is not set properly: Invalid value.", linecnt);
 
@@ -2011,6 +2014,18 @@
 	    continue;
 	}
 
+	if (!stricmp (item, "RegOnly"))
+	{
+	    if (debuglevel > 1)
+	    {
+		debug ("Parsing conf directive: RegOnly");
+		confin++;
+	    }
+
+	    regonly_on = TRUE;
+	    continue;
+	}
+
 	if (!stricmp (item, "UseFakeHost"))
 	{
 	    if (debuglevel > 1)
@@ -2142,7 +2157,8 @@
     if (update_timeout < 60)
 	printf ("Warning: Setting SyncTime less than 1 minute is unwise!\n");
 
-    defmlock_on |= CMODE_r;
+    if (ircdtype != TSORA)
+        defmlock_on |= CMODE_r;
 
     if (wait_restart < 5)
 	fatal (0, "Config: WaitRestart cannot be less than 5s.");
diff -uNrd cygnus-0.2.0/src/function.c cygnus-0.2.1+TSora/src/function.c
--- cygnus-0.2.0/src/function.c	Thu Jan 30 04:26:44 2003
+++ cygnus-0.2.1+TSora/src/function.c	Sun Apr 18 16:01:33 2004
@@ -241,7 +241,7 @@
     va_start (args, fmt);
     vsnprintf (buf, sizeof (buf), fmt, args);
 
-    send_cmd (sender ? sender : me.name, "%s :%s", me.token ? "]" : "GLOBOPS", buf);
+    send_cmd (sender ? sender : me.name, "%s :%s", me.token ? "]" : "OPERWALL", buf);
 }
 
 /* PRIVMSG our snooping channel */
@@ -335,8 +335,11 @@
     else
     {
 	/* Notice the first TLD */
-	send_cmd (s_GlobalNoticer, "%s $*.%s :%s", me.token ? "B" : "NOTICE",
-	    tmp, buf);
+        if (ircdtype == TSORA)
+            send_cmd (s_GlobalNoticer, "NOTICE $$*.%s :%s", tmp, buf);
+        else
+	    send_cmd (s_GlobalNoticer, "%s $*.%s :%s", me.token ? "B" : "NOTICE",
+	        tmp, buf);
         
 	/* Now run through the list and notice the remaining tlds.
 	   This will terminate when we run out of tlds..
@@ -1638,7 +1641,7 @@
     ChanInfo *ci = NULL;
     MemoInfo *mi;
     Memo *m = NULL;
-    char *email, *date, *subject, *expire, *tmpex, *pass = NULL;
+    char email[128], date[64], subject[256], expire[16], tmpex[16], pass[32];
     char cmsg[256], nmsg[256], mmsg[256], wchan[CHANNELLEN];
     char dBuf[2048], cmdbuf[512], timebuf[256], to[128], from[128];
     FILE *in, *out;
@@ -1672,6 +1675,8 @@
     if (type == 5)
 	number = atoi (param);
 
+    sprintf (tmpex, "%s", duration (tempexpire, 2));
+
     /* Get the nick we're talking to. */
     if (type == 1 || type == 2 || type == 5 || type == 6)
     {
@@ -1689,11 +1694,11 @@
 	   password.
 	 */
 	if ((nsregistertype == 1 || nsregistertype == 3 || nsregistertype == 6) && !(type == 2))
-	    pass = itoa (hni->key);
+	    sprintf (pass, "%s", itoa (hni->key));
 	else
-	    pass = hni->pass;
+	    sprintf (pass, "%s", hni->pass);
 
-	expire = duration (nick_expire, 2);
+	sprintf (expire, "%s", duration (nick_expire, 2));
     }
     else
     {
@@ -1711,11 +1716,11 @@
 	    hni = ni;
 
 	if (type == 3)
-	    pass = itoa (ci->key);
+	    sprintf (pass, "%s", itoa (ci->key));
 	else
-	    pass = ci->pass;
+	    sprintf (pass, "%s", ci->pass);
 
-	expire = duration (chan_expire, 2);
+	sprintf (expire, "%s", duration (chan_expire, 2));
 
 	chantmp = sstrdup (ci->name);
 
@@ -1759,9 +1764,9 @@
     }
 
     if (type == 6)
-	email = hni->temp;
+	sprintf (email, "%s", hni->temp);
     else
-	email = hni->email;
+	sprintf (email, "%s", hni->email);
 
     if (!validemail (email, hni->nick))
     {
@@ -1769,14 +1774,12 @@
 	return;
     }
 
-    tmpex = duration (tempexpire, 2);
-
     /* Set up the E-Mail headers */
     time (&t);
     tm = *gmtime (&t);
     strftime (timebuf, sizeof (timebuf) - 1, "%a, %d %b %Y %H:%M:%S %z", &tm);
 
-    date = timebuf;
+    sprintf (date, "%s", timebuf);
  
     if (type == 1 || type == 2 || type == 6)
 	sprintf (from, "%s <%s@%s>", s_NickServ, ns.user, ns.host);
@@ -1788,15 +1791,15 @@
     sprintf (to, "%s <%s>", hni->nick, email);
  
     if (type == 1)
-	subject = "Nickname Registration";
+	sprintf (subject, "%s", "Nickname Registration");
     else if (type == 2 || type == 4)
-	subject = "Password Retrieval";
+	sprintf (subject, "%s", "Password Retrieval");
     else if (type == 3)
-	subject = "Channel Registration";
+	sprintf (subject, "%s", "Channel Registration");
     else if (type == 5)
-	subject = "MemoMail";
+	sprintf (subject, "%s", "MemoMail");
     else
-	subject = "Change E-Mail Confirmation";
+	sprintf (subject, "%s", "Change E-Mail Confirmation");
 
     /* Now set up the E-Mail */
     sprintf (cmdbuf, "%s %s", sendmail_path, email);
@@ -1831,12 +1834,12 @@
 	replace (dBuf, sizeof (dBuf), "$NM", nmsg);
 	replace (dBuf, sizeof (dBuf), "$CM", cmsg);
 	replace (dBuf, sizeof (dBuf), "$P", pass);
+	replace (dBuf, sizeof (dBuf), "$TO", tmpex);
 	replace (dBuf, sizeof (dBuf), "$EX", expire);
 	replace (dBuf, sizeof (dBuf), "$E", email);
 	replace (dBuf, sizeof (dBuf), "$NS", s_NickServ);
 	replace (dBuf, sizeof (dBuf), "$CS", s_ChanServ);
 	replace (dBuf, sizeof (dBuf), "$MS", s_MemoServ);
-	replace (dBuf, sizeof (dBuf), "$TO", tmpex);
 	replace (dBuf, sizeof (dBuf), "$N", hni->nick);
 
 	if (hni->key)
@@ -1915,6 +1918,8 @@
 	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	    send_cmd (s_RootServ, "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		joinchan, s_RootServ);
+        else if (ircdtype == TSORA)
+	    send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL), joinchan, s_RootServ);
 	else
 	    send_cmd (s_RootServ, "%s %s", me.token ? "C" : "JOIN", joinchan);
     }
@@ -1924,6 +1929,8 @@
 	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	    send_cmd (s_NickServ, "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		joinchan, s_NickServ);
+        else if (ircdtype == TSORA)
+            send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL), joinchan, s_NickServ);
 	else
 	    send_cmd (s_NickServ, "%s %s", me.token ? "C" : "JOIN", joinchan);
     }
@@ -1933,6 +1940,8 @@
 	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	    send_cmd (s_ChanServ, "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		joinchan, s_ChanServ);
+        else if (ircdtype == TSORA)
+            send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL), joinchan, s_ChanServ);
 	else
 	    send_cmd (s_ChanServ, "%s %s", me.token ? "C" : "JOIN", joinchan);
     }
@@ -1942,6 +1951,8 @@
 	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	    send_cmd (s_MemoServ, "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		joinchan, s_MemoServ);
+        else if (ircdtype == TSORA)
+            send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL), joinchan, s_MemoServ);
 	else
 	    send_cmd (s_MemoServ, "%s %s", me.token ? "C" : "JOIN", joinchan);
     }
@@ -1951,6 +1962,8 @@
 	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	    send_cmd (s_GlobalNoticer, "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		joinchan, s_GlobalNoticer);
+        else if (ircdtype == TSORA)
+            send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL), joinchan, s_GlobalNoticer);
 	else
 	    send_cmd (s_GlobalNoticer, "%s %s", me.token ? "C" : "JOIN", joinchan);
     }
@@ -2333,8 +2346,12 @@
 		strscpy (c->topic, ci->topic, TOPICLEN);
 		c->topictime = ci->topictime;
 
-		send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
-		    c->topicsetter, c->topictime, c->topic);
+                if (ircdtype == TSORA)
+                    send_cmd (me.name, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
+                        c->topicsetter, c->topictime, c->topic);
+                else
+		    send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
+		        c->topicsetter, c->topictime, c->topic);
 	    }
 	    else
 	    {
@@ -3098,6 +3115,8 @@
 	    continue;
 	}
     }
+
+    save_web_dbase ();
 
     remove (WEB_LOG);
 }
diff -uNrd cygnus-0.2.0/src/main.c cygnus-0.2.1+TSora/src/main.c
--- cygnus-0.2.0/src/main.c	Thu Sep 26 17:11:16 2002
+++ cygnus-0.2.1+TSora/src/main.c	Sun Apr 18 14:36:40 2004
@@ -318,11 +318,14 @@
     if (ircdtype == DREAMFORGE)
 	send_cmd (NULL, "PROTOCTL TOKEN NOQUIT");
 
-    if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
-	send_cmd (NULL, "PASS %s :TS", me.pass);
+    if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS || ircdtype == TSORA)
+	send_cmd (NULL, "PASS %s TS", me.pass);
     else
 	send_cmd (NULL, "PASS :%s", me.pass);
 
+    if (ircdtype == TSORA)
+        send_cmd (NULL, "CAPAB QS KLN UNKLN");
+
     if (ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
 	send_cmd (NULL, "SERVER %s 1 :U0-*-%d %s", me.name, unreal_numeric, me.desc);
     else
@@ -334,6 +337,9 @@
 	send_cmd (NULL, "CAPAB TS3 NOQUIT");
     }
 
+    if (ircdtype == TSORA)
+        send_cmd (NULL, "SVINFO 5 3 0 :%lu", time (NULL));
+
     /* Now bring on our clients.. */
     if (rootserv_on == TRUE)
     {
@@ -376,7 +382,7 @@
     if (ircdtype == BAHAMUT)
 	bursting = 2;
 
-    if (ircdtype == PROMETHEUS || ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
+    if (ircdtype == PROMETHEUS || ircdtype == UNREAL3 || ircdtype == UNREAL3_2 || ircdtype == TSORA)
 	bursting = 1;
 
     /* Send status global if nessecary. */
@@ -445,6 +451,10 @@
     if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 	send_cmd (NULL, "NICK %s 1 %lu %s %s %s %s 0 :%s", nick, time (NULL), modes,
 	    user, host, me.name, real);
+
+    if (ircdtype == TSORA)
+        send_cmd (NULL, "NICK %s 1 %lu %s %s %s %s :%s", nick, time (NULL),
+            modes, user, host, me.name, real);
 
     if (ircdtype == DREAMFORGE)
     {
diff -uNrd cygnus-0.2.0/src/nickserv.c cygnus-0.2.1+TSora/src/nickserv.c
--- cygnus-0.2.0/src/nickserv.c	Mon Jan 20 20:11:55 2003
+++ cygnus-0.2.1+TSora/src/nickserv.c	Sun Apr 18 17:24:21 2004
@@ -179,8 +179,29 @@
        This makes services do -ra+ra sometimes, but it's easier.
      */
     if ((u->mode & UMODE_r) || (u->mode & UMODE_a))
-	send_cmd (s_NickServ, "%s %s -%s%s", me.token ? "n" : "SVSMODE", u->nick,
-	    (u->mode & UMODE_r) ? "r" : "", (u->mode & UMODE_a) ? "a" : "");
+    {
+        if (ircdtype != TSORA)
+	    send_cmd (s_NickServ, "%s %s -%s%s", me.token ? "n" : "SVSMODE", u->nick,
+	        (u->mode & UMODE_r) ? "r" : "", (u->mode & UMODE_a) ? "a" : "");
+    }
+
+    /* If we're running on a network that only allows registered nicks, tell them this
+       and start the timers to temp akill them.
+     */
+    if (regonly_on == TRUE && !get_nick (u))
+    {
+	notice (s_NickServ, u->nick, NS_REG_ONLY);
+
+	if (haveserv_on == TRUE)
+	    notice (s_NickServ, u->nick, NS_TO_IDENTIFY, "", s_NickServ, "", "");
+	else
+	    notice (s_NickServ, u->nick, NS_TO_IDENTIFY, "MSG ", s_NickServ,
+		securitysetting ? "@" : "", securitysetting ? me.name : "");
+
+	notice (s_NickServ, u->nick, NS_60_SECONDS, "you will be temporarily banned.");
+
+	regakill (u);
+    }
 
     if (!(ni = findnick (u->nick)))
 	return 0;
@@ -265,9 +286,9 @@
 	    }
 
 	/* CSOp stuff */
-	if (is_csop (u))
+	if (is_csop (u) && ircdtype != TSORA)
 	    send_cmd (s_NickServ, "%s %s +ra", me.token ? "n" : "SVSMODE", u->nick);
-	else
+	else if (ircdtype != TSORA)
 	    send_cmd (s_NickServ, "%s %s +r-a", me.token ? "n" : "SVSMODE", u->nick);
 
 	if (ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
@@ -318,7 +339,7 @@
 
     if (((hni->flags & NF_ENFORCE) && !aclev) || (hni->flags & NF_SECURE))
     {
-	notice (s_NickServ, u->nick, NS_60_SECONDS);
+	notice (s_NickServ, u->nick, NS_60_SECONDS, "your nick will be changed.");
 	add_ns_timeout (ni, TO_COLLIDE, 60);
 	add_ns_timeout (ni, TO_MESS20, 40);
 	add_ns_timeout (ni, TO_MESS40, 20);
@@ -470,7 +491,13 @@
 	    }
 	}
 
-	send_cmd (s_NickServ, "%s %s %s :%ld", me.token ? "e" : "SVSNICK", u->nick, guest, time (NULL));
+        if (ircdtype == TSORA)
+        {
+	    send_cmd (s_NickServ, "KILL %s :services!services!NickServ (Didn't identify for nickname)", u->nick);
+            delete_user(u);
+        }
+        else
+	    send_cmd (s_NickServ, "%s %s %s :%ld", me.token ? "e" : "SVSNICK", u->nick, guest, time (NULL));
     }
 
     if (!recovered)
@@ -480,6 +507,16 @@
     }
 }
 
+/* AKill the specified nickname for 5 minutes. */
+void regakill (User *u)
+{
+    char mask[BUFSIZE];
+
+    snprintf (mask, sizeof (mask), "*@%s", u->host);
+
+    add_akill (s_NickServ, mask, NS_KILLED_REGONLY, 0, 300);
+}
+
 /* Cancel validation flags for a nick (i.e. when the user with that nick
    signs off or changes nicks). Also cancels any impending collides.
  */
@@ -519,7 +556,7 @@
     if (debuglevel > 1)
 	debug ("delnick(): %s", ni->nick);
 
-    if (finduser (ni->nick))
+    if (finduser (ni->nick) && ircdtype != TSORA)
 	send_cmd (s_NickServ, "%s %s -r%s", me.token ? "n" : "SVSMODE", ni->nick,
 	    (ni->flags & NF_CSOP) ? "a" : "");
 
@@ -805,7 +842,7 @@
 	     */
 	    if ((ni->temptime && (time (NULL) >= ni->temptime + 86400)) ||
 		(!(ni->flags & NF_FROZEN) && (time (NULL) >= ni->lastseen + 86400)) ||
-		!stricmp (ni->email, ni->temp))
+		(ni->email && ni->temp && !stricmp (ni->email, ni->temp)))
 	    {
 		free (ni->temp);
 		ni->temp = NULL;
@@ -919,13 +956,14 @@
 
 		    if (is_sra (u))
 		    {
-			send_cmd (s_NickServ, "%s %s +ra", me.token ? "n" : "SVSMODE", u->nick);
+                        if (ircdtype != TSORA)
+			    send_cmd (s_NickServ, "%s %s +ra", me.token ? "n" : "SVSMODE", u->nick);
 
 			if (ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
 			    send_cmd (s_NickServ,
 				"%s %s :is a Services Root Admin", me.token ? "BA" : "SWHOIS", u->nick);
 		    }
-		    else
+		    else if (ircdtype != TSORA)
 			send_cmd (s_NickServ, "%s %s +r", me.token ? "n" : "SVSMODE", u->nick);
 		}
 
@@ -1206,7 +1244,7 @@
 		svssend ("AUTH %s", u->nick);
 	}
 
-	if (is_sra (u))
+	if (is_sra (u) && ircdtype != TSORA)
 	{
 	    send_cmd (s_NickServ, "%s %s +ra", me.token ? "n" : "SVSMODE", u->nick);
 
@@ -1214,7 +1252,7 @@
 		send_cmd (s_NickServ,
 		    "%s %s :is a Services Root Admin", me.token ? "BA" : "SWHOIS", u->nick);
 	}
-	else
+	else if (ircdtype != TSORA)
 	    send_cmd (s_NickServ, "%s %s +r", me.token ? "n" : "SVSMODE", u->nick);
     }
 
@@ -2403,6 +2441,13 @@
     else
 	hni = ni;
 
+    /* Don't let them use a frozen nick. */
+    if (hni->flags & NF_FROZEN)
+    {
+	notice (s_NickServ, u->nick, NS_NICK_FROZEN, ni->nick);
+	return;
+    }
+
     /* Check the given password against the stored one */
     if (!strcmp (pass, hni->pass))
     {
@@ -2446,12 +2491,12 @@
 	    }
 
 	/* SRA-specific stuff */
-	if (is_csop (u) && is_oper (u))
+	if (is_csop (u) && is_oper (u) && ircdtype != TSORA)
 	{
 	    send_cmd (s_NickServ, "%s %s +ra", me.token ? "n" : "SVSMODE", u->nick);
 	    u->mode |= (UMODE_r | UMODE_a);
 	}
-	else
+	else if (ircdtype != TSORA)
 	{
 	    send_cmd (s_NickServ, "%s %s +r", me.token ? "n" : "SVSMODE", u->nick);
 	    u->mode |= UMODE_r;
@@ -3594,6 +3639,13 @@
     if (strcmp (pass, hni->pass))
     {
 	passfail (s_NickServ, ni->nick, "NS:RECOVER:BP:", u);
+	return;
+    }
+
+    /* If this nickname is frozen and is being enforced, don't let them recover it. */
+    if ((ni->flags & NF_FROZEN) && (ni->status & NS_ENFORCED))
+    {
+	notice (s_NickServ, u->nick, NS_NICK_FROZEN, ni->nick);
 	return;
     }
 
diff -uNrd cygnus-0.2.0/src/process.c cygnus-0.2.1+TSora/src/process.c
--- cygnus-0.2.0/src/process.c	Thu Jan 30 04:18:23 2003
+++ cygnus-0.2.1+TSora/src/process.c	Sun Apr 18 20:35:05 2004
@@ -276,7 +276,7 @@
 	send_cmd (me.name, "%s %s %s", me.token ? "9" : "PONG",
 	    ac > 1 ? av[1] : me.name, av[0]);
 
-    if (ircdtype == BAHAMUT)
+    if (ircdtype == BAHAMUT || ircdtype == TSORA)
     {
 	/* Bahamut sends two PINGs at the end of the burst. We'll use that to figure
 	   out when it's over.
@@ -581,7 +581,7 @@
 	    int uptime = time (NULL) - me.since;
 	    int tmp = servcount ();
 
-	    send_cmd (me.name, "242 %s :Server Up %d days, %d:%02d:%02d",
+	    send_cmd (me.name, "242 %s :Services Up %d days, %d:%02d:%02d",
 		source, uptime/86400, (uptime/3600) % 24, (uptime/60) % 60,
 		uptime % 60);
 	    send_cmd (me.name,
@@ -712,8 +712,10 @@
 
     /* Bahamut, Prometheus and Unreal 3.2 only send SQUITs for the splitting server,
        not servers linked to it. So we have to free those servers and their users here.
+
+       ircd-hybrid/ratbox do the same thing via QS (quitstorm) instead of NOQUIT.
      */
-    if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS || ircdtype == UNREAL3_2)
+    if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS || ircdtype == UNREAL3_2 || ircdtype == TSORA)
     {
 	for (s = firstserv (); s; s = nextserv ())
 	{
@@ -1451,7 +1453,7 @@
     }
 
     /* Run it through flood checks */
-    if (floodmsgs)
+    if (floodmsgs && !is_csop(u))
     {
 	time_t now = time (NULL);
 
@@ -1588,6 +1590,9 @@
 		if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 		    send_cmd (me.name, "AKILL %s %s 0 %s %ld :%s", hostname,
 			username, s_RootServ, time (NULL), akill->reason);
+                else if (ircdtype == TSORA)
+                    send_cmd (s_RootServ, "KLINE * %d %s %s :%s",
+                        akill->expires, username, hostname, akill->reason);
 		else
 		    send_cmd (me.name, "%s %s %s :%s", me.token ? "V" : "AKILL",
 			hostname, username, akill->reason);
diff -uNrd cygnus-0.2.0/src/rootserv.c cygnus-0.2.1+TSora/src/rootserv.c
--- cygnus-0.2.0/src/rootserv.c	Thu Jan 30 04:24:32 2003
+++ cygnus-0.2.1+TSora/src/rootserv.c	Sun Apr 18 15:16:33 2004
@@ -677,81 +677,14 @@
 		}
 	    }
 
-	    if (akillcnt >= 32767)
-	    {
-		notice (s_RootServ, u->nick, RPL_LIST_FULL);
-		return;
-	    }
-
-	    /* Passed all the checks, now add it to the AKill list */
-	    if (akillcnt >= akill_size)
-	    {
-		if (akill_size < 8)
-		    akill_size = 8;
-		else if (akill_size >= 16384)
-		    akill_size = 32767;
-		else
-		    akill_size *= 2;
-
-		akills = srealloc (akills, sizeof (*akills) * akill_size);
-	    }
-
-	    akill = &akills[akillcnt];
-	    akill->mask = sstrdup (mask);
-	    akill->reason = sstrdup (reason);
-	    akill->setter = sstrdup (u->nick);
-	    akill->realname = realname;
-	    akill->set = time (NULL);
-	    akill->expires = expires;
-
-	    akillcnt++;
-
-	    notice (s_RootServ, u->nick, RS_AKILL_ADDED, mask);
+	    if ((akill = add_akill (u->nick, mask, reason, realname, expires)))
+		notice (s_RootServ, u->nick, RS_AKILL_ADDED, mask);
+	    else
+		notice (s_RootServ, u->nick, RS_AKILL_FAILED, mask);
 
 	    if (globalonakill_on == TRUE)
 		globops (s_RootServ, RS_AKILL_ADDED_GLOBOP, u->nick,
 		    realname ? "Realname " : "", perm ? "P" : "", mask, reason);
-
-	    /* Send it out to stats */
-	    if (strlen (operstats_server))
-		svssend ("1 %s %s %d %lu %lu %s", akill->mask, akill->setter,
-		    akill->realname, akill->set, akill->expires, akill->reason);
-
-	    if (!realname)
-	    {
-		username = sstrdup (akill->mask);
-		hostname = strchr (username, '@');
-
-		if (!hostname)
-		    return;
-
-		*hostname++ = 0;
-
-		if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
-		    send_cmd (me.name, "AKILL %s %s 0 %s %ld :%s", hostname,
-			username, s_RootServ, time (NULL), akill->reason);
-		else
-		    send_cmd (me.name, "%s %s %s :%s", me.token ? "V" : "AKILL",
-			hostname, username, akill->reason);
-
-		free (username);
-	    }
-	    else
-	    {
-		/* Hunt down any users that match this AKill. */
-		for (u = firstuser (); u; u = nextuser())
-		{
-		    if (u && match_wild_nocase (mask, u->real))
-		    {
-			if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
-			    send_cmd (me.name, "AKILL %s * 0 %s %ld :%s", u->host,
-				s_RootServ, time (NULL), akill->reason);
-			else
-			    send_cmd (me.name, "%s %s * :%s", me.token ? "V" :
-				"AKILL", u->host, akill->reason);
-		    }
-		}
-	    }
 	}
 	else
 	{
@@ -789,8 +722,12 @@
 		{
 		    *hostname++ = 0;
 
-		    send_cmd (me.name, "%s %s %s", me.token ? "Y" : "RAKILL",
-			hostname, username);
+                    if (ircdtype == TSORA)
+                        send_cmd (s_RootServ, "UNKLINE * %s %s", username,
+                            hostname);
+                    else
+                       send_cmd (me.name, "%s %s %s", me.token ? "Y" : "RAKILL",
+                           hostname, username);
 		}
 
 		/* Send it out to stats */
@@ -835,8 +772,12 @@
 		    {
 			*hostname++ = 0;
 
-			send_cmd (me.name, "%s %s %s", me.token ? "Y" :
-			    "RAKILL", hostname, username);
+                        if (ircdtype == TSORA)
+                            send_cmd (s_RootServ, "UNKLINE * %s %s", username,
+                                hostname);
+                        else
+                            send_cmd (me.name, "%s %s %s", me.token ? "Y" :
+                               "RAKILL", hostname, username);
 		    }
 
 		    /* Send it out to stats */
@@ -953,8 +894,12 @@
 		{
 		    *host++ = 0;
 
-		    send_cmd (me.name, "%s %s %s", me.token ? "Y" :
-			"RAKILL", host, user);
+                    if (ircdtype == TSORA)
+                        send_cmd (s_RootServ, "UNKLINE * %s %s", user,
+                            host);
+                    else
+                       send_cmd (me.name, "%s %s %s", me.token ? "Y" :
+                           "RAKILL", host, user);
 		}
 
 		/* Send it out to stats */
@@ -1025,6 +970,91 @@
     return 0;
 }
 
+/* Add an akill with the given information. Return the akill if successfull, null otherwise */
+AutoKill *add_akill (const char *setter, const char *mask, const char *reason, int realname, int expires)
+{
+    AutoKill *akill;
+    User *u;
+    char *username, *hostname;
+
+    if (akillcnt >= 32767)
+    {
+	notice (s_RootServ, setter, RPL_LIST_FULL);
+	return 0;
+    }
+
+    if (akillcnt >= akill_size)
+    {
+	if (akill_size < 8)
+	    akill_size = 8;
+	else if (akill_size >= 16384)
+	    akill_size = 32767;
+	else
+	    akill_size *= 2;
+
+	akills = srealloc (akills, sizeof (*akills) * akill_size);
+    }
+
+    akill = &akills[akillcnt];
+    akill->mask = sstrdup (mask);
+    akill->reason = sstrdup (reason);
+    akill->setter = sstrdup (setter);
+    akill->realname = realname;
+    akill->set = time (NULL);
+    akill->expires = expires;
+
+    akillcnt++;
+
+    /* Send it out to stats */
+    if (strlen (operstats_server))
+	svssend ("1 %s %s %d %lu %lu %s", akill->mask, akill->setter,
+	    akill->realname, akill->set, akill->expires, akill->reason);
+
+    if (!realname)
+    {
+	username = sstrdup (akill->mask);
+	hostname = strchr (username, '@');
+
+	if (!hostname)
+	    return 0;
+
+	*hostname++ = 0;
+
+	if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
+	    send_cmd (me.name, "AKILL %s %s 0 %s %ld :%s", hostname,
+		username, s_RootServ, time (NULL), akill->reason);
+        else if (ircdtype == TSORA)
+            send_cmd (s_RootServ, "KLINE * %d %s %s :%s",
+                akill->expires, username, hostname, akill->reason);
+	else
+	    send_cmd (me.name, "%s %s %s :%s", me.token ? "V" : "AKILL",
+		hostname, username, akill->reason);
+
+	free (username);
+    }
+    else
+    {
+	/* Hunt down any users that match this AKill. */
+	for (u = firstuser (); u; u = nextuser())
+	{
+	    if (u && match_wild_nocase (mask, u->real))
+	    {
+		if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
+		    send_cmd (me.name, "AKILL %s * 0 %s %ld :%s", u->host,
+			s_RootServ, time (NULL), akill->reason);
+                else if (ircdtype == TSORA)
+                    send_cmd (s_RootServ, "KLINE * %d * %s :%s",
+                        akill->expires, u->host, akill->reason);
+		else
+		    send_cmd (me.name, "%s %s * :%s", me.token ? "V" :
+			"AKILL", u->host, akill->reason);
+	    }
+	}
+    }
+
+    return akill;
+}
+
 /* Display the list of clones on the network */
 static void do_clones (User *u)
 {
@@ -1487,7 +1517,7 @@
 	    notice (s_RootServ, u->nick, RS_CSOP_ADDDEL, ni->nick, "w");
 
 	    /* Set the +a flag if this person is online and identified */
-	    if ((utmp = finduser (ni->nick)) && (u->lastnick == ni->nick))
+	    if ((utmp = finduser (ni->nick)) && (u->lastnick == ni->nick) && ircdtype != TSORA)
 		send_cmd (s_RootServ, "%s %s +a", me.token ? "n" : "SVSMODE", utmp->nick);
 
 	    return;
@@ -1523,7 +1553,7 @@
 			notice (s_RootServ, u->nick, RS_CSOP_ADDDEL, ni->nick, " longer");
 
 			/* Remove the +a flag if this person is online. */
-			if ((utmp = finduser (ni->nick)))
+			if ((utmp = finduser (ni->nick)) && ircdtype != TSORA)
 			    send_cmd (s_RootServ, "%s %s -a", me.token ? "n" : "SVSMODE", utmp->nick);
 
 			return;
@@ -1546,7 +1576,7 @@
 	    notice (s_RootServ, u->nick, RS_CSOP_ADDDEL, ni->nick, " longer");
 
 	    /* Set the +a flag if this person is online and identified */
-	    if ((utmp = finduser (ni->nick)) && (u->lastnick == ni->nick))
+	    if ((utmp = finduser (ni->nick)) && (u->lastnick == ni->nick) && ircdtype != TSORA)
 		send_cmd (s_RootServ, "%s %s -a", me.token ? "n" : "SVSMODE", utmp->nick);
 
 	    return;
diff -uNrd cygnus-0.2.0/src/server.c cygnus-0.2.1+TSora/src/server.c
--- cygnus-0.2.0/src/server.c	Fri Apr  4 16:52:39 2003
+++ cygnus-0.2.1+TSora/src/server.c	Sun Apr 18 20:35:52 2004
@@ -116,6 +116,10 @@
 /* Delete a server. */
 void delete_server (Server *server)
 {
+    /* Bail out here if theres no server structure (ie, a jupe) */
+    if (!server)
+	return;
+
     if (debuglevel > 1)
 	debug ("delete_server(): %s", server->name);
 
@@ -269,6 +273,9 @@
 		if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 		    send_cmd (me.name, "AKILL %s * 0 %s %ld :%s", u->host,
 			s_RootServ, time (NULL), akill->reason);
+                else if (ircdtype == TSORA)
+                    send_cmd (s_RootServ, "KLINE * %d * %s :%s",
+                        akill->expires, u->host, akill->reason);
 		else
 		    send_cmd (me.name, "%s %s * :%s", me.token ? "V" : "AKILL",
 			u->host, akill->reason);
@@ -417,6 +424,11 @@
 	    if (check_akill (av[0], av[4], av[5], av[8]))
 		return;
 	}
+        if (ircdtype == TSORA)
+        {
+            if (check_akill (av[0], av[4], av[5], av[7]))
+                return;
+        }
 	else
 	{
 	    if (check_akill (av[0], av[3], av[4], av[7]))
@@ -438,6 +450,16 @@
 	    av[1] = av[3];
 	    do_umode (av[0], 2, av);
 	}
+        else if (ircdtype == TSORA)
+        {
+            user->user = sstrdup (av[4]);
+            user->host = sstrdup (av[5]);
+            user->server = sstrdup (av[6]);
+            user->real = sstrdup (av[7]);
+
+            av[1] = av[3];
+            do_umode (av[0], 2, av);
+        }
 	else if (ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
 	{
 	    user->user = sstrdup (av[3]);
@@ -478,7 +500,8 @@
 
 	    user->sstamp = sstamp;
 
-	    send_cmd (me.name, "%s %s +d %u", me.token ? "n" : "SVSMODE", user->nick, sstamp);
+            if (ircdtype != TSORA)
+	        send_cmd (me.name, "%s %s +d %u", me.token ? "n" : "SVSMODE", user->nick, sstamp);
 	}
 	else
 	{
@@ -624,12 +647,16 @@
 		    if (add)
 		    {
 			user->mode |= UMODE_a;
-			send_cmd (s_NickServ, "%s %s +a", me.token ? "n" : "SVSMODE", user->nick);
+
+			if (ircdtype != TSORA)
+			   send_cmd (s_NickServ, "%s %s +a", me.token ? "n" : "SVSMODE", user->nick);
 		    }
 		    else
 		    {
 			user->mode &= ~UMODE_a;
-			send_cmd (s_NickServ, "%s %s -a", me.token ? "n" : "SVSMODE", user->nick);
+
+			if (ircdtype != TSORA)
+			    send_cmd (s_NickServ, "%s %s -a", me.token ? "n" : "SVSMODE", user->nick);
 		    }
 		}
 
@@ -949,11 +976,11 @@
 		break;
 
 	    case 'L':
-		if (--ac < 0)
-		    break;
-
 		if (ircdtype == UNREAL3 || ircdtype == UNREAL3_2)
 		{
+		    if (--ac < 0)
+			break;
+
 		    if (chan->link)
 		    {   
 			free (chan->link);
@@ -1222,6 +1249,9 @@
 	    if (ircdtype == BAHAMUT || ircdtype == PROMETHEUS)
 		send_cmd (av[1], "SJOIN %ld %ld %s + :%s", time (NULL), time (NULL),
 		    joinchan, av[1]);
+            else if (ircdtype == TSORA)
+                send_cmd (me.name, "SJOIN %ld %s + :@%s", time (NULL),
+                    joinchan, av[1]);
 	    else
 		send_cmd (av[1], "%s %s", me.token ? "C" : "JOIN", joinchan);
 
@@ -1342,7 +1372,7 @@
     Channel *c = findchan (chan);
     ChanInfo *ci = cs_findchan (chan);
     Channel **list;
-    NickInfo *ni;
+    NickInfo *ni, *hni;
     int ulev = 0, newchan = !c;
     struct c_userlist *u;
 
@@ -1440,9 +1470,14 @@
 	    return c;
 	}
 
-	ni = findnick (user->nick);
+	ni = get_nick (user);
 
-	if (!ni)
+	if (ni->host)
+	    hni = findnick (ni->host);
+	else
+	    hni = ni;
+
+	if (!hni)
 	{
 	    /* If their nick isn't registered, well, they shouldn't be in here! :P */
 	    return c;
@@ -1469,7 +1504,7 @@
 		}
 	    }
 
-	    if (!(u->mode & CMODE_v) && !(ni->flags & NF_NEVEROP))
+	    if (!(u->mode & CMODE_v) && !(hni->flags & NF_NEVEROP))
 	    {
 		send_cmode (s_ChanServ, c->name, "+v", user->nick);
 		u->mode |= CMODE_v;
@@ -1487,7 +1522,7 @@
 		    u->mode &= ~CMODE_o;
 		}
 
-		if (!(u->mode & CMODE_h) && !(ni->flags & NF_NEVEROP))
+		if (!(u->mode & CMODE_h) && !(hni->flags & NF_NEVEROP))
 		{
 		    send_cmode (s_ChanServ, c->name, "+h", user->nick);
 		    u->mode |= CMODE_h;
@@ -1498,7 +1533,7 @@
 	/* AOP, SOP, Founder, +o */
 	if (ulev >= AOP)
 	{
-	    if (!(ni->flags & NF_NEVEROP))
+	    if (!(hni->flags & NF_NEVEROP))
 	    {
 		send_cmode (s_ChanServ, c->name, "+o", user->nick);
 		u->mode |= CMODE_o;
@@ -1619,8 +1654,13 @@
 	    strscpy (c->topic, ci->topic, TOPICLEN);
 	    c->topictime = ci->topictime;
 
-	    send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
-		c->topicsetter, c->topictime, c->topic);
+            if (ircdtype == TSORA)
+                send_cmd (me.name, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
+                    c->topicsetter, c->topictime, c->topic);
+
+            else
+	        send_cmd (s_ChanServ, "%s %s %s %lu :%s", me.token ? ")" : "TOPIC", c->name,
+		    c->topicsetter, c->topictime, c->topic);
 
 	    return;
 	}
@@ -1720,6 +1760,13 @@
         Bahamut SSJOIN format (client source):
             av[0] = TS3 timestamp
             av[1] = channel
+        TSora SJOIN format:
+            av[0] = TS5 timestamp
+            av[1] = channel
+            av[2] = channel modes
+            av[3] = limit / key (depends on modes in av[2])
+            av[4] = limit / key (depends on modes in av[2])
+            av[ac-1] = nickname(s), with modes, joining channel
  */
 void do_sjoin (const char *source, int8 ac, char **av)
 {
diff -uNrd cygnus-0.2.0/src/socket.c cygnus-0.2.1+TSora/src/socket.c
--- cygnus-0.2.0/src/socket.c	Thu Sep 26 17:11:56 2002
+++ cygnus-0.2.1+TSora/src/socket.c	Sun Apr 18 14:47:34 2004
@@ -170,8 +170,6 @@
     va_start (args, fmt);
     vsnprintf (buf, BUFSIZE, fmt, args);
 
-    sstrlcat (buf, "\n", BUFSIZE);
-
     if ((write (servsock, buf, strlen (buf))) == -1)
     {
 	log (RPL_WRITE_ERROR);
diff -uNrd cygnus-0.2.0/src/version.sh cygnus-0.2.1+TSora/src/version.sh
--- cygnus-0.2.0/src/version.sh	Mon Aug  5 18:33:57 2002
+++ cygnus-0.2.1+TSora/src/version.sh	Sun Apr 18 14:48:40 2004
@@ -35,6 +35,7 @@
 #ifdef WIN32
     "Ported to Win32 by Matthew Millman <matthew.m@ihug.co.nz>",
 #endif
+    "+TSora patch by Eric Will <rakaur@malkier.net>",
     " ",
     "All rights reserved.",
     " ",
@@ -66,7 +67,7 @@
     "The following people have donated money or hardware to the developer:",
     " ",
     "madragoran         Mike Campbell      madragoran@avendesora.net",
-    "Lan                Eric Will          daishan@malkier.net",
+    "rakaur             Eric Will          rakaur@malkier.net",
     " ",
     0,
 };
