init
This commit is contained in:
955
common/send.c
Normal file
955
common/send.c
Normal file
@@ -0,0 +1,955 @@
|
||||
/************************************************************************
|
||||
* IRC - Internet Relay Chat, common/send.c
|
||||
* Copyright (C) 1990 Jarkko Oikarinen and
|
||||
* University of Oulu, Computing Center
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 1, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* -- Run -- 28 sept 1994
|
||||
* Corrected the wrong way varargs were treated...
|
||||
*/
|
||||
|
||||
/* -- Jto -- 16 Jun 1990
|
||||
* Added Armin's PRIVMSG patches...
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)send.c 2.32 2/28/94 (C) 1988 University of Oulu, \
|
||||
Computing Center and Jarkko Oikarinen";
|
||||
#endif
|
||||
|
||||
#include "struct.h"
|
||||
#include "common.h"
|
||||
#include "sys.h"
|
||||
#include "h.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static char sendbuf[2048];
|
||||
static void sendbufto_one PROTO((aClient *));
|
||||
static int sentalong[MAXCONNECTIONS];
|
||||
|
||||
/*
|
||||
** dead_link
|
||||
** An error has been detected. The link *must* be closed,
|
||||
** but *cannot* call ExitClient (m_bye) from here.
|
||||
** Instead, mark it with FLAGS_DEADSOCKET. This should
|
||||
** generate ExitClient from the main loop.
|
||||
**
|
||||
** If 'notice' is not NULL, it is assumed to be a format
|
||||
** for a message to local opers. I can contain only one
|
||||
** '%s', which will be replaced by the sockhost field of
|
||||
** the failing link.
|
||||
**
|
||||
** Also, the notice is skipped for "uninteresting" cases,
|
||||
** like Persons and yet unknown connections...
|
||||
*/
|
||||
char *last_dead_comment = NULL;
|
||||
|
||||
static void dead_link(to, notice)
|
||||
aClient *to;
|
||||
char *notice;
|
||||
{
|
||||
char dead_comment_buf[256]; /* SHOULD be big enough */
|
||||
|
||||
to->flags |= FLAGS_DEADSOCKET;
|
||||
/*
|
||||
* If because of BUFFERPOOL problem then clean dbuf's now so that
|
||||
* notices don't hurt operators below.
|
||||
*/
|
||||
DBufClear(&to->recvQ);
|
||||
DBufClear(&to->sendQ);
|
||||
|
||||
/* Keep a copy of the last comment, for later use... */
|
||||
sprintf(dead_comment_buf, notice, get_client_name(to, FALSE));
|
||||
if (last_dead_comment)
|
||||
MyFree(last_dead_comment);
|
||||
last_dead_comment = (char *)MyMalloc(strlen(dead_comment_buf) + 1);
|
||||
strcpy(last_dead_comment, dead_comment_buf);
|
||||
|
||||
if (!IsPerson(to) && !IsUnknown(to) && !(to->flags & FLAGS_CLOSING))
|
||||
sendto_ops(last_dead_comment);
|
||||
Debug((DEBUG_ERROR, last_dead_comment));
|
||||
}
|
||||
|
||||
/*
|
||||
** flush_connections
|
||||
** Used to empty all output buffers for all connections. Should only
|
||||
** be called once per scan of connections. There should be a select in
|
||||
** here perhaps but that means either forcing a timeout or doing a poll.
|
||||
** When flushing, all we do is empty the obuffer array for each local
|
||||
** client and try to send it. if we cant send it, it goes into the sendQ
|
||||
** -avalon
|
||||
*/
|
||||
void flush_connections(fd)
|
||||
int fd;
|
||||
{
|
||||
Reg1 int i;
|
||||
Reg2 aClient *cptr;
|
||||
|
||||
if (fd == me.fd)
|
||||
{
|
||||
for (i = highest_fd; i >= 0; i--)
|
||||
if ((cptr = local[i]) && DBufLength(&cptr->sendQ) > 0)
|
||||
send_queued(cptr);
|
||||
}
|
||||
else if (fd >= 0 && (cptr = local[fd]) && DBufLength(&cptr->sendQ) > 0)
|
||||
send_queued(cptr);
|
||||
}
|
||||
|
||||
/*
|
||||
** send_queued
|
||||
** This function is called from the main select-loop (or whatever)
|
||||
** 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(to)
|
||||
aClient *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
|
||||
*/
|
||||
return;
|
||||
}
|
||||
while (DBufLength(&to->sendQ) > 0)
|
||||
{
|
||||
char *msg;
|
||||
int len, rlen;
|
||||
|
||||
msg = dbuf_map(&to->sendQ, &len);
|
||||
/* Returns always len > 0 */
|
||||
if ((rlen = deliver_it(to, msg, len)) < 0)
|
||||
{
|
||||
dead_link(to,"Write error to %s, closing link");
|
||||
return;
|
||||
}
|
||||
(void)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 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** send message to single client
|
||||
*/
|
||||
#ifdef USE_VARARGS
|
||||
void sendto_one(to, pattern, va_alist)
|
||||
aClient *to;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl);
|
||||
vsendto_one(to, pattern, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void vsendto_one(to, pattern, vl)
|
||||
aClient *to;
|
||||
char *pattern;
|
||||
va_list vl;
|
||||
{
|
||||
#else
|
||||
void sendto_one(to, pattern, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
|
||||
aClient *to;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11;
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
(void)vsprintf(sendbuf, pattern, vl);
|
||||
#else
|
||||
(void)sprintf(sendbuf, pattern, p1, p2, p3, p4, p5, p6,
|
||||
p7, p8, p9, p10, p11);
|
||||
#endif
|
||||
sendbufto_one(to);
|
||||
}
|
||||
|
||||
static void sendbufto_one(to)
|
||||
aClient *to;
|
||||
{
|
||||
int len;
|
||||
|
||||
Debug((DEBUG_SEND,"Sending [%s] to %s", sendbuf,to->name));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
len = strlen(sendbuf);
|
||||
if (sendbuf[len-1] != '\n')
|
||||
{
|
||||
#ifndef IRCII_KLUDGE
|
||||
if (len > 510)
|
||||
len = 510;
|
||||
sendbuf[len++] = '\r';
|
||||
#else
|
||||
if (len > 511)
|
||||
len = 511;
|
||||
#endif
|
||||
sendbuf[len++] = '\n';
|
||||
sendbuf[len] = '\0';
|
||||
}
|
||||
|
||||
if (IsMe(to))
|
||||
{
|
||||
char tmp_sendbuf[sizeof(sendbuf)];
|
||||
|
||||
strcpy(tmp_sendbuf, sendbuf);
|
||||
sendto_ops("Trying to send [%s] to myself!", tmp_sendbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DBufLength(&to->sendQ) > get_sendq(to))
|
||||
{
|
||||
if (IsServer(to))
|
||||
sendto_ops("Max SendQ limit exceeded for %s: %d > %d",
|
||||
get_client_name(to, FALSE),
|
||||
DBufLength(&to->sendQ), get_sendq(to));
|
||||
dead_link(to, "Max Sendq exceeded");
|
||||
return;
|
||||
}
|
||||
|
||||
else if (dbuf_put(&to->sendQ, sendbuf, len) < 0)
|
||||
{
|
||||
dead_link(to, "Buffer allocation error for %s");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
** 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;
|
||||
/*
|
||||
** 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
|
||||
** 2k has been added to the queue since the last non-fatal write.
|
||||
** Also stops us from deliberately building a large sendQ and then
|
||||
** trying to flood that link with data (possible during the net
|
||||
** relinking done by servers with a large load).
|
||||
*/
|
||||
if (DBufLength(&to->sendQ)/1024 > to->lastsq)
|
||||
send_queued(to);
|
||||
}
|
||||
|
||||
# ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_channel_butone(one, from, chptr, pattern,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
aClient *one, *from;
|
||||
aChannel *chptr;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
# else
|
||||
void sendto_channel_butone(one, from, chptr, pattern, va_alist)
|
||||
aClient *one, *from;
|
||||
aChannel *chptr;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
# endif
|
||||
Reg1 Link *lp;
|
||||
Reg2 aClient *acptr;
|
||||
Reg3 int i;
|
||||
|
||||
# ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
# endif
|
||||
for (i = 0; i < MAXCONNECTIONS; i++)
|
||||
sentalong[i] = 0;
|
||||
for (lp = chptr->members; lp; lp = lp->next)
|
||||
{
|
||||
acptr = lp->value.cptr;
|
||||
if (acptr->from == one || /* ...was the one I should skip */
|
||||
(lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr))
|
||||
continue;
|
||||
i = acptr->from->fd;
|
||||
if (MyConnect(acptr) && IsRegisteredUser(acptr))
|
||||
{
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_prefix_one(acptr, from, pattern, vl);
|
||||
# else
|
||||
sendto_prefix_one(acptr, from, pattern, p1, p2,
|
||||
p3, p4, p5, p6, p7, p8);
|
||||
# endif
|
||||
sentalong[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Now check whether a message has been sent to this
|
||||
* remote link already */
|
||||
if (sentalong[i] == 0)
|
||||
{
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_prefix_one(acptr, from, pattern, vl);
|
||||
# else
|
||||
sendto_prefix_one(acptr, from, pattern,
|
||||
p1, p2, p3, p4,
|
||||
p5, p6, p7, p8);
|
||||
# endif
|
||||
sentalong[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
# ifdef USE_VARARGS
|
||||
va_end(vl);
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_server_butone
|
||||
*
|
||||
* Send a message to all connected servers except the client 'one'.
|
||||
*/
|
||||
# ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_serv_butone(one, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
aClient *one;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
# else
|
||||
void sendto_serv_butone(one, pattern, va_alist)
|
||||
aClient *one;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
# endif
|
||||
Reg1 Dlink *lp;
|
||||
|
||||
# ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
(void)vsprintf(sendbuf, pattern, vl);
|
||||
va_end(vl);
|
||||
# else
|
||||
(void)sprintf(sendbuf, pattern, p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
# endif
|
||||
|
||||
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 user) on local server who are
|
||||
* in same channel with user.
|
||||
*/
|
||||
# ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_common_channels(user, pattern, p1, p2, p3, p4,
|
||||
p5, p6, p7, p8)
|
||||
aClient *user;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
# else
|
||||
void sendto_common_channels(user, pattern, va_alist)
|
||||
aClient *user;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
# endif
|
||||
Reg1 int i;
|
||||
Reg2 aClient *cptr;
|
||||
Reg3 Link *lp;
|
||||
|
||||
# ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
# endif
|
||||
|
||||
for (i = 0; i <= highest_fd; i++)
|
||||
{
|
||||
if (!(cptr = local[i]) || IsServer(cptr) ||
|
||||
user == cptr || !user->user)
|
||||
continue;
|
||||
for (lp = user->user->channel; lp; lp = lp->next)
|
||||
if (IsMember(user, lp->value.chptr) &&
|
||||
IsMember(cptr, lp->value.chptr))
|
||||
{
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_prefix_one(cptr, user, pattern, vl);
|
||||
# else
|
||||
sendto_prefix_one(cptr, user, pattern,
|
||||
p1, p2, p3, p4,
|
||||
p5, p6, p7, p8);
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (MyConnect(user))
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_prefix_one(user, user, pattern, vl);
|
||||
va_end(vl);
|
||||
# else
|
||||
sendto_prefix_one(user, user, pattern, p1, p2, p3, p4,
|
||||
p5, p6, p7, p8);
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_channel_butserv
|
||||
*
|
||||
* Send a message to all members of a channel that are connected to this
|
||||
* server.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_channel_butserv(chptr, from, pattern, p1, p2, p3,
|
||||
p4, p5, p6, p7, p8)
|
||||
aChannel *chptr;
|
||||
aClient *from;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
#else
|
||||
void sendto_channel_butserv(chptr, from, pattern, va_alist)
|
||||
aChannel *chptr;
|
||||
aClient *from;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 Link *lp;
|
||||
Reg2 aClient *acptr;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
for (va_start(vl), lp = chptr->members; lp; lp = lp->next)
|
||||
if (MyConnect(acptr = lp->value.cptr) &&
|
||||
!(lp->flags & CHFL_ZOMBIE))
|
||||
vsendto_prefix_one(acptr, from, pattern, vl);
|
||||
va_end(vl);
|
||||
#else
|
||||
for (lp = chptr->members; lp; lp = lp->next)
|
||||
if (MyConnect(acptr = lp->value.cptr) &&
|
||||
!(lp->flags & CHFL_ZOMBIE))
|
||||
sendto_prefix_one(acptr, from, pattern,
|
||||
p1, p2, p3, p4,
|
||||
p5, p6, p7, p8);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** send a msg to all ppl on servers/hosts that match a specified mask
|
||||
** (used for enhanced PRIVMSGs)
|
||||
**
|
||||
** addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de)
|
||||
*/
|
||||
|
||||
static int match_it(one, mask, what)
|
||||
aClient *one;
|
||||
char *mask;
|
||||
int what;
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case MATCH_HOST:
|
||||
return (matches(mask, one->user->host)==0);
|
||||
case MATCH_SERVER:
|
||||
default:
|
||||
return (matches(mask, one->user->server->name)==0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_match_servs
|
||||
*
|
||||
* send to all servers which match the mask at the end of a channel name
|
||||
* (if there is a mask present) or to all if no mask.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_match_servs(chptr, from, format, p1,p2,p3,p4,p5,p6,p7,p8,p9)
|
||||
aChannel *chptr;
|
||||
aClient *from;
|
||||
char *format, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
|
||||
{
|
||||
#else
|
||||
void sendto_match_servs(chptr, from, format, va_alist)
|
||||
aChannel *chptr;
|
||||
aClient *from;
|
||||
char *format;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 Dlink *lp;
|
||||
Reg2 aClient *cptr;
|
||||
char *mask;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
#endif
|
||||
if (chptr)
|
||||
{
|
||||
if (*chptr->chname == '&')
|
||||
return;
|
||||
if (mask = (char *)rindex(chptr->chname, ':'))
|
||||
mask++;
|
||||
}
|
||||
else
|
||||
mask = NULL;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
vsprintf(sendbuf, format, vl);
|
||||
va_end(vl);
|
||||
#else
|
||||
sprintf(sendbuf, format, p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
#endif
|
||||
for (lp = me.serv->down; lp; lp = lp->next)
|
||||
{
|
||||
if ((cptr=lp->value.cptr) == from)
|
||||
continue;
|
||||
if (!BadPtr(mask) && matches(mask, cptr->name))
|
||||
continue;
|
||||
sendbufto_one(cptr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_match_butone
|
||||
*
|
||||
* Send to all clients which match the mask in a way defined on 'what';
|
||||
* either by user hostname or user servername.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_match_butone(one, from, mask, what, pattern,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
aClient *one, *from;
|
||||
int what;
|
||||
char *mask, *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
#else
|
||||
void sendto_match_butone(one, from, mask, what, pattern, va_alist)
|
||||
aClient *one, *from;
|
||||
int what;
|
||||
char *mask, *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 int i;
|
||||
Reg2 aClient *cptr, *acptr;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
#endif
|
||||
for (i = 0; i <= highest_fd; i++)
|
||||
{
|
||||
if (!(cptr = local[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 (IsRegisteredUser(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;
|
||||
/* ... but only if there *IS* a matching person */
|
||||
}
|
||||
/* my client, does he match ? */
|
||||
else if (!(IsRegisteredUser(cptr) &&
|
||||
match_it(cptr, mask, what)))
|
||||
continue;
|
||||
#ifdef USE_VARARGS
|
||||
vsendto_prefix_one(cptr, from, pattern, vl);
|
||||
}
|
||||
va_end(vl);
|
||||
#else
|
||||
sendto_prefix_one(cptr, from, pattern,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_all_butone.
|
||||
*
|
||||
* Send a message to all connections except 'one'. The basic wall type
|
||||
* message generator.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_all_butone(one, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
aClient *one, *from;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
#else
|
||||
void sendto_all_butone(one, from, pattern, va_alist)
|
||||
aClient *one, *from;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 int i;
|
||||
Reg2 aClient *cptr;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
for (va_start(vl), i = 0; i <= highest_fd; i++)
|
||||
if ((cptr = local[i]) && !IsMe(cptr) && one != cptr)
|
||||
vsendto_prefix_one(cptr, from, pattern, vl);
|
||||
va_end(vl);
|
||||
#else
|
||||
for (i = 0; i <= highest_fd; i++)
|
||||
if ((cptr = local[i]) && !IsMe(cptr) && one != cptr)
|
||||
sendto_prefix_one(cptr, from, pattern,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_lops_butone
|
||||
*
|
||||
* Send to *local* ops but one.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_lops_butone(one, pattern, p1, p2, p3, p4, p5, p6, p7)
|
||||
aClient *one;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
|
||||
{
|
||||
#else
|
||||
void sendto_lops_butone(one, pattern, va_alist)
|
||||
aClient *one;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 aClient *cptr;
|
||||
Reg2 Dlink *lp;
|
||||
char nbuf[1024];
|
||||
|
||||
(void)sprintf(nbuf, ":%s NOTICE %%s :*** Notice -- ", me.name);
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
(void)vsprintf(nbuf + strlen(nbuf), pattern, vl);
|
||||
va_end(vl);
|
||||
#else
|
||||
(void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
|
||||
#endif
|
||||
for (lp = me.serv->client; lp; lp=lp->next)
|
||||
if ((cptr=lp->value.cptr)!=one && SendServNotice(cptr))
|
||||
#ifdef USE_VARARGS
|
||||
{
|
||||
(void)sprintf(sendbuf, nbuf, cptr->name);
|
||||
sendbufto_one(cptr);
|
||||
}
|
||||
#else
|
||||
sendto_one(cptr, nbuf, cptr->name, p1, p2, p3, p4, p5, p6, p7);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_ops
|
||||
*
|
||||
* Send to *local* ops only.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_ops(pattern, p1, p2, p3, p4, p5, p6, p7)
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
|
||||
{
|
||||
#else
|
||||
void sendto_ops(pattern, va_alist)
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 aClient *cptr;
|
||||
Reg2 int i;
|
||||
char fmt[1024];
|
||||
char *fmt_target;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
#endif
|
||||
|
||||
(void)sprintf(fmt, ":%s NOTICE ", me.name);
|
||||
fmt_target = &fmt[strlen(fmt)];
|
||||
|
||||
for (i = 0; i <= highest_fd; i++)
|
||||
if ((cptr = local[i]) && !IsServer(cptr) && !IsMe(cptr) &&
|
||||
SendServNotice(cptr))
|
||||
{
|
||||
strcpy(fmt_target, cptr->name);
|
||||
strcat(fmt_target, " :*** Notice -- ");
|
||||
strcat(fmt_target, pattern);
|
||||
#ifdef USE_VARARGS
|
||||
vsendto_one(cptr, fmt, vl);
|
||||
#else
|
||||
sendto_one(cptr, fmt, p1, p2, p3, p4, p5, p6, p7);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_SERVICES
|
||||
else if (cptr && IsService(cptr) &&
|
||||
(cptr->service->wanted & SERVICE_WANT_SERVNOTE))
|
||||
{
|
||||
strcpy(fmt_target, cptr->name);
|
||||
strcat(fmt, " :*** Notice -- ");
|
||||
strcat(fmt, pattern);
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_one(cptr, fmt, vl);
|
||||
# else
|
||||
sendto_one(cptr, fmt, cptr->name, p1, p2, p3, p4, p5, p6, p7);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_end(vl);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** sendto_ops_butone
|
||||
** Send message to all operators.
|
||||
** one - client not to send message to
|
||||
** from- client which message is from *NEVER* NULL!!
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_ops_butone(one, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
aClient *one, *from;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
#else
|
||||
void sendto_ops_butone(one, from, pattern, va_alist)
|
||||
aClient *one, *from;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 int i;
|
||||
Reg2 aClient *cptr;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
#endif
|
||||
for (i=0; i <= highest_fd; i++)
|
||||
sentalong[i] = 0;
|
||||
for (cptr = client; cptr; cptr = cptr->next)
|
||||
{
|
||||
if (!SendWallops(cptr))
|
||||
continue;
|
||||
i = cptr->from->fd; /* find connection oper is on */
|
||||
if (sentalong[i]) /* sent message along it already ? */
|
||||
continue;
|
||||
if (cptr->from == one)
|
||||
continue; /* ...was the one I should skip */
|
||||
sentalong[i] = 1;
|
||||
# ifdef USE_VARARGS
|
||||
vsendto_prefix_one(cptr->from, from, pattern, vl);
|
||||
}
|
||||
va_end(vl);
|
||||
# else
|
||||
sendto_prefix_one(cptr->from, from, pattern,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* to - destination client
|
||||
* from - client which message is from
|
||||
*
|
||||
* NOTE: NEITHER OF THESE SHOULD *EVER* BE NULL!!
|
||||
* -avalon
|
||||
*/
|
||||
#ifdef USE_VARARGS
|
||||
void sendto_prefix_one(to, from, pattern, va_alist)
|
||||
Reg1 aClient *to;
|
||||
Reg2 aClient *from;
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl);
|
||||
vsendto_prefix_one(to, from, pattern, vl);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
void vsendto_prefix_one(to, from, pattern, vl)
|
||||
Reg1 aClient *to;
|
||||
Reg2 aClient *from;
|
||||
char *pattern;
|
||||
va_list vl;
|
||||
{
|
||||
#else
|
||||
void sendto_prefix_one(to, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
Reg1 aClient *to;
|
||||
Reg2 aClient *from;
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
|
||||
{
|
||||
#endif
|
||||
static char sender[HOSTLEN+NICKLEN+USERLEN+5];
|
||||
Reg3 anUser *user;
|
||||
char *par;
|
||||
int flag = 0;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
par = va_arg(vl, char *);
|
||||
#else
|
||||
par = p1;
|
||||
#endif
|
||||
if (to && from && MyClient(to) && IsPerson(from) &&
|
||||
!mycmp(par, from->name))
|
||||
{
|
||||
user = from->user;
|
||||
(void)strcpy(sender, from->name);
|
||||
if (user)
|
||||
{
|
||||
if (*user->username)
|
||||
{
|
||||
(void)strcat(sender, "!");
|
||||
(void)strcat(sender, user->username);
|
||||
}
|
||||
if (*user->host && !MyConnect(from))
|
||||
{
|
||||
(void)strcat(sender, "@");
|
||||
(void)strcat(sender, user->host);
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** flag is used instead of index(sender, '@') for speed and
|
||||
** also since username/nick may have had a '@' in them. -avalon
|
||||
*/
|
||||
if (!flag && MyConnect(from) && *user->host)
|
||||
{
|
||||
(void)strcat(sender, "@");
|
||||
if (IsUnixSocket(from))
|
||||
(void)strcat(sender, user->host);
|
||||
else
|
||||
(void)strcat(sender, from->sockhost);
|
||||
}
|
||||
par = sender;
|
||||
}
|
||||
#ifdef USE_VARARGS
|
||||
/* Assuming 'pattern' always starts with ":%s ..." */
|
||||
sprintf(sendbuf, ":%s", par);
|
||||
vsprintf(sendbuf + strlen(sendbuf), &pattern[3], vl);
|
||||
sendbufto_one(to);
|
||||
#else
|
||||
sendto_one(to, pattern, par, p2, p3, p4, p5, p6, p7, p8);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_realops
|
||||
*
|
||||
* Send to *local* ops only but NOT +s nonopers.
|
||||
*/
|
||||
#ifndef USE_VARARGS
|
||||
/*VARARGS*/
|
||||
void sendto_realops(pattern, p1, p2, p3, p4, p5, p6, p7)
|
||||
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
|
||||
{
|
||||
#else
|
||||
void sendto_realops(pattern, va_alist)
|
||||
char *pattern;
|
||||
va_dcl
|
||||
{
|
||||
va_list vl;
|
||||
#endif
|
||||
Reg1 aClient *cptr;
|
||||
Reg2 int i;
|
||||
char fmt[1024];
|
||||
Reg3 char *fmt_target;
|
||||
|
||||
#ifdef USE_VARARGS
|
||||
va_start(vl);
|
||||
#endif
|
||||
|
||||
(void)sprintf(fmt, ":%s NOTICE ", me.name);
|
||||
fmt_target = &fmt[strlen(fmt)];
|
||||
|
||||
for (i = 0; i <= highest_fd; i++)
|
||||
if ((cptr = local[i]) && IsOper(cptr))
|
||||
{
|
||||
strcpy(fmt_target, cptr->name);
|
||||
strcat(fmt_target, " :*** Notice -- ");
|
||||
strcat(fmt_target, pattern);
|
||||
#ifdef USE_VARARGS
|
||||
vsendto_one(cptr, fmt, vl);
|
||||
#else
|
||||
sendto_one(cptr, fmt, p1, p2, p3, p4, p5, p6, p7);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_VARARGS
|
||||
va_end(vl);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user