lists.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. * Please read the file COPYING, README and AUTHORS for more information.
  10. *
  11. * Management of IRC lists: ban, invite, ...
  12. */
  13. #include "portab.h"
  14. #include "imp.h"
  15. #include <assert.h>
  16. #include "defines.h"
  17. #include "conn.h"
  18. #include "channel.h"
  19. #include "log.h"
  20. #include "match.h"
  21. #include "messages.h"
  22. #include "irc-write.h"
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <strings.h>
  26. #include "exp.h"
  27. #include "lists.h"
  28. #define MASK_LEN (2*CLIENT_HOST_LEN)
  29. struct list_elem {
  30. struct list_elem *next;
  31. char mask[MASK_LEN];
  32. bool onlyonce;
  33. };
  34. GLOBAL const char *
  35. Lists_GetMask(const struct list_elem *e)
  36. {
  37. return e->mask;
  38. }
  39. GLOBAL struct list_elem*
  40. Lists_GetFirst(const struct list_head *h)
  41. {
  42. return h->first;
  43. }
  44. GLOBAL struct list_elem*
  45. Lists_GetNext(const struct list_elem *e)
  46. {
  47. return e->next;
  48. }
  49. bool
  50. Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
  51. {
  52. struct list_elem *e, *newelem;
  53. assert( header != NULL );
  54. assert( Mask != NULL );
  55. if (Lists_CheckDupeMask(header, Mask )) return true;
  56. e = Lists_GetFirst(header);
  57. newelem = malloc(sizeof(struct list_elem));
  58. if( ! newelem ) {
  59. Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
  60. return false;
  61. }
  62. strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
  63. newelem->onlyonce = OnlyOnce;
  64. newelem->next = e;
  65. header->first = newelem;
  66. LogDebug("Added \"%s\" to invite list", Mask);
  67. return true;
  68. }
  69. static void
  70. Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
  71. {
  72. assert(victim != NULL);
  73. assert(header != NULL);
  74. if (p) p->next = victim->next;
  75. else header->first = victim->next;
  76. free(victim);
  77. }
  78. GLOBAL void
  79. Lists_Del(struct list_head *header, const char *Mask)
  80. {
  81. struct list_elem *e, *last, *victim;
  82. assert( header != NULL );
  83. assert( Mask != NULL );
  84. last = NULL;
  85. e = Lists_GetFirst(header);
  86. while( e ) {
  87. if(strcasecmp( e->mask, Mask ) == 0 ) {
  88. LogDebug("Deleted \"%s\" from list", e->mask);
  89. victim = e;
  90. e = victim->next;
  91. Lists_Unlink(header, last, victim);
  92. continue;
  93. }
  94. last = e;
  95. e = e->next;
  96. }
  97. }
  98. GLOBAL void
  99. Lists_Free(struct list_head *head)
  100. {
  101. struct list_elem *e, *victim;
  102. assert(head != NULL);
  103. e = head->first;
  104. head->first = NULL;
  105. while (e) {
  106. LogDebug("Deleted \"%s\" from invite list" , e->mask);
  107. victim = e;
  108. e = e->next;
  109. free( victim );
  110. }
  111. }
  112. GLOBAL bool
  113. Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
  114. {
  115. struct list_elem *e;
  116. e = h->first;
  117. while (e) {
  118. if (strcasecmp( e->mask, Mask ) == 0 )
  119. return true;
  120. e = e->next;
  121. }
  122. return false;
  123. }
  124. GLOBAL const char *
  125. Lists_MakeMask(const char *Pattern)
  126. {
  127. /* This function generats a valid IRC mask of "any" string. This
  128. * mask is only valid until the next call to Lists_MakeMask(),
  129. * because a single global buffer is used. You have to copy the
  130. * generated mask to some sane location yourself! */
  131. static char TheMask[MASK_LEN];
  132. char *excl, *at;
  133. assert( Pattern != NULL );
  134. excl = strchr( Pattern, '!' );
  135. at = strchr( Pattern, '@' );
  136. if(( at ) && ( at < excl )) excl = NULL;
  137. if(( ! at ) && ( ! excl ))
  138. {
  139. /* Neither "!" nor "@" found: use string as nick name */
  140. strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
  141. strlcat( TheMask, "!*@*", sizeof( TheMask ));
  142. return TheMask;
  143. }
  144. if(( ! at ) && ( excl ))
  145. {
  146. /* Domain part is missing */
  147. strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
  148. strlcat( TheMask, "@*", sizeof( TheMask ));
  149. return TheMask;
  150. }
  151. if(( at ) && ( ! excl ))
  152. {
  153. /* User name is missing */
  154. *at = '\0'; at++;
  155. strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
  156. strlcat( TheMask, "!*@", sizeof( TheMask ));
  157. strlcat( TheMask, at, sizeof( TheMask ));
  158. return TheMask;
  159. }
  160. /* All parts (nick, user and domain name) are given */
  161. strlcpy( TheMask, Pattern, sizeof( TheMask ));
  162. return TheMask;
  163. } /* Lists_MakeMask */
  164. bool
  165. Lists_Check( struct list_head *header, CLIENT *Client)
  166. {
  167. struct list_elem *e, *last;
  168. assert( header != NULL );
  169. e = header->first;
  170. last = NULL;
  171. while( e ) {
  172. if( Match( e->mask, Client_Mask( Client ))) {
  173. if( e->onlyonce ) { /* delete entry */
  174. LogDebug("Deleted \"%s\" from list", e->mask);
  175. Lists_Unlink(header, last, e);
  176. }
  177. return true;
  178. }
  179. last = e;
  180. e = e->next;
  181. }
  182. return false;
  183. }
  184. /* -eof- */