diff -ur csircd-1.13/include/defines.h csircd-1.13+chw/include/defines.h
--- csircd-1.13/include/defines.h	2001-09-30 12:02:13.000000000 +0100
+++ csircd-1.13+chw/include/defines.h	2003-02-26 23:25:48.000000000 +0000
@@ -51,6 +51,8 @@
 
 #define ISWHITE(__x)     (((__x) == ' ') || ((__x) == '\t'))
 #define IsChannel(__x)	((*(__x) == '#') || (*(__x) == '&'))
+#define IsChannelPrefix(__x) ((*(__x) == '@') || (*(__x) == '+'))
+
 #define isvalid(c) (((c) >= 'A' && (c) <= '~') || isdigit(c) || (c) == '-')
 #define IsMe(__x)			((__x) == meptr)
 #define IsMember			_channel_ismember
diff -ur csircd-1.13/include/send.h csircd-1.13+chw/include/send.h
--- csircd-1.13/include/send.h	2001-09-30 10:54:40.000000000 +0100
+++ csircd-1.13+chw/include/send.h	2003-02-26 23:57:05.000000000 +0000
@@ -20,5 +20,6 @@
 #endif
 int send_to_channel_butone(IRCD_CLIENT *one, int servstoo, IRCD_CHANNEL *chptr, IRCD_CLIENT *pptr, char *format, ...);
 int send_to_channel_butone2(IRCD_CLIENT *one, int servstoo, IRCD_CHANNEL *chptr, char *prefix, char *format, ...);
+int send_to_channel_chw(IRCD_CLIENT *one, int servstoo, IRCD_CHANNEL *chptr, IRCD_CLIENT *pptr, char *format, ...);
 
 #endif
diff -ur csircd-1.13/include/structs.h csircd-1.13+chw/include/structs.h
--- csircd-1.13/include/structs.h	2001-09-30 12:02:13.000000000 +0100
+++ csircd-1.13+chw/include/structs.h	2003-02-26 23:50:40.000000000 +0000
@@ -462,6 +462,7 @@
 #define IRCD_CAPAB_VALUE_ZIP			0x002
 #define IRCD_CAPAB_VALUE_NOQUITSTORM	0x004
 #define IRCD_CAPAB_VALUE_EMODE			0x008
+#define IRCD_CAPAB_VALUE_CHW			0x010
 
 #define IsCapable(__x, __y)	((__x)->c_capab_flags & (__y))
 	int				c_capab_flags;
diff -ur csircd-1.13/lib/commands.c csircd-1.13+chw/lib/commands.c
--- csircd-1.13/lib/commands.c	2001-10-02 02:40:35.000000000 +0100
+++ csircd-1.13+chw/lib/commands.c	2003-02-27 00:01:26.000000000 +0000
@@ -176,6 +176,7 @@
 	{ IRCD_CAPAB_VALUE_EMODE,		"EX",		0 },
 #endif
 	{ IRCD_CAPAB_VALUE_NOQUITSTORM,	"QS",		0 },
+	{ IRCD_CAPAB_VALUE_CHW,		"CHW",		0 },
 	{ 0, NULL, 0 }
 };
 
@@ -778,6 +779,61 @@
 				continue;
 			}
 		}
+		else if(IsChannelPrefix(nick))
+		{
+			IRCD_CHANNEL	*chptr;
+			int 		type = 0;
+			char		*flagptr;
+
+			flagptr = nick;
+
+			for(;;)
+			{
+				if(*flagptr == '@')
+					type = CHANNEL_MODES_CHANOP;
+				else if(*flagptr == '+')
+					type = CHANNEL_MODES_CHANOP | CHANNEL_MODES_VOICE;
+				else
+					break;
+
+				flagptr++;
+			}
+			
+			if(type == 0)
+				continue;
+
+			/* we need an error here */
+			if(*flagptr == '\0')
+				continue;
+
+			chptr = hash_find_channel(flagptr);
+
+			if(chptr != NULL)
+			{
+				IRCD_CHANNELLIST	*chlptr = IsMember(chptr, pptr);
+
+				if(chlptr && ((chlptr->clptr->modes & CHANNEL_MODES_CHANOP) ||
+						chlptr->clptr->modes & CHANNEL_MODES_VOICE))
+				{
+					if (IsLocal(pptr) && ((chptr->numusers > 1) ||
+							(chptr->members &&
+							 (chptr->members->cptr != pptr))))
+					{
+						if(!not)
+							resetidle = 1;
+					}
+					send_to_channel_chw(lptr,
+							type,
+							chptr, pptr, "%s %s :%s",
+							cmd, nick, message);
+				}
+				else if(!not)
+				{
+					send_prefix_to_client(meptr, pptr, IRCD_REPLY(ERR_CANNOTSENDTOCHAN, pptr->name), nick);
+				}
+				continue;
+			}
+		}
 		else
 		{
 			IRCD_CLIENT		*nptr = hash_find_client(nick);
diff -ur csircd-1.13/lib/send.c csircd-1.13+chw/lib/send.c
--- csircd-1.13/lib/send.c	2001-09-30 12:02:15.000000000 +0100
+++ csircd-1.13+chw/lib/send.c	2003-02-27 00:28:39.000000000 +0000
@@ -585,6 +585,98 @@
 	return 0;
 }
 
+int send_to_channel_chw(IRCD_CLIENT *one, int flags, IRCD_CHANNEL *chptr, IRCD_CLIENT *pptr, char *format, ...)
+{
+	va_list		ap;
+	IRCD_CLIENTLIST		*users;
+	char				clientbuf[2048];
+	char				serverbuf[512];
+	char				*sptr;
+	char				*d1ptr;
+	char				*d2ptr;
+	int					len;
+	int					slen = 0;
+	IRCD_CLIENT			*cptr;
+
+	if (!Sentalong_marker || (Sentalong_marker == (unsigned int)-1))
+	{
+		register unsigned int *ptr;
+
+		for(ptr=Sentalong;ptr<Sentalong_end;ptr++)
+			*ptr = Sentalong_marker;
+	}
+	Sentalong_marker++;
+
+	*clientbuf = ':';
+	d1ptr = clientbuf+1;
+	*serverbuf = ':';
+	d2ptr = serverbuf+1;
+	sptr = pptr->name;
+	while((*d1ptr++ = *d2ptr++ = *sptr++) != '\0');
+	if (IsClient(pptr))
+	{
+		*(d1ptr-1) = '!';
+		sptr = pptr->username;
+		while((*d1ptr++ = *sptr++) != '\0');
+		*(d1ptr-1) = '@';
+		sptr = pptr->hostname;
+		while((*d1ptr++ = *sptr++) != '\0');
+	}
+	*(d1ptr-1) = ' ';
+	*(d2ptr-1) = ' ';
+	len = d1ptr - clientbuf;
+	
+	va_start(ap, format);
+#ifdef HAVE_VSNPRINTF
+	len += vsnprintf(d1ptr, sizeof(clientbuf)-1-len, format, ap);
+#else
+	len += vsprintf(d1ptr, format, ap);
+#endif
+	va_end(ap);
+	if (len > 509)
+	{
+		len = 509;
+	}
+	for(sptr=clientbuf+len-1;len;len--,sptr--)
+		if (*sptr != '\r' && *sptr != '\n')
+			break;
+	*(sptr+1) = '\r';
+	*(sptr+2) = '\n';
+	*(sptr+3) = '\0';
+	if (flags & CHANNEL_SEND_SERVERS)
+	{
+		strcpy(d2ptr, d1ptr);
+		slen = len - (d1ptr - clientbuf) + (d2ptr - serverbuf);
+	}
+
+	for(users=chptr->members;users;users=users->next)
+	{
+		if ((flags & CHANNEL_SEND_LOCALONLY) && !IsLocal(users->cptr))
+			continue;
+		if ((cptr = users->cptr->c_from) == one)
+			continue;
+		if ((users->modes & flags) == 0)
+			continue;
+		if (IsServer(cptr))
+		{
+			if (*chptr->name == '&')
+				continue;
+			if ((cptr->c_capab_flags & IRCD_CAPAB_VALUE_CHW) == 0)
+				continue;
+		}
+		assert(cptr->c_connptr->fdlistinfo.fd < Sentalong_size);
+		if (!cptr->c_connptr ||
+			(Sentalong[cptr->c_connptr->fdlistinfo.fd] == Sentalong_marker))
+				continue;
+		Sentalong[cptr->c_connptr->fdlistinfo.fd] = Sentalong_marker;
+		if (IsServer(cptr))
+			_send_message_to_client(cptr, serverbuf, slen+2);
+		else
+			_send_message_to_client(cptr, clientbuf, len+2);
+	}
+	return 0;
+}
+
 int send_to_channel_butone(IRCD_CLIENT *one, int flags, IRCD_CHANNEL *chptr, IRCD_CLIENT *pptr, char *format, ...)
 {
 	va_list		ap;
