ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/send.c
(Generate patch)

Comparing:
ircd-hybrid-8/src/send.c (file contents), Revision 1247 by michael, Sat Oct 1 07:54:24 2011 UTC vs.
ircd-hybrid/trunk/src/send.c (file contents), Revision 2867 by michael, Sun Jan 19 16:58:07 2014 UTC

# Line 34 | Line 34
34   #include "fdlist.h"
35   #include "s_bsd.h"
36   #include "s_serv.h"
37 < #include "sprintf_irc.h"
38 < #include "s_conf.h"
39 < #include "s_log.h"
37 > #include "conf.h"
38 > #include "log.h"
39   #include "memory.h"
41 #include "hook.h"
40   #include "packet.h"
41  
42  
45 struct Callback *iosend_cb = NULL;
46 struct Callback *iosendctrl_cb = NULL;
43   static unsigned int current_serial = 0;
44  
45  
# Line 66 | Line 62 | send_format(char *lsendbuf, int bufsize,
62     *
63     * IRC messages are always lines of characters terminated with a CR-LF
64     * (Carriage Return - Line Feed) pair, and these messages shall not
65 <   * exceed 512 characters in length,  counting all characters
65 >   * exceed 512 characters in length,  counting all characters
66     * including the trailing CR-LF.
67     * Thus, there are 510 characters maximum allowed
68     * for the command and its parameters.  There is no provision for
# Line 83 | Line 79 | send_format(char *lsendbuf, int bufsize,
79   }
80  
81   /*
86 * iosend_default - append a packet to the client's sendq.
87 */
88 void *
89 iosend_default(va_list args)
90 {
91  struct Client *to = va_arg(args, struct Client *);
92  int length = va_arg(args, int);
93  char *buf = va_arg(args, char *);
94
95  dbuf_put(&to->localClient->buf_sendq, buf, length);
96  return NULL;
97 }
98
99 /*
82   ** send_message
83   **      Internal utility which appends given buffer to the sockets
84   **      sendq.
# Line 107 | Line 89 | send_message(struct Client *to, char *bu
89    assert(!IsMe(to));
90    assert(to != &me);
91  
92 <  if (dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(to))
92 >  if (dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(&to->localClient->confs))
93    {
94      if (IsServer(to))
95 <      sendto_realops_flags(UMODE_ALL, L_ALL,
96 <                           "Max SendQ limit exceeded for %s: %lu > %lu",
95 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
96 >                           "Max SendQ limit exceeded for %s: %lu > %u",
97                             get_client_name(to, HIDE_IP),
98                             (unsigned long)(dbuf_length(&to->localClient->buf_sendq) + len),
99 <                           get_sendq(to));
99 >                           get_sendq(&to->localClient->confs));
100      if (IsClient(to))
101        SetSendQExceeded(to);
102      dead_link_on_write(to, 0);
103      return;
104    }
105  
106 <  execute_callback(iosend_cb, to, len, buf);
106 >  dbuf_put(&to->localClient->buf_sendq, buf, len);
107  
108    /*
109     ** Update statistics. The following is slightly incorrect
# Line 151 | Line 133 | 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,
142 <                         "server send message to %s [%s] dropped from %s(Not local server)",
143 <                         to->name, to->from->name, from->name);
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  
# Line 166 | Line 151 | send_message_remote(struct Client *to, s
151    {
152      if (IsServer(from))
153      {
154 <      sendto_realops_flags(UMODE_ALL, L_ALL,
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,
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, NULL, CAP_TS6, NOCAPS,
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, NULL, NOCAPS, CAP_TS6,
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);
# Line 195 | Line 180 | send_message_remote(struct Client *to, s
180                   to->host, to->from);
181  
182      exit_client(to, &me, "Ghosted client");
198
183      return;
184 <  }
184 >  }
185  
186    send_message(to, buf, len);
187   }
# Line 222 | Line 206 | sendq_unblocked(fde_t *fd, struct Client
206   }
207  
208   /*
225 ** slinkq_unblocked
226 **      Called when a server control socket is ready for writing.
227 */
228 static void
229 slinkq_unblocked(fde_t *fd, struct Client *client_p)
230 {
231  ClearSlinkqBlocked(client_p);
232  send_queued_slink_write(client_p);
233 }
234
235 /*
209   ** send_queued_write
210   **      This is called when there is a chance that some output would
211   **      be possible. This attempts to empty the send queue as far as
# Line 241 | Line 214 | slinkq_unblocked(fde_t *fd, struct Clien
214   void
215   send_queued_write(struct Client *to)
216   {
217 <  int retlen;
218 <  struct dbuf_block *first;
217 >  int retlen = 0;
218 >  struct dbuf_block *first = NULL;
219  
220    /*
221     ** Once socket is marked dead, we cannot start writing to it,
# Line 252 | Line 225 | send_queued_write(struct Client *to)
225      return;  /* no use calling send() now */
226  
227    /* Next, lets try to write some data */
255
228    if (dbuf_length(&to->localClient->buf_sendq))
229    {
230 <    do {
230 >    do
231 >    {
232        first = to->localClient->buf_sendq.blocks.head->data;
233  
234   #ifdef HAVE_LIBCRYPTO
# Line 264 | Line 237 | send_queued_write(struct Client *to)
237          retlen = SSL_write(to->localClient->fd.ssl, first->data, first->size);
238  
239          /* translate openssl error codes, sigh */
240 <        if (retlen < 0)
241 <          switch (SSL_get_error(to->localClient->fd.ssl, retlen))
242 <          {
240 >        if (retlen < 0)
241 >        {
242 >          switch (SSL_get_error(to->localClient->fd.ssl, retlen))
243 >          {
244              case SSL_ERROR_WANT_READ:
245 <              return;  /* retry later, don't register for write events */
246 <
247 <            case SSL_ERROR_WANT_WRITE:
274 <              errno = EWOULDBLOCK;
245 >              return;  /* retry later, don't register for write events */
246 >            case SSL_ERROR_WANT_WRITE:
247 >              errno = EWOULDBLOCK;
248              case SSL_ERROR_SYSCALL:
249 <              break;
249 >              break;
250              case SSL_ERROR_SSL:
251                if (errno == EAGAIN)
252                  break;
253              default:
254 <              retlen = errno = 0;  /* either an SSL-specific error or EOF */
255 <          }
254 >              retlen = errno = 0;  /* either an SSL-specific error or EOF */
255 >          }
256 >        }
257        }
258        else
259   #endif
# Line 300 | Line 274 | send_queued_write(struct Client *to)
274        /* we have a non-fatal error, reschedule a write */
275        SetSendqBlocked(to);
276        comm_setselect(&to->localClient->fd, COMM_SELECT_WRITE,
277 <                     (PF *)sendq_unblocked, (void *)to, 0);
277 >                     (PF *)sendq_unblocked, to, 0);
278      }
279      else if (retlen <= 0)
280      {
# Line 310 | Line 284 | send_queued_write(struct Client *to)
284    }
285   }
286  
313 /*
314 ** send_queued_slink_write
315 **      This is called when there is a chance the some output would
316 **      be possible. This attempts to empty the send queue as far as
317 **      possible, and then if any data is left, a write is rescheduled.
318 */
319 void
320 send_queued_slink_write(struct Client *to)
321 {
322  int retlen;
323
324  /*
325   ** Once socket is marked dead, we cannot start writing to it,
326   ** even if the error is removed...
327   */
328  if (IsDead(to) || IsSlinkqBlocked(to))
329    return;  /* no use calling send() now */
330
331  /* Next, lets try to write some data */
332  if (to->localClient->slinkq != NULL)
333  {
334    retlen = send(to->localClient->ctrlfd.fd,
335                   to->localClient->slinkq + to->localClient->slinkq_ofs,
336                   to->localClient->slinkq_len, 0);
337    if (retlen < 0)
338    {
339      /* If we have a fatal error */
340      if (!ignoreErrno(errno))
341      {
342        dead_link_on_write(to, errno);
343        return;
344      }
345    }
346    else if (retlen == 0)
347    {
348      /* 0 bytes is an EOF .. */
349      dead_link_on_write(to, 0);
350      return;
351    }
352    else
353    {
354      execute_callback(iosendctrl_cb, to, retlen,
355        to->localClient->slinkq + to->localClient->slinkq_ofs);
356      to->localClient->slinkq_len -= retlen;
357
358      assert(to->localClient->slinkq_len >= 0);
359      if (to->localClient->slinkq_len)
360        to->localClient->slinkq_ofs += retlen;
361      else
362      {
363        to->localClient->slinkq_ofs = 0;
364        MyFree(to->localClient->slinkq);
365        to->localClient->slinkq = NULL;
366      }
367    }
368
369    /* Finally, if we have any more data, reschedule a write */
370    if (to->localClient->slinkq_len)
371    {
372      SetSlinkqBlocked(to);
373      comm_setselect(&to->localClient->ctrlfd, COMM_SELECT_WRITE,
374                     (PF *)slinkq_unblocked, (void *)to, 0);
375    }
376  }
377 }
378
287   /* send_queued_all()
288   *
289   * input        - NONE
# Line 391 | Line 299 | send_queued_all(void)
299     * a notice to opers, which is to be delivered by this function.
300     */
301    DLINK_FOREACH(ptr, serv_list.head)
302 <    send_queued_write((struct Client *) ptr->data);
302 >    send_queued_write(ptr->data);
303  
304    DLINK_FOREACH(ptr, unknown_list.head)
305 <    send_queued_write((struct Client *) ptr->data);
305 >    send_queued_write(ptr->data);
306  
307    DLINK_FOREACH(ptr, local_client_list.head)
308 <    send_queued_write((struct Client *) ptr->data);
308 >    send_queued_write(ptr->data);
309  
310    /* NOTE: This can still put clients on aborted_list; unfortunately,
311     * exit_aborted_clients takes precedence over send_queued_all,
# Line 427 | Line 335 | sendto_one(struct Client *to, const char
335      return; /* This socket has already been marked as dead */
336  
337    va_start(args, pattern);
338 <  len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
338 >  len = send_format(buffer, sizeof(buffer), pattern, args);
339    va_end(args);
340  
341    send_message(to, buffer, len);
# Line 446 | Line 354 | sendto_one(struct Client *to, const char
354   */
355   void
356   sendto_channel_butone(struct Client *one, struct Client *from,
357 <                      struct Channel *chptr, const char *command,
357 >                      struct Channel *chptr, unsigned int type,
358                        const char *pattern, ...)
359   {
360    va_list alocal, aremote, auid;
# Line 457 | Line 365 | sendto_channel_butone(struct Client *one
365    dlink_node *ptr = NULL, *ptr_next = NULL;
366  
367    if (IsServer(from))
368 <    local_len = ircsprintf(local_buf, ":%s %s %s ",
369 <                           from->name, command, chptr->chname);
368 >    local_len = snprintf(local_buf, sizeof(local_buf), ":%s ",
369 >                        from->name);
370    else
371 <    local_len = ircsprintf(local_buf, ":%s!%s@%s %s %s ",
372 <                           from->name, from->username, from->host,
373 <                           command, chptr->chname);
374 <  remote_len = ircsprintf(remote_buf, ":%s %s %s ",
375 <                          from->name, command, chptr->chname);
468 <  uid_len = ircsprintf(uid_buf, ":%s %s %s ",
469 <                       ID(from), command, chptr->chname);
371 >    local_len = snprintf(local_buf, sizeof(local_buf), ":%s!%s@%s ",
372 >                         from->name, from->username, from->host);
373 >  remote_len = snprintf(remote_buf, sizeof(remote_buf), ":%s ",
374 >                        from->name);
375 >  uid_len = snprintf(uid_buf, sizeof(uid_buf), ":%s ", ID(from));
376  
377    va_start(alocal, pattern);
378    va_start(aremote, pattern);
# Line 485 | Line 391 | sendto_channel_butone(struct Client *one
391  
392    DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
393    {
394 <    struct Client *target_p = ((struct Membership *)ptr->data)->client_p;
394 >    struct Membership *ms = ptr->data;
395 >    struct Client *target_p = ms->client_p;
396  
397      assert(IsClient(target_p));
398  
399      if (IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF) || target_p->from == one)
400        continue;
401  
402 +    if (type != 0 && (ms->flags & type) == 0)
403 +      continue;
404 +
405      if (MyConnect(target_p))
406      {
407        if (target_p->localClient->serial != current_serial)
# Line 535 | Line 445 | sendto_channel_butone(struct Client *one
445   * lazylinks, uids, etc.
446   * -davidt
447   */
448 < void
449 < sendto_server(struct Client *one, const struct Channel *chptr,
448 > void
449 > sendto_server(struct Client *one,
450                const unsigned int caps,
451                const unsigned int nocaps,
452                const char *format, ...)
# Line 546 | Line 456 | sendto_server(struct Client *one, const
456    char buffer[IRCD_BUFSIZE];
457    int len = 0;
458  
549  if (chptr && chptr->chname[0] != '#')
550    return;
551
459    va_start(args, format);
460 <  len = send_format(buffer, IRCD_BUFSIZE, format, args);
460 >  len = send_format(buffer, sizeof(buffer), format, args);
461    va_end(args);
462  
463    DLINK_FOREACH(ptr, serv_list.head)
# Line 584 | Line 491 | sendto_server(struct Client *one, const
491   *                used by m_nick.c and exit_one_client.
492   */
493   void
494 < sendto_common_channels_local(struct Client *user, int touser,
494 > sendto_common_channels_local(struct Client *user, int touser, unsigned int cap,
495                               const char *pattern, ...)
496   {
497    va_list args;
# Line 597 | Line 504 | sendto_common_channels_local(struct Clie
504    int len;
505  
506    va_start(args, pattern);
507 <  len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
507 >  len = send_format(buffer, sizeof(buffer), pattern, args);
508    va_end(args);
509  
510    ++current_serial;
511  
512    DLINK_FOREACH(cptr, user->channel.head)
513    {
514 <    chptr = ((struct Membership *) cptr->data)->chptr;
514 >    chptr = ((struct Membership *)cptr->data)->chptr;
515      assert(chptr != NULL);
516  
517      DLINK_FOREACH(uptr, chptr->members.head)
# Line 617 | Line 524 | sendto_common_channels_local(struct Clie
524            target_p->localClient->serial == current_serial)
525          continue;
526  
527 +      if (HasCap(target_p, cap) != cap)
528 +        continue;
529 +
530        target_p->localClient->serial = current_serial;
531        send_message(target_p, buffer, len);
532      }
# Line 624 | Line 534 | sendto_common_channels_local(struct Clie
534  
535    if (touser && MyConnect(user) && !IsDead(user) &&
536        user->localClient->serial != current_serial)
537 <    send_message(user, buffer, len);
537 >    if (HasCap(user, cap) == cap)
538 >      send_message(user, buffer, len);
539   }
540  
541   /* sendto_channel_local()
# Line 638 | Line 549 | sendto_common_channels_local(struct Clie
549   *                locally connected to this server.
550   */
551   void
552 < sendto_channel_local(int type, int nodeaf, struct Channel *chptr,
552 > sendto_channel_local(unsigned int type, int nodeaf, struct Channel *chptr,
553                       const char *pattern, ...)
554   {
555    va_list args;
556    char buffer[IRCD_BUFSIZE];
557 <  int len;
558 <  dlink_node *ptr;
648 <  struct Membership *ms;
649 <  struct Client *target_p;
557 >  int len = 0;
558 >  dlink_node *ptr = NULL;
559  
560    va_start(args, pattern);
561 <  len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
561 >  len = send_format(buffer, sizeof(buffer), pattern, args);
562    va_end(args);
563  
564    DLINK_FOREACH(ptr, chptr->members.head)
565    {
566 <    ms = ptr->data;
567 <    target_p = ms->client_p;
566 >    struct Membership *ms = ptr->data;
567 >    struct Client *target_p = ms->client_p;
568  
569      if (type != 0 && (ms->flags & type) == 0)
570        continue;
# Line 680 | Line 589 | sendto_channel_local(int type, int nodea
589   *
590   * WARNING - +D clients are omitted
591   */
592 < void      
593 < sendto_channel_local_butone(struct Client *one, int type,
594 <                            struct Channel *chptr, const char *pattern, ...)
592 > void
593 > sendto_channel_local_butone(struct Client *one, unsigned int type, unsigned int cap,
594 >                            struct Channel *chptr, const char *pattern, ...)
595   {
596    va_list args;
597    char buffer[IRCD_BUFSIZE];
598 <  int len;
599 <  struct Client *target_p;
691 <  struct Membership *ms;
692 <  dlink_node *ptr;
598 >  int len = 0;
599 >  dlink_node *ptr = NULL;
600  
601 <  va_start(args, pattern);
602 <  len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
601 >  va_start(args, pattern);
602 >  len = send_format(buffer, sizeof(buffer), pattern, args);
603    va_end(args);
604  
605 <  DLINK_FOREACH(ptr, chptr->members.head)      
606 <  {  
607 <    ms = ptr->data;
608 <    target_p = ms->client_p;
605 >  DLINK_FOREACH(ptr, chptr->members.head)
606 >  {
607 >    struct Membership *ms = ptr->data;
608 >    struct Client *target_p = ms->client_p;
609  
610      if (type != 0 && (ms->flags & type) == 0)
611        continue;
# Line 706 | Line 613 | sendto_channel_local_butone(struct Clien
613      if (!MyConnect(target_p) || target_p == one ||
614          IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF))
615        continue;
616 +
617 +    if (HasCap(target_p, cap) != cap)
618 +      continue;
619 +
620      send_message(target_p, buffer, len);
621    }
622   }
# Line 723 | Line 634 | sendto_channel_local_butone(struct Clien
634   *                remote to this server.
635   */
636   void
637 < sendto_channel_remote(struct Client *one, struct Client *from, int type,
637 > sendto_channel_remote(struct Client *one, struct Client *from, unsigned int type,
638                        const unsigned int caps, const unsigned int nocaps,
639                        struct Channel *chptr, const char *pattern, ...)
640   {
641    va_list args;
642    char buffer[IRCD_BUFSIZE];
643 <  int len;
644 <  dlink_node *ptr;
734 <  struct Client *target_p;
735 <  struct Membership *ms;
643 >  int len = 0;
644 >  dlink_node *ptr = NULL;
645  
646    va_start(args, pattern);
647 <  len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
647 >  len = send_format(buffer, sizeof(buffer), pattern, args);
648    va_end(args);
649  
650    ++current_serial;
651  
652    DLINK_FOREACH(ptr, chptr->members.head)
653    {
654 <    ms = ptr->data;
655 <    target_p = ms->client_p;
654 >    struct Membership *ms = ptr->data;
655 >    struct Client *target_p = ms->client_p;
656  
657      if (type != 0 && (ms->flags & type) == 0)
658        continue;
659  
660      if (MyConnect(target_p))
661        continue;
662 +
663      target_p = target_p->from;
664  
665      if (target_p == one->from ||
666          ((target_p->from->localClient->caps & caps) != caps) ||
667          ((target_p->from->localClient->caps & nocaps) != 0))
668        continue;
669 +
670      if (target_p->from->localClient->serial != current_serial)
671      {
672        send_message(target_p, buffer, len);
673        target_p->from->localClient->serial = current_serial;
674      }
675 <  }
675 >  }
676   }
677  
678   /*
# Line 782 | Line 693 | sendto_channel_remote(struct Client *one
693   * side effects - NONE
694   */
695   static int
696 < match_it(const struct Client *one, const char *mask, int what)
696 > match_it(const struct Client *one, const char *mask, unsigned int what)
697   {
698    if (what == MATCH_HOST)
699 <    return match(mask, one->host);
699 >    return !match(mask, one->host);
700  
701 <  return match(mask, one->servptr->name);
701 >  return !match(mask, one->servptr->name);
702   }
703  
704   /* sendto_match_butone()
# Line 805 | Line 716 | sendto_match_butone(struct Client *one,
716    struct Client *client_p;
717    dlink_node *ptr, *ptr_next;
718    char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE];
719 <  int local_len = ircsprintf(local_buf, ":%s!%s@%s ", from->name,
720 <                             from->username, from->host);
721 <  int remote_len = ircsprintf(remote_buf, ":%s ", from->name);
719 >  int local_len = snprintf(local_buf, sizeof(local_buf), ":%s!%s@%s ",
720 >                           from->name, from->username, from->host);
721 >  int remote_len = snprintf(remote_buf, sizeof(remote_buf), ":%s ",
722 >                            from->name);
723  
724    va_start(alocal, pattern);
725    va_start(aremote, pattern);
# Line 872 | Line 784 | sendto_match_butone(struct Client *one,
784   * side effects - data sent to servers matching with capab
785   */
786   void
787 < sendto_match_servs(struct Client *source_p, const char *mask, int cap,
787 > sendto_match_servs(struct Client *source_p, const char *mask, unsigned int cap,
788                     const char *pattern, ...)
789   {
790    va_list args;
791 <  struct Client *target_p;
792 <  dlink_node *ptr;
793 <  char buffer[IRCD_BUFSIZE];
794 <  int found = 0;
791 >  dlink_node *ptr = NULL;
792 >  char buff_suid[IRCD_BUFSIZE];
793 >  char buff_name[IRCD_BUFSIZE];
794 >  int len_suid = 0;
795 >  int len_name = 0;
796  
797    va_start(args, pattern);
798 <  vsnprintf(buffer, sizeof(buffer), pattern, args);
798 >  len_suid  = snprintf(buff_suid, sizeof(buff_suid), ":%s ", ID(source_p));
799 >  len_suid += send_format(&buff_suid[len_suid], sizeof(buff_suid) - len_suid,
800 >                          pattern, args);
801 >  va_end(args);
802 >
803 >  va_start(args, pattern);
804 >  len_name = snprintf(buff_name, sizeof(buff_name), ":%s ", source_p->name);
805 >  len_name += send_format(&buff_name[len_name], sizeof(buff_name) - len_name,
806 >                          pattern, args);
807    va_end(args);
808  
809    ++current_serial;
810  
811    DLINK_FOREACH(ptr, global_serv_list.head)
812    {
813 <    target_p = ptr->data;
813 >    struct Client *target_p = ptr->data;
814  
815      /* Do not attempt to send to ourselves, or the source */
816      if (IsMe(target_p) || target_p->from == source_p->from)
# Line 898 | Line 819 | sendto_match_servs(struct Client *source
819      if (target_p->from->localClient->serial == current_serial)
820        continue;
821  
822 <    if (match(mask, target_p->name))
822 >    if (!match(mask, target_p->name))
823      {
824        /*
825         * if we set the serial here, then we'll never do a
826         * match() again, if !IsCapable()
827         */
828        target_p->from->localClient->serial = current_serial;
908      found++;
829  
830        if (!IsCapable(target_p->from, cap))
831          continue;
832  
833 <      sendto_anywhere(target_p, source_p, "%s", buffer);
833 >      if (HasID(target_p->from))
834 >        send_message_remote(target_p->from, source_p, buff_suid, len_suid);
835 >      else
836 >        send_message_remote(target_p->from, source_p, buff_name, len_name);
837      }
838    }
839   }
# Line 926 | Line 849 | sendto_match_servs(struct Client *source
849   */
850   void
851   sendto_anywhere(struct Client *to, struct Client *from,
852 +                const char *command,
853                  const char *pattern, ...)
854   {
855    va_list args;
856    char buffer[IRCD_BUFSIZE];
857 <  int len;
934 <  struct Client *send_to = (to->from != NULL ? to->from : to);
857 >  int len = 0;
858  
859 <  if (IsDead(send_to))
859 >  if (IsDead(to->from))
860      return;
861  
862    if (MyClient(to))
863    {
864      if (IsServer(from))
865 <    {
866 <      if (IsCapable(to, CAP_TS6) && HasID(from))
944 <        len = ircsprintf(buffer, ":%s ", from->id);
945 <      else
946 <        len = ircsprintf(buffer, ":%s ", from->name);
947 <    }
865 >      len = snprintf(buffer, sizeof(buffer), ":%s %s %s ",
866 >                     from->name, command, to->name);
867      else
868 <      len = ircsprintf(buffer, ":%s!%s@%s ",
869 <                       from->name, from->username, from->host);
868 >      len = snprintf(buffer, sizeof(buffer), ":%s!%s@%s %s %s ",
869 >                     from->name, from->username, from->host, command, to->name);
870    }
871 <  else len = ircsprintf(buffer, ":%s ", ID_or_name(from, send_to));
871 >  else
872 >    len = snprintf(buffer, sizeof(buffer), ":%s %s %s ",
873 >                   ID_or_name(from, to), command,
874 >                   ID_or_name(to, to));
875  
876    va_start(args, pattern);
877 <  len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
877 >  len += send_format(&buffer[len], sizeof(buffer) - len, pattern, args);
878    va_end(args);
879  
880 <  if(MyClient(to))
881 <    send_message(send_to, buffer, len);
880 >  if (MyClient(to))
881 >    send_message(to, buffer, len);
882    else
883 <    send_message_remote(send_to, from, buffer, len);
883 >    send_message_remote(to, from, buffer, len);
884   }
885  
886   /* sendto_realops_flags()
# Line 970 | Line 892 | sendto_anywhere(struct Client *to, struc
892   * side effects - Send to *local* ops only but NOT +s nonopers.
893   */
894   void
895 < sendto_realops_flags(unsigned int flags, int level, const char *pattern, ...)
895 > sendto_realops_flags(unsigned int flags, int level, int type, const char *pattern, ...)
896   {
897 +  const char *ntype = NULL;
898    dlink_node *ptr = NULL;
899    char nbuf[IRCD_BUFSIZE];
900    va_list args;
901  
902    va_start(args, pattern);
903 <  vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args);
903 >  vsnprintf(nbuf, sizeof(nbuf), pattern, args);
904    va_end(args);
905  
906 <  DLINK_FOREACH(ptr, oper_list.head)
906 >  switch (type)
907    {
908 <    struct Client *client_p = ptr->data;
909 <    assert(HasUMode(client_p, UMODE_OPER));
910 <
911 <    /* If we're sending it to opers and theyre an admin, skip.
912 <     * If we're sending it to admins, and theyre not, skip.
913 <     */
914 <    if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) ||
915 <        ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN)))
916 <      continue;
917 <
918 <    if (HasUMode(client_p, flags))
996 <      sendto_one(client_p, ":%s NOTICE %s :*** Notice -- %s",
997 <                 me.name, client_p->name, nbuf);
908 >    case SEND_NOTICE:
909 >      ntype = "Notice";
910 >      break;
911 >    case SEND_GLOBAL:
912 >      ntype = "Global";
913 >      break;
914 >    case SEND_LOCOPS:
915 >      ntype = "LocOps";
916 >      break;
917 >    default:
918 >      assert(0);
919    }
999 }
1000
1001 void
1002 sendto_globops_flags(unsigned int flags, int level, const char *pattern, ...)
1003 {
1004  dlink_node *ptr = NULL;
1005  char nbuf[IRCD_BUFSIZE];
1006  va_list args;
1007
1008  va_start(args, pattern);
1009  vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args);
1010  va_end(args);
920  
921    DLINK_FOREACH(ptr, oper_list.head)
922    {
923      struct Client *client_p = ptr->data;
924 <    assert(client_p->umodes & UMODE_OPER);
924 >    assert(HasUMode(client_p, UMODE_OPER));
925  
926 <    /* If we're sending it to opers and theyre an admin, skip.
927 <     * If we're sending it to admins, and theyre not, skip.
926 >    /*
927 >     * If we're sending it to opers and they're an admin, skip.
928 >     * If we're sending it to admins, and they're not, skip.
929       */
930      if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) ||
931          ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN)))
932        continue;
933  
934      if (HasUMode(client_p, flags))
935 <      sendto_one(client_p, ":%s NOTICE %s :*** Global -- %s",
936 <                 me.name, client_p->name, nbuf);
935 >      sendto_one(client_p, ":%s NOTICE %s :*** %s -- %s",
936 >                 me.name, client_p->name, ntype, nbuf);
937    }
938   }
939  
# Line 1045 | Line 955 | sendto_wallops_flags(unsigned int flags,
955    int len;
956  
957    if (IsClient(source_p))
958 <    len = ircsprintf(buffer, ":%s!%s@%s WALLOPS :",
959 <                     source_p->name, source_p->username, source_p->host);
958 >    len = snprintf(buffer, sizeof(buffer), ":%s!%s@%s WALLOPS :",
959 >                   source_p->name, source_p->username,
960 >                   source_p->host);
961    else
962 <    len = ircsprintf(buffer, ":%s WALLOPS :", source_p->name);
962 >    len = snprintf(buffer, sizeof(buffer), ":%s WALLOPS :",
963 >                   source_p->name);
964  
965    va_start(args, pattern);
966    len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
# Line 1101 | Line 1013 | ts_warn(const char *pattern, ...)
1013    vsnprintf(buffer, sizeof(buffer), pattern, args);
1014    va_end(args);
1015  
1016 <  sendto_realops_flags(UMODE_ALL, L_ALL, "%s", buffer);
1016 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s", buffer);
1017    ilog(LOG_TYPE_IRCD, "%s", buffer);
1018   }
1019  
# Line 1126 | Line 1038 | kill_client(struct Client *client_p, str
1038    if (IsDead(client_p))
1039      return;
1040  
1041 <  len = ircsprintf(buffer, ":%s KILL %s :", ID_or_name(&me, client_p->from),
1042 <                   ID_or_name(diedie, client_p));
1041 >  len = snprintf(buffer, sizeof(buffer), ":%s KILL %s :",
1042 >                 ID_or_name(&me, client_p->from),
1043 >                 ID_or_name(diedie, client_p));
1044  
1045    va_start(args, pattern);
1046    len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
# Line 1147 | Line 1060 | kill_client(struct Client *client_p, str
1060   *                client being unknown to leaf, as in lazylink...
1061   */
1062   void
1063 < kill_client_ll_serv_butone(struct Client *one, struct Client *source_p,
1064 <                           const char *pattern, ...)
1063 > kill_client_serv_butone(struct Client *one, struct Client *source_p,
1064 >                        const char *pattern, ...)
1065   {
1066    va_list args;
1067    int have_uid = 0;
# Line 1160 | Line 1073 | kill_client_ll_serv_butone(struct Client
1073    {
1074      have_uid = 1;
1075      va_start(args, pattern);
1076 <    len_uid = ircsprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p));
1077 <    len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern,
1078 <                           args);
1076 >    len_uid = snprintf(buf_uid, sizeof(buf_uid), ":%s KILL %s :",
1077 >                       me.id, ID(source_p));
1078 >    len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern, args);
1079      va_end(args);
1080    }
1081  
1082    va_start(args, pattern);
1083 <  len_nick = ircsprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name);
1084 <  len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern,
1085 <                          args);
1083 >  len_nick = snprintf(buf_nick, sizeof(buf_nick), ":%s KILL %s :",
1084 >                      me.name, source_p->name);
1085 >  len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern, args);
1086    va_end(args);
1087  
1088    DLINK_FOREACH(ptr, serv_list.head)
# Line 1186 | Line 1099 | kill_client_ll_serv_butone(struct Client
1099      else
1100        send_message(client_p, buf_nick, len_nick);
1101    }
1102 < }
1102 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)