lists.c 4.6 KB

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