ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/send.c
Revision: 3078
Committed: Fri Feb 28 20:34:07 2014 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 29307 byte(s)
Log Message:
- Renamed ts_warn() to sendto_realops_flags_ratelimited()

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2014 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file send.c
23 * \brief Functions for sending messages.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "send.h"
30 #include "channel.h"
31 #include "client.h"
32 #include "dbuf.h"
33 #include "irc_string.h"
34 #include "ircd.h"
35 #include "numeric.h"
36 #include "fdlist.h"
37 #include "s_bsd.h"
38 #include "s_serv.h"
39 #include "conf.h"
40 #include "log.h"
41 #include "memory.h"
42 #include "packet.h"
43
44
45 static unsigned int current_serial = 0;
46
47
48 /* send_format()
49 *
50 * inputs - buffer to format into
51 * - size of the buffer
52 * - format pattern to use
53 * - var args
54 * output - number of bytes formatted output
55 * side effects - modifies sendbuf
56 */
57 static inline int
58 send_format(char *lsendbuf, int bufsize, const char *pattern, va_list args)
59 {
60 int len;
61
62 /*
63 * from rfc1459
64 *
65 * IRC messages are always lines of characters terminated with a CR-LF
66 * (Carriage Return - Line Feed) pair, and these messages shall not
67 * exceed 512 characters in length, counting all characters
68 * including the trailing CR-LF.
69 * Thus, there are 510 characters maximum allowed
70 * for the command and its parameters. There is no provision for
71 * continuation message lines. See section 7 for more details about
72 * current implementations.
73 */
74 len = vsnprintf(lsendbuf, bufsize - 1, pattern, args);
75 if (len > bufsize - 2)
76 len = bufsize - 2; /* required by some versions of vsnprintf */
77
78 lsendbuf[len++] = '\r';
79 lsendbuf[len++] = '\n';
80 return len;
81 }
82
83 /*
84 ** send_message
85 ** Internal utility which appends given buffer to the sockets
86 ** sendq.
87 */
88 static void
89 send_message(struct Client *to, char *buf, int len)
90 {
91 assert(!IsMe(to));
92 assert(to != &me);
93
94 if (dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(&to->localClient->confs))
95 {
96 if (IsServer(to))
97 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
98 "Max SendQ limit exceeded for %s: %lu > %u",
99 get_client_name(to, HIDE_IP),
100 (unsigned long)(dbuf_length(&to->localClient->buf_sendq) + len),
101 get_sendq(&to->localClient->confs));
102 if (IsClient(to))
103 SetSendQExceeded(to);
104 dead_link_on_write(to, 0);
105 return;
106 }
107
108 dbuf_put(&to->localClient->buf_sendq, buf, len);
109
110 /*
111 ** Update statistics. The following is slightly incorrect
112 ** because it counts messages even if queued, but bytes
113 ** only really sent. Queued bytes get updated in SendQueued.
114 */
115 ++to->localClient->send.messages;
116 ++me.localClient->send.messages;
117
118 send_queued_write(to);
119 }
120
121 /* send_message_remote()
122 *
123 * inputs - pointer to client from message is being sent
124 * - pointer to client to send to
125 * - pointer to preformatted buffer
126 * - length of input buffer
127 * output - none
128 * side effects - Despite the function name, this only sends to directly
129 * connected clients.
130 *
131 */
132 static void
133 send_message_remote(struct Client *to, struct Client *from,
134 char *buf, int len)
135 {
136 if (to->from)
137 to = to->from;
138
139 if (!MyConnect(to))
140 {
141 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
142 "Server send message to %s [%s] dropped from %s(Not local server)",
143 to->name, to->from->name, from->name);
144 return;
145 }
146
147 /* Optimize by checking if (from && to) before everything */
148 /* we set to->from up there.. */
149
150 if (!MyClient(from) && IsClient(to) && (to == from->from))
151 {
152 if (IsServer(from))
153 {
154 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
155 "Send message to %s [%s] dropped from %s(Fake Dir)",
156 to->name, to->from->name, from->name);
157 return;
158 }
159
160 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
161 "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
162 to->name, to->username, to->host,
163 from->name, from->username, from->host,
164 to->from->name);
165
166 sendto_server(NULL, CAP_TS6, NOCAPS,
167 ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
168 me.id, to->name, me.name, to->name,
169 to->username, to->host, to->from->name);
170 sendto_server(NULL, NOCAPS, CAP_TS6,
171 ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
172 me.name, to->name, me.name, to->name,
173 to->username, to->host, to->from->name);
174
175 AddFlag(to, FLAGS_KILLED);
176
177 if (IsClient(from))
178 sendto_one(from, form_str(ERR_GHOSTEDCLIENT),
179 me.name, from->name, to->name, to->username,
180 to->host, to->from);
181
182 exit_client(to, &me, "Ghosted client");
183 return;
184 }
185
186 send_message(to, buf, len);
187 }
188
189 /*
190 ** sendq_unblocked
191 ** Called when a socket is ready for writing.
192 */
193 void
194 sendq_unblocked(fde_t *fd, struct Client *client_p)
195 {
196 assert(fd == &client_p->localClient->fd);
197 send_queued_write(client_p);
198 }
199
200 /*
201 ** send_queued_write
202 ** This is called when there is a chance that some output would
203 ** be possible. This attempts to empty the send queue as far as
204 ** possible, and then if any data is left, a write is rescheduled.
205 */
206 void
207 send_queued_write(struct Client *to)
208 {
209 int retlen = 0;
210 struct dbuf_block *first = NULL;
211
212 /*
213 ** Once socket is marked dead, we cannot start writing to it,
214 ** even if the error is removed...
215 */
216 if (IsDead(to))
217 return; /* no use calling send() now */
218
219 /* Next, lets try to write some data */
220 if (dbuf_length(&to->localClient->buf_sendq))
221 {
222 do
223 {
224 first = to->localClient->buf_sendq.blocks.head->data;
225
226 #ifdef HAVE_LIBCRYPTO
227 if (to->localClient->fd.ssl)
228 {
229 retlen = SSL_write(to->localClient->fd.ssl, first->data, first->size);
230
231 /* translate openssl error codes, sigh */
232 if (retlen < 0)
233 {
234 switch (SSL_get_error(to->localClient->fd.ssl, retlen))
235 {
236 case SSL_ERROR_WANT_READ:
237 return; /* retry later, don't register for write events */
238 case SSL_ERROR_WANT_WRITE:
239 errno = EWOULDBLOCK;
240 case SSL_ERROR_SYSCALL:
241 break;
242 case SSL_ERROR_SSL:
243 if (errno == EAGAIN)
244 break;
245 default:
246 retlen = errno = 0; /* either an SSL-specific error or EOF */
247 }
248 }
249 }
250 else
251 #endif
252 retlen = send(to->localClient->fd.fd, first->data, first->size, 0);
253
254 if (retlen <= 0)
255 break;
256
257 dbuf_delete(&to->localClient->buf_sendq, retlen);
258
259 /* We have some data written .. update counters */
260 to->localClient->send.bytes += retlen;
261 me.localClient->send.bytes += retlen;
262 } while (dbuf_length(&to->localClient->buf_sendq));
263
264 if ((retlen < 0) && (ignoreErrno(errno)))
265 {
266 /* we have a non-fatal error, reschedule a write */
267 comm_setselect(&to->localClient->fd, COMM_SELECT_WRITE,
268 (PF *)sendq_unblocked, to, 0);
269 }
270 else if (retlen <= 0)
271 {
272 dead_link_on_write(to, errno);
273 return;
274 }
275 }
276 }
277
278 /* send_queued_all()
279 *
280 * input - NONE
281 * output - NONE
282 * side effects - try to flush sendq of each client
283 */
284 void
285 send_queued_all(void)
286 {
287 dlink_node *ptr;
288
289 /* Servers are processed first, mainly because this can generate
290 * a notice to opers, which is to be delivered by this function.
291 */
292 DLINK_FOREACH(ptr, serv_list.head)
293 send_queued_write(ptr->data);
294
295 DLINK_FOREACH(ptr, unknown_list.head)
296 send_queued_write(ptr->data);
297
298 DLINK_FOREACH(ptr, local_client_list.head)
299 send_queued_write(ptr->data);
300
301 /* NOTE: This can still put clients on aborted_list; unfortunately,
302 * exit_aborted_clients takes precedence over send_queued_all,
303 * because exiting clients can generate server/oper traffic.
304 * The easiest approach is dealing with aborted clients in the next I/O lap.
305 * -adx
306 */
307 }
308
309 /* sendto_one()
310 *
311 * inputs - pointer to destination client
312 * - var args message
313 * output - NONE
314 * side effects - send message to single client
315 */
316 void
317 sendto_one(struct Client *to, const char *pattern, ...)
318 {
319 va_list args;
320 char buffer[IRCD_BUFSIZE];
321 int len;
322
323 if (to->from != NULL)
324 to = to->from;
325 if (IsDead(to))
326 return; /* This socket has already been marked as dead */
327
328 va_start(args, pattern);
329 len = send_format(buffer, sizeof(buffer), pattern, args);
330 va_end(args);
331
332 send_message(to, buffer, len);
333 }
334
335 /* sendto_channel_butone()
336 *
337 * inputs - pointer to client(server) to NOT send message to
338 * - pointer to client that is sending this message
339 * - pointer to channel being sent to
340 * - vargs message
341 * output - NONE
342 * side effects - message as given is sent to given channel members.
343 *
344 * WARNING - +D clients are ignored
345 */
346 void
347 sendto_channel_butone(struct Client *one, struct Client *from,
348 struct Channel *chptr, unsigned int type,
349 const char *pattern, ...)
350 {
351 va_list alocal, aremote, auid;
352 char local_buf[IRCD_BUFSIZE];
353 char remote_buf[IRCD_BUFSIZE];
354 char uid_buf[IRCD_BUFSIZE];
355 int local_len, remote_len, uid_len;
356 dlink_node *ptr = NULL, *ptr_next = NULL;
357
358 if (IsServer(from))
359 local_len = snprintf(local_buf, sizeof(local_buf), ":%s ",
360 from->name);
361 else
362 local_len = snprintf(local_buf, sizeof(local_buf), ":%s!%s@%s ",
363 from->name, from->username, from->host);
364 remote_len = snprintf(remote_buf, sizeof(remote_buf), ":%s ",
365 from->name);
366 uid_len = snprintf(uid_buf, sizeof(uid_buf), ":%s ", ID(from));
367
368 va_start(alocal, pattern);
369 va_start(aremote, pattern);
370 va_start(auid, pattern);
371 local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len,
372 pattern, alocal);
373 remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
374 pattern, aremote);
375 uid_len += send_format(&uid_buf[uid_len], IRCD_BUFSIZE - uid_len, pattern,
376 auid);
377 va_end(auid);
378 va_end(aremote);
379 va_end(alocal);
380
381 ++current_serial;
382
383 DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
384 {
385 struct Membership *ms = ptr->data;
386 struct Client *target_p = ms->client_p;
387
388 assert(IsClient(target_p));
389
390 if (IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF) || target_p->from == one)
391 continue;
392
393 if (type != 0 && (ms->flags & type) == 0)
394 continue;
395
396 if (MyConnect(target_p))
397 {
398 if (target_p->localClient->serial != current_serial)
399 {
400 send_message(target_p, local_buf, local_len);
401 target_p->localClient->serial = current_serial;
402 }
403 }
404 else
405 {
406 /* Now check whether a message has been sent to this
407 * remote link already
408 */
409 if (target_p->from->localClient->serial != current_serial)
410 {
411 if (IsCapable(target_p->from, CAP_TS6))
412 send_message_remote(target_p->from, from, uid_buf, uid_len);
413 else
414 send_message_remote(target_p->from, from, remote_buf, remote_len);
415 target_p->from->localClient->serial = current_serial;
416 }
417 }
418 }
419 }
420
421 /* sendto_server()
422 *
423 * inputs - pointer to client to NOT send to
424 * - pointer to channel
425 * - caps or'd together which must ALL be present
426 * - caps or'd together which must ALL NOT be present
427 * - printf style format string
428 * - args to format string
429 * output - NONE
430 * side effects - Send a message to all connected servers, except the
431 * client 'one' (if non-NULL), as long as the servers
432 * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
433 *
434 * This function was written in an attempt to merge together the other
435 * billion sendto_*serv*() functions, which sprung up with capabs,
436 * lazylinks, uids, etc.
437 * -davidt
438 */
439 void
440 sendto_server(struct Client *one,
441 const unsigned int caps,
442 const unsigned int nocaps,
443 const char *format, ...)
444 {
445 va_list args;
446 dlink_node *ptr = NULL;
447 char buffer[IRCD_BUFSIZE];
448 int len = 0;
449
450 va_start(args, format);
451 len = send_format(buffer, sizeof(buffer), format, args);
452 va_end(args);
453
454 DLINK_FOREACH(ptr, serv_list.head)
455 {
456 struct Client *client_p = ptr->data;
457
458 /* If dead already skip */
459 if (IsDead(client_p))
460 continue;
461 /* check against 'one' */
462 if (one != NULL && (client_p == one->from))
463 continue;
464 /* check we have required capabs */
465 if ((client_p->localClient->caps & caps) != caps)
466 continue;
467 /* check we don't have any forbidden capabs */
468 if ((client_p->localClient->caps & nocaps) != 0)
469 continue;
470
471 send_message(client_p, buffer, len);
472 }
473 }
474
475 /* sendto_common_channels_local()
476 *
477 * inputs - pointer to client
478 * - pattern to send
479 * output - NONE
480 * side effects - Sends a message to all people on local server who are
481 * in same channel with user.
482 * used by m_nick.c and exit_one_client.
483 */
484 void
485 sendto_common_channels_local(struct Client *user, int touser, unsigned int cap,
486 const char *pattern, ...)
487 {
488 va_list args;
489 dlink_node *uptr;
490 dlink_node *cptr;
491 struct Channel *chptr;
492 struct Membership *ms;
493 struct Client *target_p;
494 char buffer[IRCD_BUFSIZE];
495 int len;
496
497 va_start(args, pattern);
498 len = send_format(buffer, sizeof(buffer), pattern, args);
499 va_end(args);
500
501 ++current_serial;
502
503 DLINK_FOREACH(cptr, user->channel.head)
504 {
505 chptr = ((struct Membership *)cptr->data)->chptr;
506 assert(chptr != NULL);
507
508 DLINK_FOREACH(uptr, chptr->members.head)
509 {
510 ms = uptr->data;
511 target_p = ms->client_p;
512 assert(target_p != NULL);
513
514 if (!MyConnect(target_p) || target_p == user || IsDefunct(target_p) ||
515 target_p->localClient->serial == current_serial)
516 continue;
517
518 if (HasCap(target_p, cap) != cap)
519 continue;
520
521 target_p->localClient->serial = current_serial;
522 send_message(target_p, buffer, len);
523 }
524 }
525
526 if (touser && MyConnect(user) && !IsDead(user) &&
527 user->localClient->serial != current_serial)
528 if (HasCap(user, cap) == cap)
529 send_message(user, buffer, len);
530 }
531
532 /* sendto_channel_local()
533 *
534 * inputs - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE
535 * - whether to ignore +D clients (YES/NO)
536 * - pointer to channel to send to
537 * - var args pattern
538 * output - NONE
539 * side effects - Send a message to all members of a channel that are
540 * locally connected to this server.
541 */
542 void
543 sendto_channel_local(unsigned int type, int nodeaf, struct Channel *chptr,
544 const char *pattern, ...)
545 {
546 va_list args;
547 char buffer[IRCD_BUFSIZE];
548 int len = 0;
549 dlink_node *ptr = NULL;
550
551 va_start(args, pattern);
552 len = send_format(buffer, sizeof(buffer), pattern, args);
553 va_end(args);
554
555 DLINK_FOREACH(ptr, chptr->members.head)
556 {
557 struct Membership *ms = ptr->data;
558 struct Client *target_p = ms->client_p;
559
560 if (type != 0 && (ms->flags & type) == 0)
561 continue;
562
563 if (!MyConnect(target_p) || IsDefunct(target_p) ||
564 (nodeaf && HasUMode(target_p, UMODE_DEAF)))
565 continue;
566
567 send_message(target_p, buffer, len);
568 }
569 }
570
571 /* sendto_channel_local_butone()
572 *
573 * inputs - pointer to client to NOT send message to
574 * - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE
575 * - pointer to channel to send to
576 * - var args pattern
577 * output - NONE
578 * side effects - Send a message to all members of a channel that are
579 * locally connected to this server except one.
580 *
581 * WARNING - +D clients are omitted
582 */
583 void
584 sendto_channel_local_butone(struct Client *one, unsigned int type, unsigned int cap,
585 struct Channel *chptr, const char *pattern, ...)
586 {
587 va_list args;
588 char buffer[IRCD_BUFSIZE];
589 int len = 0;
590 dlink_node *ptr = NULL;
591
592 va_start(args, pattern);
593 len = send_format(buffer, sizeof(buffer), pattern, args);
594 va_end(args);
595
596 DLINK_FOREACH(ptr, chptr->members.head)
597 {
598 struct Membership *ms = ptr->data;
599 struct Client *target_p = ms->client_p;
600
601 if (type != 0 && (ms->flags & type) == 0)
602 continue;
603
604 if (!MyConnect(target_p) || target_p == one ||
605 IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF))
606 continue;
607
608 if (HasCap(target_p, cap) != cap)
609 continue;
610
611 send_message(target_p, buffer, len);
612 }
613 }
614
615 /*
616 ** match_it() and sendto_match_butone() ARE only used
617 ** to send a msg to all ppl on servers/hosts that match a specified mask
618 ** (used for enhanced PRIVMSGs) for opers
619 **
620 ** addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de)
621 **
622 */
623
624 /* match_it()
625 *
626 * inputs - client pointer to match on
627 * - actual mask to match
628 * - what to match on, HOST or SERVER
629 * output - 1 or 0 if match or not
630 * side effects - NONE
631 */
632 static int
633 match_it(const struct Client *one, const char *mask, unsigned int what)
634 {
635 if (what == MATCH_HOST)
636 return !match(mask, one->host);
637
638 return !match(mask, one->servptr->name);
639 }
640
641 /* sendto_match_butone()
642 *
643 * Send to all clients which match the mask in a way defined on 'what';
644 * either by user hostname or user servername.
645 *
646 * ugh. ONLY used by m_message.c to send an "oper magic" message. ugh.
647 */
648 void
649 sendto_match_butone(struct Client *one, struct Client *from, char *mask,
650 int what, const char *pattern, ...)
651 {
652 va_list alocal, aremote;
653 struct Client *client_p;
654 dlink_node *ptr, *ptr_next;
655 char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE];
656 int local_len = snprintf(local_buf, sizeof(local_buf), ":%s!%s@%s ",
657 from->name, from->username, from->host);
658 int remote_len = snprintf(remote_buf, sizeof(remote_buf), ":%s ",
659 from->name);
660
661 va_start(alocal, pattern);
662 va_start(aremote, pattern);
663 local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len,
664 pattern, alocal);
665 remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
666 pattern, aremote);
667 va_end(aremote);
668 va_end(alocal);
669
670 /* scan the local clients */
671 DLINK_FOREACH(ptr, local_client_list.head)
672 {
673 client_p = ptr->data;
674
675 if (client_p != one && !IsDefunct(client_p) &&
676 match_it(client_p, mask, what))
677 send_message(client_p, local_buf, local_len);
678 }
679
680 /* Now scan servers */
681 DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
682 {
683 client_p = ptr->data;
684
685 /*
686 * The old code looped through every client on the
687 * network for each server to check if the
688 * server (client_p) has at least 1 client matching
689 * the mask, using something like:
690 *
691 * for (target_p = GlobalClientList; target_p; target_p = target_p->next)
692 * if (IsRegisteredUser(target_p) &&
693 * match_it(target_p, mask, what) &&
694 * (target_p->from == client_p))
695 * vsendto_prefix_one(client_p, from, pattern, args);
696 *
697 * That way, we wouldn't send the message to
698 * a server who didn't have a matching client.
699 * However, on a network such as EFNet, that
700 * code would have looped through about 50
701 * servers, and in each loop, loop through
702 * about 50k clients as well, calling match()
703 * in each nested loop. That is a very bad
704 * thing cpu wise - just send the message
705 * to every connected server and let that
706 * server deal with it.
707 * -wnder
708 */
709 if (client_p != one && !IsDefunct(client_p))
710 send_message_remote(client_p, from, remote_buf, remote_len);
711 }
712 }
713
714 /* sendto_match_servs()
715 *
716 * inputs - source client
717 * - mask to send to
718 * - capab needed
719 * - data
720 * outputs - none
721 * side effects - data sent to servers matching with capab
722 */
723 void
724 sendto_match_servs(struct Client *source_p, const char *mask, unsigned int cap,
725 const char *pattern, ...)
726 {
727 va_list args;
728 dlink_node *ptr = NULL;
729 char buff_suid[IRCD_BUFSIZE];
730 char buff_name[IRCD_BUFSIZE];
731 int len_suid = 0;
732 int len_name = 0;
733
734 va_start(args, pattern);
735 len_suid = snprintf(buff_suid, sizeof(buff_suid), ":%s ", ID(source_p));
736 len_suid += send_format(&buff_suid[len_suid], sizeof(buff_suid) - len_suid,
737 pattern, args);
738 va_end(args);
739
740 va_start(args, pattern);
741 len_name = snprintf(buff_name, sizeof(buff_name), ":%s ", source_p->name);
742 len_name += send_format(&buff_name[len_name], sizeof(buff_name) - len_name,
743 pattern, args);
744 va_end(args);
745
746 ++current_serial;
747
748 DLINK_FOREACH(ptr, global_serv_list.head)
749 {
750 struct Client *target_p = ptr->data;
751
752 /* Do not attempt to send to ourselves, or the source */
753 if (IsMe(target_p) || target_p->from == source_p->from)
754 continue;
755
756 if (target_p->from->localClient->serial == current_serial)
757 continue;
758
759 if (!match(mask, target_p->name))
760 {
761 /*
762 * if we set the serial here, then we'll never do a
763 * match() again, if !IsCapable()
764 */
765 target_p->from->localClient->serial = current_serial;
766
767 if (!IsCapable(target_p->from, cap))
768 continue;
769
770 if (HasID(target_p->from))
771 send_message_remote(target_p->from, source_p, buff_suid, len_suid);
772 else
773 send_message_remote(target_p->from, source_p, buff_name, len_name);
774 }
775 }
776 }
777
778 /* sendto_anywhere()
779 *
780 * inputs - pointer to dest client
781 * - pointer to from client
782 * - varags
783 * output - NONE
784 * side effects - less efficient than sendto_remote and sendto_one
785 * but useful when one does not know where target "lives"
786 */
787 void
788 sendto_anywhere(struct Client *to, struct Client *from,
789 const char *command,
790 const char *pattern, ...)
791 {
792 va_list args;
793 char buffer[IRCD_BUFSIZE];
794 int len = 0;
795
796 if (IsDead(to->from))
797 return;
798
799 if (MyClient(to))
800 {
801 if (IsServer(from))
802 len = snprintf(buffer, sizeof(buffer), ":%s %s %s ",
803 from->name, command, to->name);
804 else
805 len = snprintf(buffer, sizeof(buffer), ":%s!%s@%s %s %s ",
806 from->name, from->username, from->host, command, to->name);
807 }
808 else
809 len = snprintf(buffer, sizeof(buffer), ":%s %s %s ",
810 ID_or_name(from, to), command,
811 ID_or_name(to, to));
812
813 va_start(args, pattern);
814 len += send_format(&buffer[len], sizeof(buffer) - len, pattern, args);
815 va_end(args);
816
817 if (MyClient(to))
818 send_message(to, buffer, len);
819 else
820 send_message_remote(to, from, buffer, len);
821 }
822
823 /* sendto_realops_flags()
824 *
825 * inputs - flag types of messages to show to real opers
826 * - flag indicating opers/admins
827 * - var args input message
828 * output - NONE
829 * side effects - Send to *local* ops only but NOT +s nonopers.
830 */
831 void
832 sendto_realops_flags(unsigned int flags, int level, int type, const char *pattern, ...)
833 {
834 const char *ntype = NULL;
835 dlink_node *ptr = NULL;
836 char nbuf[IRCD_BUFSIZE];
837 va_list args;
838
839 va_start(args, pattern);
840 vsnprintf(nbuf, sizeof(nbuf), pattern, args);
841 va_end(args);
842
843 switch (type)
844 {
845 case SEND_NOTICE:
846 ntype = "Notice";
847 break;
848 case SEND_GLOBAL:
849 ntype = "Global";
850 break;
851 case SEND_LOCOPS:
852 ntype = "LocOps";
853 break;
854 default:
855 assert(0);
856 }
857
858 DLINK_FOREACH(ptr, oper_list.head)
859 {
860 struct Client *client_p = ptr->data;
861 assert(HasUMode(client_p, UMODE_OPER));
862
863 /*
864 * If we're sending it to opers and they're an admin, skip.
865 * If we're sending it to admins, and they're not, skip.
866 */
867 if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) ||
868 ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN)))
869 continue;
870
871 if (HasUMode(client_p, flags))
872 sendto_one(client_p, ":%s NOTICE %s :*** %s -- %s",
873 me.name, client_p->name, ntype, nbuf);
874 }
875 }
876
877 /* sendto_wallops_flags()
878 *
879 * inputs - flag types of messages to show to real opers
880 * - client sending request
881 * - var args input message
882 * output - NONE
883 * side effects - Send a wallops to local opers
884 */
885 void
886 sendto_wallops_flags(unsigned int flags, struct Client *source_p,
887 const char *pattern, ...)
888 {
889 dlink_node *ptr = NULL;
890 va_list args;
891 char buffer[IRCD_BUFSIZE];
892 int len;
893
894 if (IsClient(source_p))
895 len = snprintf(buffer, sizeof(buffer), ":%s!%s@%s WALLOPS :",
896 source_p->name, source_p->username,
897 source_p->host);
898 else
899 len = snprintf(buffer, sizeof(buffer), ":%s WALLOPS :",
900 source_p->name);
901
902 va_start(args, pattern);
903 len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
904 va_end(args);
905
906 DLINK_FOREACH(ptr, oper_list.head)
907 {
908 struct Client *client_p = ptr->data;
909 assert(client_p->umodes & UMODE_OPER);
910
911 if (HasUMode(client_p, flags) && !IsDefunct(client_p))
912 send_message(client_p, buffer, len);
913 }
914 }
915
916 /* ts_warn()
917 *
918 * inputs - var args message
919 * output - NONE
920 * side effects - Call sendto_realops_flags, with some flood checking
921 * (at most 5 warnings every 5 seconds)
922 */
923 void
924 sendto_realops_flags_ratelimited(const char *pattern, ...)
925 {
926 va_list args;
927 char buffer[IRCD_BUFSIZE];
928 static time_t last = 0;
929 static int warnings = 0;
930
931 /*
932 ** if we're running with TS_WARNINGS enabled and someone does
933 ** something silly like (remotely) connecting a nonTS server,
934 ** we'll get a ton of warnings, so we make sure we don't send
935 ** more than 5 every 5 seconds. -orabidoo
936 */
937
938 if (CurrentTime - last < 5)
939 {
940 if (++warnings > 5)
941 return;
942 }
943 else
944 {
945 last = CurrentTime;
946 warnings = 0;
947 }
948
949 va_start(args, pattern);
950 vsnprintf(buffer, sizeof(buffer), pattern, args);
951 va_end(args);
952
953 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s", buffer);
954 ilog(LOG_TYPE_IRCD, "%s", buffer);
955 }
956
957 /* kill_client()
958 *
959 * inputs - client to send kill towards
960 * - pointer to client to kill
961 * - reason for kill
962 * output - NONE
963 * side effects - NONE
964 */
965 void
966 kill_client(struct Client *client_p, struct Client *diedie,
967 const char *pattern, ...)
968 {
969 va_list args;
970 char buffer[IRCD_BUFSIZE];
971 int len;
972
973 if (client_p->from != NULL)
974 client_p = client_p->from;
975 if (IsDead(client_p))
976 return;
977
978 len = snprintf(buffer, sizeof(buffer), ":%s KILL %s :",
979 ID_or_name(&me, client_p),
980 ID_or_name(diedie, client_p));
981
982 va_start(args, pattern);
983 len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
984 va_end(args);
985
986 send_message(client_p, buffer, len);
987 }
988
989 /* kill_client_ll_serv_butone()
990 *
991 * inputs - pointer to client to not send to
992 * - pointer to client to kill
993 * output - NONE
994 * side effects - Send a KILL for the given client
995 * message to all connected servers
996 * except the client 'one'. Also deal with
997 * client being unknown to leaf, as in lazylink...
998 */
999 void
1000 kill_client_serv_butone(struct Client *one, struct Client *source_p,
1001 const char *pattern, ...)
1002 {
1003 va_list args;
1004 int have_uid = 0;
1005 dlink_node *ptr = NULL;
1006 char buf_uid[IRCD_BUFSIZE], buf_nick[IRCD_BUFSIZE];
1007 int len_uid = 0, len_nick = 0;
1008
1009 if (HasID(source_p))
1010 {
1011 have_uid = 1;
1012 va_start(args, pattern);
1013 len_uid = snprintf(buf_uid, sizeof(buf_uid), ":%s KILL %s :",
1014 me.id, ID(source_p));
1015 len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern, args);
1016 va_end(args);
1017 }
1018
1019 va_start(args, pattern);
1020 len_nick = snprintf(buf_nick, sizeof(buf_nick), ":%s KILL %s :",
1021 me.name, source_p->name);
1022 len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern, args);
1023 va_end(args);
1024
1025 DLINK_FOREACH(ptr, serv_list.head)
1026 {
1027 struct Client *client_p = ptr->data;
1028
1029 if (one != NULL && (client_p == one->from))
1030 continue;
1031 if (IsDefunct(client_p))
1032 continue;
1033
1034 if (have_uid && IsCapable(client_p, CAP_TS6))
1035 send_message(client_p, buf_uid, len_uid);
1036 else
1037 send_message(client_p, buf_nick, len_nick);
1038 }
1039 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision