* 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 <stdio.h>
-#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 <assert.h>
+#include <stdio.h>
+#include <string.h>
-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;
* 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;
/*
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), get_client_name(to, FALSE));
+ 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
*
* 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);
}
/*
* 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);
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,
- get_client_name(to, FALSE), 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
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);
{
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;
}
}
/*
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);
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);
}
}
/* 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);
}
}
}
*
* 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);
* 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)
{
}
}
+
/*
* 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);
* 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;
}
* 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)
{
* 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 ? */
*
* 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;
+ }
}
/*
* 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++;
* 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]))
*/
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);
* 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 (!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);
}
*
* 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;
* 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);
/*
* 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)
/*
* 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)