2
0

xlog.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /**
  2. * Copyright (C) 2001-2003 FhG Fokus
  3. *
  4. * This file is part of Kamailio, a free SIP server.
  5. *
  6. * Kamailio is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * Kamailio is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /*!
  21. * \file
  22. * \brief Module interface
  23. * \ingroup xlog
  24. * Module: \ref xlog
  25. */
  26. /**
  27. * @defgroup xlog xlog :: Kamailio xlog module
  28. * @brief Kamailio xlog module
  29. * Extended logging from the configuration script using pv:s.
  30. * Can log to multiple channels as well as standard out.
  31. *
  32. */
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include <sys/types.h>
  37. #include <sys/ipc.h>
  38. #include <unistd.h>
  39. #include <fcntl.h>
  40. #include <time.h>
  41. #include <ctype.h>
  42. #include "../../sr_module.h"
  43. #include "../../dprint.h"
  44. #include "../../error.h"
  45. #include "../../cfg/cfg.h"
  46. #include "../../mem/mem.h"
  47. #include "../../parser/parse_param.h"
  48. #include "xl_lib.h"
  49. #include "../../pvar.h"
  50. #define NOFACILITY -1
  51. MODULE_VERSION
  52. char *_xlog_buf = NULL;
  53. char *_xlog_prefix = "<script>: ";
  54. /** parameters */
  55. static int buf_size=4096;
  56. static int force_color=0;
  57. static int long_format=0;
  58. static int xlog_facility = DEFAULT_FACILITY;
  59. static char *xlog_facility_name = NULL;
  60. /** cfg dynamic parameters */
  61. struct cfg_group_xlog {
  62. int methods_filter;
  63. };
  64. static struct cfg_group_xlog xlog_default_cfg = {
  65. -1 /* methods filter */
  66. };
  67. static void *xlog_cfg = &xlog_default_cfg;
  68. static cfg_def_t xlog_cfg_def[] = {
  69. {"methods_filter", CFG_VAR_INT | CFG_ATOMIC, 0, 0, 0, 0,
  70. "Methods filter value for xlogm(...)."},
  71. {0, 0, 0, 0, 0, 0}
  72. };
  73. /** module functions */
  74. static int mod_init(void);
  75. static int xlog_1(struct sip_msg*, char*, char*);
  76. static int xlog_2(struct sip_msg*, char*, char*);
  77. static int xlog_3(struct sip_msg*, char*, char*, char*);
  78. static int xdbg(struct sip_msg*, char*, char*);
  79. static int xlogl_1(struct sip_msg*, char*, char*);
  80. static int xlogl_2(struct sip_msg*, char*, char*);
  81. static int xlogl_3(struct sip_msg*, char*, char*, char*);
  82. static int xdbgl(struct sip_msg*, char*, char*);
  83. static int xlogm_2(struct sip_msg*, char*, char*);
  84. static int xlog_fixup(void** param, int param_no);
  85. static int xlog3_fixup(void** param, int param_no);
  86. static int xdbg_fixup(void** param, int param_no);
  87. static int xlogl_fixup(void** param, int param_no);
  88. static int xlogl3_fixup(void** param, int param_no);
  89. static int xdbgl_fixup(void** param, int param_no);
  90. static void destroy(void);
  91. static int xlog_log_colors_param(modparam_t type, void *val);
  92. int pv_parse_color_name(pv_spec_p sp, str *in);
  93. static int pv_get_color(struct sip_msg *msg, pv_param_t *param,
  94. pv_value_t *res);
  95. typedef struct _xl_level
  96. {
  97. int type;
  98. union {
  99. long level;
  100. pv_spec_t sp;
  101. } v;
  102. } xl_level_t, *xl_level_p;
  103. typedef struct _xl_msg
  104. {
  105. pv_elem_t *m;
  106. struct action *a;
  107. } xl_msg_t;
  108. static pv_export_t mod_items[] = {
  109. { {"C", sizeof("C")-1}, PVT_OTHER, pv_get_color, 0,
  110. pv_parse_color_name, 0, 0, 0 },
  111. { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
  112. };
  113. static cmd_export_t cmds[]={
  114. {"xlog", (cmd_function)xlog_1, 1, xdbg_fixup, 0, ANY_ROUTE},
  115. {"xlog", (cmd_function)xlog_2, 2, xlog_fixup, 0, ANY_ROUTE},
  116. {"xlog", (cmd_function)xlog_3, 3, xlog3_fixup, 0, ANY_ROUTE},
  117. {"xdbg", (cmd_function)xdbg, 1, xdbg_fixup, 0, ANY_ROUTE},
  118. {"xlogl", (cmd_function)xlogl_1, 1, xdbgl_fixup, 0, ANY_ROUTE},
  119. {"xlogl", (cmd_function)xlogl_2, 2, xlogl_fixup, 0, ANY_ROUTE},
  120. {"xlogl", (cmd_function)xlogl_3, 3, xlogl3_fixup,0, ANY_ROUTE},
  121. {"xdbgl", (cmd_function)xdbgl, 1, xdbgl_fixup, 0, ANY_ROUTE},
  122. {"xlogm", (cmd_function)xlogm_2, 2, xlog_fixup, 0, ANY_ROUTE},
  123. {0,0,0,0,0,0}
  124. };
  125. static param_export_t params[]={
  126. {"buf_size", INT_PARAM, &buf_size},
  127. {"force_color", INT_PARAM, &force_color},
  128. {"long_format", INT_PARAM, &long_format},
  129. {"prefix", PARAM_STRING, &_xlog_prefix},
  130. {"log_facility", PARAM_STRING, &xlog_facility_name},
  131. {"log_colors", PARAM_STRING|USE_FUNC_PARAM, (void*)xlog_log_colors_param},
  132. {"methods_filter", PARAM_INT, &xlog_default_cfg.methods_filter},
  133. {0,0,0}
  134. };
  135. /** module exports */
  136. struct module_exports exports= {
  137. "xlog",
  138. DEFAULT_DLFLAGS, /* dlopen flags */
  139. cmds,
  140. params,
  141. 0, /* exported statistics */
  142. 0 , /* exported MI functions */
  143. mod_items, /* exported pseudo-variables */
  144. 0, /* extra processes */
  145. mod_init, /* module initialization function */
  146. 0,
  147. (destroy_function) destroy,
  148. 0 /* per-child init function */
  149. };
  150. /**
  151. * init module function
  152. */
  153. static int mod_init(void)
  154. {
  155. int lf;
  156. if(cfg_declare("xlog", xlog_cfg_def, &xlog_default_cfg,
  157. cfg_sizeof(xlog), &xlog_cfg)){
  158. LM_ERR("Fail to declare the xlog cfg framework structure\n");
  159. return -1;
  160. }
  161. if (xlog_facility_name!=NULL) {
  162. lf = str2facility(xlog_facility_name);
  163. if (lf != -1) {
  164. xlog_facility = lf;
  165. } else {
  166. LM_ERR("invalid syslog facility %s\n", xlog_facility_name);
  167. return -1;
  168. }
  169. }
  170. _xlog_buf = (char*)pkg_malloc((buf_size+1)*sizeof(char));
  171. if(_xlog_buf==NULL)
  172. {
  173. LM_ERR("no pkg memory left\n");
  174. return -1;
  175. }
  176. return 0;
  177. }
  178. static inline int xlog_helper(struct sip_msg* msg, xl_msg_t *xm,
  179. int level, int line, int facility)
  180. {
  181. str txt;
  182. txt.len = buf_size;
  183. if(xl_print_log(msg, xm->m, _xlog_buf, &txt.len)<0)
  184. return -1;
  185. txt.s = _xlog_buf;
  186. /* if facility is not explicitely defined use the xlog default facility */
  187. if (facility==NOFACILITY) {
  188. facility = xlog_facility;
  189. }
  190. if(line>0)
  191. if(long_format==1)
  192. LOG_(facility, level, _xlog_prefix,
  193. "%s:%d:%.*s",
  194. (xm->a)?(((xm->a->cfile)?xm->a->cfile:"")):"",
  195. (xm->a)?xm->a->cline:0, txt.len, txt.s);
  196. else
  197. LOG_(facility, level, _xlog_prefix,
  198. "%d:%.*s", (xm->a)?xm->a->cline:0, txt.len, txt.s);
  199. else
  200. LOG_(facility, level, _xlog_prefix,
  201. "%.*s", txt.len, txt.s);
  202. return 1;
  203. }
  204. /**
  205. * print log message to L_ERR level
  206. */
  207. static int xlog_1_helper(struct sip_msg* msg, char* frm, char* str2, int mode, int facility)
  208. {
  209. if(!is_printable(L_ERR))
  210. return 1;
  211. return xlog_helper(msg, (xl_msg_t*)frm, L_ERR, mode, facility);
  212. }
  213. static int xlog_1(struct sip_msg* msg, char* frm, char* str2)
  214. {
  215. return xlog_1_helper(msg, frm, str2, 0, NOFACILITY);
  216. }
  217. /**
  218. * print log message to L_ERR level along with cfg line
  219. */
  220. static int xlogl_1(struct sip_msg* msg, char* frm, char* str2)
  221. {
  222. return xlog_1_helper(msg, frm, str2, 1, NOFACILITY);
  223. }
  224. static int xlog_2_helper(struct sip_msg* msg, char* lev, char* frm, int mode, int facility)
  225. {
  226. long level;
  227. xl_level_p xlp;
  228. pv_value_t value;
  229. xlp = (xl_level_p)lev;
  230. if(xlp->type==1)
  231. {
  232. if(pv_get_spec_value(msg, &xlp->v.sp, &value)!=0
  233. || value.flags&PV_VAL_NULL || !(value.flags&PV_VAL_INT))
  234. {
  235. LM_ERR("invalid log level value [%d]\n", value.flags);
  236. return -1;
  237. }
  238. level = (long)value.ri;
  239. } else {
  240. level = xlp->v.level;
  241. }
  242. if(!is_printable((int)level))
  243. return 1;
  244. return xlog_helper(msg, (xl_msg_t*)frm, (int)level, mode, facility);
  245. }
  246. /**
  247. * print log message to level given in parameter
  248. */
  249. static int xlog_2(struct sip_msg* msg, char* lev, char* frm)
  250. {
  251. return xlog_2_helper(msg, lev, frm, 0, NOFACILITY);
  252. }
  253. /**
  254. * print log message to level given in parameter along with cfg line
  255. */
  256. static int xlogl_2(struct sip_msg* msg, char* lev, char* frm)
  257. {
  258. return xlog_2_helper(msg, lev, frm, 1, NOFACILITY);
  259. }
  260. /**
  261. * print log message to level given in parameter applying methods filter
  262. */
  263. static int xlogm_2(struct sip_msg* msg, char* lev, char* frm)
  264. {
  265. int mfilter;
  266. mfilter = cfg_get(xlog, xlog_cfg, methods_filter);
  267. if(mfilter==-1)
  268. return 1;
  269. if(msg->first_line.type==SIP_REQUEST) {
  270. if (msg->first_line.u.request.method_value & mfilter) {
  271. return 1;
  272. }
  273. } else {
  274. if (parse_headers(msg, HDR_CSEQ_F, 0) != 0 || msg->cseq==NULL) {
  275. LM_ERR("cannot parse cseq header\n");
  276. return -1;
  277. }
  278. if (get_cseq(msg)->method_id & mfilter) {
  279. return 1;
  280. }
  281. }
  282. return xlog_2_helper(msg, lev, frm, 0, NOFACILITY);
  283. }
  284. static int xlog_3_helper(struct sip_msg* msg, char* fac, char* lev, char* frm, int mode)
  285. {
  286. long level;
  287. int facility;
  288. xl_level_p xlp;
  289. pv_value_t value;
  290. xlp = (xl_level_p)lev;
  291. if(xlp->type==1)
  292. {
  293. if(pv_get_spec_value(msg, &xlp->v.sp, &value)!=0
  294. || value.flags&PV_VAL_NULL || !(value.flags&PV_VAL_INT))
  295. {
  296. LM_ERR("invalid log level value [%d]\n", value.flags);
  297. return -1;
  298. }
  299. level = (long)value.ri;
  300. } else {
  301. level = xlp->v.level;
  302. }
  303. facility = *(int*)fac;
  304. if(!is_printable((int)level))
  305. return 1;
  306. return xlog_helper(msg, (xl_msg_t*)frm, (int)level, mode, facility);
  307. }
  308. /**
  309. * print log message to level given in parameter
  310. * add dedicated logfacility
  311. */
  312. static int xlog_3(struct sip_msg* msg, char* fac, char* lev, char* frm)
  313. {
  314. return xlog_3_helper(msg, fac, lev, frm, 0);
  315. }
  316. /**
  317. * print log message to level given in parameter along with cfg line
  318. * add dedicated logfacility
  319. */
  320. static int xlogl_3(struct sip_msg* msg, char* fac, char* lev, char* frm)
  321. {
  322. return xlog_3_helper(msg, fac, lev, frm, 1);
  323. }
  324. static int xdbg_helper(struct sip_msg* msg, char* frm, char* str2, int mode, int facility)
  325. {
  326. if(!is_printable(L_DBG))
  327. return 1;
  328. return xlog_helper(msg, (xl_msg_t*)frm, L_DBG, mode, facility);
  329. }
  330. /**
  331. * print log message to L_DBG level
  332. */
  333. static int xdbg(struct sip_msg* msg, char* frm, char* str2)
  334. {
  335. return xdbg_helper(msg, frm, str2, 0, NOFACILITY);
  336. }
  337. /**
  338. * print log message to L_DBG level along with cfg line
  339. */
  340. static int xdbgl(struct sip_msg* msg, char* frm, char* str2)
  341. {
  342. return xdbg_helper(msg, frm, str2, 1, NOFACILITY);
  343. }
  344. /**
  345. * module destroy function
  346. */
  347. static void destroy(void)
  348. {
  349. if(_xlog_buf)
  350. pkg_free(_xlog_buf);
  351. }
  352. static int xdbg_fixup_helper(void** param, int param_no, int mode)
  353. {
  354. xl_msg_t *xm;
  355. str s;
  356. xm = (xl_msg_t*)pkg_malloc(sizeof(xl_msg_t));
  357. if(xm==NULL)
  358. {
  359. LM_ERR("no more pkg\n");
  360. return -1;
  361. }
  362. memset(xm, 0, sizeof(xl_msg_t));
  363. if(mode==1)
  364. xm->a = get_action_from_param(param, param_no);
  365. s.s = (char*)(*param); s.len = strlen(s.s);
  366. if(pv_parse_format(&s, &xm->m)<0)
  367. {
  368. LM_ERR("wrong format[%s]\n", (char*)(*param));
  369. return E_UNSPEC;
  370. }
  371. *param = (void*)xm;
  372. return 0;
  373. }
  374. static int xlog_fixup_helper(void** param, int param_no, int mode)
  375. {
  376. xl_level_p xlp;
  377. str s;
  378. if(param_no==1)
  379. {
  380. s.s = (char*)(*param);
  381. if(s.s==NULL || strlen(s.s)<2)
  382. {
  383. LM_ERR("wrong log level\n");
  384. return E_UNSPEC;
  385. }
  386. xlp = (xl_level_p)pkg_malloc(sizeof(xl_level_t));
  387. if(xlp == NULL)
  388. {
  389. LM_ERR("no more memory\n");
  390. return E_UNSPEC;
  391. }
  392. memset(xlp, 0, sizeof(xl_level_t));
  393. if(s.s[0]==PV_MARKER)
  394. {
  395. xlp->type = 1;
  396. s.len = strlen(s.s);
  397. if(pv_parse_spec(&s, &xlp->v.sp)==NULL)
  398. {
  399. LM_ERR("invalid level param\n");
  400. return E_UNSPEC;
  401. }
  402. } else {
  403. xlp->type = 0;
  404. switch(((char*)(*param))[2])
  405. {
  406. case 'A': xlp->v.level = L_ALERT; break;
  407. case 'B': xlp->v.level = L_BUG; break;
  408. case 'C': xlp->v.level = L_CRIT2; break;
  409. case 'E': xlp->v.level = L_ERR; break;
  410. case 'W': xlp->v.level = L_WARN; break;
  411. case 'N': xlp->v.level = L_NOTICE; break;
  412. case 'I': xlp->v.level = L_INFO; break;
  413. case 'D': xlp->v.level = L_DBG; break;
  414. default:
  415. LM_ERR("unknown log level\n");
  416. return E_UNSPEC;
  417. }
  418. }
  419. pkg_free(*param);
  420. *param = (void*)xlp;
  421. return 0;
  422. }
  423. if(param_no==2)
  424. return xdbg_fixup_helper(param, 2, mode);
  425. return 0;
  426. }
  427. /*
  428. * fixup log facility
  429. */
  430. static int xlog3_fixup_helper(void** param, int param_no)
  431. {
  432. int *facility;
  433. str s;
  434. s.s = (char*)(*param);
  435. if(s.s==NULL)
  436. {
  437. LM_ERR("wrong log facility\n");
  438. return E_UNSPEC;
  439. }
  440. facility = (int*)pkg_malloc(sizeof(int));
  441. if(facility == NULL)
  442. {
  443. LM_ERR("no more memory\n");
  444. return E_UNSPEC;
  445. }
  446. *facility = str2facility(s.s);
  447. if (*facility == -1) {
  448. LM_ERR("invalid syslog facility %s\n", s.s);
  449. pkg_free(facility);
  450. return E_UNSPEC;
  451. }
  452. pkg_free(*param);
  453. *param = (void*)facility;
  454. return 0;
  455. }
  456. static int xlog_fixup(void** param, int param_no)
  457. {
  458. if(param==NULL || *param==NULL)
  459. {
  460. LM_ERR("invalid parameter number %d\n", param_no);
  461. return E_UNSPEC;
  462. }
  463. return xlog_fixup_helper(param, param_no, 0);
  464. }
  465. static int xlog3_fixup(void** param, int param_no)
  466. {
  467. if(param==NULL || *param==NULL)
  468. {
  469. LM_ERR("invalid parameter number %d\n", param_no);
  470. return E_UNSPEC;
  471. }
  472. /* fixup loglevel */
  473. if (param_no == 2) {
  474. return xlog_fixup_helper(param, 1, 0);
  475. }
  476. /* fixup log message */
  477. if (param_no == 3) {
  478. return xdbg_fixup_helper(param, 3, 0);
  479. }
  480. /* fixup facility */
  481. return xlog3_fixup_helper(param, param_no);
  482. }
  483. static int xdbg_fixup(void** param, int param_no)
  484. {
  485. if(param_no!=1 || param==NULL || *param==NULL)
  486. {
  487. LM_ERR("invalid parameter number %d\n", param_no);
  488. return E_UNSPEC;
  489. }
  490. return xdbg_fixup_helper(param, param_no, 0);
  491. }
  492. static int xlogl3_fixup(void** param, int param_no)
  493. {
  494. if(param==NULL || *param==NULL)
  495. {
  496. LM_ERR("invalid parameter number %d\n", param_no);
  497. return E_UNSPEC;
  498. }
  499. /* fixup loglevel */
  500. if (param_no == 2) {
  501. return xlog_fixup_helper(param, 1, 1);
  502. }
  503. /* fixup log message */
  504. if (param_no == 3) {
  505. return xdbg_fixup_helper(param, 3, 1);
  506. }
  507. /* fixup facility */
  508. return xlog3_fixup_helper(param, param_no);
  509. }
  510. static int xlogl_fixup(void** param, int param_no)
  511. {
  512. if(param==NULL || *param==NULL)
  513. {
  514. LM_ERR("invalid parameter number %d\n", param_no);
  515. return E_UNSPEC;
  516. }
  517. return xlog_fixup_helper(param, param_no, 1);
  518. }
  519. static int xdbgl_fixup(void** param, int param_no)
  520. {
  521. if(param_no!=1 || param==NULL || *param==NULL)
  522. {
  523. LM_ERR("invalid parameter number %d\n", param_no);
  524. return E_UNSPEC;
  525. }
  526. return xdbg_fixup_helper(param, param_no, 1);
  527. }
  528. int pv_parse_color_name(pv_spec_p sp, str *in)
  529. {
  530. if(in==NULL || in->s==NULL || sp==NULL)
  531. return -1;
  532. if(in->len != 2)
  533. {
  534. LM_ERR("color name must have two chars\n");
  535. return -1;
  536. }
  537. /* foreground */
  538. switch(in->s[0])
  539. {
  540. case 'x':
  541. case 's': case 'r': case 'g':
  542. case 'y': case 'b': case 'p':
  543. case 'c': case 'w': case 'S':
  544. case 'R': case 'G': case 'Y':
  545. case 'B': case 'P': case 'C':
  546. case 'W':
  547. break;
  548. default:
  549. goto error;
  550. }
  551. /* background */
  552. switch(in->s[1])
  553. {
  554. case 'x':
  555. case 's': case 'r': case 'g':
  556. case 'y': case 'b': case 'p':
  557. case 'c': case 'w':
  558. break;
  559. default:
  560. goto error;
  561. }
  562. sp->pvp.pvn.type = PV_NAME_INTSTR;
  563. sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
  564. sp->pvp.pvn.u.isname.name.s = *in;
  565. sp->getf = pv_get_color;
  566. /* force the color PV type */
  567. sp->type = PVT_COLOR;
  568. return 0;
  569. error:
  570. LM_ERR("invalid color name\n");
  571. return -1;
  572. }
  573. static int pv_get_color(struct sip_msg *msg, pv_param_t *param,
  574. pv_value_t *res)
  575. {
  576. str s = {"", 0};
  577. if(log_stderr==0 && force_color==0)
  578. {
  579. LM_DBG("ignoring colors\n");
  580. return pv_get_strval(msg, param, res, &s);
  581. }
  582. dprint_term_color(param->pvn.u.isname.name.s.s[0],
  583. param->pvn.u.isname.name.s.s[1], &s);
  584. return pv_get_strval(msg, param, res, &s);
  585. }
  586. /**
  587. *
  588. */
  589. static int xlog_log_colors_param(modparam_t type, void *val)
  590. {
  591. param_t* params_list = NULL;
  592. param_hooks_t phooks;
  593. param_t *pit=NULL;
  594. str s;
  595. int level;
  596. if(val==NULL)
  597. goto error;
  598. s.s = (char*)val;
  599. s.len = strlen(s.s);
  600. if(s.len<=0)
  601. goto error;
  602. if(s.s[s.len-1]==';')
  603. s.len--;
  604. if (parse_params(&s, CLASS_ANY, &phooks, &params_list)<0)
  605. goto error;
  606. for (pit = params_list; pit; pit=pit->next)
  607. {
  608. if (pit->name.len==7
  609. && strncasecmp(pit->name.s, "l_alert", 7)==0) {
  610. level = L_ALERT;
  611. } else if (pit->name.len==5
  612. && strncasecmp(pit->name.s, "l_bug", 5)==0) {
  613. level = L_BUG;
  614. } else if (pit->name.len==7
  615. && strncasecmp(pit->name.s, "l_crit2", 7)==0) {
  616. level = L_CRIT2;
  617. } else if (pit->name.len==6
  618. && strncasecmp(pit->name.s, "l_crit", 6)==0) {
  619. level = L_CRIT;
  620. } else if (pit->name.len==5
  621. && strncasecmp(pit->name.s, "l_err", 5)==0) {
  622. level = L_ERR;
  623. } else if (pit->name.len==6
  624. && strncasecmp(pit->name.s, "l_warn", 6)==0) {
  625. level = L_WARN;
  626. } else if (pit->name.len==8
  627. && strncasecmp(pit->name.s, "l_notice", 8)==0) {
  628. level = L_NOTICE;
  629. } else if (pit->name.len==6
  630. && strncasecmp(pit->name.s, "l_info", 6)==0) {
  631. level = L_INFO;
  632. } else if (pit->name.len==5
  633. && strncasecmp(pit->name.s, "l_dbg", 5)==0) {
  634. level = L_DBG;
  635. } else {
  636. LM_ERR("invalid level name %.*s\n",
  637. pit->name.len, pit->name.s);
  638. goto error;
  639. }
  640. if(pit->body.len!=2) {
  641. LM_ERR("invalid color spec for level %.*s (%.*s)\n",
  642. pit->name.len, pit->name.s,
  643. pit->body.len, pit->body.s);
  644. goto error;
  645. }
  646. dprint_color_update(level, pit->body.s[0], pit->body.s[1]);
  647. }
  648. if(params_list!=NULL)
  649. free_params(params_list);
  650. return 0;
  651. error:
  652. if(params_list!=NULL)
  653. free_params(params_list);
  654. return -1;
  655. }