lists.c 4.6 KB

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