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

Comparing:
ircd-hybrid-8/src/hash.c (file contents), Revision 1332 by michael, Sun Apr 1 16:25:50 2012 UTC vs.
ircd-hybrid/trunk/src/hash.c (file contents), Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  hash.c: Maintains hashtables.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2019 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 16 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file hash.c
23 > * \brief Hash table management.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
28   #include "list.h"
27 – #include "balloc.h"
29   #include "conf.h"
30   #include "channel.h"
31   #include "channel_mode.h"
32   #include "client.h"
32 – #include "modules.h"
33   #include "hash.h"
34 < #include "resv.h"
34 > #include "id.h"
35   #include "rng_mt.h"
36 – #include "userhost.h"
36   #include "irc_string.h"
37   #include "ircd.h"
38   #include "numeric.h"
39   #include "send.h"
40   #include "memory.h"
41   #include "dbuf.h"
43 – #include "s_user.h"
42  
43  
44 < static BlockHeap *userhost_heap = NULL;
47 < static BlockHeap *namehost_heap = NULL;
48 < static struct UserHost *find_or_add_userhost(const char *);
49 <
50 < static unsigned int hashf_xor_key = 0;
44 > static unsigned int hashf_xor_key;
45  
46   /* The actual hash tables, They MUST be of the same HASHSIZE, variable
47   * size tables could be supported but the rehash routine should also
48 < * rebuild the transformation maps, I kept the tables of equal size
48 > * rebuild the transformation maps, I kept the tables of equal size
49   * so that I can use one hash function.
50   */
51   static struct Client *idTable[HASHSIZE];
52   static struct Client *clientTable[HASHSIZE];
53   static struct Channel *channelTable[HASHSIZE];
60 – static struct UserHost *userhostTable[HASHSIZE];
61 – static struct ResvChannel *resvchannelTable[HASHSIZE];
54  
55  
56 < /* init_hash()
56 > /* hash_init()
57   *
58   * inputs       - NONE
59   * output       - NONE
# Line 69 | Line 61 | static struct ResvChannel *resvchannelTa
61   *                functions and clear the tables
62   */
63   void
64 < init_hash(void)
64 > hash_init(void)
65   {
66 <  /* Default the userhost/namehost sizes to CLIENT_HEAP_SIZE for now,
67 <   * should be a good close approximation anyway
68 <   * - Dianora
77 <   */
78 <  userhost_heap = BlockHeapCreate("userhost", sizeof(struct UserHost), CLIENT_HEAP_SIZE);
79 <  namehost_heap = BlockHeapCreate("namehost", sizeof(struct NameHost), CLIENT_HEAP_SIZE);
80 <
81 <  hashf_xor_key = genrand_int32() % 256;  /* better than nothing --adx */
66 >  do
67 >    hashf_xor_key = genrand_int32() % 256;  /* better than nothing --adx */
68 >  while (!hashf_xor_key);
69   }
70  
71   /*
# Line 94 | Line 81 | strhash(const char *name)
81    const unsigned char *p = (const unsigned char *)name;
82    unsigned int hval = FNV1_32_INIT;
83  
84 <  if (*p == '\0')
84 >  if (EmptyString(p))
85      return 0;
86 <  for (; *p != '\0'; ++p)
86 >
87 >  for (; *p; ++p)
88    {
89 <    hval += (hval << 1) + (hval <<  4) + (hval << 7) +
90 <            (hval << 8) + (hval << 24);
89 >    hval += (hval << 1) + (hval << 4) +
90 >            (hval << 7) + (hval << 8) + (hval << 24);
91      hval ^= (ToLower(*p) ^ hashf_xor_key);
92    }
93  
# Line 128 | Line 116 | strhash(const char *name)
116   void
117   hash_add_client(struct Client *client_p)
118   {
119 <  unsigned int hashv = strhash(client_p->name);
119 >  const unsigned int hashv = strhash(client_p->name);
120  
121    client_p->hnext = clientTable[hashv];
122    clientTable[hashv] = client_p;
# Line 147 | Line 135 | hash_add_client(struct Client *client_p)
135   void
136   hash_add_channel(struct Channel *chptr)
137   {
138 <  unsigned int hashv = strhash(chptr->chname);
138 >  const unsigned int hashv = strhash(chptr->name);
139  
140    chptr->hnextch = channelTable[hashv];
141    channelTable[hashv] = chptr;
142   }
143  
144   void
157 – hash_add_resv(struct ResvChannel *chptr)
158 – {
159 –  unsigned int hashv = strhash(chptr->name);
160 –
161 –  chptr->hnext = resvchannelTable[hashv];
162 –  resvchannelTable[hashv] = chptr;
163 – }
164 –
165 – void
166 – hash_add_userhost(struct UserHost *userhost)
167 – {
168 –  unsigned int hashv = strhash(userhost->host);
169 –
170 –  userhost->next = userhostTable[hashv];
171 –  userhostTable[hashv] = userhost;
172 – }
173 –
174 – void
145   hash_add_id(struct Client *client_p)
146   {
147 <  unsigned int hashv = strhash(client_p->id);
147 >  const unsigned int hashv = strhash(client_p->id);
148  
149    client_p->idhnext = idTable[hashv];
150    idTable[hashv] = client_p;
# Line 189 | Line 159 | hash_add_id(struct Client *client_p)
159   void
160   hash_del_id(struct Client *client_p)
161   {
162 <  unsigned int hashv = strhash(client_p->id);
162 >  const unsigned int hashv = strhash(client_p->id);
163    struct Client *tmp = idTable[hashv];
164  
165 <  if (tmp != NULL)
165 >  if (tmp)
166    {
167      if (tmp == client_p)
168      {
# Line 220 | Line 190 | hash_del_id(struct Client *client_p)
190   void
191   hash_del_client(struct Client *client_p)
192   {
193 <  unsigned int hashv = strhash(client_p->name);
193 >  const unsigned int hashv = strhash(client_p->name);
194    struct Client *tmp = clientTable[hashv];
195  
196 <  if (tmp != NULL)
196 >  if (tmp)
197    {
198      if (tmp == client_p)
199      {
# Line 242 | Line 212 | hash_del_client(struct Client *client_p)
212    }
213   }
214  
245 – /* hash_del_userhost()
246 – *
247 – * inputs       - pointer to userhost
248 – * output       - NONE
249 – * side effects - Removes a userhost from the hash linked list
250 – */
251 – void
252 – hash_del_userhost(struct UserHost *userhost)
253 – {
254 –  unsigned int hashv = strhash(userhost->host);
255 –  struct UserHost *tmp = userhostTable[hashv];
256 –
257 –  if (tmp != NULL)
258 –  {
259 –    if (tmp == userhost)
260 –    {
261 –      userhostTable[hashv] = userhost->next;
262 –      userhost->next = userhost;
263 –    }
264 –    else
265 –    {
266 –      while (tmp->next != userhost)
267 –        if ((tmp = tmp->next) == NULL)
268 –          return;
269 –
270 –      tmp->next = tmp->next->next;
271 –      userhost->next = userhost;
272 –    }
273 –  }
274 – }
275 –
215   /* hash_del_channel()
216   *
217   * inputs       - pointer to client
# Line 283 | Line 222 | hash_del_userhost(struct UserHost *userh
222   void
223   hash_del_channel(struct Channel *chptr)
224   {
225 <  unsigned int hashv = strhash(chptr->chname);
225 >  const unsigned int hashv = strhash(chptr->name);
226    struct Channel *tmp = channelTable[hashv];
227  
228 <  if (tmp != NULL)
228 >  if (tmp)
229    {
230      if (tmp == chptr)
231      {
# Line 305 | Line 244 | hash_del_channel(struct Channel *chptr)
244    }
245   }
246  
308 – void
309 – hash_del_resv(struct ResvChannel *chptr)
310 – {
311 –  unsigned int hashv = strhash(chptr->name);
312 –  struct ResvChannel *tmp = resvchannelTable[hashv];
313 –
314 –  if (tmp != NULL)
315 –  {
316 –    if (tmp == chptr)
317 –    {
318 –      resvchannelTable[hashv] = chptr->hnext;
319 –      chptr->hnext = chptr;
320 –    }
321 –    else
322 –    {
323 –      while (tmp->hnext != chptr)
324 –        if ((tmp = tmp->hnext) == NULL)
325 –          return;
326 –
327 –      tmp->hnext = tmp->hnext->hnext;
328 –      chptr->hnext = chptr;
329 –    }
330 –  }
331 – }
332 –
247   /* hash_find_client()
248   *
249   * inputs       - pointer to name
# Line 341 | Line 255 | hash_del_resv(struct ResvChannel *chptr)
255   struct Client *
256   hash_find_client(const char *name)
257   {
258 <  unsigned int hashv = strhash(name);
258 >  const unsigned int hashv = strhash(name);
259    struct Client *client_p;
260  
261 <  if ((client_p = clientTable[hashv]) != NULL)
261 >  if ((client_p = clientTable[hashv]))
262    {
263      if (irccmp(name, client_p->name))
264      {
265        struct Client *prev;
266  
267 <      while (prev = client_p, (client_p = client_p->hnext) != NULL)
267 >      while (prev = client_p, (client_p = client_p->hnext))
268        {
269          if (!irccmp(name, client_p->name))
270          {
# Line 369 | Line 283 | hash_find_client(const char *name)
283   struct Client *
284   hash_find_id(const char *name)
285   {
286 <  unsigned int hashv = strhash(name);
286 >  const unsigned int hashv = strhash(name);
287    struct Client *client_p;
288  
289 <  if ((client_p = idTable[hashv]) != NULL)
289 >  if ((client_p = idTable[hashv]))
290    {
291      if (strcmp(name, client_p->id))
292      {
293        struct Client *prev;
294  
295 <      while (prev = client_p, (client_p = client_p->idhnext) != NULL)
295 >      while (prev = client_p, (client_p = client_p->idhnext))
296        {
297          if (!strcmp(name, client_p->id))
298          {
# Line 397 | Line 311 | hash_find_id(const char *name)
311   struct Client *
312   hash_find_server(const char *name)
313   {
314 <  unsigned int hashv = strhash(name);
314 >  const unsigned int hashv = strhash(name);
315    struct Client *client_p = NULL;
316  
317    if (IsDigit(*name) && strlen(name) == IRC_MAXSID)
318 <    client_p = hash_find_id(name);
318 >    return hash_find_id(name);
319  
320 <  if ((client_p == NULL) && (client_p = clientTable[hashv]) != NULL)
320 >  if ((client_p = clientTable[hashv]))
321    {
322      if ((!IsServer(client_p) && !IsMe(client_p)) ||
323          irccmp(name, client_p->name))
324      {
325        struct Client *prev;
326  
327 <      while (prev = client_p, (client_p = client_p->hnext) != NULL)
327 >      while (prev = client_p, (client_p = client_p->hnext))
328        {
329          if ((IsServer(client_p) || IsMe(client_p)) &&
330              !irccmp(name, client_p->name))
# Line 431 | Line 345 | hash_find_server(const char *name)
345   *
346   * inputs       - pointer to name
347   * output       - NONE
348 < * side effects - New semantics: finds a channel whose name is 'name',
348 > * side effects - New semantics: finds a channel whose name is 'name',
349   *                if can't find one returns NULL, if can find it moves
350   *                it to the top of the list and returns it.
351   */
352   struct Channel *
353   hash_find_channel(const char *name)
354   {
355 <  unsigned int hashv = strhash(name);
355 >  const unsigned int hashv = strhash(name);
356    struct Channel *chptr = NULL;
357  
358 <  if ((chptr = channelTable[hashv]) != NULL)
358 >  if ((chptr = channelTable[hashv]))
359    {
360 <    if (irccmp(name, chptr->chname))
360 >    if (irccmp(name, chptr->name))
361      {
362        struct Channel *prev;
363  
364 <      while (prev = chptr, (chptr = chptr->hnextch) != NULL)
364 >      while (prev = chptr, (chptr = chptr->hnextch))
365        {
366 <        if (!irccmp(name, chptr->chname))
366 >        if (!irccmp(name, chptr->name))
367          {
368            prev->hnextch = chptr->hnextch;
369            chptr->hnextch = channelTable[hashv];
# Line 477 | Line 391 | void *
391   hash_get_bucket(int type, unsigned int hashv)
392   {
393    assert(hashv < HASHSIZE);
394 +
395    if (hashv >= HASHSIZE)
396 <      return NULL;
396 >    return NULL;
397  
398    switch (type)
399    {
# Line 491 | Line 406 | hash_get_bucket(int type, unsigned int h
406      case HASH_TYPE_CLIENT:
407        return clientTable[hashv];
408        break;
494 –    case HASH_TYPE_USERHOST:
495 –      return userhostTable[hashv];
496 –      break;
497 –    case HASH_TYPE_RESERVED:
498 –      return resvchannelTable[hashv];
499 –      break;
409      default:
410        assert(0);
411    }
# Line 504 | Line 413 | hash_get_bucket(int type, unsigned int h
413    return NULL;
414   }
415  
507 – /* hash_find_resv()
508 – *
509 – * inputs       - pointer to name
510 – * output       - NONE
511 – * side effects - New semantics: finds a reserved channel whose name is 'name',
512 – *                if can't find one returns NULL, if can find it moves
513 – *                it to the top of the list and returns it.
514 – */
515 – struct ResvChannel *
516 – hash_find_resv(const char *name)
517 – {
518 –  unsigned int hashv = strhash(name);
519 –  struct ResvChannel *chptr;
520 –
521 –  if ((chptr = resvchannelTable[hashv]) != NULL)
522 –  {
523 –    if (irccmp(name, chptr->name))
524 –    {
525 –      struct ResvChannel *prev;
526 –
527 –      while (prev = chptr, (chptr = chptr->hnext) != NULL)
528 –      {
529 –        if (!irccmp(name, chptr->name))
530 –        {
531 –          prev->hnext = chptr->hnext;
532 –          chptr->hnext = resvchannelTable[hashv];
533 –          resvchannelTable[hashv] = chptr;
534 –          break;
535 –        }
536 –      }
537 –    }
538 –  }
539 –
540 –  return chptr;
541 – }
542 –
543 – struct UserHost *
544 – hash_find_userhost(const char *host)
545 – {
546 –  unsigned int hashv = strhash(host);
547 –  struct UserHost *userhost;
548 –
549 –  if ((userhost = userhostTable[hashv]))
550 –  {
551 –    if (irccmp(host, userhost->host))
552 –    {
553 –      struct UserHost *prev;
554 –
555 –      while (prev = userhost, (userhost = userhost->next) != NULL)
556 –      {
557 –        if (!irccmp(host, userhost->host))
558 –        {
559 –          prev->next = userhost->next;
560 –          userhost->next = userhostTable[hashv];
561 –          userhostTable[hashv] = userhost;
562 –          break;
563 –        }
564 –      }
565 –    }
566 –  }
567 –
568 –  return userhost;
569 – }
570 –
571 – /* count_user_host()
572 – *
573 – * inputs       - user name
574 – *              - hostname
575 – *              - int flag 1 if global, 0 if local
576 – *              - pointer to where global count should go
577 – *              - pointer to where local count should go
578 – *              - pointer to where identd count should go (local clients only)
579 – * output       - none
580 – * side effects -
581 – */
582 – void
583 – count_user_host(const char *user, const char *host, int *global_p,
584 –                int *local_p, int *icount_p)
585 – {
586 –  dlink_node *ptr;
587 –  struct UserHost *found_userhost;
588 –  struct NameHost *nameh;
589 –
590 –  if ((found_userhost = hash_find_userhost(host)) == NULL)
591 –    return;
592 –
593 –  DLINK_FOREACH(ptr, found_userhost->list.head)
594 –  {
595 –    nameh = ptr->data;
596 –
597 –    if (!irccmp(user, nameh->name))
598 –    {
599 –      if (global_p != NULL)
600 –        *global_p = nameh->gcount;
601 –      if (local_p != NULL)
602 –        *local_p  = nameh->lcount;
603 –      if (icount_p != NULL)
604 –        *icount_p = nameh->icount;
605 –      return;
606 –    }
607 –  }
608 – }
609 –
610 – /* add_user_host()
611 – *
612 – * inputs       - user name
613 – *              - hostname
614 – *              - int flag 1 if global, 0 if local
615 – * output       - none
616 – * side effects - add given user@host to hash tables
617 – */
618 – void
619 – add_user_host(const char *user, const char *host, int global)
620 – {
621 –  dlink_node *ptr;
622 –  struct UserHost *found_userhost;
623 –  struct NameHost *nameh;
624 –  int hasident = 1;
625 –
626 –  if (*user == '~')
627 –  {
628 –    hasident = 0;
629 –    ++user;
630 –  }
631 –
632 –  if ((found_userhost = find_or_add_userhost(host)) == NULL)
633 –    return;
634 –
635 –  DLINK_FOREACH(ptr, found_userhost->list.head)
636 –  {
637 –    nameh = ptr->data;
638 –
639 –    if (!irccmp(user, nameh->name))
640 –    {
641 –      nameh->gcount++;
642 –      if (!global)
643 –      {
644 –        if (hasident)
645 –          nameh->icount++;
646 –        nameh->lcount++;
647 –      }
648 –      return;
649 –    }
650 –  }
651 –
652 –  nameh = BlockHeapAlloc(namehost_heap);
653 –  strlcpy(nameh->name, user, sizeof(nameh->name));
654 –
655 –  nameh->gcount = 1;
656 –  if (!global)
657 –  {
658 –    if (hasident)
659 –      nameh->icount = 1;
660 –    nameh->lcount = 1;
661 –  }
662 –
663 –  dlinkAdd(nameh, &nameh->node, &found_userhost->list);
664 – }
665 –
666 – /* delete_user_host()
667 – *
668 – * inputs       - user name
669 – *              - hostname
670 – *              - int flag 1 if global, 0 if local
671 – * output       - none
672 – * side effects - delete given user@host to hash tables
673 – */
674 – void
675 – delete_user_host(const char *user, const char *host, int global)
676 – {
677 –  dlink_node *ptr = NULL, *next_ptr = NULL;
678 –  struct UserHost *found_userhost;
679 –  struct NameHost *nameh;
680 –  int hasident = 1;
681 –
682 –  if (*user == '~')
683 –  {
684 –    hasident = 0;
685 –    ++user;
686 –  }
687 –
688 –  if ((found_userhost = hash_find_userhost(host)) == NULL)
689 –    return;
690 –
691 –  DLINK_FOREACH_SAFE(ptr, next_ptr, found_userhost->list.head)
692 –  {
693 –    nameh = ptr->data;
694 –
695 –    if (!irccmp(user, nameh->name))
696 –    {
697 –      if (nameh->gcount > 0)
698 –        nameh->gcount--;
699 –      if (!global)
700 –      {
701 –        if (nameh->lcount > 0)
702 –          nameh->lcount--;
703 –        if (hasident && nameh->icount > 0)
704 –          nameh->icount--;
705 –      }
706 –
707 –      if (nameh->gcount == 0 && nameh->lcount == 0)
708 –      {
709 –        dlinkDelete(&nameh->node, &found_userhost->list);
710 –        BlockHeapFree(namehost_heap, nameh);
711 –      }
712 –
713 –      if (dlink_list_length(&found_userhost->list) == 0)
714 –      {
715 –        hash_del_userhost(found_userhost);
716 –        BlockHeapFree(userhost_heap, found_userhost);
717 –      }
718 –
719 –      return;
720 –    }
721 –  }
722 – }
723 –
724 – /* find_or_add_userhost()
725 – *
726 – * inputs       - host name
727 – * output       - none
728 – * side effects - find UserHost * for given host name
729 – */
730 – static struct UserHost *
731 – find_or_add_userhost(const char *host)
732 – {
733 –  struct UserHost *userhost;
734 –
735 –  if ((userhost = hash_find_userhost(host)) != NULL)
736 –    return userhost;
737 –
738 –  userhost = BlockHeapAlloc(userhost_heap);
739 –  strlcpy(userhost->host, host, sizeof(userhost->host));
740 –  hash_add_userhost(userhost);
741 –
742 –  return userhost;
743 – }
744 –
416   /*
417   * Safe list code.
418   *
# Line 764 | Line 435 | find_or_add_userhost(const char *host)
435   *
436   * Sendq limit is fairly conservative at 1/2 (In original anyway)
437   */
438 < static int
439 < exceeding_sendq(struct Client *to)
438 > static bool
439 > exceeding_sendq(const struct Client *to)
440   {
441 <  if (dbuf_length(&to->localClient->buf_sendq) > (get_sendq(to) / 2))
442 <    return 1;
441 >  if (dbuf_length(&to->connection->buf_sendq) > (get_sendq(&to->connection->confs) / 2))
442 >    return true;
443    else
444 <    return 0;
444 >    return false;
445   }
446  
447   void
448 < free_list_task(struct ListTask *lt, struct Client *source_p)
448 > free_list_task(struct Client *source_p)
449   {
450 <  dlink_node *dl, *dln;
450 >  struct ListTask *const lt = source_p->connection->list_task;
451 >  dlink_node *node, *node_next;
452  
453 <  if ((dl = dlinkFindDelete(&listing_client_list, source_p)) != NULL)
782 <    free_dlink_node(dl);
453 >  dlinkDelete(&lt->node, &listing_client_list);
454  
455 <  DLINK_FOREACH_SAFE(dl, dln, lt->show_mask.head)
455 >  DLINK_FOREACH_SAFE(node, node_next, lt->show_mask.head)
456    {
457 <    MyFree(dl->data);
458 <    free_dlink_node(dl);
457 >    xfree(node->data);
458 >    dlinkDelete(node, &lt->show_mask);
459 >    free_dlink_node(node);
460    }
461  
462 <  DLINK_FOREACH_SAFE(dl, dln, lt->hide_mask.head)
462 >  DLINK_FOREACH_SAFE(node, node_next, lt->hide_mask.head)
463    {
464 <    MyFree(dl->data);
465 <    free_dlink_node(dl);
464 >    xfree(node->data);
465 >    dlinkDelete(node, &lt->hide_mask);
466 >    free_dlink_node(node);
467    }
468  
469 <  MyFree(lt);
470 <
798 <  if (MyConnect(source_p))
799 <    source_p->localClient->list_task = NULL;
469 >  xfree(lt);
470 >  source_p->connection->list_task = NULL;
471   }
472  
473   /* list_allow_channel()
# Line 807 | Line 478 | free_list_task(struct ListTask *lt, stru
478   *                0 otherwise
479   * side effects -
480   */
481 < static int
482 < list_allow_channel(const char *chname, struct ListTask *lt)
481 > static bool
482 > list_allow_channel(const char *name, const struct ListTask *lt)
483   {
484 <  dlink_node *dl = NULL;
484 >  dlink_node *node;
485  
486 <  DLINK_FOREACH(dl, lt->show_mask.head)
487 <    if (!match_chan(dl->data, chname))
488 <      return 0;
486 >  DLINK_FOREACH(node, lt->show_mask.head)
487 >    if (match(node->data, name) != 0)
488 >      return false;
489  
490 <  DLINK_FOREACH(dl, lt->hide_mask.head)
491 <    if (match_chan(dl->data, chname))
492 <      return 0;
490 >  DLINK_FOREACH(node, lt->hide_mask.head)
491 >    if (match(node->data, name) == 0)
492 >      return false;
493  
494 <  return 1;
494 >  return true;
495   }
496  
497   /* list_one_channel()
# Line 832 | Line 503 | list_allow_channel(const char *chname, s
503   * side effects -
504   */
505   static void
506 < list_one_channel(struct Client *source_p, struct Channel *chptr,
836 <                 struct ListTask *list_task)
506 > list_one_channel(struct Client *source_p, struct Channel *chptr)
507   {
508 <  if (SecretChannel(chptr) && !IsMember(source_p, chptr))
508 >  const struct ListTask *const lt = source_p->connection->list_task;
509 >  char listbuf[MODEBUFLEN] = "";
510 >  char modebuf[MODEBUFLEN] = "";
511 >  char parabuf[MODEBUFLEN] = "";
512 >
513 >  if (SecretChannel(chptr) &&
514 >      !(HasUMode(source_p, UMODE_ADMIN) || IsMember(source_p, chptr)))
515      return;
516 <  if (dlink_list_length(&chptr->members) < list_task->users_min ||
517 <      dlink_list_length(&chptr->members) > list_task->users_max ||
518 <      (chptr->channelts != 0 &&
519 <       ((unsigned int)chptr->channelts < list_task->created_min ||
520 <        (unsigned int)chptr->channelts > list_task->created_max)) ||
521 <      (unsigned int)chptr->topic_time < list_task->topicts_min ||
516 >
517 >  if (dlink_list_length(&chptr->members) < lt->users_min ||
518 >      dlink_list_length(&chptr->members) > lt->users_max ||
519 >      (chptr->creationtime != 0 &&
520 >       ((unsigned int)chptr->creationtime < lt->created_min ||
521 >        (unsigned int)chptr->creationtime > lt->created_max)) ||
522 >      (unsigned int)chptr->topic_time < lt->topicts_min ||
523        (chptr->topic_time ? (unsigned int)chptr->topic_time : UINT_MAX) >
524 <      list_task->topicts_max)
524 >      lt->topicts_max)
525      return;
526  
527 <  if (!list_allow_channel(chptr->chname, list_task))
527 >  if (lt->topic[0] && match(lt->topic, chptr->topic))
528      return;
529 <  sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
530 <             chptr->chname, dlink_list_length(&chptr->members),
531 <             chptr->topic);
529 >
530 >  if (list_allow_channel(chptr->name, lt) == false)
531 >    return;
532 >
533 >  channel_modes(chptr, source_p, modebuf, parabuf);
534 >
535 >  if (chptr->topic[0])
536 >    snprintf(listbuf, sizeof(listbuf), "[%s] ", modebuf);
537 >  else
538 >    snprintf(listbuf, sizeof(listbuf), "[%s]",  modebuf);
539 >
540 >  sendto_one_numeric(source_p, &me, RPL_LIST, chptr->name,
541 >                     dlink_list_length(&chptr->members),
542 >                     listbuf, chptr->topic);
543   }
544  
545   /* safe_list_channels()
# Line 863 | Line 551 | list_one_channel(struct Client *source_p
551   * Walk the channel buckets, ensure all pointers in a bucket are
552   * traversed before blocking on a sendq. This means, no locking is needed.
553   *
866 – * N.B. This code is "remote" safe, but is not currently used for
867 – * remote clients.
868 – *
554   * - Dianora
555   */
556   void
557 < safe_list_channels(struct Client *source_p, struct ListTask *list_task,
873 <                   int only_unmasked_channels)
557 > safe_list_channels(struct Client *source_p, bool only_unmasked_channels)
558   {
559 +  struct ListTask *const lt = source_p->connection->list_task;
560    struct Channel *chptr = NULL;
561  
562 <  if (!only_unmasked_channels)
562 >  if (only_unmasked_channels == false)
563    {
564 <    unsigned int i;
880 <
881 <    for (i = list_task->hash_index; i < HASHSIZE; ++i)
564 >    for (unsigned int i = lt->hash_index; i < HASHSIZE; ++i)
565      {
566 <      if (exceeding_sendq(source_p->from))
566 >      if (exceeding_sendq(source_p) == true)
567        {
568 <        list_task->hash_index = i;
569 <        return;    /* still more to do */
568 >        lt->hash_index = i;
569 >        return;  /* Still more to do */
570        }
571  
572        for (chptr = channelTable[i]; chptr; chptr = chptr->hnextch)
573 <        list_one_channel(source_p, chptr, list_task);
573 >        list_one_channel(source_p, chptr);
574      }
575    }
576    else
577    {
578 <    dlink_node *dl;
578 >    dlink_node *node;
579  
580 <    DLINK_FOREACH(dl, list_task->show_mask.head)
581 <      if ((chptr = hash_find_channel(dl->data)) != NULL)
582 <        list_one_channel(source_p, chptr, list_task);
580 >    DLINK_FOREACH(node, lt->show_mask.head)
581 >      if ((chptr = hash_find_channel(node->data)))
582 >        list_one_channel(source_p, chptr);
583    }
584  
585 <  free_list_task(list_task, source_p);
586 <  sendto_one(source_p, form_str(RPL_LISTEND),
904 <             me.name, source_p->name);
585 >  free_list_task(source_p);
586 >  sendto_one_numeric(source_p, &me, RPL_LISTEND);
587   }

Comparing:
ircd-hybrid-8/src/hash.c (property svn:keywords), Revision 1332 by michael, Sun Apr 1 16:25:50 2012 UTC vs.
ircd-hybrid/trunk/src/hash.c (property svn:keywords), Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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