script_cb.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Script callbacks -- they add the ability to register callback
  3. * functions which are always called when script for request
  4. * processing is entered or left
  5. *
  6. *
  7. * Copyright (C) 2001-2003 FhG Fokus
  8. *
  9. * This file is part of Kamailio, a free SIP server.
  10. *
  11. * Kamailio is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version
  15. *
  16. * Kamailio is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. */
  26. /*!
  27. * \file
  28. * \brief Kamailio core :: Script callbacks
  29. *
  30. * Script callbacks adds the ability to register callback
  31. * functions which are always called when script for request
  32. * processing is entered or left
  33. * \ingroup core
  34. * Module: \ref core
  35. */
  36. #include <stdlib.h>
  37. #include "script_cb.h"
  38. #include "dprint.h"
  39. #include "error.h"
  40. #include "mem/mem.h"
  41. /* Number of cb types = last cb type */
  42. #define SCRIPT_CB_NUM (MAX_CB_TYPE-1)
  43. static struct script_cb *pre_script_cb[SCRIPT_CB_NUM];
  44. static struct script_cb *post_script_cb[SCRIPT_CB_NUM];
  45. /* Add a script callback to the beginning of the linked list.
  46. * Returns -1 on error
  47. */
  48. static inline int add_callback( struct script_cb **list,
  49. cb_function f, void *param)
  50. {
  51. struct script_cb *new_cb;
  52. new_cb=pkg_malloc(sizeof(struct script_cb));
  53. if (new_cb==0) {
  54. LM_CRIT("out of memory\n");
  55. return -1;
  56. }
  57. new_cb->cbf = f;
  58. new_cb->param = param;
  59. /* link at the beginning of the list */
  60. new_cb->next = *list;
  61. *list = new_cb;
  62. return 0;
  63. }
  64. /* Register pre- or post-script callbacks.
  65. * Returns -1 on error, 0 on success
  66. */
  67. int register_script_cb( cb_function f, unsigned int flags, void *param )
  68. {
  69. struct script_cb **cb_array;
  70. int i;
  71. /* type checkings */
  72. if ( (flags&((1<<SCRIPT_CB_NUM)-1))==0 ) {
  73. LOG(L_BUG, "register_script_cb: callback flag not specified\n");
  74. return -1;
  75. }
  76. if ( (flags&(~(PRE_SCRIPT_CB|POST_SCRIPT_CB))) >= 1<<SCRIPT_CB_NUM ) {
  77. LOG(L_BUG, "register_script_cb: unsupported callback flags: %u\n",
  78. flags);
  79. return -1;
  80. }
  81. if ( (flags&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
  82. (flags&PRE_SCRIPT_CB && flags&POST_SCRIPT_CB) ) {
  83. LOG(L_BUG, "register_script_cb: callback POST or PRE type must "
  84. "be exactly one\n");
  85. return -1;
  86. }
  87. if (flags&PRE_SCRIPT_CB)
  88. cb_array = pre_script_cb;
  89. else
  90. cb_array = post_script_cb;
  91. /* Add the callback to the lists.
  92. * (as many times as many flags are set)
  93. */
  94. for (i=0; i<SCRIPT_CB_NUM; i++) {
  95. if ((flags&(1<<i)) == 0)
  96. continue;
  97. if (add_callback(&cb_array[i], f, param) < 0)
  98. goto add_error;
  99. }
  100. return 0;
  101. add_error:
  102. LM_ERR("failed to add callback\n");
  103. return -1;
  104. }
  105. int init_script_cb()
  106. {
  107. memset(pre_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
  108. memset(post_script_cb, 0, SCRIPT_CB_NUM * sizeof(struct script_cb *));
  109. return 0;
  110. }
  111. static inline void destroy_cb_list(struct script_cb **list)
  112. {
  113. struct script_cb *foo;
  114. while( *list ) {
  115. foo = *list;
  116. *list = (*list)->next;
  117. pkg_free( foo );
  118. }
  119. }
  120. void destroy_script_cb()
  121. {
  122. int i;
  123. for (i=0; i<SCRIPT_CB_NUM; i++) {
  124. destroy_cb_list(&pre_script_cb[i]);
  125. destroy_cb_list(&post_script_cb[i]);
  126. }
  127. }
  128. /* Execute pre-script callbacks of a given type.
  129. * Returns 0 on error, 1 on success
  130. */
  131. int exec_pre_script_cb( struct sip_msg *msg, enum script_cb_type type)
  132. {
  133. struct script_cb *cb;
  134. unsigned int flags;
  135. #ifdef EXTRA_DEBUG
  136. if (type > SCRIPT_CB_NUM) {
  137. LOG(L_BUG, "Uknown callback type\n");
  138. abort();
  139. }
  140. #endif
  141. flags = PRE_SCRIPT_CB | (1<<(type-1));
  142. for (cb=pre_script_cb[type-1]; cb ; cb=cb->next ) {
  143. /* stop on error */
  144. if (cb->cbf(msg, flags, cb->param)==0)
  145. return 0;
  146. }
  147. return 1;
  148. }
  149. /* Execute post-script callbacks of a given type.
  150. * Always returns 1, success.
  151. */
  152. int exec_post_script_cb( struct sip_msg *msg, enum script_cb_type type)
  153. {
  154. struct script_cb *cb;
  155. unsigned int flags;
  156. #ifdef EXTRA_DEBUG
  157. if (type > SCRIPT_CB_NUM) {
  158. LOG(L_BUG, "exec_pre_script_cb: Uknown callback type\n");
  159. abort();
  160. }
  161. #endif
  162. flags = POST_SCRIPT_CB | (1<<(type-1));
  163. for (cb=post_script_cb[type-1]; cb ; cb=cb->next){
  164. cb->cbf(msg, flags, cb->param);
  165. }
  166. return 1;
  167. }