select.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2005-2006 iptelorg GmbH
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. *
  27. * History:
  28. * --------
  29. * 2005-12-19 select framework (mma)
  30. * 2006-01-19 multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
  31. * DIVERSION flag checked
  32. * 2006-02-26 don't free str when changing type STR -> DIVERSION (mma)
  33. * it can't be freeable sometimes (e.g. xlog's select)
  34. * 2006-05-30 parse_select (mma)
  35. * 2006-06-02 shm_parse_select (mma)
  36. *
  37. */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <unistd.h>
  42. #include <ctype.h>
  43. #include "select.h"
  44. #include "dprint.h"
  45. #include "select_core.h"
  46. #include "mem/mem.h"
  47. #include "mem/shm_mem.h"
  48. /*
  49. * The main parser table list placeholder
  50. * at startup use core table, modules can
  51. * add their own via register_select_table call
  52. */
  53. static select_table_t *select_list = &select_core_table;
  54. /* the level of the select call that is beeing evaluated
  55. * by the child process
  56. */
  57. int select_level = 0;
  58. /*
  59. * Parse select string into select structure s
  60. * moves pointer p to the first unused char
  61. *
  62. * Returns -1 error
  63. * p points to the first unconsumed char
  64. * 0 success
  65. * p points to the first unconsumed char
  66. * s points to the select structure
  67. */
  68. int w_parse_select(char**p, select_t* sel)
  69. {
  70. str name;
  71. char* select_name;
  72. if (**p=='@') (*p)++;
  73. select_name=*p;
  74. sel->n=0;
  75. while (isalpha((unsigned char)*(*p))) {
  76. if (sel->n > MAX_SELECT_PARAMS -2) {
  77. ERR("parse_select: select depth exceeds max\n");
  78. goto error;
  79. }
  80. name.s=(*p);
  81. while (isalpha((unsigned char)*(*p)) ||
  82. isdigit((unsigned char)*(*p)) || (*(*p)=='_')) (*p)++;
  83. name.len=(*p)-name.s;
  84. sel->params[sel->n].type=SEL_PARAM_STR;
  85. sel->params[sel->n].v.s=name;
  86. DBG("parse_select: part %d: %.*s\n", sel->n, sel->params[sel->n].v.s.len, sel->params[sel->n].v.s.s);
  87. sel->n++;
  88. if (*(*p)=='[') {
  89. (*p)++;
  90. if (*(*p)=='\\') (*p)++;
  91. if (*(*p)=='"') {
  92. (*p)++;
  93. name.s=(*p);
  94. while ((*(*p)!='\0') && (*(*p)!='"')) (*p)++;
  95. if (*(*p)!='"') {
  96. ERR("parse_select: end of string is missing\n");
  97. goto error;
  98. }
  99. name.len=(*p)-name.s;
  100. if (*((*p)-1)=='\\') name.len--;
  101. (*p)++;
  102. if (*(*p)!=']') {
  103. ERR("parse_select: invalid string index, no closing ]\n");
  104. goto error;
  105. };
  106. (*p)++;
  107. sel->params[sel->n].type=SEL_PARAM_STR;
  108. sel->params[sel->n].v.s=name;
  109. DBG("parse_select: part %d: [\"%.*s\"]\n", sel->n, sel->params[sel->n].v.s.len, sel->params[sel->n].v.s.s);
  110. } else {
  111. name.s=(*p);
  112. if (*(*p)=='-') (*p)++;
  113. while (isdigit((unsigned char)*(*p))) (*p)++;
  114. name.len=(*p)-name.s;
  115. if (*(*p)!=']') {
  116. ERR("parse_select: invalid index, no closing ]\n");
  117. goto error;
  118. };
  119. (*p)++;
  120. sel->params[sel->n].type=SEL_PARAM_INT;
  121. sel->params[sel->n].v.i=atoi(name.s);
  122. DBG("parse_select: part %d: [%d]\n", sel->n, sel->params[sel->n].v.i);
  123. }
  124. sel->n++;
  125. }
  126. if (*(*p)!='.') break;
  127. (*p)++;
  128. };
  129. if (sel->n==0) {
  130. ERR("parse_select: invalid select '%.*s'\n", (int)(*p - select_name), select_name);
  131. goto error;
  132. };
  133. DBG("parse_select: end, total elements: %d, calling resolve_select\n", sel->n);
  134. if (resolve_select(sel)<0) {
  135. ERR("parse_select: error while resolve_select '%.*s'\n", (int)(*p - select_name), select_name);
  136. goto error;
  137. }
  138. return 0;
  139. error:
  140. return -1;
  141. }
  142. int parse_select (char** p, select_t** s)
  143. {
  144. select_t* sel;
  145. sel=(select_t*)pkg_malloc(sizeof(select_t));
  146. if (!sel) {
  147. ERR("parse_select: no free memory\n");
  148. return -1;
  149. }
  150. if (w_parse_select(p, sel)<0) {
  151. pkg_free(sel);
  152. return -2;
  153. }
  154. *s=sel;
  155. return 0;
  156. }
  157. void free_select(select_t *s)
  158. {
  159. if (s)
  160. pkg_free(s);
  161. }
  162. int shm_parse_select (char** p, select_t** s)
  163. {
  164. select_t* sel;
  165. sel=(select_t*)shm_malloc(sizeof(select_t));
  166. if (!sel) {
  167. ERR("parse_select: no free shared memory\n");
  168. return -1;
  169. }
  170. if (w_parse_select(p, sel)<0) {
  171. shm_free(sel);
  172. return -2;
  173. }
  174. *s=sel;
  175. return 0;
  176. }
  177. int resolve_select(select_t* s)
  178. {
  179. select_f f;
  180. int nested;
  181. int param_idx = 0;
  182. int table_idx = 0;
  183. select_table_t* t = NULL;
  184. int accept = 0;
  185. f = NULL;
  186. nested = 0;
  187. memset (s->f, 0, sizeof(s->f));
  188. while (param_idx<s->n) {
  189. accept = 0;
  190. switch (s->params[param_idx].type) {
  191. case SEL_PARAM_STR:
  192. DBG("resolve_select: '%.*s'\n", s->params[param_idx].v.s.len, s->params[param_idx].v.s.s);
  193. break;
  194. case SEL_PARAM_INT:
  195. DBG("resolve_select: [%d]\n", s->params[param_idx].v.i);
  196. break;
  197. default:
  198. /* just to avoid the warning */
  199. break;
  200. }
  201. for (t=select_list; t; t=t->next) {
  202. table_idx = 0;
  203. if (!t->table) continue;
  204. while (t->table[table_idx].curr_f || t->table[table_idx].new_f) {
  205. if (t->table[table_idx].curr_f == f) {
  206. if ((t->table[table_idx].flags & (NESTED | CONSUME_NEXT_INT | CONSUME_NEXT_STR)) == NESTED) {
  207. accept = 1;
  208. } else if (t->table[table_idx].type == s->params[param_idx].type) {
  209. switch (t->table[table_idx].type) {
  210. case SEL_PARAM_INT:
  211. accept = 1;
  212. break;
  213. case SEL_PARAM_STR:
  214. accept = (((t->table[table_idx].name.len == s->params[param_idx].v.s.len) || !t->table[table_idx].name.len)
  215. && (!t->table[table_idx].name.s || !strncasecmp(t->table[table_idx].name.s, s->params[param_idx].v.s.s, s->params[param_idx].v.s.len)));
  216. break;
  217. default:
  218. break;
  219. }
  220. };
  221. }
  222. if (accept) goto accepted;
  223. table_idx++;
  224. }
  225. }
  226. switch (s->params[param_idx].type) {
  227. case SEL_PARAM_STR:
  228. LOG(L_ERR, "Unable to resolve select '%.*s' at level %d\n", s->params[param_idx].v.s.len, s->params[param_idx].v.s.s, param_idx);
  229. break;
  230. case SEL_PARAM_INT:
  231. LOG(L_ERR, "Unable to resolve select [%d] at level %d\n", s->params[param_idx].v.i, param_idx);
  232. break;
  233. default:
  234. BUG ("Unable to resolve select at level %d\n", param_idx);
  235. break;
  236. break;
  237. }
  238. goto not_found;
  239. accepted:
  240. if (t->table[table_idx].flags & DIVERSION) {
  241. /* if (s->params[param_idx].type == SEL_PARAM_STR) pkg_free(s->params[param_idx].v.s.s); */
  242. /* don't free it (the mem can leak only once at startup)
  243. * the parsed string can live inside larger string block
  244. * e.g. when xlog's select is parsed
  245. */
  246. s->params[param_idx].type = SEL_PARAM_DIV;
  247. s->params[param_idx].v.i = t->table[table_idx].flags & DIVERSION_MASK;
  248. }
  249. if (t->table[table_idx].flags & CONSUME_NEXT_STR) {
  250. if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_STR)) {
  251. param_idx++;
  252. } else if (!(t->table[table_idx].flags & OPTIONAL)) {
  253. BUG ("Mandatory STR parameter not found\n");
  254. goto not_found;
  255. }
  256. }
  257. if (t->table[table_idx].flags & CONSUME_NEXT_INT) {
  258. if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_INT)) {
  259. param_idx++;
  260. } else if (!(t->table[table_idx].flags & OPTIONAL)) {
  261. BUG ("Mandatory INT parameter not found\n");
  262. goto not_found;
  263. }
  264. }
  265. if (t->table[table_idx].flags & NESTED) {
  266. if (nested < MAX_NESTED_CALLS-1) { /* need space for final function */
  267. s->f[nested++] = f;
  268. s->param_offset[nested] = param_idx;
  269. } else {
  270. BUG("MAX_NESTED_CALLS too small to resolve select\n");
  271. goto not_found;
  272. }
  273. } else {
  274. param_idx++;
  275. }
  276. if (t->table[table_idx].flags & FIXUP_CALL) {
  277. select_level = nested;
  278. s->param_offset[nested+1] = param_idx;
  279. if (t->table[table_idx].new_f(NULL, s, NULL)<0) goto not_found;
  280. }
  281. f = t->table[table_idx].new_f;
  282. if (t->table[table_idx].flags & CONSUME_ALL) {
  283. /* sanity checks */
  284. if (t->table[table_idx].flags & NESTED)
  285. WARN("resolve_select: CONSUME_ALL should not be set "
  286. "together with NESTED flag!\n");
  287. if ((t->table[table_idx].flags & FIXUP_CALL) == 0)
  288. WARN("resolve_select: FIXUP_CALL should be defined "
  289. "if CONSUME_ALL flag is set!\n");
  290. break;
  291. }
  292. }
  293. if (t->table[table_idx].flags & SEL_PARAM_EXPECTED) {
  294. BUG ("final node has SEL_PARAM_EXPECTED set (no more parameters available)\n");
  295. goto not_found;
  296. }
  297. if (nested >= MAX_NESTED_CALLS) {
  298. BUG("MAX_NESTED_CALLS too small, no space for finally resolved function\n");
  299. goto not_found;
  300. }
  301. if ((nested>0) && (s->f[nested-1] == f)) {
  302. BUG("Topmost nested function equals to final function, won't call it twice\n");
  303. } else {
  304. s->f[nested++] = f;
  305. }
  306. s->param_offset[nested] = s->n;
  307. return 0;
  308. not_found:
  309. return -1;
  310. }
  311. int run_select(str* res, select_t* s, struct sip_msg* msg)
  312. {
  313. int ret, orig_level;
  314. if (res == NULL) {
  315. BUG("Select unprepared result space\n");
  316. return -1;
  317. }
  318. if (s == 0) {
  319. BUG("Select structure is NULL\n");
  320. return -1;
  321. }
  322. if (s->f[0] == 0) {
  323. BUG("Select structure has not been resolved\n");
  324. return -1;
  325. }
  326. DBG("Calling SELECT %p \n", s->f);
  327. /* save and restore the original select_level
  328. * because of the nested selects */
  329. orig_level = select_level;
  330. ret = 0;
  331. for ( select_level=0;
  332. (ret == 0) && (s->f[select_level] !=0 ) && (select_level<MAX_NESTED_CALLS);
  333. select_level++
  334. ) {
  335. ret = s->f[select_level](res, s, msg);
  336. }
  337. select_level = orig_level;
  338. return ret;
  339. }
  340. void print_select(select_t* s)
  341. {
  342. int i;
  343. DBG("select(");
  344. for(i = 0; i < s->n; i++) {
  345. if (s->params[i].type == SEL_PARAM_INT) {
  346. DBG("%d,", s->params[i].v.i);
  347. } else {
  348. DBG("%.*s,", s->params[i].v.s.len, s->params[i].v.s.s);
  349. }
  350. }
  351. DBG(")\n");
  352. }
  353. int register_select_table(select_row_t* mod_tab)
  354. {
  355. select_table_t* t;
  356. t=(select_table_t*)pkg_malloc(sizeof(select_table_t));
  357. if (!t) {
  358. ERR("No memory for new select_table structure\n");
  359. return -1;
  360. }
  361. t->table=mod_tab;
  362. t->next=select_list;
  363. select_list=t;
  364. return 0;
  365. }