dlist.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Presence Agent, domain list
  3. *
  4. * $Id$
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #include "dlist.h"
  30. #include "../../dprint.h"
  31. #include "../../mem/shm_mem.h"
  32. #include "../../sr_module.h"
  33. #include "../../ut.h"
  34. #include "paerrno.h"
  35. #include <string.h>
  36. #include "ptime.h"
  37. #include "presentity.h"
  38. /*
  39. * List of all registered domains
  40. */
  41. dlist_t* root = 0;
  42. /*
  43. * Find domain with the given name
  44. * Returns 0 if the domain was found
  45. * and 1 of not
  46. */
  47. static inline int find_dlist(str* _n, dlist_t** _d)
  48. {
  49. dlist_t* ptr;
  50. ptr = root;
  51. while(ptr) {
  52. if ((_n->len == ptr->name.len) &&
  53. !memcmp(_n->s, ptr->name.s, _n->len)) {
  54. *_d = ptr;
  55. return 0;
  56. }
  57. ptr = ptr->next;
  58. }
  59. return 1;
  60. }
  61. /*
  62. * Create a new domain structure
  63. * Returns 0 if everything went OK, otherwise value < 0
  64. * is returned
  65. *
  66. * The structure is NOT created in shared memory so the
  67. * function must be called before ser forks if it should
  68. * be available to all processes
  69. */
  70. static inline int new_dlist(str* _n, dlist_t** _d)
  71. {
  72. cmd_function reg;
  73. cmd_function unreg;
  74. dlist_t* ptr;
  75. /* Domains are created before ser forks,
  76. * so we can create them using pkg_malloc
  77. */
  78. ptr = (dlist_t*)mem_alloc(sizeof(dlist_t));
  79. if (ptr == 0) {
  80. paerrno = PA_NO_MEMORY;
  81. LOG(L_ERR, "new_dlist(): No memory left\n");
  82. return -1;
  83. }
  84. memset(ptr, 0, sizeof(dlist_t));
  85. ptr->name.s = (char*)mem_alloc(_n->len);
  86. if (ptr->name.s == 0) {
  87. paerrno = PA_NO_MEMORY;
  88. LOG(L_ERR, "new_dlist(): No memory left 2\n");
  89. mem_free(ptr);
  90. return -2;
  91. }
  92. memcpy(ptr->name.s, _n->s, _n->len);
  93. ptr->name.len = _n->len;
  94. if ((_n->len == 9) && (!strncasecmp(_n->s, "registrar", 9))) {
  95. reg = find_export("ul_register_watcher", 1, 0);
  96. if (reg == 0) {
  97. LOG(L_ERR, "new_dlist(): ~ul_register_watcher not found\n");
  98. return -3;
  99. }
  100. unreg = find_export("ul_unregister_watcher", 1, 0);
  101. if (unreg == 0) {
  102. LOG(L_ERR, "new_dlist(): ~ul_unregister_watcher not found\n");
  103. return -4;
  104. }
  105. } else if ((_n->len == 6) && (!strncasecmp(_n->s, "jabber", 6))) {
  106. reg = find_export("jab_register_watcher", 1, 0);
  107. if (reg == 0) {
  108. LOG(L_ERR, "new_dlist(): jab_register_watcher not found\n");
  109. return -5;
  110. }
  111. unreg = find_export("jab_unregister_watcher", 1, 0);
  112. if (unreg == 0) {
  113. LOG(L_ERR, "new_dlist(): jab_unregister_watcher not found\n");
  114. return -6;
  115. }
  116. } else {
  117. LOG(L_ERR, "new_dlist(): Unknown module to bind: %.*s\n", _n->len, ZSW(_n->s));
  118. return -7;
  119. }
  120. if (new_pdomain(&(ptr->name), 512, &(ptr->d), (register_watcher_t)reg, (unregister_watcher_t)unreg) < 0) {
  121. LOG(L_ERR, "new_dlist(): Error while creating domain structure\n");
  122. mem_free(ptr->name.s);
  123. mem_free(ptr);
  124. return -8;
  125. }
  126. *_d = ptr;
  127. return 0;
  128. }
  129. int find_pdomain(const char* _n, pdomain_t** _d)
  130. {
  131. dlist_t* d;
  132. str s;
  133. s.s = (char*)_n;
  134. s.len = strlen(_n);
  135. if (find_dlist(&s, &d) == 0) {
  136. *_d = d->d;
  137. return 0;
  138. }
  139. return 1;
  140. }
  141. /*
  142. * Function registers a new domain with presence agent
  143. * if the domain exists, pointer to existing structure
  144. * will be returned, otherwise a new domain will be
  145. * created
  146. */
  147. int register_pdomain(const char* _n, pdomain_t** _d)
  148. {
  149. pdomain_t *pdomain;
  150. dlist_t* d;
  151. str s;
  152. s.s = (char*)_n;
  153. s.len = strlen(_n);
  154. if (find_dlist(&s, &d) == 0) {
  155. *_d = d->d;
  156. return 0;
  157. }
  158. if (new_dlist(&s, &d) < 0) {
  159. LOG(L_ERR, "register_pdomain(): Error while creating new domain\n");
  160. return -1;
  161. }
  162. pdomain = d->d;
  163. lock_pdomain(pdomain); /* do not enable timer to delete presentities in it */
  164. d->next = root;
  165. root = d;
  166. *_d = pdomain;
  167. /* Preload domain with data from database if we are gonna
  168. * to use database
  169. */
  170. pdomain_load_presentities(pdomain);
  171. unlock_pdomain(pdomain);
  172. return 0;
  173. }
  174. /*
  175. * Free all allocated memory
  176. */
  177. void free_all_pdomains(void)
  178. {
  179. dlist_t* ptr;
  180. while(root) {
  181. ptr = root;
  182. root = root->next;
  183. free_pdomain(ptr->d);
  184. mem_free(ptr->name.s);
  185. mem_free(ptr);
  186. }
  187. }
  188. /*
  189. * Run timer handler of all domains
  190. */
  191. int timer_all_pdomains(void)
  192. {
  193. int res = 0;
  194. dlist_t* ptr;
  195. get_act_time(); /* Get and save actual time */
  196. ptr = root;
  197. while(ptr) {
  198. res |= timer_pdomain(ptr->d);
  199. ptr = ptr->next;
  200. }
  201. return res;
  202. }