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/trunk/src/send.c (file contents):
Revision 1844 by michael, Mon Apr 22 15:35:39 2013 UTC vs.
Revision 2793 by michael, Thu Jan 9 17:38:12 2014 UTC

# Line 62 | 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 102 | Line 102 | send_message(struct Client *to, char *bu
102      dead_link_on_write(to, 0);
103      return;
104    }
105 <
105 >
106    dbuf_put(&to->localClient->buf_sendq, buf, len);
107  
108    /*
# Line 133 | 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, SEND_NOTICE,
142 <                         "server send message to %s [%s] dropped from %s(Not local server)",
143 <                         to->name, to->from->name, from->name);
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 177 | Line 180 | send_message_remote(struct Client *to, s
180                   to->host, to->from);
181  
182      exit_client(to, &me, "Ghosted client");
180
183      return;
184 <  }
184 >  }
185  
186    send_message(to, buf, len);
187   }
# Line 212 | Line 214 | sendq_unblocked(fde_t *fd, struct Client
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 223 | Line 225 | send_queued_write(struct Client *to)
225      return;  /* no use calling send() now */
226  
227    /* Next, lets try to write some data */
226
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 235 | 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:
245 <              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 271 | 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 296 | 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 332 | 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 362 | Line 365 | sendto_channel_butone(struct Client *one
365    dlink_node *ptr = NULL, *ptr_next = NULL;
366  
367    if (IsServer(from))
368 <    local_len = sprintf(local_buf, ":%s ",
368 >    local_len = snprintf(local_buf, sizeof(local_buf), ":%s ",
369                          from->name);
370    else
371 <    local_len = sprintf(local_buf, ":%s!%s@%s ",
372 <                        from->name, from->username, from->host);
373 <  remote_len = sprintf(remote_buf, ":%s ",
374 <                          from->name);
375 <  uid_len = sprintf(uid_buf, ":%s ",
373 <                    ID(from));
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 443 | Line 445 | sendto_channel_butone(struct Client *one
445   * lazylinks, uids, etc.
446   * -davidt
447   */
448 < void
448 > void
449   sendto_server(struct Client *one,
450                const unsigned int caps,
451                const unsigned int nocaps,
# Line 455 | Line 457 | sendto_server(struct Client *one,
457    int len = 0;
458  
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 502 | 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 547 | 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;
557 <  struct Membership *ms;
558 <  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 589 | 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, unsigned int cap,
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;
600 <  struct Membership *ms;
601 <  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 617 | Line 615 | sendto_channel_local_butone(struct Clien
615        continue;
616  
617      if (HasCap(target_p, cap) != cap)
618 <        continue;
618 >      continue;
619 >
620      send_message(target_p, buffer, len);
621    }
622   }
# Line 635 | 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;
646 <  struct Client *target_p;
647 <  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 717 | 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 = sprintf(local_buf, ":%s!%s@%s ", from->name,
720 <                          from->username, from->host);
721 <  int remote_len = sprintf(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 784 | 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 817 | Line 826 | sendto_match_servs(struct Client *source
826         * match() again, if !IsCapable()
827         */
828        target_p->from->localClient->serial = current_serial;
820      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 838 | 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;
846 <  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))
856 <        len = sprintf(buffer, ":%s ", from->id);
857 <      else
858 <        len = sprintf(buffer, ":%s ", from->name);
859 <    }
865 >      len = snprintf(buffer, sizeof(buffer), ":%s %s %s ",
866 >                     from->name, command, to->name);
867      else
868 <      len = sprintf(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 = sprintf(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 918 | Line 928 | sendto_realops_flags(unsigned int flags,
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)))
931 >        ((level == L_OPER) && HasUMode(client_p, UMODE_ADMIN)))
932        continue;
933  
934      if (HasUMode(client_p, flags))
# Line 945 | Line 955 | sendto_wallops_flags(unsigned int flags,
955    int len;
956  
957    if (IsClient(source_p))
958 <    len = sprintf(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 = sprintf(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 1026 | Line 1038 | kill_client(struct Client *client_p, str
1038    if (IsDead(client_p))
1039      return;
1040  
1041 <  len = sprintf(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 1047 | 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 1060 | Line 1073 | kill_client_ll_serv_butone(struct Client
1073    {
1074      have_uid = 1;
1075      va_start(args, pattern);
1076 <    len_uid = sprintf(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 = sprintf(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 1086 | 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)