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-7.3/src/send.c (file contents), Revision 1123 by michael, Sun Feb 6 21:57:50 2011 UTC vs.
ircd-hybrid/trunk/src/send.c (file contents), Revision 1798 by michael, Sun Mar 31 17:09:50 2013 UTC

# Line 27 | Line 27
27   #include "send.h"
28   #include "channel.h"
29   #include "client.h"
30 #include "common.h"
30   #include "dbuf.h"
31   #include "irc_string.h"
32   #include "ircd.h"
34 #include "handlers.h"
33   #include "numeric.h"
34   #include "fdlist.h"
35   #include "s_bsd.h"
36   #include "s_serv.h"
37 < #include "sprintf_irc.h"
38 < #include "s_conf.h"
41 < #include "s_log.h"
37 > #include "conf.h"
38 > #include "log.h"
39   #include "memory.h"
43 #include "hook.h"
40   #include "packet.h"
41  
42  
47 struct Callback *iosend_cb = NULL;
48 struct Callback *iosendctrl_cb = NULL;
43   static unsigned int current_serial = 0;
44  
45  
# Line 85 | Line 79 | send_format(char *lsendbuf, int bufsize,
79   }
80  
81   /*
88 * iosend_default - append a packet to the client's sendq.
89 */
90 void *
91 iosend_default(va_list args)
92 {
93  struct Client *to = va_arg(args, struct Client *);
94  int length = va_arg(args, int);
95  char *buf = va_arg(args, char *);
96
97  dbuf_put(&to->localClient->buf_sendq, buf, length);
98  return NULL;
99 }
100
101 /*
82   ** send_message
83   **      Internal utility which appends given buffer to the sockets
84   **      sendq.
# Line 109 | 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);
105 >
106 >  dbuf_put(&to->localClient->buf_sendq, buf, len);
107  
108    /*
109     ** Update statistics. The following is slightly incorrect
# Line 155 | Line 135 | send_message_remote(struct Client *to, s
135   {
136    if (!MyConnect(to))
137    {
138 <    sendto_realops_flags(UMODE_ALL, L_ALL,
138 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
139                           "server send message to %s [%s] dropped from %s(Not local server)",
140                           to->name, to->from->name, from->name);
141      return;
# Line 168 | Line 148 | send_message_remote(struct Client *to, s
148    {
149      if (IsServer(from))
150      {
151 <      sendto_realops_flags(UMODE_ALL, L_ALL,
151 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
152                             "Send message to %s [%s] dropped from %s(Fake Dir)",
153                             to->name, to->from->name, from->name);
154        return;
155      }
156  
157 <    sendto_realops_flags(UMODE_ALL, L_ALL,
157 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
158                           "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
159                           to->name, to->username, to->host,
160                           from->name, from->username, from->host,
161                           to->from->name);
162  
163 <    sendto_server(NULL, NULL, CAP_TS6, NOCAPS,
163 >    sendto_server(NULL, CAP_TS6, NOCAPS,
164                    ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
165                    me.id, to->name, me.name, to->name,
166                    to->username, to->host, to->from->name);
167 <    sendto_server(NULL, NULL, NOCAPS, CAP_TS6,
167 >    sendto_server(NULL, NOCAPS, CAP_TS6,
168                    ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
169                    me.name, to->name, me.name, to->name,
170                    to->username, to->host, to->from->name);
171  
172 <    SetKilled(to);
172 >    AddFlag(to, FLAGS_KILLED);
173  
174      if (IsClient(from))
175        sendto_one(from, form_str(ERR_GHOSTEDCLIENT),
# Line 224 | Line 204 | sendq_unblocked(fde_t *fd, struct Client
204   }
205  
206   /*
227 ** slinkq_unblocked
228 **      Called when a server control socket is ready for writing.
229 */
230 static void
231 slinkq_unblocked(fde_t *fd, struct Client *client_p)
232 {
233  ClearSlinkqBlocked(client_p);
234  send_queued_slink_write(client_p);
235 }
236
237 /*
207   ** send_queued_write
208   **      This is called when there is a chance that some output would
209   **      be possible. This attempts to empty the send queue as far as
# Line 312 | Line 281 | send_queued_write(struct Client *to)
281    }
282   }
283  
315 /*
316 ** send_queued_slink_write
317 **      This is called when there is a chance the some output would
318 **      be possible. This attempts to empty the send queue as far as
319 **      possible, and then if any data is left, a write is rescheduled.
320 */
321 void
322 send_queued_slink_write(struct Client *to)
323 {
324  int retlen;
325
326  /*
327   ** Once socket is marked dead, we cannot start writing to it,
328   ** even if the error is removed...
329   */
330  if (IsDead(to) || IsSlinkqBlocked(to))
331    return;  /* no use calling send() now */
332
333  /* Next, lets try to write some data */
334  if (to->localClient->slinkq != NULL)
335  {
336    retlen = send(to->localClient->ctrlfd.fd,
337                   to->localClient->slinkq + to->localClient->slinkq_ofs,
338                   to->localClient->slinkq_len, 0);
339    if (retlen < 0)
340    {
341      /* If we have a fatal error */
342      if (!ignoreErrno(errno))
343      {
344        dead_link_on_write(to, errno);
345        return;
346      }
347    }
348    else if (retlen == 0)
349    {
350      /* 0 bytes is an EOF .. */
351      dead_link_on_write(to, 0);
352      return;
353    }
354    else
355    {
356      execute_callback(iosendctrl_cb, to, retlen,
357        to->localClient->slinkq + to->localClient->slinkq_ofs);
358      to->localClient->slinkq_len -= retlen;
359
360      assert(to->localClient->slinkq_len >= 0);
361      if (to->localClient->slinkq_len)
362        to->localClient->slinkq_ofs += retlen;
363      else
364      {
365        to->localClient->slinkq_ofs = 0;
366        MyFree(to->localClient->slinkq);
367        to->localClient->slinkq = NULL;
368      }
369    }
370
371    /* Finally, if we have any more data, reschedule a write */
372    if (to->localClient->slinkq_len)
373    {
374      SetSlinkqBlocked(to);
375      comm_setselect(&to->localClient->ctrlfd, COMM_SELECT_WRITE,
376                     (PF *)slinkq_unblocked, (void *)to, 0);
377    }
378  }
379 }
380
284   /* send_queued_all()
285   *
286   * input        - NONE
# Line 448 | Line 351 | sendto_one(struct Client *to, const char
351   */
352   void
353   sendto_channel_butone(struct Client *one, struct Client *from,
354 <                      struct Channel *chptr, const char *command,
354 >                      struct Channel *chptr, unsigned int type,
355                        const char *pattern, ...)
356   {
357    va_list alocal, aremote, auid;
# Line 459 | Line 362 | sendto_channel_butone(struct Client *one
362    dlink_node *ptr = NULL, *ptr_next = NULL;
363  
364    if (IsServer(from))
365 <    local_len = ircsprintf(local_buf, ":%s %s %s ",
366 <                           from->name, command, chptr->chname);
365 >    local_len = sprintf(local_buf, ":%s ",
366 >                        from->name);
367    else
368 <    local_len = ircsprintf(local_buf, ":%s!%s@%s %s %s ",
369 <                           from->name, from->username, from->host,
370 <                           command, chptr->chname);
371 <  remote_len = ircsprintf(remote_buf, ":%s %s %s ",
372 <                          from->name, command, chptr->chname);
373 <  uid_len = ircsprintf(uid_buf, ":%s %s %s ",
471 <                       ID(from), command, chptr->chname);
368 >    local_len = sprintf(local_buf, ":%s!%s@%s ",
369 >                        from->name, from->username, from->host);
370 >  remote_len = sprintf(remote_buf, ":%s ",
371 >                          from->name);
372 >  uid_len = sprintf(uid_buf, ":%s ",
373 >                    ID(from));
374  
375    va_start(alocal, pattern);
376    va_start(aremote, pattern);
# Line 487 | Line 389 | sendto_channel_butone(struct Client *one
389  
390    DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
391    {
392 <    struct Client *target_p = ((struct Membership *)ptr->data)->client_p;
392 >    struct Membership *ms = ptr->data;
393 >    struct Client *target_p = ms->client_p;
394  
395      assert(IsClient(target_p));
396  
397 <    if (IsDefunct(target_p) || IsDeaf(target_p) || target_p->from == one)
397 >    if (IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF) || target_p->from == one)
398 >      continue;
399 >
400 >    if (type != 0 && (ms->flags & type) == 0)
401        continue;
402  
403      if (MyConnect(target_p))
# Line 538 | Line 444 | sendto_channel_butone(struct Client *one
444   * -davidt
445   */
446   void
447 < sendto_server(struct Client *one, const struct Channel *chptr,
447 > sendto_server(struct Client *one,
448                const unsigned int caps,
449                const unsigned int nocaps,
450                const char *format, ...)
# Line 548 | Line 454 | sendto_server(struct Client *one, const
454    char buffer[IRCD_BUFSIZE];
455    int len = 0;
456  
551  if (chptr && chptr->chname[0] != '#')
552    return;
553
457    va_start(args, format);
458    len = send_format(buffer, IRCD_BUFSIZE, format, args);
459    va_end(args);
# Line 586 | Line 489 | sendto_server(struct Client *one, const
489   *                used by m_nick.c and exit_one_client.
490   */
491   void
492 < sendto_common_channels_local(struct Client *user, int touser,
492 > sendto_common_channels_local(struct Client *user, int touser, unsigned int cap,
493                               const char *pattern, ...)
494   {
495    va_list args;
# Line 619 | Line 522 | sendto_common_channels_local(struct Clie
522            target_p->localClient->serial == current_serial)
523          continue;
524  
525 +      if (HasCap(target_p, cap) != cap)
526 +        continue;
527 +
528        target_p->localClient->serial = current_serial;
529        send_message(target_p, buffer, len);
530      }
# Line 626 | Line 532 | sendto_common_channels_local(struct Clie
532  
533    if (touser && MyConnect(user) && !IsDead(user) &&
534        user->localClient->serial != current_serial)
535 <    send_message(user, buffer, len);
535 >    if (HasCap(target_p, cap) == cap)
536 >      send_message(user, buffer, len);
537   }
538  
539   /* sendto_channel_local()
# Line 663 | Line 570 | sendto_channel_local(int type, int nodea
570        continue;
571  
572      if (!MyConnect(target_p) || IsDefunct(target_p) ||
573 <        (nodeaf && IsDeaf(target_p)))
573 >        (nodeaf && HasUMode(target_p, UMODE_DEAF)))
574        continue;
575  
576      send_message(target_p, buffer, len);
# Line 683 | Line 590 | sendto_channel_local(int type, int nodea
590   * WARNING - +D clients are omitted
591   */
592   void      
593 < sendto_channel_local_butone(struct Client *one, int type,
593 > sendto_channel_local_butone(struct Client *one, int type, unsigned int cap,
594                              struct Channel *chptr, const char *pattern, ...)
595   {
596    va_list args;
# Line 706 | Line 613 | sendto_channel_local_butone(struct Clien
613        continue;
614  
615      if (!MyConnect(target_p) || target_p == one ||
616 <        IsDefunct(target_p) || IsDeaf(target_p))
616 >        IsDefunct(target_p) || HasUMode(target_p, UMODE_DEAF))
617        continue;
618 +
619 +    if (HasCap(target_p, cap) != cap)
620 +        continue;
621      send_message(target_p, buffer, len);
622    }
623   }
# Line 787 | Line 697 | static int
697   match_it(const struct Client *one, const char *mask, int what)
698   {
699    if (what == MATCH_HOST)
700 <    return match(mask, one->host);
700 >    return !match(mask, one->host);
701  
702 <  return match(mask, one->servptr->name);
702 >  return !match(mask, one->servptr->name);
703   }
704  
705   /* sendto_match_butone()
# Line 807 | Line 717 | sendto_match_butone(struct Client *one,
717    struct Client *client_p;
718    dlink_node *ptr, *ptr_next;
719    char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE];
720 <  int local_len = ircsprintf(local_buf, ":%s!%s@%s ", from->name,
721 <                             from->username, from->host);
722 <  int remote_len = ircsprintf(remote_buf, ":%s ", from->name);
720 >  int local_len = sprintf(local_buf, ":%s!%s@%s ", from->name,
721 >                          from->username, from->host);
722 >  int remote_len = sprintf(remote_buf, ":%s ", from->name);
723  
724    va_start(alocal, pattern);
725    va_start(aremote, pattern);
# Line 900 | Line 810 | sendto_match_servs(struct Client *source
810      if (target_p->from->localClient->serial == current_serial)
811        continue;
812  
813 <    if (match(mask, target_p->name))
813 >    if (!match(mask, target_p->name))
814      {
815        /*
816         * if we set the serial here, then we'll never do a
# Line 943 | Line 853 | sendto_anywhere(struct Client *to, struc
853      if (IsServer(from))
854      {
855        if (IsCapable(to, CAP_TS6) && HasID(from))
856 <        len = ircsprintf(buffer, ":%s ", from->id);
856 >        len = sprintf(buffer, ":%s ", from->id);
857        else
858 <        len = ircsprintf(buffer, ":%s ", from->name);
858 >        len = sprintf(buffer, ":%s ", from->name);
859      }
860      else
861 <      len = ircsprintf(buffer, ":%s!%s@%s ",
861 >      len = sprintf(buffer, ":%s!%s@%s ",
862                         from->name, from->username, from->host);
863    }
864 <  else len = ircsprintf(buffer, ":%s ", ID_or_name(from, send_to));
864 >  else len = sprintf(buffer, ":%s ", ID_or_name(from, send_to));
865  
866    va_start(args, pattern);
867    len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
# Line 972 | Line 882 | sendto_anywhere(struct Client *to, struc
882   * side effects - Send to *local* ops only but NOT +s nonopers.
883   */
884   void
885 < sendto_realops_flags(unsigned int flags, int level, const char *pattern, ...)
885 > sendto_realops_flags(unsigned int flags, int level, int type, const char *pattern, ...)
886   {
887 +  const char *ntype = NULL;
888    dlink_node *ptr = NULL;
889    char nbuf[IRCD_BUFSIZE];
890    va_list args;
891  
892    va_start(args, pattern);
893 <  vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args);
893 >  vsnprintf(nbuf, sizeof(nbuf), pattern, args);
894    va_end(args);
895  
896 +  switch (type)
897 +  {
898 +    case SEND_NOTICE:
899 +      ntype = "Notice";
900 +      break;
901 +    case SEND_GLOBAL:
902 +      ntype = "Global";
903 +      break;
904 +    case SEND_LOCOPS:
905 +      ntype = "LocOps";
906 +      break;
907 +    default:
908 +      assert(0);
909 +  }
910 +
911    DLINK_FOREACH(ptr, oper_list.head)
912    {
913      struct Client *client_p = ptr->data;
914 <    assert(client_p->umodes & UMODE_OPER);
914 >    assert(HasUMode(client_p, UMODE_OPER));
915  
916 <    /* If we're sending it to opers and theyre an admin, skip.
917 <     * If we're sending it to admins, and theyre not, skip.
916 >    /*
917 >     * If we're sending it to opers and they're an admin, skip.
918 >     * If we're sending it to admins, and they're not, skip.
919       */
920 <    if (((level == L_ADMIN) && !IsAdmin(client_p)) ||
921 <        ((level == L_OPER) && IsAdmin(client_p)))
920 >    if (((level == L_ADMIN) && !HasUMode(client_p, UMODE_ADMIN)) ||
921 >        ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN)))
922        continue;
923  
924 <    if (client_p->umodes & flags)
925 <      sendto_one(client_p, ":%s NOTICE %s :*** Notice -- %s",
926 <                 me.name, client_p->name, nbuf);
924 >    if (HasUMode(client_p, flags))
925 >      sendto_one(client_p, ":%s NOTICE %s :*** %s -- %s",
926 >                 me.name, client_p->name, ntype, nbuf);
927    }
928   }
929  
# Line 1018 | Line 945 | sendto_wallops_flags(unsigned int flags,
945    int len;
946  
947    if (IsClient(source_p))
948 <    len = ircsprintf(buffer, ":%s!%s@%s WALLOPS :",
949 <                     source_p->name, source_p->username, source_p->host);
948 >    len = sprintf(buffer, ":%s!%s@%s WALLOPS :",
949 >                  source_p->name, source_p->username, source_p->host);
950    else
951 <    len = ircsprintf(buffer, ":%s WALLOPS :", source_p->name);
951 >    len = sprintf(buffer, ":%s WALLOPS :", source_p->name);
952  
953    va_start(args, pattern);
954    len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
# Line 1032 | Line 959 | sendto_wallops_flags(unsigned int flags,
959      struct Client *client_p = ptr->data;
960      assert(client_p->umodes & UMODE_OPER);
961  
962 <    if ((client_p->umodes & flags) && !IsDefunct(client_p))
962 >    if (HasUMode(client_p, flags) && !IsDefunct(client_p))
963        send_message(client_p, buffer, len);
964    }
965   }
# Line 1074 | Line 1001 | ts_warn(const char *pattern, ...)
1001    vsnprintf(buffer, sizeof(buffer), pattern, args);
1002    va_end(args);
1003  
1004 <  sendto_realops_flags(UMODE_ALL, L_ALL, "%s", buffer);
1005 <  ilog(L_CRIT, "%s", buffer);
1004 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s", buffer);
1005 >  ilog(LOG_TYPE_IRCD, "%s", buffer);
1006   }
1007  
1008   /* kill_client()
# Line 1099 | Line 1026 | kill_client(struct Client *client_p, str
1026    if (IsDead(client_p))
1027      return;
1028  
1029 <  len = ircsprintf(buffer, ":%s KILL %s :", ID_or_name(&me, client_p->from),
1030 <                   ID_or_name(diedie, client_p));
1029 >  len = sprintf(buffer, ":%s KILL %s :", ID_or_name(&me, client_p->from),
1030 >                ID_or_name(diedie, client_p));
1031  
1032    va_start(args, pattern);
1033    len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
# Line 1133 | Line 1060 | kill_client_ll_serv_butone(struct Client
1060    {
1061      have_uid = 1;
1062      va_start(args, pattern);
1063 <    len_uid = ircsprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p));
1063 >    len_uid = sprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p));
1064      len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern,
1065                             args);
1066      va_end(args);
1067    }
1068  
1069    va_start(args, pattern);
1070 <  len_nick = ircsprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name);
1070 >  len_nick = sprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name);
1071    len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern,
1072                            args);
1073    va_end(args);

Diff Legend

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