X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fsend.c;h=9920407777df4973c2ad95ac5c083c2614653ed8;hb=ae91ef6320f611af74e70a0db2620c338fbaa7d5;hp=cd4913271f3f0420a021c150698804434e7e6f45;hpb=eeff5dd006459c6c56f025f13852fdafb2961339;p=ircu2.10.12-pk.git diff --git a/ircd/send.c b/ircd/send.c index cd49132..9920407 100644 --- a/ircd/send.c +++ b/ircd/send.c @@ -16,34 +16,37 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ */ - -#include "sys.h" -#include -#include "h.h" -#include "struct.h" -#include "s_bsd.h" -#include "s_serv.h" #include "send.h" -#include "s_misc.h" -#include "common.h" -#include "match.h" -#include "s_bsd.h" -#include "list.h" -#include "ircd.h" #include "channel.h" -#include "bsd.h" #include "class.h" +#include "client.h" +#include "ircd.h" +#include "ircd_string.h" +#include "list.h" +#include "match.h" +#include "msg.h" +#include "numnicks.h" +#include "s_bsd.h" +#include "s_debug.h" +#include "s_misc.h" #include "s_user.h" #include "sprintf_irc.h" +#include "struct.h" +#include "sys.h" + +#include +#include +#include -RCSTAG_CC("$Id$"); char sendbuf[2048]; static int sentalong[MAXCONNECTIONS]; static int sentalong_marker; -struct SLink *opsarray[32]; /* don't use highest bit unless you change - atoi to strtoul in sendto_op_mask() */ +struct SLink *opsarray[32]; /* don't use highest bit unless you change + atoi to strtoul in sendto_op_mask() */ #ifdef GODMODE char sendbuf2[2048]; int sdbflag; @@ -66,7 +69,7 @@ int sdbflag; * like Persons and yet unknown connections... */ -static void dead_link(aClient *to, char *notice) +static void dead_link(struct Client *to, char *notice) { to->flags |= FLAGS_DEADSOCKET; /* @@ -77,14 +80,20 @@ static void dead_link(aClient *to, char *notice) DBufClear(&to->sendQ); /* Keep a copy of the last comment, for later use... */ - strncpy(LastDeadComment(to), notice, sizeof(LastDeadComment(to))); - LastDeadComment(to)[sizeof(LastDeadComment(to)) - 1] = 0; + ircd_strncpy(LastDeadComment(to), notice, sizeof(LastDeadComment(to) - 1)); + LastDeadComment(to)[sizeof(LastDeadComment(to)) - 1] = '\0'; if (!IsUser(to) && !IsUnknown(to) && !(to->flags & FLAGS_CLOSING)) sendto_ops("%s for %s", LastDeadComment(to), to->name); Debug((DEBUG_ERROR, LastDeadComment(to))); } +static int can_send(struct Client* to) +{ + assert(0 != to); + return (IsDead(to) || IsMe(to) || -1 == to->fd) ? 0 : 1; +} + /* * flush_connections * @@ -95,19 +104,35 @@ static void dead_link(aClient *to, char *notice) * client and try to send it. if we cant send it, it goes into the sendQ * -avalon */ -void flush_connections(int fd) +void flush_connections(struct Client* cptr) { - Reg1 int i; - Reg2 aClient *cptr; + if (cptr) { + send_queued(cptr); + } + else { + int i; + for (i = HighestFd; i >= 0; i--) { + if ((cptr = LocalClientArray[i])) + send_queued(cptr); + } + } +} - if (fd == me.fd) - { - for (i = highest_fd; i >= 0; i--) - if ((cptr = loc_clients[i]) && DBufLength(&cptr->sendQ) > 0) - send_queued(cptr); +/* + * flush_sendq_except - run through local client array and flush + * the sendq for each client, if the address of the client sendq + * is the same as the one specified, it is skipped. This is used + * by dbuf_put to try to get some more memory before bailing and + * causing the client to be disconnected. + */ +void flush_sendq_except(const struct DBuf* one) +{ + int i; + struct Client* cptr; + for (i = HighestFd; i >= 0; i--) { + if ( (cptr = LocalClientArray[i]) && one != &cptr->sendQ) + send_queued(cptr); } - else if (fd >= 0 && (cptr = loc_clients[fd]) && DBufLength(&cptr->sendQ) > 0) - send_queued(cptr); } /* @@ -117,63 +142,36 @@ void flush_connections(int fd) * when there is a chance that some output would be possible. This * attempts to empty the send queue as far as possible... */ -void send_queued(aClient *to) +void send_queued(struct Client *to) { -#ifndef pyr - if (to->flags & FLAGS_BLOCKED) - return; /* Don't bother */ -#endif - /* - * Once socket is marked dead, we cannot start writing to it, - * even if the error is removed... - */ - if (IsDead(to)) - { - /* - * Actually, we should *NEVER* get here--something is - * not working correct if send_queued is called for a - * dead socket... --msa - * - * But we DO get here since flush_connections() is called - * from the main loop when a server still had remaining data - * in its buffer (not ending on a new-line). - * I rather leave the test here then move it to the main loop - * though: It wouldn't save cpu and it might introduce a bug :/. - * --Run - */ - return; - } - while (DBufLength(&to->sendQ) > 0) - { - const char *msg; - size_t len, rlen; - int tmp; + assert(0 != to); + assert(0 != to->local); - msg = dbuf_map(&to->sendQ, &len); - /* Returns always len > 0 */ - if ((tmp = deliver_it(to, msg, len)) < 0) - { - dead_link(to, "Write error, closing link"); - return; + if (IsBlocked(to) || !can_send(to)) + return; /* Don't bother */ + + while (DBufLength(&to->sendQ) > 0) { + size_t len; + const char* msg = dbuf_map(&to->sendQ, &len); + + if ((len = deliver_it(to, msg, len))) { + dbuf_delete(&to->sendQ, len); + to->lastsq = DBufLength(&to->sendQ) / 1024; + if (IsBlocked(to)) + break; } - rlen = tmp; - dbuf_delete(&to->sendQ, rlen); - to->lastsq = DBufLength(&to->sendQ) / 1024; - if (rlen < len) - { - to->flags |= FLAGS_BLOCKED; /* Wait till select() says - we can write again */ + else { + if (IsDead(to)) + dead_link(to, "Write error, closing link"); break; } } - - return; } /* * send message to single client */ -void sendto_one(aClient *to, char *pattern, ...) +void sendto_one(struct Client *to, const char* pattern, ...) { va_list vl; va_start(vl, pattern); @@ -181,101 +179,87 @@ void sendto_one(aClient *to, char *pattern, ...) va_end(vl); } -void vsendto_one(aClient *to, char *pattern, va_list vl) + +void vsendto_one(struct Client *to, const char* pattern, va_list vl) { vsprintf_irc(sendbuf, pattern, vl); sendbufto_one(to); } -void sendbufto_one(aClient *to) +#ifdef GODMODE +static void send_to_god(struct Client* to, const char* buf) { - int len; + if (!sdbflag && !IsUser(to)) { + char sbuf2[BUFSIZE + 1]; + size_t len = strlen(buf) - 2; /* Remove "\r\n" */ - Debug((DEBUG_SEND, "Sending [%s] to %s", sendbuf, to->name)); + sdbflag = 1; + len = IRCD_MIN(len, BUFSIZE); + ircd_strncpy(sbuf2, buf, len); + sbuf2[len] = '\0'; - if (to->from) - to = to->from; - if (IsDead(to)) - return; /* This socket has already - been marked as dead */ - if (to->fd < 0) - { - /* This is normal when 'to' was being closed (via exit_client - * and close_connection) --Run - * Print the debug message anyway... - */ - Debug((DEBUG_ERROR, "Local socket %s with negative fd %d... AARGH!", - to->name, to->fd)); - return; + if (len > 402) { + char c = sbuf2[200]; + sbuf2[200] = '\0'; + sendto_ops("SND:%-8.8s(%.4d): \"%s...%s\"", + to->name, len, sbuf2, &sbuf2[len - 200]); + } + else + sendto_ops("SND:%-8.8s(%.4d): \"%s\"", to->name, len, sbuf2); + sdbflag = 0; } +} +#endif /* GODMODE */ - len = strlen(sendbuf); - if (sendbuf[len - 1] != '\n') - { - if (len > 510) - len = 510; - sendbuf[len++] = '\r'; - sendbuf[len++] = '\n'; - sendbuf[len] = '\0'; - } +void send_buffer(struct Client* to, char* buf) +{ + size_t len; + assert(0 != to); + assert(0 != buf); - if (IsMe(to)) - { - char tmp_sendbuf[sizeof(sendbuf)]; + if (to->from) + to = to->from; - strcpy(tmp_sendbuf, sendbuf); - sendto_ops("Trying to send [%s] to myself!", tmp_sendbuf); + if (!can_send(to)) + /* + * This socket has already been marked as dead + */ return; - } - if (DBufLength(&to->sendQ) > get_sendq(to)) - { + if (DBufLength(&to->sendQ) > get_sendq(to)) { if (IsServer(to)) - sendto_ops("Max SendQ limit exceeded for %s: " - SIZE_T_FMT " > " SIZE_T_FMT, to->name, - DBufLength(&to->sendQ), get_sendq(to)); + sendto_ops("Max SendQ limit exceeded for %s: " SIZE_T_FMT " > " SIZE_T_FMT, + to->name, DBufLength(&to->sendQ), get_sendq(to)); dead_link(to, "Max sendQ exceeded"); return; } - else if (!dbuf_put(&to->sendQ, sendbuf, len)) - { - dead_link(to, "Buffer allocation error"); - return; + Debug((DEBUG_SEND, "Sending [%s] to %s", buf, to->name)); + + len = strlen(buf); + if (buf[len - 1] != '\n') { + if (len > 510) + len = 510; + buf[len++] = '\r'; + buf[len++] = '\n'; + buf[len] = '\0'; } -#ifdef GODMODE - if (!sdbflag && !IsUser(to)) - { - size_t len = strlen(sendbuf) - 2; /* Remove "\r\n" */ - sdbflag = 1; - strncpy(sendbuf2, sendbuf, len); - sendbuf2[len] = '\0'; - if (len > 402) - { - char c = sendbuf2[200]; - sendbuf2[200] = 0; - sendto_ops("SND:%-8.8s(%.4d): \"%s...%s\"", - to->name, len, sendbuf2, &sendbuf2[len - 200]); - sendbuf2[200] = c; - } - else - sendto_ops("SND:%-8.8s(%.4d): \"%s\"", to->name, len, sendbuf2); - strcpy(sendbuf, sendbuf2); - strcat(sendbuf, "\r\n"); - sdbflag = 0; + if (0 == dbuf_put(&to->sendQ, buf, len)) { + dead_link(to, "Buffer allocation error"); + return; } +#ifdef GODMODE + send_to_god(to, buf); #endif /* GODMODE */ /* * Update statistics. The following is slightly incorrect * because it counts messages even if queued, but bytes * only really sent. Queued bytes get updated in SendQueued. */ - to->sendM += 1; - me.sendM += 1; - if (to->acpt != &me) - to->acpt->sendM += 1; + ++to->sendM; + ++me.sendM; /* * This little bit is to stop the sendQ from growing too large when * there is no need for it to. Thus we call send_queued() every time @@ -288,15 +272,20 @@ void sendbufto_one(aClient *to) send_queued(to); } -static void vsendto_prefix_one(register aClient *to, register aClient *from, - char *pattern, va_list vl) +void sendbufto_one(struct Client* to) +{ + send_buffer(to, sendbuf); +} + +static void vsendto_prefix_one(struct Client *to, struct Client *from, + const char* pattern, va_list vl) { if (to && from && MyUser(to) && IsUser(from)) { static char sender[HOSTLEN + NICKLEN + USERLEN + 5]; char *par; int flag = 0; - Reg3 anUser *user = from->user; + struct User *user = from->user; par = va_arg(vl, char *); strcpy(sender, from->name); @@ -304,14 +293,14 @@ static void vsendto_prefix_one(register aClient *to, register aClient *from, { if (*user->username) { - strcat(sender, "!"); - strcat(sender, user->username); + strcat(sender, "!"); + strcat(sender, user->username); } if (*user->host && !MyConnect(from)) { - strcat(sender, "@"); - strcat(sender, user->host); - flag = 1; + strcat(sender, "@"); + strcat(sender, user->host); + flag = 1; } } /* @@ -321,10 +310,7 @@ static void vsendto_prefix_one(register aClient *to, register aClient *from, if (!flag && MyConnect(from) && *user->host) { strcat(sender, "@"); - if (IsUnixSocket(from)) - strcat(sender, user->host); - else - strcat(sender, from->sockhost); + strcat(sender, from->sockhost); } *sendbuf = ':'; strcpy(&sendbuf[1], sender); @@ -336,94 +322,161 @@ static void vsendto_prefix_one(register aClient *to, register aClient *from, sendbufto_one(to); } -void sendto_channel_butone(aClient *one, aClient *from, aChannel *chptr, - char *pattern, ...) +void sendto_channel_butone(struct Client *one, struct Client *from, struct Channel *chptr, + const char* pattern, ...) { va_list vl; - Reg1 Link *lp; - Reg2 aClient *acptr; - Reg3 int i; + struct Membership* member; + struct Client *acptr; + int i; va_start(vl, pattern); ++sentalong_marker; - for (lp = chptr->members; lp; lp = lp->next) + for (member = chptr->members; member; member = member->next_member) { - acptr = lp->value.cptr; - if (acptr->from == one || /* ...was the one I should skip */ - (lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr)) + acptr = member->user; + /* ...was the one I should skip */ + if (acptr->from == one || IsZombie(member) || IsDeaf(acptr)) continue; - if (MyConnect(acptr)) /* (It is always a client) */ + if (MyConnect(acptr)) /* (It is always a client) */ vsendto_prefix_one(acptr, from, pattern, vl); - else if (sentalong[(i = acptr->from->fd)] != sentalong_marker) + else if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker) { sentalong[i] = sentalong_marker; - /* Don't send channel messages to links that are still eating - the net.burst: -- Run 2/1/1997 */ + /* + * Don't send channel messages to links that are still eating + * the net.burst: -- Run 2/1/1997 + */ if (!IsBurstOrBurstAck(acptr->from)) - vsendto_prefix_one(acptr, from, pattern, vl); + vsendto_prefix_one(acptr, from, pattern, vl); } } va_end(vl); - return; } -void sendto_lchanops_butone(aClient *one, aClient *from, aChannel *chptr, - char *pattern, ...) + +void sendmsgto_channel_butone(struct Client *one, struct Client *from, + struct Channel *chptr, const char *sender, + const char *cmd, const char *chname, const char *msg) +{ + /* + * Sends a PRIVMSG/NOTICE to all members on a channel but 'one', translating + * TOKENS to full messages when sent to local clients. --Gte (12/12/99) + */ + struct Membership* member; + struct Client *acptr; + char userbuf[2048]; + char servbuf[2048]; + int i; + int flag=-1; + + /* + * Precalculate the buffers we sent to the clients instead of doing an + * expensive sprintf() per member that we send to. We still have to + * use strcpy() which is evil. + */ + if (IsServer(from)) { + sprintf(userbuf,":%s %s %s :%s", + from->name, + ((cmd[0] == 'P') ? MSG_PRIVATE : MSG_NOTICE), + chname, msg); + sprintf(servbuf,"%s " TOK_PRIVATE " %s :%s", + NumServ(from), chname, msg); + } else { + sprintf(userbuf,":%s!%s@%s %s %s :%s", + from->name, from->username, from->user->host, + ((cmd[0] == 'P') ? MSG_PRIVATE : MSG_NOTICE), + chname, msg); + sprintf(servbuf,"%s%s %s %s :%s", + NumNick(from), + ((cmd[0] == 'P') ? TOK_PRIVATE : TOK_NOTICE), + chname, msg); + } + + ++sentalong_marker; + for (member = chptr->members; member; member = member->next_member) + { + acptr = member->user; + /* ...was the one I should skip */ + if (acptr->from == one || IsZombie(member) || IsDeaf(acptr)) + continue; + if (MyConnect(acptr)) { /* (It is always a client) */ + if (flag!=0) + strcpy(sendbuf,userbuf); + flag=0; + sendbufto_one(acptr); + } + else if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker) + { + sentalong[i] = sentalong_marker; + if (!IsBurstOrBurstAck(acptr->from)) { + if (flag != 1) + strcpy(sendbuf,servbuf); + flag = 1; + sendbufto_one(acptr); + } + } /* of if MyConnect() */ + } /* of for(members) */ +} + +void sendto_lchanops_butone(struct Client *one, struct Client *from, struct Channel *chptr, + const char* pattern, ...) { va_list vl; - Reg1 Link *lp; - Reg2 aClient *acptr; + struct Membership* member; + struct Client *acptr; va_start(vl, pattern); - for (lp = chptr->members; lp; lp = lp->next) + for (member = chptr->members; member; member = member->next_member) { - acptr = lp->value.cptr; - if (acptr == one || /* ...was the one I should skip */ - !(lp->flags & CHFL_CHANOP) || /* Skip non chanops */ - (lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr)) + acptr = member->user; + /* ...was the one I should skip */ + if (acptr == one || !IsChanOp(member) || IsZombie(member) || IsDeaf(acptr)) continue; - if (MyConnect(acptr)) /* (It is always a client) */ + if (MyConnect(acptr)) /* (It is always a client) */ vsendto_prefix_one(acptr, from, pattern, vl); } va_end(vl); return; } -void sendto_chanopsserv_butone(aClient *one, aClient *from, aChannel *chptr, - char *pattern, ...) +void sendto_chanopsserv_butone(struct Client *one, struct Client *from, struct Channel *chptr, + const char* pattern, ...) { va_list vl; - Reg1 Link *lp; - Reg2 aClient *acptr; - Reg3 int i; + struct Membership* member; + struct Client *acptr; + int i; #ifndef NO_PROTOCOL9 - char target[128]; - char *source, *tp, *msg; + char target[128]; + char* source; + char* tp; + char* msg; #endif va_start(vl, pattern); ++sentalong_marker; - for (lp = chptr->members; lp; lp = lp->next) + for (member = chptr->members; member; member = member->next_member) { - acptr = lp->value.cptr; - if (acptr->from == acptr || /* Skip local clients */ + acptr = member->user; + if (acptr->from == acptr || /* Skip local clients */ #ifndef NO_PROTOCOL9 - Protocol(acptr->from) < 10 || /* Skip P09 links */ + Protocol(acptr->from) < 10 || /* Skip P09 links */ #endif - acptr->from == one || /* ...was the one I should skip */ - !(lp->flags & CHFL_CHANOP) || /* Skip non chanops */ - (lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr)) + acptr->from == one || /* ...was the one I should skip */ + !IsChanOp(member) || /* Skip non chanops */ + IsZombie(member) || IsDeaf(acptr)) continue; - if (sentalong[(i = acptr->from->fd)] != sentalong_marker) + if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker) { sentalong[i] = sentalong_marker; /* Don't send channel messages to links that are still eating the net.burst: -- Run 2/1/1997 */ if (!IsBurstOrBurstAck(acptr->from)) - vsendto_prefix_one(acptr, from, pattern, vl); + vsendto_prefix_one(acptr, from, pattern, vl); } } @@ -431,52 +484,52 @@ void sendto_chanopsserv_butone(aClient *one, aClient *from, aChannel *chptr, /* Send message to all 2.9 servers */ /* This is a hack, because it assumes that we know how `vl' is build up */ source = va_arg(vl, char *); - tp = va_arg(vl, char *); /* Channel */ + tp = va_arg(vl, char *); /* Channel */ msg = va_arg(vl, char *); - for (lp = chptr->members; lp; lp = lp->next) + for (member = chptr->members; member; member = member->next_member) { - acptr = lp->value.cptr; - if (acptr->from == acptr || /* Skip local clients */ - Protocol(acptr->from) > 9 || /* Skip P10 servers */ - acptr->from == one || /* ...was the one I should skip */ - !(lp->flags & CHFL_CHANOP) || /* Skip non chanops */ - (lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr)) + acptr = member->user; + if (acptr->from == acptr || /* Skip local clients */ + Protocol(acptr->from) > 9 || /* Skip P10 servers */ + acptr->from == one || /* ...was the one I should skip */ + !IsChanOp(member) || /* Skip non chanops */ + IsZombie(member) || IsDeaf(acptr)) continue; - if (sentalong[(i = acptr->from->fd)] != sentalong_marker) + if (-1 < (i = acptr->from->fd) && sentalong[i] != sentalong_marker) { sentalong[i] = sentalong_marker; /* Don't send channel messages to links that are still eating the net.burst: -- Run 2/1/1997 */ if (!IsBurstOrBurstAck(acptr->from)) { - Link *lp2; - aClient *acptr2; - tp = target; - *tp = 0; - /* Find all chanops in this direction: */ - for (lp2 = chptr->members; lp2; lp2 = lp2->next) - { - acptr2 = lp2->value.cptr; - if (acptr2->from == acptr->from && acptr2->from != one && - (lp2->flags & CHFL_CHANOP) && !(lp2->flags & CHFL_ZOMBIE) && - !IsDeaf(acptr2)) - { - int len = strlen(acptr2->name); - if (tp + len + 2 > target + sizeof(target)) - { - sendto_prefix_one(acptr, from, - ":%s NOTICE %s :%s", source, target, msg); - tp = target; - *tp = 0; - } - if (*target) - strcpy(tp++, ","); - strcpy(tp, acptr2->name); - tp += len; - } - } - sendto_prefix_one(acptr, from, - ":%s NOTICE %s :%s", source, target, msg); + struct Membership* other_member; + struct Client* acptr2; + tp = target; + *tp = 0; + /* Find all chanops in this direction: */ + for (other_member = chptr->members; other_member; other_member = other_member->next_member) + { + acptr2 = other_member->user; + if (acptr2->from == acptr->from && acptr2->from != one && + IsChanOp(other_member) && !IsZombie(other_member) && + !IsDeaf(acptr2)) + { + int len = strlen(acptr2->name); + if (tp + len + 2 > target + sizeof(target)) + { + sendto_prefix_one(acptr, from, + ":%s NOTICE %s :%s", source, target, msg); + tp = target; + *tp = 0; + } + if (*target) + strcpy(tp++, ","); + strcpy(tp, acptr2->name); + tp += len; + } + } + sendto_prefix_one(acptr, from, + ":%s NOTICE %s :%s", source, target, msg); } } } @@ -491,10 +544,10 @@ void sendto_chanopsserv_butone(aClient *one, aClient *from, aChannel *chptr, * * Send a message to all connected servers except the client 'one'. */ -void sendto_serv_butone(aClient *one, char *pattern, ...) +void sendto_serv_butone(struct Client *one, const char* pattern, ...) { va_list vl; - Reg1 Dlink *lp; + struct DLink *lp; va_start(vl, pattern); vsprintf_irc(sendbuf, pattern, vl); @@ -515,9 +568,9 @@ void sendto_serv_butone(aClient *one, char *pattern, ...) * Send prepared sendbuf to all connected servers except the client 'one' * -Ghostwolf 18-May-97 */ -void sendbufto_serv_butone(aClient *one) +void sendbufto_serv_butone(struct Client *one) { - Reg1 Dlink *lp; + struct DLink *lp; for (lp = me.serv->down; lp; lp = lp->next) { @@ -527,35 +580,44 @@ void sendbufto_serv_butone(aClient *one) } } + /* * sendto_common_channels() * * Sends a message to all people (inclusing `acptr') on local server * who are in same channel with client `acptr'. */ -void sendto_common_channels(aClient *acptr, char *pattern, ...) +void sendto_common_channels(struct Client *acptr, const char* pattern, ...) { va_list vl; - Reg1 Link *chan; - Reg2 Link *member; + struct Membership* chan; + struct Membership* member; + + assert(0 != acptr); + assert(0 != acptr->from); + assert(0 != pattern); va_start(vl, pattern); ++sentalong_marker; - if (acptr->fd >= 0) - sentalong[acptr->fd] = sentalong_marker; - /* loop through acptr's channels, and the members on their channels */ - if (acptr->user) - for (chan = acptr->user->channel; chan; chan = chan->next) - for (member = chan->value.chptr->members; member; member = member->next) - { - Reg3 aClient *cptr = member->value.cptr; - if (MyConnect(cptr) && sentalong[cptr->fd] != sentalong_marker) - { - sentalong[cptr->fd] = sentalong_marker; - vsendto_prefix_one(cptr, acptr, pattern, vl); - } + if (-1 < acptr->from->fd) + sentalong[acptr->from->fd] = sentalong_marker; + /* + * loop through acptr's channels, and the members on their channels + */ + if (acptr->user) { + for (chan = acptr->user->channel; chan; chan = chan->next_channel) { + for (member = chan->channel->members; member; member = member->next_member) { + struct Client *cptr = member->user; + int i; + if (MyConnect(cptr) && + -1 < (i = cptr->fd) && sentalong[i] != sentalong_marker) { + sentalong[i] = sentalong_marker; + vsendto_prefix_one(cptr, acptr, pattern, vl); + } } + } + } if (MyConnect(acptr)) vsendto_prefix_one(acptr, acptr, pattern, vl); va_end(vl); @@ -568,15 +630,18 @@ void sendto_common_channels(aClient *acptr, char *pattern, ...) * Send a message to all members of a channel that * are connected to this server. */ -void sendto_channel_butserv(aChannel *chptr, aClient *from, char *pattern, ...) +void sendto_channel_butserv(struct Channel *chptr, struct Client *from, const char* pattern, ...) { va_list vl; - Reg1 Link *lp; - Reg2 aClient *acptr; + struct Membership* member; + struct Client *acptr; + + va_start(vl, pattern); - for (va_start(vl, pattern), lp = chptr->members; lp; lp = lp->next) - if (MyConnect(acptr = lp->value.cptr) && !(lp->flags & CHFL_ZOMBIE)) + for (member = chptr->members; member; member = member->next_member) { + if (MyConnect(acptr = member->user) && !IsZombie(member)) vsendto_prefix_one(acptr, from, pattern, vl); + } va_end(vl); return; } @@ -588,7 +653,7 @@ void sendto_channel_butserv(aChannel *chptr, aClient *from, char *pattern, ...) * addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de) */ -static int match_it(aClient *one, char *mask, int what) +static int match_it(struct Client *one, const char *mask, int what) { switch (what) { @@ -606,30 +671,30 @@ static int match_it(aClient *one, char *mask, int what) * Send to all clients which match the mask in a way defined on 'what'; * either by user hostname or user servername. */ -void sendto_match_butone(aClient *one, aClient *from, - char *mask, int what, char *pattern, ...) +void sendto_match_butone(struct Client *one, struct Client *from, + const char *mask, int what, const char* pattern, ...) { va_list vl; - Reg1 int i; - Reg2 aClient *cptr, *acptr; + int i; + struct Client *cptr, *acptr; va_start(vl, pattern); - for (i = 0; i <= highest_fd; i++) + for (i = 0; i <= HighestFd; i++) { - if (!(cptr = loc_clients[i])) - continue; /* that clients are not mine */ - if (cptr == one) /* must skip the origin !! */ + if (!(cptr = LocalClientArray[i])) + continue; /* that clients are not mine */ + if (cptr == one) /* must skip the origin !! */ continue; if (IsServer(cptr)) { - for (acptr = client; acptr; acptr = acptr->next) - if (IsUser(acptr) && match_it(acptr, mask, what) && acptr->from == cptr) - break; + for (acptr = GlobalClientList; acptr; acptr = acptr->next) + if (IsUser(acptr) && match_it(acptr, mask, what) && acptr->from == cptr) + break; /* a person on that server matches the mask, so we * send *one* msg to that server ... */ if (acptr == NULL) - continue; + continue; /* ... but only if there *IS* a matching person */ } /* my client, does he match ? */ @@ -647,25 +712,27 @@ void sendto_match_butone(aClient *one, aClient *from, * * Send to *local* ops but one. */ -void sendto_lops_butone(aClient *one, char *pattern, ...) +void sendto_lops_butone(struct Client* one, const char* pattern, ...) { - va_list vl; - Reg1 aClient *cptr; - aClient **cptrp; - int i; - char nbuf[1024]; + va_list vl; + struct Client* cptr; + struct Client** clients = me.serv->client_list; + int i; + char nbuf[1024]; + + assert(0 != clients); sprintf_irc(nbuf, ":%s NOTICE %%s :*** Notice -- ", me.name); va_start(vl, pattern); vsprintf_irc(nbuf + strlen(nbuf), pattern, vl); va_end(vl); - for (cptrp = me.serv->client_list, i = 0; i <= me.serv->nn_mask; ++cptrp, ++i) - if ((cptr = *cptrp) && cptr != one && SendServNotice(cptr)) - { + + for (i = 0; i <= me.serv->nn_mask; ++i) { + if ((cptr = clients[i]) && cptr != one && SendServNotice(cptr)) { sprintf_irc(sendbuf, nbuf, cptr->name); sendbufto_one(cptr); } - return; + } } /* @@ -675,12 +742,12 @@ void sendto_lops_butone(aClient *one, char *pattern, ...) * Don't try to send to more than one list! That is not supported. * Xorath 5/1/97 */ -void vsendto_op_mask(register snomask_t mask, const char *pattern, va_list vl) +void vsendto_op_mask(unsigned int mask, const char *pattern, va_list vl) { static char fmt[1024]; char *fmt_target; - register int i = 0; /* so that 1 points to opsarray[0] */ - Link *opslist; + int i = 0; /* so that 1 points to opsarray[0] */ + struct SLink *opslist; while ((mask >>= 1)) i++; @@ -705,10 +772,10 @@ void vsendto_op_mask(register snomask_t mask, const char *pattern, va_list vl) * Send a prepared sendbuf to the list indicated by the bitmask field. * Ghostwolf 16-May-97 */ -void sendbufto_op_mask(snomask_t mask) +void sendbufto_op_mask(unsigned int mask) { - register int i = 0; /* so that 1 points to opsarray[0] */ - Link *opslist; + int i = 0; /* so that 1 points to opsarray[0] */ + struct SLink *opslist; while ((mask >>= 1)) i++; if (!(opslist = opsarray[i])) @@ -729,27 +796,25 @@ void sendbufto_op_mask(snomask_t mask) */ void vsendto_ops(const char *pattern, va_list vl) { - Reg1 aClient *cptr; - Reg2 int i; + struct Client *cptr; + int i; char fmt[1024]; char *fmt_target; fmt_target = sprintf_irc(fmt, ":%s NOTICE ", me.name); - for (i = 0; i <= highest_fd; i++) - if ((cptr = loc_clients[i]) && !IsServer(cptr) && !IsMe(cptr) && - SendServNotice(cptr)) + for (i = 0; i <= HighestFd; i++) + if ((cptr = LocalClientArray[i]) && !IsServer(cptr) && + SendServNotice(cptr)) { strcpy(fmt_target, cptr->name); strcat(fmt_target, " :*** Notice -- "); strcat(fmt_target, pattern); vsendto_one(cptr, fmt, vl); } - - return; } -void sendto_op_mask(snomask_t mask, const char *pattern, ...) +void sendto_op_mask(unsigned int mask, const char *pattern, ...) { va_list vl; va_start(vl, pattern); @@ -772,24 +837,23 @@ void sendto_ops(const char *pattern, ...) * one - client not to send message to * from- client which message is from *NEVER* NULL!! */ -void sendto_ops_butone(aClient *one, aClient *from, char *pattern, ...) +void sendto_ops_butone(struct Client *one, struct Client *from, const char *pattern, ...) { va_list vl; - Reg1 int i; - Reg2 aClient *cptr; + int i; + struct Client *cptr; va_start(vl, pattern); ++sentalong_marker; - for (cptr = client; cptr; cptr = cptr->next) + for (cptr = GlobalClientList; cptr; cptr = cptr->next) { - /*if (!IsAnOper(cptr)) */ if (!SendWallops(cptr)) continue; - i = cptr->from->fd; /* find connection oper is on */ - if (sentalong[i] == sentalong_marker) /* sent message along it already ? */ + i = cptr->from->fd; /* find connection oper is on */ + if (i < 0 || sentalong[i] == sentalong_marker) /* sent message along it already ? */ continue; if (cptr->from == one) - continue; /* ...was the one I should skip */ + continue; /* ...was the one I should skip */ sentalong[i] = sentalong_marker; vsendto_prefix_one(cptr->from, from, pattern, vl); } @@ -805,21 +869,21 @@ void sendto_ops_butone(aClient *one, aClient *from, char *pattern, ...) * * one - server not to send message to. */ -void sendto_g_serv_butone(aClient *one, char *pattern, ...) +void sendto_g_serv_butone(struct Client *one, const char *pattern, ...) { va_list vl; - aClient *cptr; + struct Client *cptr; int i; va_start(vl, pattern); ++sentalong_marker; vsprintf_irc(sendbuf, pattern, vl); - for (cptr = client; cptr; cptr = cptr->next) + for (cptr = GlobalClientList; cptr; cptr = cptr->next) { if (!SendDebug(cptr)) continue; - i = cptr->from->fd; /* find connection user is on */ - if (sentalong[i] == sentalong_marker) /* sent message along it already ? */ + i = cptr->from->fd; /* find connection user is on */ + if (i < 0 || sentalong[i] == sentalong_marker) /* sent message along it already ? */ continue; if (MyConnect(cptr)) continue; @@ -842,7 +906,7 @@ void sendto_g_serv_butone(aClient *one, char *pattern, ...) * NOTE: NEITHER OF THESE SHOULD *EVER* BE NULL!! * -avalon */ -void sendto_prefix_one(Reg1 aClient *to, Reg2 aClient *from, char *pattern, ...) +void sendto_prefix_one(struct Client *to, struct Client *from, const char *pattern, ...) { va_list vl; va_start(vl, pattern); @@ -869,10 +933,10 @@ void sendto_realops(const char *pattern, ...) /* * Send message to all servers of protocol 'p' and lower. */ -void sendto_lowprot_butone(aClient *cptr, int p, char *pattern, ...) +void sendto_lowprot_butone(struct Client *cptr, int p, const char *pattern, ...) { va_list vl; - Dlink *lp; + struct DLink *lp; va_start(vl, pattern); for (lp = me.serv->down; lp; lp = lp->next) if (lp->value.cptr != cptr && Protocol(lp->value.cptr) <= p) @@ -883,10 +947,10 @@ void sendto_lowprot_butone(aClient *cptr, int p, char *pattern, ...) /* * Send message to all servers of protocol 'p' and higher. */ -void sendto_highprot_butone(aClient *cptr, int p, char *pattern, ...) +void sendto_highprot_butone(struct Client *cptr, int p, const char *pattern, ...) { va_list vl; - Dlink *lp; + struct DLink *lp; va_start(vl, pattern); for (lp = me.serv->down; lp; lp = lp->next) if (lp->value.cptr != cptr && Protocol(lp->value.cptr) >= p)