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

Comparing:
ircd-hybrid-7.2/src/parse.c (file contents), Revision 896 by michael, Sat Nov 3 08:54:09 2007 UTC vs.
ircd-hybrid/trunk/src/parse.c (file contents), Revision 1592 by michael, Sat Oct 27 21:02:32 2012 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 – #include "parse.h"
26   #include "client.h"
27 + #include "parse.h"
28   #include "channel.h"
29 – #include "handlers.h"
30 – #include "common.h"
29   #include "hash.h"
30   #include "irc_string.h"
31   #include "sprintf_irc.h"
32   #include "ircd.h"
33   #include "numeric.h"
34 < #include "s_log.h"
34 > #include "log.h"
35   #include "send.h"
36 < #include "ircd_handler.h"
39 < #include "msg.h"
40 < #include "s_conf.h"
36 > #include "conf.h"
37   #include "memory.h"
38   #include "s_user.h"
39   #include "s_serv.h"
# Line 106 | Line 102 | static struct MessageTree msg_tree;
102   * NOTE: parse() should not be called recursively by other functions!
103   */
104   static char *sender;
105 < static char *para[MAXPARA + 1];
105 > static char *para[MAXPARA + 2]; /* <prefix> + <params> + NULL */
106   static char buffer[1024];
107  
108   static int cancel_clients(struct Client *, struct Client *, char *);
109   static void remove_unknown(struct Client *, char *, char *);
110 < static void do_numeric(char[], struct Client *, struct Client *, int, char **);
111 < static void handle_command(struct Message *, struct Client *, struct Client *, unsigned int, char **);
116 < static void recurse_report_messages(struct Client *source_p, struct MessageTree *mtree);
117 < static void add_msg_element(struct MessageTree *mtree_p, struct Message *msg_p, const char *cmd);
118 < static void del_msg_element(struct MessageTree *mtree_p, const char *cmd);
119 <
120 < /* turn a string into a parc/parv pair */
121 < static inline int
122 < string_to_array(char *string, char *parv[MAXPARA])
123 < {
124 <  char *p;
125 <  char *buf = string;
126 <  int x = 1;
110 > static void handle_numeric(char[], struct Client *, struct Client *, int, char *[]);
111 > static void handle_command(struct Message *, struct Client *, struct Client *, unsigned int, char *[]);
112  
128 –  parv[x] = NULL;
129 –
130 –  while (*buf == ' ') /* skip leading spaces */
131 –    buf++;
132 –
133 –  if (*buf == '\0') /* ignore all-space args */
134 –    return(x);
135 –
136 –  do
137 –  {
138 –    if (*buf == ':') /* Last parameter */
139 –    {
140 –      buf++;
141 –      parv[x++] = buf;
142 –      parv[x]   = NULL;
143 –      return(x);
144 –    }
145 –    else
146 –    {
147 –      parv[x++] = buf;
148 –      parv[x]   = NULL;
149 –
150 –      if ((p = strchr(buf, ' ')) != NULL)
151 –      {
152 –        *p++ = '\0';
153 –        buf  = p;
154 –      }
155 –      else
156 –        return(x);
157 –    }      
158 –
159 –    while (*buf == ' ')
160 –      buf++;
161 –
162 –    if (*buf == '\0')
163 –      return(x);
164 –  } while (x < MAXPARA - 1);
165 –
166 –  if (*p == ':')
167 –    p++;
168 –
169 –  parv[x++] = p;
170 –  parv[x]   = NULL;
171 –  return(x);
172 – }
113  
114   /*
115   * parse a buffer.
# Line 180 | Line 120 | void
120   parse(struct Client *client_p, char *pbuffer, char *bufend)
121   {
122    struct Client *from = client_p;
123 <  char *ch;
124 <  char *s;
125 <  char *numeric = 0;
126 <  unsigned int i = 0;
127 <  int paramcount;
128 <  int mpara = 0;
189 <  struct Message *mptr = NULL;
123 >  struct Message *msg_ptr = NULL;
124 >  char *ch = NULL;
125 >  char *s = NULL;
126 >  char *numeric = NULL;
127 >  unsigned int parc = 0;
128 >  unsigned int paramcount;
129  
130    if (IsDefunct(client_p))
131      return;
# Line 194 | Line 133 | parse(struct Client *client_p, char *pbu
133    assert(client_p->localClient->fd.flags.open);
134    assert((bufend - pbuffer) < 512);
135  
136 <  for (ch = pbuffer; *ch == ' '; ch++) /* skip spaces */
136 >  for (ch = pbuffer; *ch == ' '; ++ch) /* skip spaces */
137      /* null statement */ ;
138  
200 –  para[0] = from->name;
201 –
139    if (*ch == ':')
140    {
141 <    ch++;
142 <
206 <    /* Copy the prefix to 'sender' assuming it terminates
141 >    /*
142 >     * Copy the prefix to 'sender' assuming it terminates
143       * with SPACE (or NULL, which is an error, though).
144       */
145 <    sender = ch;
145 >    sender = ++ch;
146  
147      if ((s = strchr(ch, ' ')) != NULL)
148      {
149        *s = '\0';
150 <      s++;
215 <      ch = s;
150 >      ch = ++s;
151      }
152  
153      if (*sender && IsServer(client_p))
154      {
220 –      /*
221 –       * XXX it could be useful to know which of these occurs most frequently.
222 –       * the ID check should always come first, though, since it is so easy.
223 –       */
155        if ((from = find_person(client_p, sender)) == NULL)
156 <      {
226 <        from = find_server(sender);
156 >        from = hash_find_server(sender);
157  
228 –        if (from == NULL && IsCapable(client_p, CAP_TS6) &&
229 –          client_p->name[0] == '*' && IsDigit(*sender) && strlen(sender) == 3)
230 –        {
231 –          /* Dirty hack to allow messages from masked SIDs (i.e. the ones
232 –           * hidden by fakename="..."). It shouldn't break anything, since
233 –           * unknown SIDs don't happen during normal ircd work --adx
234 –           */
235 –          from = client_p;
236 –        }
237 –      }
238 –      
158        /* Hmm! If the client corresponding to the
159         * prefix is not found--what is the correct
160         * action??? Now, I will ignore the message
# Line 249 | Line 168 | parse(struct Client *client_p, char *pbu
168          return;
169        }
170  
252 –      para[0] = from->name;
253 –
171        if (from->from != client_p)
172        {
173          ++ServerStats.is_wrdi;
# Line 260 | Line 177 | parse(struct Client *client_p, char *pbu
177      }
178  
179      while (*ch == ' ')
180 <      ch++;
180 >      ++ch;
181    }
182  
183    if (*ch == '\0')
# Line 280 | Line 197 | parse(struct Client *client_p, char *pbu
197    if (*(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */
198        IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
199    {
283 –    mptr = NULL;
200      numeric = ch;
201      paramcount = MAXPARA;
202      ++ServerStats.is_num;
# Line 289 | Line 205 | parse(struct Client *client_p, char *pbu
205    }
206    else
207    {
208 <    int ii = 0;
208 >    unsigned int ii = 0;
209  
210      if ((s = strchr(ch, ' ')) != NULL)
211        *s++ = '\0';
212  
213 <    if ((mptr = find_command(ch)) == NULL)
213 >    if ((msg_ptr = find_command(ch)) == NULL)
214      {
215        /* Note: Give error message *only* to recognized
216         * persons. It's a nightmare situation to have
# Line 306 | Line 222 | parse(struct Client *client_p, char *pbu
222         * Hm, when is the buffer empty -- if a command
223         * code has been found ?? -Armin
224         */
225 <      if (pbuffer[0] != '\0')
225 >      if (*pbuffer != '\0')
226        {
227          if (IsClient(from))
228            sendto_one(from, form_str(ERR_UNKNOWNCOMMAND),
# Line 317 | Line 233 | parse(struct Client *client_p, char *pbu
233        return;
234      }
235  
236 <    assert(mptr->cmd != NULL);
321 <
322 <    paramcount = mptr->parameters;
323 <    mpara      = mptr->maxpara;
236 >    assert(msg_ptr->cmd != NULL);
237  
238 +    paramcount = msg_ptr->args_max;
239      ii = bufend - ((s) ? s : ch);
240 <    mptr->bytes += ii;
240 >    msg_ptr->bytes += ii;
241    }
242  
243 <  if (s != NULL)
244 <    i = string_to_array(s, para);
245 <  else
243 >  /*
244 >   * Must the following loop really be so devious? On surface it
245 >   * splits the message to parameters from blank spaces. But, if
246 >   * paramcount has been reached, the rest of the message goes into
247 >   * this last parameter (about same effect as ":" has...) --msa
248 >   */
249 >
250 >  /* Note initially true: s==NULL || *(s-1) == '\0' !! */
251 >
252 >  para[parc] = from->name;
253 >
254 >  if (s)
255    {
256 <    i = 0;
257 <    para[1] = NULL;
256 >    if (paramcount > MAXPARA)
257 >      paramcount = MAXPARA;
258 >
259 >    while (1)
260 >    {
261 >       while (*s == ' ')
262 >         *s++ = '\0';
263 >
264 >       if (*s == '\0')
265 >         break;
266 >
267 >       if (*s == ':')
268 >       {
269 >         /* The rest is a single parameter */
270 >         para[++parc] = s + 1;
271 >         break;
272 >       }
273 >
274 >       para[++parc] = s;
275 >
276 >       if (parc >= paramcount)
277 >         break;
278 >
279 >       while (*s && *s != ' ')
280 >         ++s;
281 >    }
282    }
283  
284 <  if (mptr == NULL)
285 <    do_numeric(numeric, client_p, from, i, para);
284 >  para[++parc] = NULL;
285 >
286 >  if (msg_ptr != NULL)
287 >    handle_command(msg_ptr, client_p, from, parc, para);
288    else
289 <    handle_command(mptr, client_p, from, i, para);
289 >    handle_numeric(numeric, client_p, from, parc, para);
290   }
291  
292   /* handle_command()
# Line 352 | Line 301 | parse(struct Client *client_p, char *pbu
301   */
302   static void
303   handle_command(struct Message *mptr, struct Client *client_p,
304 <               struct Client *from, unsigned int i, char *hpara[MAXPARA])
304 >               struct Client *from, unsigned int i, char *hpara[])
305   {
306    MessageHandler handler = 0;
307  
# Line 361 | Line 310 | handle_command(struct Message *mptr, str
310  
311    mptr->count++;
312  
364 –  /* New patch to avoid server flooding from unregistered connects
365 –   * - Pie-Man 07/27/2000 */
366 –  if (!IsRegistered(client_p))
367 –  {
368 –    /* if its from a possible server connection
369 –     * ignore it.. more than likely its a header thats sneaked through
370 –     */
371 –    if ((IsHandshake(client_p) || IsConnecting(client_p) ||
372 –        IsServer(client_p)) && !(mptr->flags & MFLG_UNREG))
373 –      return;
374 –  }
375 –
313    handler = mptr->handlers[client_p->handler];
314  
315    /* check right amount of params is passed... --is */
316 <  if (i < mptr->parameters)
316 >  if (i < mptr->args_min)
317    {
318      if (!IsServer(client_p))
319      {
320 <      sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
321 <                   me.name, EmptyString(hpara[0]) ? "*" : hpara[0], mptr->cmd);
320 >      sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS), me.name,
321 >                 EmptyString(hpara[0]) ? "*" : hpara[0], mptr->cmd);
322      }
323      else
324      {
325        sendto_realops_flags(UMODE_ALL, L_ALL,
326                             "Dropping server %s due to (invalid) command '%s' "
327                             "with only %d arguments (expecting %d).",
328 <                           client_p->name, mptr->cmd, i, mptr->parameters);
329 <      ilog(L_CRIT, "Insufficient parameters (%d) for command '%s' from %s.",
328 >                           client_p->name, mptr->cmd, i, mptr->args_min);
329 >      ilog(LOG_TYPE_IRCD, "Insufficient parameters (%d) for command '%s' from %s.",
330             i, mptr->cmd, client_p->name);
331        exit_client(client_p, client_p,
332                    "Not enough arguments to server command.");
# Line 399 | Line 336 | handle_command(struct Message *mptr, str
336      (*handler)(client_p, from, i, hpara);
337   }
338  
402 – /* clear_tree_parse()
403 – *
404 – * inputs       - NONE
405 – * output       - NONE
406 – * side effects - MUST MUST be called at startup ONCE before
407 – *                any other keyword routine is used.
408 – */
409 – void
410 – clear_tree_parse(void)
411 – {
412 –  memset(&msg_tree, 0, sizeof(msg_tree));
413 – }
414 –
339   /* add_msg_element()
340   *
341   * inputs       - pointer to MessageTree
# Line 433 | Line 357 | clear_tree_parse(void)
357   * in the parent.
358   */
359   static void
360 < add_msg_element(struct MessageTree *mtree_p,
361 <                struct Message *msg_p, const char *cmd)
360 > add_msg_element(struct MessageTree *mtree_p, struct Message *msg_p,
361 >                const char *cmd)
362   {
363    struct MessageTree *ntree_p;
364  
365    if (*cmd == '\0')
366    {
367      mtree_p->msg = msg_p;
368 <    mtree_p->links++;           /* Have msg pointer, so up ref count */
368 >    mtree_p->links++;  /* Have msg pointer, so up ref count */
369    }
370    else
371    {
# Line 451 | Line 375 | add_msg_element(struct MessageTree *mtre
375       * Thus 'A' -> 0x1 'B' -> 0x2 'c' -> 0x3 etc.
376       */
377  
378 <    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN-1)]) == NULL)
378 >    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]) == NULL)
379      {
380 <      ntree_p = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree));
381 <      mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = ntree_p;
380 >      ntree_p = MyMalloc(sizeof(struct MessageTree));
381 >      mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = ntree_p;
382  
383 <      mtree_p->links++;         /* Have new pointer, so up ref count */
383 >      mtree_p->links++;  /* Have new pointer, so up ref count */
384      }
385  
386 <    add_msg_element(ntree_p, msg_p, cmd+1);
386 >    add_msg_element(ntree_p, msg_p, cmd + 1);
387    }
388   }
389  
# Line 491 | Line 415 | del_msg_element(struct MessageTree *mtre
415   {
416    struct MessageTree *ntree_p;
417  
418 <  /* In case this is called for a nonexistent command
418 >  /*
419 >   * In case this is called for a nonexistent command
420     * check that there is a msg pointer here, else links-- goes -ve
421     * -db
422     */
498 –
423    if ((*cmd == '\0') && (mtree_p->msg != NULL))
424    {
425      mtree_p->msg = NULL;
# Line 503 | Line 427 | del_msg_element(struct MessageTree *mtre
427    }
428    else
429    {
430 <    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN-1)]) != NULL)
430 >    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]) != NULL)
431      {
432 <      del_msg_element(ntree_p, cmd+1);
432 >      del_msg_element(ntree_p, cmd + 1);
433  
434        if (ntree_p->links == 0)
435        {
436 <        mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = NULL;
437 <        mtree_p->links--;
438 <        MyFree(ntree_p);
436 >        mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = NULL;
437 >        mtree_p->links--;
438 >        MyFree(ntree_p);
439        }
440      }
441    }
# Line 525 | Line 449 | del_msg_element(struct MessageTree *mtre
449   * side effects - none
450   */
451   static struct Message *
452 < msg_tree_parse(const char *cmd, struct MessageTree *root)
452 > msg_tree_parse(const char *cmd)
453   {
454 <  struct MessageTree *mtree = root;
454 >  struct MessageTree *mtree = &msg_tree;
455    assert(cmd && *cmd);
456  
457    while (IsAlpha(*cmd) && (mtree = mtree->pointers[*cmd & (MAXPTRLEN - 1)]))
# Line 548 | Line 472 | msg_tree_parse(const char *cmd, struct M
472   void
473   mod_add_cmd(struct Message *msg)
474   {
475 <  struct Message *found_msg;
552 <
553 <  if (msg == NULL)
554 <    return;
555 <
556 <  /* someone loaded a module with a bad messagetab */
557 <  assert(msg->cmd != NULL);
475 >  assert(msg && msg->cmd);
476  
477    /* command already added? */
478 <  if ((found_msg = msg_tree_parse(msg->cmd, &msg_tree)) != NULL)
478 >  if (msg_tree_parse(msg->cmd))
479      return;
480  
481    add_msg_element(&msg_tree, msg, msg->cmd);
# Line 573 | Line 491 | mod_add_cmd(struct Message *msg)
491   void
492   mod_del_cmd(struct Message *msg)
493   {
494 <  assert(msg != NULL);
577 <
578 <  if (msg == NULL)
579 <    return;
494 >  assert(msg && msg->cmd);
495  
496    del_msg_element(&msg_tree, msg->cmd);
497   }
# Line 590 | Line 505 | mod_del_cmd(struct Message *msg)
505   struct Message *
506   find_command(const char *cmd)
507   {
508 <  return msg_tree_parse(cmd, &msg_tree);
508 >  return msg_tree_parse(cmd);
509 > }
510 >
511 > static void
512 > recurse_report_messages(struct Client *source_p, const struct MessageTree *mtree)
513 > {
514 >  unsigned int i;
515 >
516 >  if (mtree->msg != NULL)
517 >    sendto_one(source_p, form_str(RPL_STATSCOMMANDS),
518 >               me.name, source_p->name, mtree->msg->cmd,
519 >               mtree->msg->count, mtree->msg->bytes,
520 >               mtree->msg->rcount);
521 >
522 >  for (i = 0; i < MAXPTRLEN; ++i)
523 >    if (mtree->pointers[i] != NULL)
524 >      recurse_report_messages(source_p, mtree->pointers[i]);
525   }
526  
527   /* report_messages()
# Line 602 | Line 533 | find_command(const char *cmd)
533   void
534   report_messages(struct Client *source_p)
535   {
536 <  struct MessageTree *mtree = &msg_tree;
537 <  int i;
536 >  const struct MessageTree *mtree = &msg_tree;
537 >  unsigned int i;
538  
539 <  for (i = 0; i < MAXPTRLEN; i++)
609 <    if (mtree->pointers[i] != NULL)
610 <      recurse_report_messages(source_p, mtree->pointers[i]);
611 < }
612 <
613 < static void
614 < recurse_report_messages(struct Client *source_p, struct MessageTree *mtree)
615 < {
616 <  int i;
617 <
618 <  if (mtree->msg != NULL)
619 <    sendto_one(source_p, form_str(RPL_STATSCOMMANDS),
620 <               me.name, source_p->name, mtree->msg->cmd,
621 <               mtree->msg->count, mtree->msg->bytes,
622 <               mtree->msg->rcount);
623 <
624 <  for (i = 0; i < MAXPTRLEN; i++)
539 >  for (i = 0; i < MAXPTRLEN; ++i)
540      if (mtree->pointers[i] != NULL)
541        recurse_report_messages(source_p, mtree->pointers[i]);
542   }
# Line 740 | Line 655 | remove_unknown(struct Client *client_p,
655   *      a ping pong error message...
656   */
657   static void
658 < do_numeric(char numeric[], struct Client *client_p, struct Client *source_p,
659 <           int parc, char *parv[])
658 > handle_numeric(char numeric[], struct Client *client_p, struct Client *source_p,
659 >               int parc, char *parv[])
660   {
661    struct Client *target_p;
662    struct Channel *chptr;
# Line 767 | Line 682 | do_numeric(char numeric[], struct Client
682      t += tl;
683    }
684  
685 <  ircsprintf(t," :%s", parv[parc-1]);
685 >  ircsprintf(t, " :%s", parv[parc-1]);
686  
687    if (((target_p = find_person(client_p, parv[1])) != NULL) ||
688 <      ((target_p = find_server(parv[1])) != NULL))
688 >      ((target_p = hash_find_server(parv[1])) != NULL))
689    {
690      if (IsMe(target_p))
691      {
# Line 802 | Line 717 | do_numeric(char numeric[], struct Client
717  
718        if ((num != ERR_NOSUCHNICK))
719          sendto_realops_flags(UMODE_ALL, L_ADMIN,
720 <                             "*** %s(via %s) sent a %s numeric to me: %s",
721 <                             source_p->name, client_p->name, numeric, buffer);
720 >                             "*** %s(via %s) sent a %s numeric to me: %s",
721 >                             source_p->name, client_p->name, numeric, buffer);
722        return;
723      }
724      else if (target_p->from == client_p)
# Line 820 | Line 735 | do_numeric(char numeric[], struct Client
735      
736      /* Fake it for server hiding, if its our client */
737      if (ConfigServerHide.hide_servers &&
738 <        MyClient(target_p) && !IsOper(target_p))
738 >        MyClient(target_p) && !HasUMode(target_p, UMODE_OPER))
739        sendto_one(target_p, ":%s %s %s%s", me.name, numeric, target_p->name, buffer);
740      else
741        sendto_one(target_p, ":%s %s %s%s", ID_or_name(source_p, target_p->from),
# Line 828 | Line 743 | do_numeric(char numeric[], struct Client
743      return;
744    }
745    else if ((chptr = hash_find_channel(parv[1])) != NULL)
746 <    sendto_channel_local(ALL_MEMBERS, NO, chptr,
747 <                         ":%s %s %s %s",
748 <                         source_p->name,
834 <                         numeric, chptr->chname, buffer);
746 >    sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s %s %s %s",
747 >                         source_p->name,
748 >                         numeric, chptr->chname, buffer);
749   }
750  
751   /* m_not_oper()
# Line 844 | Line 758 | m_not_oper(struct Client *client_p, stru
758             int parc, char *parv[])
759   {
760    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
761 <             me.name, parv[0]);
761 >             me.name, source_p->name);
762   }
763  
764   void
765   m_unregistered(struct Client *client_p, struct Client *source_p,
766                 int parc, char *parv[])
767   {
768 <  /* bit of a hack.
769 <   * I don't =really= want to waste a bit in a flag
856 <   * number_of_nick_changes is only really valid after the client
857 <   * is fully registered..
858 <   */
859 <  if (client_p->localClient->number_of_nick_changes == 0)
860 <  {
861 <    sendto_one(client_p, ":%s %d * %s :Register first.",
862 <               me.name, ERR_NOTREGISTERED, parv[0]);
863 <    client_p->localClient->number_of_nick_changes++;
864 <  }
768 >  sendto_one(source_p, form_str(ERR_NOTREGISTERED), me.name,
769 >             source_p->name[0] ? source_p->name : "*");
770   }
771  
772   void
773   m_registered(struct Client *client_p, struct Client *source_p,
774               int parc, char *parv[])
775   {
776 <  sendto_one(client_p, form_str(ERR_ALREADYREGISTRED),  
777 <             me.name, parv[0]);
776 >  sendto_one(source_p, form_str(ERR_ALREADYREGISTRED),  
777 >             me.name, source_p->name);
778   }
779  
780   void
# Line 879 | Line 784 | m_ignore(struct Client *client_p, struct
784    return;
785   }
786  
787 + void
788 + rfc1459_command_send_error(struct Client *client_p, struct Client *source_p,
789 +                           int parc, char *parv[])
790 + {
791 +  const char *in_para;
792 +
793 +  in_para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
794 +
795 +  ilog(LOG_TYPE_IRCD, "Received ERROR message from %s: %s",
796 +       source_p->name, in_para);
797 +
798 +  if (client_p == source_p)
799 +  {
800 +    sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s -- %s",
801 +                         get_client_name(client_p, HIDE_IP), in_para);
802 +    sendto_realops_flags(UMODE_ALL, L_OPER,  "ERROR :from %s -- %s",
803 +                         get_client_name(client_p, MASK_IP), in_para);
804 +  }
805 +  else
806 +  {
807 +    sendto_realops_flags(UMODE_ALL, L_OPER, "ERROR :from %s via %s -- %s",
808 +                         source_p->name, get_client_name(client_p, MASK_IP), in_para);
809 +    sendto_realops_flags(UMODE_ALL, L_ADMIN, "ERROR :from %s via %s -- %s",
810 +                         source_p->name, get_client_name(client_p, HIDE_IP), in_para);
811 +  }
812 +
813 +  if (MyClient(source_p))
814 +    exit_client(source_p, source_p, "ERROR");
815 + }

Diff Legend

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