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;ptrname; + 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;