diff -burN irc2.11.0/doc/README-jp irc2.11.0+jp8/doc/README-jp
--- irc2.11.0/doc/README-jp	Thu Jan  1 09:00:00 1970
+++ irc2.11.0+jp8/doc/README-jp	Mon Jan 10 08:35:57 2005
@@ -0,0 +1,101 @@
+IRC server jp-patched version (2005/01/07 irc2.11.0-irc2.11.0+jp8.patch)
+
+  $B$3$N(Bjp-patched version$B$O!"(BIRC server (ftp://ftp.irc.org/irc/server/) $B$K(B
+  $BBP$7$F<g$K0J2<$N$h$&$J5!G=$rIU2C$7$?$b$N$G$9!#(B
+
+   $B!&F|K\8lBP1~(BIRC$B%/%i%$%"%s%H$NB?$/$,;}$C$F$$$kITHw$rJd$&$?$a!"(B
+     $BB?$/$N%1!<%9$G%f!<%6$,ITJX$J>uBV$K$J$k$N$rKI$0$?$a$N5!G=!#(B
+     ($B:G=*E*$K$O!"3F%/%i%$%"%s%H$N<BAu$G2r7h$9$k$Y$-ItJ,!#(B)
+   $B!&(BIRC$B%5!<%P$N85!9$N;EMM$N$?$a$KF|K\8l$rMQ$$$k>e$G%f!<%6$NMxJX@-$,(B
+     $B<:$o$l$F$$$kLL$rItJ,E*$K2r7h$9$k$?$a$N5!G=!#(B
+
+  $B:G?7$N(Bjp6$BHG$K$*$$$F$O!"$$$^$^$G$O%A%c%M%kL>$K;HMQ$9$k$3$H$,$G$-$J$+$C$?!"(B
+  $B$"$k$$$O!";HMQ$K$*$$$F@)8B$5$l$F$$$?!"(BISO-2022-JP$B$K$*$1$k?tI4J8;z$N4A;z$r(B
+  $B%A%c%M%kL>$NCf$G$9$Y$F;HMQ$9$k$3$H$,$G$-$k$h$&$KBP1~$7$F$$$^$9!#(B($B$$$o$f$k(B
+  #$B$,$,(B $BLdBj$X$NBP1~!"$*$h$S!"(B#$B$:$:(B $BLdBj$X$NBP1~!#(B) $B$3$N5!G=$O(Bjp6$BHG0J9_$N(B
+  $BBP1~%5!<%P4V$G$N$_M-8z$H$J$j$^$9$,!"3:Ev$9$k%A%c%M%k$O$A$g$&$I%^%9%/IU(B
+  $B%A%c%M%k(B($BNc$($P!"(B#abc:*.jp$B$J$I(B)$B$HF1$80LCVIU$1$K$J$k$?$a!"F1$8(BIRC$BLVFb$K(B
+  $BHsBP1~%5!<%P$H$N@\B3$,$"$C$F$bAj8_@\B3>e$N%W%m%H%3%k$K1F6A$,$J$$$h$&$K(B
+  $B<BAu$5$l$F$$$^$9!#(B
+
+  $B:#8e$b!"K\BN$N(B irc2.x $B$HL7=b$J$/<B8=2DG=$J5!G=$K$D$$$F2DG=$J8B$j<BAu$r(B
+  $B9T$J$C$F$$$/M=Dj$G$9!#MWK>$d2~A10F$J$I$,$"$j$^$7$?$i$h$m$7$/$*4j$$$7$^$9!#(B
+  $B$^$?!"(Bbug$B>pJs$*$h$SIT6q9g$dLdBjE@$J$I$b2DG=$J8B$jBP1~$7$?$$$H;W$$$^$9$N$G!"(B
+  $B$=$l$i$K$D$$$F$b$_$J$5$^$+$i$N>pJs$r$*BT$A$7$F$*$j$^$9!#(B
+  
+$BJQ99MzNr(B
+
+  jp8 $B"+(B jp7
+      irc2.11.0$BBP1~(B
+
+  jp7 $B"+(B jp6
+      irc2.10.3p3$BBP1~(B
+
+  jp6 $B"+(B jp5
+      irc2.10.3$BBP1~(B
+      ircd/s_user.c$B$K$*$1$k%A%c%M%kL>@55,2=1L$l$r(Bfix
+      split$B;~$KH/@8$9$k%A%c%M%k%^%9%/4X78$NEAGE1L$l(Bbug$B$r(Bfix
+      GOOD_USERNAME$B$r(B A-Z,a-z,0-9,_,-,. $B$X$HA}2C(B
+      $B$$$o$f$k(B #$B$,$,(B $BLdBj$KBP1~$7$FMxMQ2DG=$X(B
+      $B$$$o$f$k(B #$B$:$:(B $BLdBj$KBP1~$7$FMxMQ2DG=$X(B
+
+  jp5 $B"+(B jp4
+      ircd/channel.c$B$K$*$1$k%A%c%M%kL>@55,2=(Bbug$B$r(Bfix
+
+  jp4 $B"+(B jp3
+      irc2.9.5$BBP1~(B
+      common/send.c$B$K$*$1$k(Bdeliver_it()$B$G$N%(%i!<;~$K%(%i!<>pJs$rJV$9$?$a!"(B
+      common/bsd.c$B$G$N(Bdeliver_it()$B$NLa$jCM$r(B-1$B$G$O$J$/(B-errno$B$rJV$9$h$&$K$7$?!#(B
+
+  jp3 $B"+(B jp2
+      irc2.9.4$BBP1~(B
+      GOOD_USERNAME$B$G$N(Bjp2y1b$BHG$K9g$o$;$?!#(B
+         A-Z,a-z,0-9,_,- $B$NG$0U$NAH$_9g$o$;$G(BOK$B$H4KOB(B
+
+$BCm0U;v9`(B
+
+  $BF~<j@h(B:   http://www.ircnet.jp/dist/server/jp-patch/
+  $B9pCN@h(B:   http://www.ircnet.jp/
+  $BO"Mm@h(B:   mailto:jp-patch@ircnet.jp
+
+  $B$3$N(Bjp-patched$BHG$O(B $B5FCO9b9-(B <kick@kyoto.wide.ad.jp> $B$,:n@.4IM}$7$F$$$^$9!#(B
+  $BIT6q9g$J$I$,$"$j$^$7$?$i(B jp-patch@ircnet.jp $B$^$G$*4j$$$7$^$9!#(B
+  $B:#8e$N>pJs$J$I$O(B http://www.ircnet.jp/ $B$G9pCN$9$kM=Dj$G$9!#(B
+
+  $BK\BN5Z$S(Bpatch$B$H$b$K(BGPL$B$K=>$$$^$9!#>\$7$/$O(Bdoc/$B$N2<$NJ8=qN`$r$I$&$>!#(B
+  $B$?$@$7!"$3$N(Bpatch$B$rMxMQ$7$?$b$N$r2~JQ$7$F:FG[I[$9$k>l9g$O!"$3$NJ8=q$r(B
+  $B$=$N$^$^IU$1$k$H$H$b$K(B jp-patch@kyoto.wide.ad.jp $B$^$GO"Mm$r$$$?$@$1$k(B
+  $B$H9,$$$G$9!#2~JQ$J$/$=$N$^$^:FG[I[$9$k>l9g$O<+M3$K$7$F$/$@$5$C$F7k9=$G$9!#(B
+
+$B$=$NB>$N4XO">pJs(B
+
+  JIRCC (Japan Internet-Relay-Chat Club)
+    JIRCC$B$OF|K\$K$*$1$k(BIRC$B$NIa5Z$H(BIRCer$B4V$N8rN.$r$r$O$+$k$?$a$K(B
+    1990$BG/(B3$B7n$K$G$-$?(BIRC$B$N%f!<%62q$G$9!#%a!<%j%s%0%j%9%H$,$"$j!"(B
+    IRC$B$K4X$9$k<o!9$N>pJs8r49$d5DO@$d9pCN$,9T$J$o$l$F$-$F$$$^$9!#(B
+
+      jircc mailing list
+         IRC$BA4HL$K4X$9$k%a!<%j%s%0%j%9%H$G$9!#(B
+         jircc-request@irc.kyoto-u.ac.jp $B$X%a!<%k$rAw$k$H;22CJ}K!$,(B
+         $B<+F0JVAw$5$l$F$-$^$9!#%a!<%k$NFbMF$O$"$C$F$b6u$G$bBg>fIW$G$9!#(B
+
+      jircc-oper mailing list
+         IRC$B1?MQ$K4X$9$k%a!<%j%s%0%j%9%H$G$9!#(B
+         jircc-oper-request@irc.kyoto-u.ac.jp $B$X%a!<%k$rAw$k$H;22CJ}K!$,(B
+         $B<+F0JVAw$5$l$F$-$^$9!#%a!<%k$NFbMF$O$"$C$F$b6u$G$bBg>fIW$G$9!#(B
+         $B$J$*!"(Bjircc-oper$B%a!<%j%s%0%j%9%H$O(B jircc$B%a!<%j%s%0%j%9%H$N(B
+         $B%5%V%j%9%HE*$J0LCVIU$1$H$J$C$F$*$jFC$K%5!<%P$dLV$N1?MQ$r07$$$^$9!#(B
+         $BFbMF$K1~$8$F(B jircc$B%a!<%j%s%0%j%9%HK\BN$XLa$C$F9T$J$&$3$H$,$"$j(B
+         $B$^$9$N$G!"(Bjircc$B%a!<%j%s%0%j%9%H$N$[$&$X$b;22C$r$7$F$*$$$F2<$5$$!#(B
+          
+  http://www.ircnet.jp/
+  ($B5l(B) http://irc.kyoto-u.ac.jp/
+    IRC$B$K4X$9$k>pJs$r=8$a$?%Z!<%8$G$9!#(B
+
+$B<U<-(B
+
+  $BK\(Bpatch$B$N3+H/5Z$S(Bdebugging$B$K$*$$$F!"3+H/4D6-$dB?$/$NJX59$rM?$($F$/$l$?(B
+  $B>pJs5;=Q3+H/3t<02q<R5~ET%M%C%H%o!<%/5;=Q8&5f=j(B http://www.rcac.tdi.co.jp/
+  $B5Z$S!"$=$N3'MMJ}$K46<U$N0U$rI=$o$7$?$$$H;W$$$^$9!#$^$?!"F0:n3NG'$J$I(B
+  $B<B1?MQ$K:]$7$FMxMQ$5$;$F$$$?$@$$$?(BIRCnet$B!"5Z$S!"$=$NB?$/$N%f!<%6$N3'MMJ}$K(B
+  $BBP$7!"$3$3$K46<U$N0U$rI=$o$7$?$$$H;W$$$^$9!#(B
Exit 1
diff -burN irc2.11.0/ircd/channel.c irc2.11.0+jp8/ircd/channel.c
--- irc2.11.0/ircd/channel.c	Wed Dec 15 10:23:45 2004
+++ irc2.11.0+jp8/ircd/channel.c	Mon Jan 10 10:34:42 2005
@@ -53,6 +53,11 @@
 static	int	can_join (aClient *, aChannel *, char *);
 void	channel_modes (aClient *, char *, char *, aChannel *);
 static	int	check_channelmask (aClient *, aClient *, char *);
+
+#ifdef JAPANESE
+static	int	special_channel __P((char *));
+#endif
+
 static	aChannel *get_channel (aClient *, char *, int);
 static	int	set_mode (aClient *, aClient *, aChannel *, int *, 
 			int, char **);
@@ -619,6 +624,83 @@
 	return 0;
 }
 
+#ifdef JAPANESE
+char	*get_channelmask(chname)
+char	*chname;
+{
+	char	*mask;
+
+	mask = rindex(chname, ':');
+	if (mask && !index(mask, '\033'))
+		return mask;
+
+	return NULL;
+}
+
+int	special_channel(chname)
+char	*chname;
+{
+	char *mask;
+	char *cn;
+	int flag=0;
+	mask = rindex(chname, ':');
+	if (mask && index(mask, '\033'))
+		return 1;
+	if (index(chname, ','))
+		return 1;
+
+	cn=chname;
+	while (*cn)
+	  {
+	      switch (*cn)
+		{
+		case '\033':
+		  if (cn[1] == '$' && cn[2] == 'B') {
+		    cn += 3;
+		    flag = 1;
+		    break;
+		  } else if (cn[1] == '(' && cn[2] == 'B') {
+		    cn += 3;
+		    flag = 0;
+		    break;
+		  }else{
+		    cn++; break;
+		  }
+		  /* Never Reach Here */
+
+		case '{':
+		case '}':
+		case '~':
+		case '\\':
+		  if (flag ==1){
+		    return 1;
+		  }else{
+		    cn++;
+		    break;
+		  }
+		  /* Never Reach Here */
+
+		default:
+		  cn++; break;
+		}
+	  }
+	return 0;
+}
+
+int	valid_channel(cptr, chptr, chname)
+aClient	*cptr;
+aChannel *chptr;
+char	*chname;
+{
+	if (((chptr && (chptr->flags & FLAGS_JP)) ||
+	     (chname && special_channel(chname))) &&
+	    (!cptr || (IsServer(cptr) && !(cptr->flags & FLAGS_JP))))
+		return 0;
+
+	return 1;
+}
+#endif
+
 aChannel	*find_channel(char *chname, aChannel *chptr)
 {
 	aChannel *achptr = chptr;
@@ -844,6 +926,10 @@
 
 	if (check_channelmask(&me, cptr, chptr->chname))
 		return;
+#ifdef JAPANESE
+	if (!valid_channel (cptr, chptr, 0))
+                return;
+#endif
 
 	*modebuf = *parabuf = '\0';
 	channel_modes(cptr, modebuf, parabuf, chptr);
@@ -900,6 +986,10 @@
 
 	if (check_channelmask(&me, cptr, chptr->chname) == -1)
 		return;
+#ifdef JAPANESE
+	if (!valid_channel(cptr, chptr, 0))
+                return;
+#endif
 	sprintf(buf, ":%s NJOIN %s :", me2, chptr->chname);
 	len = strlen(buf);
 
@@ -992,8 +1082,13 @@
 			*modebuf = *parabuf = '\0';
 			modebuf[1] = '\0';
 			channel_modes(sptr, modebuf, parabuf, chptr);
+#ifdef JAPANESE
+			sendto_one(sptr, replies[RPL_CHANNELMODEIS], ME, BadTo(parv[0]),
+				   chptr->chname, modebuf, parabuf);
+#else
 			sendto_one(sptr, replies[RPL_CHANNELMODEIS], ME, BadTo(parv[0]),
 				   name, modebuf, parabuf);
+#endif
 			penalty += 1;
 		    }
 		else	/* Check parameters for the channel */
@@ -1952,12 +2047,34 @@
 
 void	clean_channelname(char *cn)
 {
+#ifdef JAPANESE
+  int flag = 0;
+
+  while (*cn) {
+    if (*cn == '\007' || *cn == ' ') {
+      *cn = '\0';
+      return;
+    } else if (!flag && *cn == ',') {
+      *cn = '\0';
+      return;
+    } else if (cn[0] == '\033' && cn[1] == '$' && cn[2] == 'B') {
+      cn += 3;
+      flag = 1;
+    } else if (cn[0] == '\033' && cn[1] == '(' && cn[2] == 'B') {
+      cn += 3;
+      flag = 0;
+    } else {
+      cn++;
+    }
+  }
+#else
 	for (; *cn; cn++)
 		if (*cn == '\007' || *cn == ' ' || *cn == ',')
 		    {
 			*cn = '\0';
 			return;
 		    }
+#endif
 }
 
 /*
@@ -1973,6 +2090,57 @@
 */
 static	void   convert_scandinavian(Reg char *cn, aClient *cptr)
 {
+#ifdef JAPANESE
+  int flag=0;
+  if (ST_NOTUID(cptr) || MyPerson(cptr))
+    {
+      while (*cn)
+	{
+	  switch (*cn)
+	    {
+	    case    '{':
+	      if(flag==0){
+		*cn = '[';
+	      }
+	      cn++;
+	      break;
+	    case    '}':
+	      if (flag==0){
+		*cn = ']';
+	      }
+	      cn++;
+	      break;
+	    case    '~':
+	      if (flag==0){
+		*cn = '^';
+	      }
+	      cn++;
+	      break;
+	    case    '\\':
+	      if (flag==0){
+		*cn = '|';
+	      }
+	      cn++;
+	      break;
+	    case '\033':
+	      if (cn[1] == '$' && cn[2] == 'B') {
+		cn += 3;
+		flag = 1;
+		break;
+	      } else if (cn[1] == '(' && cn[2] == 'B') {
+		cn += 3;
+		flag = 0;
+		break;
+	      }else{
+		cn++; break;
+	      }
+	    default:
+	      cn++; break;
+	    }
+	}
+    }
+  
+#else
 	if (ST_NOTUID(cptr) || MyPerson(cptr))
 	{
 		for (; *cn; cn++)
@@ -1990,6 +2158,8 @@
 			}
 		}
 	}
+
+#endif
 }
 
 /*
@@ -2001,7 +2171,11 @@
 
 	if (*chname == '&' && IsServer(cptr))
 		return -1;
+#ifdef JAPANESE
+	s = get_channelmask(chname);
+#else
 	s = rindex(chname, ':');
+#endif
 	if (!s)
 		return 0;
 	if ((t = index(s, '\007')))
@@ -2016,8 +2190,14 @@
 	if (match(s, ME) || (IsServer(cptr) && match(s, cptr->name)))
 	    {
 		if (MyClient(sptr))
+#ifdef JAPANESE
+			sendto_one(sptr, replies[ERR_BADCHANMASK], 
+                                   ME, BadTo(sptr->name),
+				   chname);
+#else
 			sendto_one(sptr, replies[ERR_BADCHANMASK], ME, BadTo(sptr->name),
 				   chname);
+#endif
 		if (t)
 			*t = '\007';
 		return -1;
@@ -2044,6 +2224,10 @@
 	    {
 		len = CHANNELLEN;
 		*(chname+CHANNELLEN) = '\0';
+#ifdef JAPANESE		
+                if (check_channelmask(cptr, cptr, chname) == -1)
+                    return NULL;
+#endif
 	    }
 	if ((chptr = find_channel(chname, (aChannel *)NULL)))
 		return (chptr);
@@ -2057,6 +2241,12 @@
 		chptr->prevch = NULL;
 		chptr->nextch = channel;
 		chptr->history = 0;
+
+#ifdef JAPANESE
+                chptr->flags = 0;
+                if (special_channel(chname))
+                        chptr->flags = FLAGS_JP;
+#endif
 		channel = chptr;
 		(void)add_to_channel_hash_table(chname, chptr);
 	    }
@@ -2513,17 +2703,31 @@
 		/*
 		** notify all users on the channel
 		*/
+#ifdef JAPANESE
+		sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s",
+						parv[0], chptr->chname);
+#else
 		sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s",
 						parv[0], name);
+#endif
 		if (s && UseModes(name))
 		    {
 			/* no need if user is creating the channel */
 			if (chptr->users != 1)
+#ifdef JAPANESE
+				sendto_channel_butserv(chptr, sptr,
+						       ":%s MODE %s +%s %s %s",
+						       cptr->name,
+                                                       chptr->chname, s,
+						       parv[0],
+						       *(s+1)=='v'?parv[0]:"");
+#else
 				sendto_channel_butserv(chptr, sptr,
 						       ":%s MODE %s +%s %s %s",
 						       cptr->name, name, s,
 						       parv[0],
 						       *(s+1)=='v'?parv[0]:"");
+#endif
 		    }
 		/*
 		** If s wasn't set to chop+1 above, name is now #chname^Gov
@@ -2539,17 +2743,31 @@
 			del_invite(sptr, chptr);
 			if (chptr->topic[0] != '\0')
 			{
+#ifdef JAPANESE
+				sendto_one(sptr, replies[RPL_TOPIC], ME,
+					BadTo(parv[0]), chptr->chname, chptr->topic);
+#else
 				sendto_one(sptr, replies[RPL_TOPIC], ME,
 					BadTo(parv[0]), name, chptr->topic);
+#endif
 #ifdef TOPIC_WHO_TIME
 				if (chptr->topic_t > 0)
 				{
+#ifdef JAPANESE
+					sendto_one(sptr, replies[RPL_TOPIC_WHO_TIME],
+						ME, BadTo(parv[0]),
+						chptr->chname, IsAnonymous(chptr) ?
+						"anonymous!anonymous@anonymous." :
+						chptr->topic_nuh,
+						chptr->topic_t);
+#else
 					sendto_one(sptr, replies[RPL_TOPIC_WHO_TIME],
 						ME, BadTo(parv[0]),
 						name, IsAnonymous(chptr) ?
 						"anonymous!anonymous@anonymous." :
 						chptr->topic_nuh,
 						chptr->topic_t);
+#endif
 				}
 #endif
 			}
@@ -2564,7 +2782,12 @@
 		/*
 	        ** notify other servers
 		*/
+#ifdef JAPANESE
+		if (!valid_channel(0,chptr, 0) || get_channelmask(name)
+                    || *chptr->chname == '!') /* compat */
+#else
 		if (index(name, ':') || *chptr->chname == '!') /* compat */
+#endif
 		{
 			sendto_match_servs_v(chptr, cptr, SV_UID,
 				":%s NJOIN %s :%s%s", me.serv->sid, name,
@@ -2800,8 +3023,13 @@
 		** join from netjoin. 2.10.x is using NJOIN only during
 		** burst, but 2.11 always. Hence we check for EOB from 2.11
 		** to know what kind of NJOIN it is. --B. */
+#ifdef JAPANESE
+		sendto_channel_butserv(chptr, acptr, ":%s JOIN %s%s", acptr->name,
+			(ST_NOTUID(sptr) || IsBursting(sptr)) ? "" : ":", chptr->chname);
+#else
 		sendto_channel_butserv(chptr, acptr, ":%s JOIN %s%s", acptr->name,
 			(ST_NOTUID(sptr) || IsBursting(sptr)) ? "" : ":", parv[1]);
+#endif
 		/* build MODE for local users on channel, eventually send it */
 		if (*mbuf)
 		    {
@@ -2831,11 +3059,20 @@
 				    }
 				break;
 			case 2:
+#ifdef JAPANESE
 				sendto_channel_butserv(chptr, &me,
 					       ":%s MODE %s +%s%c %s %s",
 						       sptr->name, parv[1],
 						       modebuf, mbuf[1],
 						       parabuf, acptr->name);
+#else
+				sendto_channel_butserv(chptr, &me,
+					       ":%s MODE %s +%s%c %s %s",
+						       sptr->name,
+                                                       chptr->chname,
+						       modebuf, mbuf[1],
+						       parabuf, acptr->name);
+#endif
 				if (mbuf[2])
 				    {
 					strcpy(modebuf, mbuf+2);
@@ -2848,18 +3085,32 @@
 			    }
 			if (cnt == MAXMODEPARAMS)
 			    {
+#ifdef JAPANESE
 				sendto_channel_butserv(chptr, &me,
 						       ":%s MODE %s +%s %s",
 						       sptr->name, parv[1],
 						       modebuf, parabuf);
+#else
+				sendto_channel_butserv(chptr, &me,
+						       ":%s MODE %s +%s %s",
+						       sptr->name,
+                                                       chptr->chname,
+						       modebuf, parabuf);
+#endif
 				cnt = 0;
 			    }
 		    }
 	    }
 	/* send eventual MODE leftover */
 	if (cnt)
+#ifdef JAPANESE
+		sendto_channel_butserv(chptr, &me, ":%s MODE %s +%s %s",
+				       sptr->name, chptr->chname,
+                                       modebuf, parabuf);
+#else
 		sendto_channel_butserv(chptr, &me, ":%s MODE %s +%s %s",
 				       sptr->name, parv[1], modebuf, parabuf);
+#endif
 
 	/* send NJOIN */
 	*q = '\0';
@@ -2925,7 +3176,12 @@
 		/*
 		**  Remove user from the old channel (if any)
 		*/
+#ifdef JAPANESE
+		if (valid_channel(0, chptr, 0)
+                    && !get_channelmask(name) && (*chptr->chname != '!'))
+#else
 		if (!index(name, ':') && (*chptr->chname != '!'))
+#endif
 		    {	/* channel:*.mask */
 			if (*name != '&')
 			    {
@@ -2949,8 +3205,13 @@
 		else
 			sendto_match_servs(chptr, cptr, PartFmt,
 				   	   parv[0], name, comment);
+#ifdef JAPANESE
+		sendto_channel_butserv(chptr, sptr, PartFmt,
+				       parv[0], chptr->chname, comment);
+#else
 		sendto_channel_butserv(chptr, sptr, PartFmt,
 				       parv[0], name, comment);
+#endif
 		remove_user_from_channel(sptr, chptr);
 	    }
 	if (*buf)
@@ -3057,9 +3318,16 @@
 			if (IsMember(who, chptr))
 			    {
 				/* Local clients. */
+#ifdef JAPANESE
+				sendto_channel_butserv(chptr, sptr,
+					":%s KICK %s %s :%s", sptr->name,
+					chptr->chname,
+                                        who->name, comment);
+#else
 				sendto_channel_butserv(chptr, sptr,
 					":%s KICK %s %s :%s", sptr->name,
 					name, who->name, comment);
+#endif
 
 				/* nick buffer to kick out, build for 2.11 */
 				/* as we need space for ",nick", we should add
@@ -3278,6 +3546,14 @@
 	if (*parv[2] == '&' && !MyClient(acptr))
 		return 1;
 	chptr = find_channel(parv[2], NullChn);
+#ifdef JAPANESE
+        if(!valid_channel(acptr->from, chptr, parv[2]))
+           {
+	     sendto_one(sptr, replies[ERR_BADCHANMASK], ME,
+                        chptr ? chptr->chname : parv[2]);
+             return 1;
+           }
+#endif
 	if (!chptr && parv[2][0] == '!')
 	{
 		/* Try to find !channel using shortname */
@@ -3448,9 +3724,15 @@
 			chptr = find_channel(name, NullChn);
 			if (chptr && ShowChannel(sptr, chptr) && sptr->user)
 			    {
+#ifdef JAPANESE
+				rlen += sendto_one(sptr, replies[RPL_LIST],
+						   ME, BadTo(parv[0]), chptr->chname,
+						   chptr->users, chptr->topic);
+#else
 				rlen += sendto_one(sptr, replies[RPL_LIST],
 						   ME, BadTo(parv[0]), name,
 						   chptr->users, chptr->topic);
+#endif
 				if (!MyConnect(sptr) && rlen > CHREPLLEN)
 					break;
 			    }
diff -burN irc2.11.0/ircd/channel_ext.h irc2.11.0+jp8/ircd/channel_ext.h
--- irc2.11.0/ircd/channel_ext.h	Sat Oct 18 06:28:18 2003
+++ irc2.11.0+jp8/ircd/channel_ext.h	Mon Jan 10 08:35:57 2005
@@ -38,6 +38,12 @@
 EXTERN int is_chan_op (aClient *cptr, aChannel *chptr);
 EXTERN int has_voice (aClient *cptr, aChannel *chptr);
 EXTERN int can_send (aClient *cptr, aChannel *chptr);
+
+#ifdef JAPANESE
+EXTERN char *get_channelmask __P((char *));
+EXTERN int valid_channel __P((aClient *, aChannel *, char *));
+#endif
+
 EXTERN aChannel *find_channel (Reg char *chname, Reg aChannel *chptr);
 EXTERN void setup_server_channels (aClient *mp);
 EXTERN void channel_modes (aClient *cptr, Reg char *mbuf, Reg char *pbuf,
diff -burN irc2.11.0/ircd/s_bsd.c irc2.11.0+jp8/ircd/s_bsd.c
--- irc2.11.0/ircd/s_bsd.c	Sat Nov 20 00:42:08 2004
+++ irc2.11.0+jp8/ircd/s_bsd.c	Mon Jan 10 08:35:57 2005
@@ -1231,14 +1231,27 @@
 	    }
 	if (!BadPtr(aconf->passwd))
 #ifndef	ZIP_LINKS
+#ifdef JAPANESE
+		sendto_one(cptr, "PASS %s %s IRC|%s %sj", aconf->passwd,
+			   pass_version, serveropts,
+			   (bootopt & BOOT_STRICTPROT) ? "P" : "");
+#else
 		sendto_one(cptr, "PASS %s %s IRC|%s %s", aconf->passwd,
 			   pass_version, serveropts,
 			   (bootopt & BOOT_STRICTPROT) ? "P" : "");
+#endif
+#else
+#ifdef JAPANESE
+		sendto_one(cptr, "PASS %s %s IRC|%s %s%sj", aconf->passwd,
+			   pass_version, serveropts,
+			   (bootopt & BOOT_STRICTPROT) ? "P" : "",
+			   (aconf->status == CONF_ZCONNECT_SERVER) ? "Z" : "");
 #else
 		sendto_one(cptr, "PASS %s %s IRC|%s %s%s", aconf->passwd,
 			   pass_version, serveropts,
 			   (bootopt & BOOT_STRICTPROT) ? "P" : "",
 			   (aconf->status == CONF_ZCONNECT_SERVER) ? "Z" : "");
+#endif
 #endif
 
 	aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
diff -burN irc2.11.0/ircd/s_send.c irc2.11.0+jp8/ircd/s_send.c
--- irc2.11.0/ircd/s_send.c	Sat Oct  9 21:40:29 2004
+++ irc2.11.0+jp8/ircd/s_send.c	Mon Jan 10 08:35:57 2005
@@ -367,7 +367,11 @@
 		{
 		    return;
 		}
+#ifdef JAPANESE
+		if ((mask = get_channelmask(chptr->chname)))
+#else
 		if ((mask = rindex(chptr->chname, ':')))
+#endif
 		{
 		    mask++;
 		}
diff -burN irc2.11.0/ircd/s_serv.c irc2.11.0+jp8/ircd/s_serv.c
--- irc2.11.0/ircd/s_serv.c	Wed Dec 15 10:25:31 2004
+++ irc2.11.0+jp8/ircd/s_serv.c	Mon Jan 10 08:35:57 2005
@@ -440,6 +440,11 @@
 		}
 	}
 
+#ifdef JAPANESE
+	if (link && strchr(link, 'j'))	/* jp version */
+		cptr->flags |= FLAGS_JP;
+#endif
+
 	/* right now, I can't code anything good for this */
 	/* Stop whining, and do it! ;) */
 	if (link && strchr(link, 'Z'))	/* Compression requested */
@@ -1161,14 +1166,27 @@
 
 		if (bconf->passwd[0])
 #ifndef	ZIP_LINKS
-			sendto_one(cptr, "PASS %s %s IRC|%s %s", bconf->passwd,
-				   pass_version, serveropts,
+#ifdef JAPANESE
+			sendto_one(cptr, "PASS %s %s IRC|%s %sj",
+				    bconf->passwd, pass_version, serveropts,
+				   (bootopt & BOOT_STRICTPROT) ? "P" : "");
+#else
+			sendto_one(cptr, "PASS %s %s IRC|%s %s",
+				    bconf->passwd, pass_version, serveropts,
+				   (bootopt & BOOT_STRICTPROT) ? "P" : "");
+#endif
+#else
+#ifdef JAPANESE
+			sendto_one(cptr, "PASS %s %s IRC|%s %s%sj",
+				   bconf->passwd, pass_version, serveropts,
+			   (bconf->status == CONF_ZCONNECT_SERVER) ? "Z" : "",
 				   (bootopt & BOOT_STRICTPROT) ? "P" : "");
 #else
 			sendto_one(cptr, "PASS %s %s IRC|%s %s%s",
 				   bconf->passwd, pass_version, serveropts,
 			   (bconf->status == CONF_ZCONNECT_SERVER) ? "Z" : "",
 				   (bootopt & BOOT_STRICTPROT) ? "P" : "");
+#endif
 #endif
 		/*
 		** Pass my info to the new server
diff -burN irc2.11.0/ircd/s_user.c irc2.11.0+jp8/ircd/s_user.c
--- irc2.11.0/ircd/s_user.c	Mon Dec 13 02:25:16 2004
+++ irc2.11.0+jp8/ircd/s_user.c	Mon Jan 10 08:35:57 2005
@@ -611,9 +611,54 @@
 				XLINE_EXIT_REASON);
 		}
 #endif
+
+#ifdef  GOOD_USERNAME
+                for (i = 0; i < USERLEN; i++)
+		  {
+		    if (!user->username[i])
+		      break;
+		    if (i == 0 && prefix)
+		      continue;
+		    if (!isalnum(user->username[i]) &&
+			!strchr("-_.", user->username[i]))
+		      {
+			sendto_flag(SCH_LOCAL, "Bad username %s@%s.",
+				    user->username, sptr->sockhost);
+			ircstp->is_ref++;
+			sptr->exitc = EXITC_REF;
+#if defined(USE_SYSLOG) && defined(SYSLOG_CONN)
+			syslog(LOG_NOTICE, "%s (%s): %s@%s [%s] %c\n",
+			       myctime(sptr->firsttime), "  Badname  ",
+			       user->username, user->host,
+			       sptr->auth, '-');
+#endif
+#ifdef FNAME_CONNLOG
+			sendto_flog(sptr, " Badname ", user->username,
+				    user->host);
+#endif
+			sprintf(buf, "Bad username: %s",
+				user->username);
+			return exit_client(cptr, sptr, &me, buf);
+		      }
+		  }
+#endif
 	    }
 	else
+#ifdef  GOOD_USERNAME
+	  {
+                for (i = 0; i < USERLEN; i++)
+                    {
+                        if (!username[i])
+                            break;
+                        if (!isalnum(username[i]) &&
+                            !strchr("^~+=-_.", username[i]))
+                            username[i] = '.';
+                    }
+#endif
 		strncpyzt(user->username, username, USERLEN+1);
+#ifdef GOOD_USERNAME
+          }
+#endif
 
 	SetClient(sptr);
 	if (!MyConnect(sptr))
diff -burN irc2.11.0/ircd/version.c.SH.in irc2.11.0+jp8/ircd/version.c.SH.in
--- irc2.11.0/ircd/version.c.SH.in	Sat Oct  2 05:22:16 2004
+++ irc2.11.0+jp8/ircd/version.c.SH.in	Mon Jan 10 08:35:57 2005
@@ -111,6 +111,11 @@
 	"Thanks also to those who provide the kind sys admins who let me and",
 	"others continue to develop IRC.",
 	"",
+	"This program is a jp-patched version. The jp-patch was written by",
+	"KIKUCHI Takahiro <kick@wide.ad.jp>, and is ported to 2.11 by",
+        "MARUYAMA Shin <marushin@wide.ad.jp>. You can find it in",
+	"http://www.ircnet.jp/dist/server/jp-patch/.",
+	"",
 	"[$sumsserv] [$sumchan] [$sumsbsd] [$sumsuser]",
 	"[$sumhash] [$sumsmisc] [$sumircd]",
 	0,
Exit 1
diff -burN irc2.11.0/common/bsd.c irc2.11.0+jp8/common/bsd.c
--- irc2.11.0/common/bsd.c	Wed Nov 17 01:39:46 2004
+++ irc2.11.0+jp8/common/bsd.c	Mon Jan 10 08:35:57 2005
@@ -91,6 +91,12 @@
 	writecalls++;
 #endif
 	retval = send(cptr->fd, str, len, 0);
+
+#ifdef JAPANESE
+	if (retval < 0)
+	  retval = -errno;
+#endif
+
 	/*
 	** Convert WOULDBLOCK to a return of "0 bytes moved". This
 	** should occur only if socket was non-blocking. Note, that
diff -burN irc2.11.0/common/send.c irc2.11.0+jp8/common/send.c
--- irc2.11.0/common/send.c	Fri Dec 10 23:39:04 2004
+++ irc2.11.0+jp8/common/send.c	Mon Jan 10 08:35:57 2005
@@ -803,8 +803,13 @@
 	    {
 		if (*chptr->chname == '&')
 			return;
+#ifdef JAPANESE
+		if ((mask = get_channelmask(chptr->chname)))
+		  mask++;
+#else
 		if ((mask = (char *)rindex(chptr->chname, ':')))
 			mask++;
+#endif
 	    }
 	else
 		mask = (char *)NULL;
@@ -816,6 +821,10 @@
 			continue;
 		if (!BadPtr(mask) && match(mask, cptr->name))
 			continue;
+#ifdef JAPANESE
+		if (!valid_channel(cptr, chptr, 0))
+			continue;
+#endif
 		if (!len)
 		    {
 			va_list	va;
@@ -838,8 +847,14 @@
 	    {
 		if (*chptr->chname == '&')
 			return 0;
+#ifdef JAPANESE
+		if ((mask = get_channelmask(chptr->chname)))
+		  mask++;
+#else
 		if ((mask = (char *)rindex(chptr->chname, ':')))
 			mask++;
+#endif
+
 	    }
 	else
 		mask = (char *)NULL;
@@ -851,6 +866,12 @@
 			continue;
 		if (!BadPtr(mask) && match(mask, cptr->name))
 			continue;
+
+#ifdef JAPANESE
+		if (!valid_channel(cptr, chptr, 0))
+			continue;
+#endif
+
 		if ((ver & cptr->serv->version) == 0)
 		    {
 			rc = 1;
@@ -879,8 +900,13 @@
 	    {
 		if (*chptr->chname == '&')
 			return 0;
+#ifdef JAPANESE
+		if ((mask = get_channelmask(chptr->chname)))
+		  mask++;
+#else
 		if ((mask = (char *)rindex(chptr->chname, ':')))
 			mask++;
+#endif
 	    }
 	else
 		mask = (char *)NULL;
@@ -892,6 +918,12 @@
 			continue;
 		if (!BadPtr(mask) && match(mask, cptr->name))
 			continue;
+
+#ifdef JAPANESE
+		if (!valid_channel(cptr, chptr, 0))
+ 			continue;
+#endif
+
 		if ((ver & cptr->serv->version) != 0)
 		    {
 			rc = 1;
diff -burN irc2.11.0/common/struct_def.h irc2.11.0+jp8/common/struct_def.h
--- irc2.11.0/common/struct_def.h	Sat Nov 20 00:12:59 2004
+++ irc2.11.0+jp8/common/struct_def.h	Mon Jan 10 08:35:57 2005
@@ -181,6 +181,9 @@
 				  ** a SQUIT. */
 #define	FLAGS_EOB	0x4000000 /* EOB received */
 #define FLAGS_LISTENINACTIVE 0x8000000 /* Listener does not listen() */
+#ifdef JAPANESE
+#define FLAGS_JP            0x10000000 /* jp version */
+#endif
 	
 #define	FLAGS_OPER	0x0001 /* operator */
 #define	FLAGS_LOCOP	0x0002 /* local operator -- SRB */
@@ -688,6 +691,9 @@
 	Link	*clist;		/* list of local! connections which are members */
 	time_t	history;	/* channel history (aka channel delay) */
 	time_t	reop;		/* server reop stamp for !channels */
+#ifdef JAPANESE
+	int flags;
+#endif
 	char	chname[1];
 };
 
diff -burN irc2.11.0/common/support.c irc2.11.0+jp8/common/support.c
--- irc2.11.0/common/support.c	Sat Oct  2 05:22:12 2004
+++ irc2.11.0+jp8/common/support.c	Mon Jan 10 08:35:57 2005
@@ -54,6 +54,12 @@
 {
     char *pos = *save;	/* keep last position across calls */
     Reg char *tmp;
+#ifdef JAPANESE
+    int flag = 0;
+
+    if (fs[0] == ',' && fs[1] == '\0' )
+      flag=1;
+#endif
 
     if (str)
 	pos = str;		/* new string scan */
@@ -66,9 +72,30 @@
 
     tmp = pos; 			/* now, keep position of the token */
 
+#ifdef JAPANESE
+    if (flag) {
+       flag = 0;
+       while (*pos) {
+	   if (!flag && *pos == ',') {
+	       break;
+	   } else if (pos[0] == '\033' && pos[1] == '$' && pos[2] == 'B') {
+	       pos += 3;
+	       flag = 1;
+	   } else if (pos[0] == '\033' && pos[1] == '(' && pos[2] == 'B') {
+	       pos += 3;
+	       flag = 0;
+	   } else {
+               pos++;
+	   }
+       }
+    } else {
+#endif
     while (*pos && index(fs, *pos) == NULL)
 	pos++; 			/* skip content of the token */
 
+#ifdef JAPANESE
+    }
+#endif
     if (*pos)
 	*pos++ = '\0';		/* remove first sep after the token */
     else
@@ -742,7 +769,11 @@
 char	*make_version(void)
 {
 	int ve, re, mi, dv, pl;
+#ifdef JAPANESE
+	char ver[20];
+#else
 	char ver[15];
+#endif
 
 	sscanf(PATCHLEVEL, "%2d%2d%2d%2d%2d", &ve, &re, &mi, &dv, &pl);
 	/* version & revision */
@@ -754,6 +785,9 @@
 		sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv);
 	if (pl)	/* patchlevel */
 		sprintf(ver + strlen(ver), "p%d", pl);
+#ifdef JAPANESE
+	strcat(ver,"+jp8");
+#endif
 	return mystrdup(ver);
 }
 
Exit 1
diff -burN irc2.11.0/support/config.h.dist irc2.11.0+jp8/support/config.h.dist
--- irc2.11.0/support/config.h.dist	Fri Dec 10 23:56:41 2004
+++ irc2.11.0+jp8/support/config.h.dist	Mon Jan 10 08:35:57 2005
@@ -693,6 +693,12 @@
 #define LISTENER_MAXACCEPT 10
 #endif
 
+/*
+ * Defining this will make the server accept a only good username.
+ * (isalnum(c) || strchr("-_.", c))
+ */
+#define GOOD_USERNAME
+
 /*   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  */
