diff -ur irc2.10.3p6/common/struct_def.h irc2.10.3p6+noos/common/struct_def.h
--- irc2.10.3p6/common/struct_def.h	Mon May 14 14:02:08 2001
+++ irc2.10.3p6+noos/common/struct_def.h	Thu May  6 23:04:41 2004
@@ -166,6 +166,11 @@
 #define	FLAGS_ZIP      0x400000 /* link is zipped */
 #define	FLAGS_ZIPRQ    0x800000 /* zip requested */
 #define	FLAGS_ZIPSTART 0x1000000 /* start of zip (ignore any CRLF) */
+
+#ifdef SPLIT_HANDLE
+#define FLAGS_EOBWAIT  0x2000000 /* waiting for EOB */
+#endif
+
 #define	FLAGS_HELD     0x8000000 /* connection held and reconnect try */
 
 #define	FLAGS_OPER       0x0001	/* Operator */
@@ -222,6 +227,12 @@
 #define	ClearXAuth(x)		((x)->flags &= ~FLAGS_XAUTH)
 #define	ClearWXAuth(x)		((x)->flags &= ~FLAGS_WXAUTH)
 
+#ifdef SPLIT_HANDLE
+#define SetBurst(x)            ((x)->flags |= FLAGS_EOBWAIT)
+#define ClearBurst(x)          ((x)->flags &= ~FLAGS_EOBWAIT)
+#define IsBurst(x)             ((x)->flags & FLAGS_EOBWAIT)
+#endif
+
 /*
  * defined debugging levels
  */
@@ -531,6 +542,16 @@
 	u_long	bytes;
 };
 
+#ifdef SPLIT_HANDLE
+#define SET_TYPE_INT 0
+#define SET_TYPE_STRING 1
+struct Set_Message {
+       char *cmd;
+       int *value;
+       char **values;
+};
+#endif
+
 #define	MSG_LAG		0x0001
 #define	MSG_NOU		0x0002	/* Not available to users */
 #define	MSG_SVC		0x0004	/* Services only */
@@ -715,7 +736,14 @@
 	u_int	is_dbufmin;	/* min number of dbuf in use */
 	u_int	is_dbufmax;	/* max number of dbuf in use */
 	u_int	is_dbufmore;	/* how many times we increased the bufferpool*/
+#ifdef SPLIT_HANDLE
+        u_long  is_eobservers;  /* # of servers which sent EOB */
+#endif
 } istat_t;
+
+typedef struct {
+       u_int split;
+} iconf_t;
 
 /* String manipulation macros */
 
Only in irc2.10.3p6+noos/common: struct_def.h.orig
diff -ur irc2.10.3p6/common/support.c irc2.10.3p6+noos/common/support.c
--- irc2.10.3p6/common/support.c	Thu May 31 16:00:02 2001
+++ irc2.10.3p6+noos/common/support.c	Thu May  6 23:04:41 2004
@@ -861,6 +861,7 @@
 		sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv);
 	if (pl)	/* patchlevel */
 		sprintf(ver + strlen(ver), "p%d", pl);
+	strcat(ver,"+noos");
 	return mystrdup(ver);
 }
 
Only in irc2.10.3p6+noos/common: support.c.orig
diff -ur irc2.10.3p6/ircd/channel.c irc2.10.3p6+noos/ircd/channel.c
--- irc2.10.3p6/ircd/channel.c	Wed Feb 25 17:47:41 2004
+++ irc2.10.3p6+noos/ircd/channel.c	Thu May  6 23:04:41 2004
@@ -2247,9 +2247,24 @@
 		*/
 		flags = 0;
 		chop[0] = '\0';
-		if (MyConnect(sptr) && UseModes(name) &&
-		    (!IsRestricted(sptr) || (*name == '&')) && !chptr->users &&
-		    !(chptr->history && *chptr->chname == '!'))
+#ifdef SPLIT_HANDLE
+                if (MyConnect(sptr) && UseModes(name) &&
+                   ((*name != '#') || !iconf.split) &&
+#else
+                if (
+                        MyConnect(sptr) &&
+                        UseModes(name) &&
+#endif
+                    (
+                         !IsRestricted(sptr) ||
+                         (*name == '&')
+                        ) &&
+                        !chptr->users &&
+                    !(
+                         chptr->history &&
+                         *chptr->chname == '!'
+                    )
+                   )
 		    {
 			if (*name == '!')
 				strcpy(chop, "\007O");
Only in irc2.10.3p6+noos/ircd: channel.c.orig
diff -ur irc2.10.3p6/ircd/ircd.c irc2.10.3p6+noos/ircd/ircd.c
--- irc2.10.3p6/ircd/ircd.c	Sat Oct 11 19:13:03 2003
+++ irc2.10.3p6+noos/ircd/ircd.c	Thu May  6 23:04:42 2004
@@ -34,6 +34,7 @@
 static	void	open_debugfile(), setup_signals(), io_loop();
 
 istat_t	istat;
+iconf_t iconf;
 char	**myargv;
 int	rehashed = 0;
 int	portnum = -1;		    /* Server port number, listening this */
Only in irc2.10.3p6+noos/ircd: ircd.c.orig
diff -ur irc2.10.3p6/ircd/ircd_ext.h irc2.10.3p6+noos/ircd/ircd_ext.h
--- irc2.10.3p6/ircd/ircd_ext.h	Fri Feb 12 05:00:47 1999
+++ irc2.10.3p6+noos/ircd/ircd_ext.h	Thu May  6 23:04:42 2004
@@ -27,6 +27,7 @@
 extern aClient me;
 extern aClient *client;
 extern istat_t istat;
+extern iconf_t iconf;
 extern char **myargv;
 extern int rehashed;
 extern int portnum;
Only in irc2.10.3p6+noos/ircd: ircd_ext.h.orig
diff -ur irc2.10.3p6/ircd/s_debug.c irc2.10.3p6+noos/ircd/s_debug.c
--- irc2.10.3p6/ircd/s_debug.c	Fri Oct 19 20:44:27 2001
+++ irc2.10.3p6+noos/ircd/s_debug.c	Thu May  6 23:04:42 2004
@@ -358,6 +358,12 @@
 		   -1, -1
 #endif
 		   );
+#ifdef SPLIT_HANDLE
+	sendto_one(cptr, ":%s %d %s :noos: Split Servers: %d (%d) Users: %d",
+                   ME, RPL_STATSDEFINE,nick,SPLIT_SERV, istat.is_eobservers,
+		   SPLIT_USERS);
+#endif
+
 }
 
 void	count_memory(cptr, nick, debug)
Only in irc2.10.3p6+noos/ircd: s_debug.c.orig
diff -ur irc2.10.3p6/ircd/s_misc.c irc2.10.3p6+noos/ircd/s_misc.c
--- irc2.10.3p6/ircd/s_misc.c	Fri Oct 19 20:44:27 2001
+++ irc2.10.3p6+noos/ircd/s_misc.c	Thu May  6 23:04:42 2004
@@ -504,6 +504,15 @@
 				    }
 			    }
 		    } /* If (IsServer(sptr)) */
+#ifdef SPLIT_HANDLE
+                if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV)
+                {
+                        if (!iconf.split)
+                        {
+                                check_split();
+                        }
+                }
+#endif
 	    } /* if (MyConnect(sptr) || (sptr->flags & FLAGS_HELD)) */
 
  	if (IsServer(sptr) && GotDependantClient(sptr))
@@ -531,6 +540,15 @@
  			acptr->flags |= flags;
 			exit_one_client(cptr, acptr, &me, comment1);
  		}
+#ifdef SPLIT_HANDLE
+                if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV)
+                {
+                        if (!iconf.split)
+                        {
+                                check_split();
+                        }
+                }
+#endif
  	}
  	
 	/*
@@ -577,6 +595,15 @@
 			    cptr->name, comment);
 	
 	exit_one_client(cptr, sptr, from, (*comment1) ? comment1 : comment);
+#ifdef SPLIT_HANDLE
+                if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV)
+                {
+                        if (!iconf.split)
+                        {
+                                check_split();
+                        }
+                }
+#endif
 	return cptr == sptr ? FLUSH_BUFFER : 0;
     }
 
@@ -611,6 +638,12 @@
 	 ** (domain name matching)
 	 */
 		istat.is_serv--;
+#ifdef SPLIT_HANDLE
+               if (!IsBurst(sptr))
+               {
+                       istat.is_eobservers--;
+               }
+#endif
 	 	for (i = fdas.highest; i >= 0; i--)
 		    {
 			Reg	aConfItem *aconf;
@@ -825,6 +858,8 @@
 	istat.is_serv = 1;
 	istat.is_remc = 1;	/* don't ask me why, I forgot. */
 	bzero((char *)&ircst, sizeof(ircst));
+        bzero((char *)&iconf, sizeof(iconf));
+        iconf.split = 1;
 }
 
 void	tstats(cptr, name)
@@ -985,4 +1020,51 @@
 	(void)dgets(-1, NULL, 0); /* make sure buffer is at empty pos */
 	close(fd);
 }     
+#endif
+
+#ifdef SPLIT_HANDLE
+void check_split()
+{
+        if (istat.is_eobservers < SPLIT_SERV ||
+           (istat.is_user[0] + istat.is_user[1] < SPLIT_USERS))
+        {
+                if (!iconf.split)
+                {
+                        sendto_flag(SCH_NOTICE,"Network split detected, split mode activated");
+                }
+                iconf.split = 1;
+        }
+        else
+        {
+                if (iconf.split)
+                {
+                        sendto_flag(SCH_NOTICE,"Network rejoined, split mode deactivated");
+                }
+                iconf.split = 0;
+ 
+        }
+
+}
+void bubble_eob(sptr)
+aClient *sptr;
+{
+        aClient *acptr = sptr;
+        char *up = sptr->serv->up;
+        while (up && mycmp(up,me.name))
+        {
+                up = acptr->serv->up;
+                acptr = find_server(up,NULL);
+                if (!acptr)
+                {
+                         sendto_flag(SCH_ERROR,"Unknown uplink %s while bubbling EOB ?!",up);
+                        break;
+                }
+                if (IsBurst(acptr))
+                {
+                        ClearBurst(acptr);
+                        istat.is_eobservers++;
+                        sendto_flag(SCH_DEBUG,"EOB from %s (bubbled)",up);
+                }
+        }
+}
 #endif
Only in irc2.10.3p6+noos/ircd: s_misc.c.orig
diff -ur irc2.10.3p6/ircd/s_misc_ext.h irc2.10.3p6+noos/ircd/s_misc_ext.h
--- irc2.10.3p6/ircd/s_misc_ext.h	Mon Aug  3 16:09:23 1998
+++ irc2.10.3p6+noos/ircd/s_misc_ext.h	Thu May  6 23:04:42 2004
@@ -55,4 +55,8 @@
 #ifdef  CACHED_MOTD
 EXTERN void read_motd __P((char *filename));
 #endif /* CACHED_MOTD */
+#ifdef SPLIT_HANDLE
+EXTERN void check_split();
+EXTERN void bubble_eob __P((aClient *sptr));
+#endif
 #undef EXTERN
Only in irc2.10.3p6+noos/ircd: s_misc_ext.h.orig
diff -ur irc2.10.3p6/ircd/s_numeric.c irc2.10.3p6+noos/ircd/s_numeric.c
--- irc2.10.3p6/ircd/s_numeric.c	Sun Dec 13 00:48:17 1998
+++ irc2.10.3p6+noos/ircd/s_numeric.c	Thu May  6 23:04:42 2004
@@ -96,11 +96,27 @@
 			** - Avalon
 			*/
 			if (IsMe(acptr) || acptr->from == cptr)
+                        {
+#ifdef SPLIT_HANDLE
+                                if (IsServer(sptr) && IsBurst(sptr) &&
+                                        numeric == ERR_NOSUCHSERVER)
+                                {    /* we got EOB-emulation reply */
+                                        ClearBurst(sptr);
+                                        sendto_flag(SCH_DEBUG,"End of burst from %s (emulated)",sptr->name);
+                                        istat.is_eobservers++;
+                                        bubble_eob(sptr);
+                                        check_split();
+                                }
+                                else
+#endif
+                                {
 				sendto_flag(SCH_NUM,
 					    "From %s for %s: %s %d %s %s.",
 					    get_client_name(cptr, TRUE),
 					    acptr->name, sptr->name,
 					    numeric, nick, buffer);
+				}
+			}
 			else if (IsPerson(acptr) || IsServer(acptr) ||
 				 IsService(acptr))
 				sendto_prefix_one(acptr, sptr,":%s %d %s%s",
Only in irc2.10.3p6+noos/ircd: s_numeric.c.orig
diff -ur irc2.10.3p6/ircd/s_serv.c irc2.10.3p6+noos/ircd/s_serv.c
--- irc2.10.3p6/ircd/s_serv.c	Wed Apr 14 18:49:13 2004
+++ irc2.10.3p6+noos/ircd/s_serv.c	Thu May  6 23:04:42 2004
@@ -610,6 +610,12 @@
 		acptr->serv->snum = find_server_num(acptr->name);
 		SetServer(acptr);
 		istat.is_serv++;
+#ifdef         SPLIT_HANDLE
+                SetBurst(acptr);
+                sendto_one(cptr,":%s PING %s :%s",my_name_for_link(ME,cptr->serv->nline->port),
+                        my_name_for_link(ME,cptr->serv->nline->port),
+                        acptr->name);
+#endif
 		add_client_to_list(acptr);
 		(void)add_to_client_hash_table(acptr->name, acptr);
 		(void)add_to_server_hash_table(acptr->serv, cptr);
@@ -857,6 +863,9 @@
 	**	code is more neat this way...  --msa
 	*/
 	SetServer(cptr);
+#ifdef SPLIT_HANDLE
+        SetBurst(cptr);
+#endif
 	istat.is_unknown--;
 	istat.is_serv++;
 	istat.is_myserv++;
@@ -1004,7 +1013,10 @@
 				send_channel_modes(cptr, chptr);
 			    }
 	    }
-
+#ifdef SPLIT_HANDLE
+        /* send PING- emulate EOB */
+        sendto_one(cptr,":%s PING %s %s",my_name_for_link(ME, aconf->port),my_name_for_link(ME, aconf->port),cptr->name);
+#endif
 	cptr->flags &= ~FLAGS_CBURST;
 #ifdef	ZIP_LINKS
  	/*
diff -ur irc2.10.3p6/ircd/s_serv.c.orig irc2.10.3p6+noos/ircd/s_serv.c.orig
--- irc2.10.3p6/ircd/s_serv.c.orig	Thu Feb 26 14:28:41 2004
+++ irc2.10.3p6+noos/ircd/s_serv.c.orig	Wed Apr 14 18:49:13 2004
@@ -22,7 +22,7 @@
  */
 
 #ifndef lint
-static  char rcsid[] = "@(#)$Id: s_serv.c,v 1.65.2.11 2004/02/26 13:28:41 chopin Exp $";
+static  char rcsid[] = "@(#)$Id: s_serv.c,v 1.65.2.13 2004/03/01 18:00:33 chopin Exp $";
 #endif
 
 #include "os.h"
@@ -123,7 +123,8 @@
 	Reg	aConfItem *aconf;
 	char	*server;
 	Reg	aClient	*acptr;
-	char	*comment = (parc > 2 && parv[2]) ? parv[2] : cptr->name;
+	char	*comment = (parc > 2 && parv[2]) ? parv[2] : "no reason";
+	static char	comment2[TOPICLEN+1];
 
 	if (parc > 1)
 	    {
@@ -212,12 +213,18 @@
 	    }
 	if (MyPerson(sptr))
 	{
-		char bufn[HOSTLEN+7];
+		int	k=TOPICLEN-strlen(sptr->name)-7;
 
-		sprintf(bufn, " (by %s)", sptr->name);
-		if (strlen(comment) > TOPICLEN)
-			comment[TOPICLEN] = '\0';
-		strcat(comment, bufn);
+		/* Shorten original comment, should it be too long. */
+		if (strlen(comment) > k)
+		{
+			comment[k] = '\0';
+		}
+		/* As we change comment, we have to copy, who knows what
+		** parv[2] can overwrite. */
+		comment2[0] = '\0';
+		sprintf(comment2, "%s (by %s)", comment, sptr->name);
+		comment = comment2;
 	}
 	if (!MyConnect(acptr) && (cptr != acptr->from))
 	    {
diff -ur irc2.10.3p6/ircd/s_user.c irc2.10.3p6+noos/ircd/s_user.c
--- irc2.10.3p6/ircd/s_user.c	Thu Feb 26 19:00:59 2004
+++ irc2.10.3p6+noos/ircd/s_user.c	Thu May  6 23:04:42 2004
@@ -632,6 +632,12 @@
 		istat.is_user[1]++;	/* Local and server defaults +i */
 	else
 		istat.is_user[0]++;
+#ifdef SPLIT_HANDLE
+        if (istat.is_user[1] + istat.is_user[0] >= SPLIT_USERS)
+        {
+                check_split();
+        }
+#endif
 	if (MyConnect(sptr))
 	    {
 		istat.is_unknown--;
@@ -650,6 +656,12 @@
 		if (IsRestricted(sptr))
 			sendto_one(sptr, err_str(ERR_RESTRICTED, nick));
 		send_umode(sptr, sptr, 0, ALL_UMODES, buf);
+#ifdef SPLIT_HANDLE
+                if (iconf.split)
+                {
+                        sendto_one(sptr,":%s NOTICE %s :Server is currently in split-mode. You will NOT get channel operator status on new channels.",ME,nick);
+                }
+#endif
 		nextping = timeofday;
 	    }
 #ifdef	USE_SERVICES
@@ -2336,6 +2348,30 @@
 	cptr->flags &= ~FLAGS_PINGSENT;
 	sptr->flags &= ~FLAGS_PINGSENT;
 
+#ifdef SPLIT_HANDLE
+        if (IsServer(cptr) && IsServer(sptr) && (BadPtr(destination) || !match(destination,ME)))
+        {
+                if (IsBurst(sptr))
+                {
+                        ClearBurst(sptr);
+                        istat.is_eobservers++;
+                        if (MyConnect(sptr))
+                        {
+                                sendto_flag(SCH_NOTICE,"End of burst from %s. Lasted %d seconds.",
+                                        cptr->name,timeofday - cptr->firsttime);
+                        }
+                        else
+                        {
+                                sendto_flag(SCH_DEBUG,"EOB from %s (PONG)",sptr->name);
+                        }
+                        bubble_eob(sptr);
+                        if (iconf.split)
+                        {
+                                check_split();
+                        }
+                }
+        }
+#endif
 	if (!BadPtr(destination) && mycmp(destination, ME) != 0)
 	    {
 		if ((acptr = find_client(destination, NULL)) ||
Only in irc2.10.3p6+noos/ircd: s_user.c.orig
diff -ur irc2.10.3p6/support/config.h.dist irc2.10.3p6+noos/support/config.h.dist
--- irc2.10.3p6/support/config.h.dist	Sat Oct 11 15:25:14 2003
+++ irc2.10.3p6+noos/support/config.h.dist	Thu May  6 23:04:42 2004
@@ -389,6 +389,19 @@
  */
 #define SIXBONE_HACK
 
+/* noos defines */
+/* based on jv's +hemp2 patch */
+
+/* Split handling - replaces QPI
+ * works as follows:
+ * PINGs all servers behind the link and waits for PONG.
+ */
+#define SPLIT_HANDLE
+
+/* defines minimum for GLOBAL channels */
+#define SPLIT_SERV  25
+#define SPLIT_USERS 40000
+
 /*   STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP  */
 /*   STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP  */
 /*   STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP  */
Only in irc2.10.3p6+noos/support: config.h.dist.orig
