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

Comparing ircd-hybrid/trunk/src/parse.c (file contents):
Revision 8431 by michael, Tue Mar 27 18:49:15 2018 UTC vs.
Revision 9400 by michael, Fri May 15 20:43:28 2020 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2018 ircd-hybrid development team
4 > *  Copyright (c) 1997-2020 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 39 | Line 39
39   #include "memory.h"
40   #include "user.h"
41   #include "server.h"
42 + #include "packet.h"
43  
44  
45   /*
# Line 103 | Line 104 | static struct MessageTree
104   * side effects -
105   */
106   static void
107 < parse_remove_unknown(struct Client *client_p, const char *lsender, char *lbuffer)
107 > parse_remove_unknown(struct Client *client, const char *lsender, char *lbuffer)
108   {
109    /*
110     * Do kill if it came from a server because it means there is a ghost
# Line 119 | Line 120 | parse_remove_unknown(struct Client *clie
120    {
121      sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
122                           "Unknown prefix (%s) from %s, Squitting %s",
123 <                         lbuffer, client_get_name(client_p, SHOW_IP), lsender);
123 >                         lbuffer, client_get_name(client, SHOW_IP), lsender);
124      sendto_realops_flags(UMODE_DEBUG, L_OPER, SEND_NOTICE,
125                           "Unknown prefix (%s) from %s, Squitting %s",
126 <                         lbuffer, client_get_name(client_p, MASK_IP), lsender);
127 <    sendto_one(client_p, ":%s SQUIT %s :(Unknown prefix (%s) from %s)",
128 <               me.id, lsender, lbuffer, client_p->name);
126 >                         lbuffer, client_get_name(client, MASK_IP), lsender);
127 >    sendto_one(client, ":%s SQUIT %s :(Unknown prefix (%s) from %s)",
128 >               me.id, lsender, lbuffer, client->name);
129    }
130    else
131 <    sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)",
131 >    sendto_one(client, ":%s KILL %s :%s (Unknown Client)",
132                 me.id, lsender, me.name);
133   }
134  
# Line 153 | Line 154 | parse_remove_unknown(struct Client *clie
154   * the savvy approach is NEVER generate an error in response to an... error :)
155   */
156   static void
157 < parse_handle_numeric(unsigned int numeric, struct Client *source_p, int parc, char *parv[])
157 > parse_handle_numeric(unsigned int numeric, struct Client *source, int parc, char *parv[])
158   {
158 –  struct Client *target_p = NULL;
159 –  struct Channel *chptr = NULL;
160 –
159    /*
160     * Avoid trash, we need it to come from a server and have a target
161     */
162 <  if (parc < 2 || !IsServer(source_p))
165 <    return;
166 <
167 <  /*
168 <   * Who should receive this message ? Will we do something with it ?
169 <   * Note that we use findUser functions, so the target can't be neither
170 <   * a server, nor a channel (?) nor a list of targets (?) .. u2.10
171 <   * should never generate numeric replies to non-users anyway
172 <   * Ahem... it can be a channel actually, csc bots use it :\ --Nem
173 <   */
174 <  if (IsChanPrefix(*parv[1]))
175 <    chptr = hash_find_channel(parv[1]);
176 <  else
177 <    target_p = find_person(source_p, parv[1]);
178 <
179 <  if ((!target_p || target_p->from == source_p->from) && !chptr)
162 >  if (parc < 2 || !IsServer(source))
163      return;
164  
165    /*
# Line 191 | Line 174 | parse_handle_numeric(unsigned int numeri
174    if (numeric < 100)
175      numeric += 100;
176  
177 <  if (target_p)
177 >  /*
178 >   * Who should receive this message ? Will we do something with it ?
179 >   * Note that we use findUser functions, so the target can't be neither
180 >   * a server, nor a channel (?) nor a list of targets (?) .. u2.10
181 >   * should never generate numeric replies to non-users anyway
182 >   * Ahem... it can be a channel actually, csc bots use it :\ --Nem
183 >   */
184 >  if (IsChanPrefix(*parv[1]))
185 >  {
186 >    struct Channel *channel = hash_find_channel(parv[1]);
187 >    if (channel == NULL)
188 >      return;
189 >
190 >    sendto_channel_butone(source, source, channel, 0, "%u %s %s",
191 >                          numeric, channel->name, parv[2]);
192 >  }
193 >  else
194    {
195 +    struct Client *target = find_person(source, parv[1]);
196 +    if (target == NULL || target->from == source->from)
197 +      return;
198 +
199      /* Fake it for server hiding, if it's our client */
200 <    if ((ConfigServerHide.hide_servers || IsHidden(source_p)) && MyConnect(target_p) &&
201 <        !HasUMode(target_p, UMODE_OPER))
202 <      sendto_one_numeric(target_p, &me, numeric | SND_EXPLICIT, "%s", parv[2]);
200 >    if ((ConfigServerHide.hide_servers || IsHidden(source)) && MyConnect(target) &&
201 >        !HasUMode(target, UMODE_OPER))
202 >      sendto_one_numeric(target, &me, numeric | SND_EXPLICIT, "%s", parv[2]);
203      else
204 <      sendto_one_numeric(target_p, source_p, numeric | SND_EXPLICIT, "%s", parv[2]);
204 >      sendto_one_numeric(target, source, numeric | SND_EXPLICIT, "%s", parv[2]);
205    }
203 –  else
204 –    sendto_channel_butone(source_p, source_p, chptr, 0, "%u %s %s",
205 –                          numeric, chptr->name, parv[2]);
206   }
207  
208   /* handle_command()
# Line 216 | Line 216 | parse_handle_numeric(unsigned int numeri
216   * side effects -
217   */
218   static void
219 < parse_handle_command(struct Message *message, struct Client *source_p,
219 > parse_handle_command(struct Message *message, struct Client *source,
220                       unsigned int i, char *para[])
221   {
222 <  if (IsServer(source_p->from))
223 <    ++message->rcount;
222 >  const struct MessageHandler *const handler = &message->handlers[source->from->handler];
223  
224 +  if (IsServer(source->from))
225 +    ++message->rcount;
226    ++message->count;
227  
228 +  if (handler->end_grace_period == true && MyClient(source))
229 +    flood_endgrace(source);
230 +
231    /* Check right amount of parameters is passed... --is */
232 <  if (i < message->args_min)
233 <    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, message->cmd);
232 >  if (handler->args_min &&
233 >      ((i < handler->args_min) ||
234 >       (handler->empty_last_arg != true && EmptyString(para[handler->args_min - 1]))))
235 >    sendto_one_numeric(source, &me, ERR_NEEDMOREPARAMS, message->cmd);
236    else
237 <    message->handlers[source_p->from->handler](source_p, i, para);
237 >    handler->handler(source, i, para);
238   }
239  
240   /*
# Line 237 | Line 243 | parse_handle_command(struct Message *mes
243   * NOTE: parse() should not be called recusively by any other functions!
244   */
245   void
246 < parse(struct Client *client_p, char *pbuffer, char *bufend)
246 > parse(struct Client *client, char *pbuffer, char *bufend)
247   {
248 <  struct Client *from = client_p;
248 >  struct Client *from = client;
249    struct Message *message = NULL;
250    char *para[MAXPARA + 2];  /* <command> + <parameters> + NULL */
251    char *ch = NULL;
# Line 248 | Line 254 | parse(struct Client *client_p, char *pbu
254    unsigned int parc = 0;
255    unsigned int paramcount;
256  
257 <  if (IsDefunct(client_p))
257 >  if (IsDead(client))
258      return;
259  
260 <  assert(client_p->connection);
261 <  assert(client_p->connection->fd);
262 <  assert(client_p->connection->fd->flags.open);
260 >  assert(client->connection);
261 >  assert(client->connection->fd);
262 >  assert(client->connection->fd->flags.open);
263  
264  
265    assert((bufend - pbuffer) < IRCD_BUFSIZE);
# Line 275 | Line 281 | parse(struct Client *client_p, char *pbu
281        ch = ++s;
282      }
283  
284 <    if (*sender && IsServer(client_p))
284 >    if (*sender && IsServer(client))
285      {
286        if ((from = hash_find_id(sender)) == NULL)
287          from = hash_find_client(sender);
# Line 288 | Line 294 | parse(struct Client *client_p, char *pbu
294        if (from == NULL)
295        {
296          ++ServerStats.is_unpf;
297 <        parse_remove_unknown(client_p, sender, pbuffer);
297 >        parse_remove_unknown(client, sender, pbuffer);
298          return;
299        }
300  
301 <      if (from->from != client_p)
301 >      if (from->from != client)
302        {
303          ++ServerStats.is_wrdi;
304          sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
305                               "Fake direction: dropped message from %s[%s] via %s",
306                               from->name, from->from->name,
307 <                             client_get_name(client_p, SHOW_IP));
307 >                             client_get_name(client, SHOW_IP));
308          sendto_realops_flags(UMODE_DEBUG, L_OPER, SEND_NOTICE,
309                               "Fake direction: dropped message from %s[%s] via %s",
310                               from->name, from->from->name,
311 <                             client_get_name(client_p, MASK_IP));
311 >                             client_get_name(client, MASK_IP));
312          return;
313        }
314      }
# Line 363 | Line 369 | parse(struct Client *client_p, char *pbu
369  
370      assert(message->cmd);
371  
372 <    paramcount = message->args_max;
372 >    paramcount = message->handlers[from->from->handler].args_max;
373  
374      size_t length = bufend - ((s) ? s : ch);
375      message->bytes += length;
376    }
377  
378 +  memset(para, 0, sizeof(para));
379 +
380    /*
381     * Must the following loop really be so devious? On surface it
382     * splits the message to parameters from blank spaces. But, if
# Line 380 | Line 388 | parse(struct Client *client_p, char *pbu
388  
389    para[parc] = ch;
390  
391 <  if (message && (message->flags & MFLG_EXTRA))
391 >  if (message && message->extra)
392    {
393      /*
394       * XXX: This will have to go away after the command handler rewrite
# Line 390 | Line 398 | parse(struct Client *client_p, char *pbu
398  
399    if (s)
400    {
401 <    if (paramcount > MAXPARA)
401 >    if (paramcount == 0 || paramcount > MAXPARA)
402        paramcount = MAXPARA;
403  
404 <    while (1)
404 >    while (true)
405      {
406         while (*s == ' ')
407           *s++ = '\0';
# Line 404 | Line 412 | parse(struct Client *client_p, char *pbu
412         if (*s == ':')
413         {
414           /* The rest is single parameter--can include blanks also. */
415 <         para[++parc] = s + (!numeric);  /* Keep the colon if it's a numeric */
415 >         para[++parc] = s + (numeric == 0);  /* Keep the colon if it's a numeric */
416           break;
417         }
418  
# Line 450 | Line 458 | static void
458   add_msg_element(struct MessageTree *mtree_p, struct Message *msg_p,
459                  const char *cmd)
460   {
453 –  struct MessageTree *ntree_p = NULL;
454 –
461    if (*cmd == '\0')
462    {
463      mtree_p->msg = msg_p;
# Line 465 | Line 471 | add_msg_element(struct MessageTree *mtre
471       * between 0 and MAXPTRLEN.
472       * Thus 'A' -> 0x1 'B' -> 0x2 'c' -> 0x3 etc.
473       */
474 <    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]) == NULL)
474 >    struct MessageTree *ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)];
475 >    if (ntree_p == NULL)
476      {
477        ntree_p = xcalloc(sizeof(*ntree_p));
478        mtree_p->pointers[*cmd & (MAXPTRLEN - 1)] = ntree_p;
# Line 503 | Line 510 | add_msg_element(struct MessageTree *mtre
510   static void
511   del_msg_element(struct MessageTree *mtree_p, const char *cmd)
512   {
506 –  struct MessageTree *ntree_p = NULL;
507 –
513    /*
514     * In case this is called for a nonexistent command
515     * check that there is a msg pointer here, else links-- goes -ve
# Line 517 | Line 522 | del_msg_element(struct MessageTree *mtre
522    }
523    else
524    {
525 <    if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)]))
525 >    struct MessageTree *ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN - 1)];
526 >    if (ntree_p)
527      {
528        del_msg_element(ntree_p, cmd + 1);
529  
# Line 598 | Line 604 | find_command(const char *cmd)
604   }
605  
606   static void
607 < recurse_report_messages(struct Client *source_p, const struct MessageTree *mtree)
607 > recurse_report_messages(struct Client *source, const struct MessageTree *mtree)
608   {
609    if (mtree->msg)
610 <    sendto_one_numeric(source_p, &me, RPL_STATSCOMMANDS,
610 >    sendto_one_numeric(source, &me, RPL_STATSCOMMANDS,
611                         mtree->msg->cmd,
612 <                       mtree->msg->count, mtree->msg->bytes,
613 <                       mtree->msg->rcount);
612 >                       mtree->msg->count,
613 >                       mtree->msg->bytes,
614 >                       mtree->msg->rcount,
615 >                       mtree->msg->ecount);
616  
617    for (unsigned int i = 0; i < MAXPTRLEN; ++i)
618      if (mtree->pointers[i])
619 <      recurse_report_messages(source_p, mtree->pointers[i]);
619 >      recurse_report_messages(source, mtree->pointers[i]);
620   }
621  
622   /* report_messages()
# Line 618 | Line 626 | recurse_report_messages(struct Client *s
626   * side effects - client is shown list of commands
627   */
628   void
629 < report_messages(struct Client *source_p)
629 > report_messages(struct Client *source)
630   {
631    const struct MessageTree *const mtree = &msg_tree;
632  
633    for (unsigned int i = 0; i < MAXPTRLEN; ++i)
634      if (mtree->pointers[i])
635 <      recurse_report_messages(source_p, mtree->pointers[i]);
635 >      recurse_report_messages(source, mtree->pointers[i]);
636   }
637  
638   /* m_not_oper()
# Line 632 | Line 640 | report_messages(struct Client *source_p)
640   * output       -
641   * side effects - just returns a nastyogram to given user
642   */
643 < int
644 < m_not_oper(struct Client *source_p, int parc, char *parv[])
643 > void
644 > m_not_oper(struct Client *source, int parc, char *parv[])
645   {
646 <  sendto_one_numeric(source_p, &me, ERR_NOPRIVILEGES);
639 <  return 0;
646 >  sendto_one_numeric(source, &me, ERR_NOPRIVILEGES);
647   }
648  
649 < int
650 < m_unregistered(struct Client *source_p, int parc, char *parv[])
649 > void
650 > m_unregistered(struct Client *source, int parc, char *parv[])
651   {
652 <  sendto_one_numeric(source_p, &me, ERR_NOTREGISTERED);
646 <  return 0;
652 >  sendto_one_numeric(source, &me, ERR_NOTREGISTERED);
653   }
654  
655 < int
656 < m_registered(struct Client *source_p, int parc, char *parv[])
655 > void
656 > m_registered(struct Client *source, int parc, char *parv[])
657   {
658 <  sendto_one_numeric(source_p, &me, ERR_ALREADYREGISTRED);
653 <  return 0;
658 >  sendto_one_numeric(source, &me, ERR_ALREADYREGISTRED);
659   }
660  
661 < int
662 < m_ignore(struct Client *source_p, int parc, char *parv[])
661 > void
662 > m_ignore(struct Client *source, int parc, char *parv[])
663   {
664 <  return 0;
664 >  return;
665   }

Diff Legend

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