-void sendbufto_one(struct Client* to)
-{
- send_buffer(to, sendbuf);
-}
-
-/* See vsendcmdto_one, below */
-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;
- struct User *user = from->user;
-
- par = va_arg(vl, char *);
- strcpy(sender, from->name);
- if (user)
- {
- if (*user->username)
- {
- strcat(sender, "!");
- strcat(sender, user->username);
- }
- if (*user->host && !MyConnect(from))
- {
- strcat(sender, "@");
- strcat(sender, user->host);
- flag = 1;
- }
- }
- /*
- * Flag is used instead of strchr(sender, '@') for speed and
- * also since username/nick may have had a '@' in them. -avalon
- */
- if (!flag && MyConnect(from) && *user->host)
- {
- strcat(sender, "@");
- strcat(sender, from->sockhost);
- }
- *sendbuf = ':';
- strcpy(&sendbuf[1], sender);
- /* Assuming 'pattern' always starts with ":%s ..." */
- vsprintf_irc(sendbuf + strlen(sendbuf), &pattern[3], vl);
- }
- else
- vsprintf_irc(sendbuf, pattern, vl);
- sendbufto_one(to);
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendto_channel_butone(struct Client *one, struct Client *from, struct Channel *chptr,
- const char* pattern, ...)
-{
- va_list vl;
- struct Membership* member;
- struct Client *acptr;
- int i;
-
- va_start(vl, pattern);
-
- ++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) */
- vsendto_prefix_one(acptr, from, pattern, vl);
- 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
- */
- if (!IsBurstOrBurstAck(acptr->from))
- vsendto_prefix_one(acptr, from, pattern, vl);
- }
- }
- va_end(vl);
-}
-
-/* See sendcmdto_channel_butone, below */
-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;
-
- assert(0 != cmd);
- /*
- * 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, ('P' == *cmd) ? MSG_PRIVATE : MSG_NOTICE, chname, msg);
- sprintf(servbuf,"%s %s %s :%s", NumServ(from), cmd, chname, msg);
- }
- else {
- sprintf(userbuf,":%s!%s@%s %s %s :%s",
- from->name, from->user->username, from->user->host,
- ('P' == *cmd) ? MSG_PRIVATE : MSG_NOTICE, chname, msg);
- sprintf(servbuf,"%s%s %s %s :%s", NumNick(from), cmd, 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) */
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendto_lchanops_butone(struct Client *one, struct Client *from, struct Channel *chptr,
- const char* pattern, ...)
-{
- va_list vl;
- struct Membership* member;
- struct Client *acptr;
-
- va_start(vl, pattern);
-
- for (member = chptr->members; member; member = member->next_member)
- {
- 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) */
- vsendto_prefix_one(acptr, from, pattern, vl);
- }
- va_end(vl);
- return;
-}
-
-/* See sendcmdto_channel_butone, below */
-void sendto_chanopsserv_butone(struct Client *one, struct Client *from, struct Channel *chptr,
- const char* pattern, ...)
-{
- va_list vl;
- struct Membership* member;
- struct Client *acptr;
- int i;
-#ifndef NO_PROTOCOL9
- char target[128];
- char* source;
- char* tp;
- char* msg;
-#endif
-
- va_start(vl, pattern);
-
- ++sentalong_marker;
- for (member = chptr->members; member; member = member->next_member)
- {
- acptr = member->user;
- if (acptr->from == acptr || /* Skip local clients */
-#ifndef NO_PROTOCOL9
- Protocol(acptr->from) < 10 || /* Skip P09 links */
-#endif
- acptr->from == one || /* ...was the one I should skip */
- !IsChanOp(member) || /* Skip non chanops */
- IsZombie(member) || IsDeaf(acptr))
- continue;
- 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);
- }
- }
-
-#ifndef NO_PROTOCOL9
- /* 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 */
- msg = va_arg(vl, char *);
- for (member = chptr->members; member; member = member->next_member)
- {
- 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 (-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))
- {
- 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);
- }
- }
- }
-#endif
-
- va_end(vl);
- return;
-}
-
-/*
- * sendto_serv_butone
- *
- * Send a message to all connected servers except the client 'one'.
- */
-/* See sendcmdto_serv_butone, below */
-void sendto_serv_butone(struct Client *one, const char* pattern, ...)
-{
- va_list vl;
- struct DLink *lp;
-
- va_start(vl, pattern);
- vsprintf_irc(sendbuf, pattern, vl);
- va_end(vl);
-
- for (lp = me.serv->down; lp; lp = lp->next)
- {
- if (one && lp->value.cptr == one->from)
- continue;
- sendbufto_one(lp->value.cptr);
- }
-
-}
-
-/*
- * sendbufto_serv_butone()
- *
- * Send prepared sendbuf to all connected servers except the client 'one'
- * -Ghostwolf 18-May-97
- */
-void sendbufto_serv_butone(struct Client *one)
-{
- struct DLink *lp;
-
- for (lp = me.serv->down; lp; lp = lp->next)
- {
- if (one && lp->value.cptr == one->from)
- continue;
- sendbufto_one(lp->value.cptr);
- }
-}
-
-
-/*
- * sendto_common_channels()
- *
- * Sends a message to all people (inclusing `acptr') on local server
- * who are in same channel with client `acptr'.
- */
-/* See sendcmdto_common_channels, below */
-void sendto_common_channels(struct Client *acptr, const char* pattern, ...)
-{
- va_list vl;
- struct Membership* chan;
- struct Membership* member;
-
- assert(0 != acptr);
- assert(0 != acptr->from);
- assert(0 != pattern);
-
- va_start(vl, pattern);
-
- ++sentalong_marker;
- 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);
- return;
-}
-
-/*
- * sendto_channel_butserv
- *
- * Send a message to all members of a channel that
- * are connected to this server.
- *
- * This contains a subtle bug; after the first call to vsendto_prefix_one()
- * below, vl is in an indeterminate state, according to ANSI; we'd have to
- * move va_start() and va_end() into the loop to correct the problem. It's
- * easier, however, just to use sendcmdto_channel_butserv(), which builds a
- * buffer and sends that prepared buffer to each channel member.
- */
-/* See sendcmdto_channel_butserv, below */
-void sendto_channel_butserv(struct Channel *chptr, struct Client *from, const char* pattern, ...)
-{
- va_list vl;
- struct Membership* member;
- struct Client *acptr;
-
- va_start(vl, pattern);
-
- for (member = chptr->members; member; member = member->next_member) {
- acptr = member->user;
- if (MyConnect(acptr) && !IsZombie(member))
- vsendto_prefix_one(acptr, from, pattern, vl);
- }
- va_end(vl);
- return;
-}
-