cpl_parser.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio 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. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <fcntl.h>
  28. #include <errno.h>
  29. #include <unistd.h>
  30. #include <libxml/xmlmemory.h>
  31. #include <libxml/parser.h>
  32. #include "../../parser/parse_uri.h"
  33. #include "../../trim.h"
  34. #include "../../dprint.h"
  35. #include "../../str.h"
  36. #include "../../ut.h"
  37. #include "CPL_tree.h"
  38. #include "sub_list.h"
  39. #include "cpl_log.h"
  40. static struct node *list = 0;
  41. static xmlDtdPtr dtd; /* DTD file */
  42. static xmlValidCtxt cvp; /* validating context */
  43. typedef unsigned short length_type ;
  44. typedef length_type* length_type_ptr;
  45. enum {EMAIL_TO,EMAIL_HDR_NAME,EMAIL_KNOWN_HDR_BODY,EMAIL_UNKNOWN_HDR_BODY};
  46. #define ENCONDING_BUFFER_SIZE 65536
  47. #define FOR_ALL_ATTR(_node,_attr) \
  48. for( (_attr)=(_node)->properties ; (_attr) ; (_attr)=(_attr)->next)
  49. #define check_overflow(_p_,_offset_,_end_,_error_) \
  50. do{\
  51. if ((_p_)+(_offset_)>=(_end_)) { \
  52. LM_ERR("%s:%d: overflow -> buffer to small\n",\
  53. __FILE__,__LINE__);\
  54. goto _error_;\
  55. }\
  56. }while(0)\
  57. #define set_attr_type(_p_,_type_,_end_,_error_) \
  58. do{\
  59. check_overflow(_p_,sizeof(length_type),_end_,_error_);\
  60. *((length_type_ptr)(_p_)) = htons((length_type)(_type_));\
  61. (_p_) += sizeof(length_type);\
  62. }while(0)\
  63. #define append_short_attr(_p_,_n_,_end_,_error_) \
  64. do{\
  65. check_overflow(_p_,sizeof(length_type),_end_,_error_);\
  66. *((length_type_ptr)(_p_)) = htons((length_type)(_n_));\
  67. (_p_) += sizeof(length_type);\
  68. }while(0)
  69. #define append_str_attr(_p_,_s_,_end_,_error_) \
  70. do{\
  71. check_overflow(_p_,(_s_).len + 1*((((_s_).len)&0x0001)==1),\
  72. _end_,_error_);\
  73. *((length_type_ptr)(_p_)) = htons((length_type)(_s_).len);\
  74. (_p_) += sizeof(length_type);\
  75. memcpy( (_p_), (_s_).s, (_s_).len);\
  76. (_p_) += (_s_).len + 1*((((_s_).len)&0x0001)==1);\
  77. }while(0)
  78. #define append_double_str_attr(_p_,_s1_,_s2_,_end_,_error_) \
  79. do{\
  80. check_overflow(_p_,(_s1_).len + (_s2_).len +\
  81. 1*((((_s2_).len+(_s2_).len)&0x0001)==1), _end_, _error_);\
  82. *((length_type_ptr)(_p_))=htons((length_type)((_s1_).len)+(_s2_).len);\
  83. (_p_) += sizeof(length_type);\
  84. memcpy( (_p_), (_s1_).s, (_s1_).len);\
  85. (_p_) += (_s1_).len;\
  86. memcpy( (_p_), (_s2_).s, (_s2_).len);\
  87. (_p_) += (_s2_).len + 1*((((_s1_).len+(_s2_).len)&0x0001)==1);\
  88. }while(0)
  89. #define get_attr_val(_attr_name_,_val_,_error_) \
  90. do { \
  91. (_val_).s = (char*)xmlGetProp(node,(_attr_name_));\
  92. (_val_).len = strlen((_val_).s);\
  93. /* remove all spaces from begin and end */\
  94. trim_spaces_lr( (_val_) );\
  95. if ((_val_).len==0) {\
  96. LM_ERR("%s:%d: attribute <%s> has an "\
  97. "empty value\n",__FILE__,__LINE__,(_attr_name_));\
  98. goto _error_;\
  99. }\
  100. }while(0)\
  101. #define MAX_EMAIL_HDR_SIZE 7 /*we are looking only for SUBJECT and BODY ;-)*/
  102. #define MAX_EMAIL_BODY_SIZE 512
  103. #define MAX_EMAIL_SUBJECT_SIZE 32
  104. static inline char *decode_mail_url(char *p, char *p_end, char *url,
  105. unsigned char *nr_attr)
  106. {
  107. static char buf[ MAX_EMAIL_HDR_SIZE ];
  108. char c;
  109. char foo;
  110. unsigned short hdr_len;
  111. unsigned short *len;
  112. int max_len;
  113. int status;
  114. /* init */
  115. hdr_len = 0;
  116. max_len = 0;
  117. status = EMAIL_TO;
  118. (*nr_attr) ++;
  119. set_attr_type(p, TO_ATTR, p_end, error); /* attr type */
  120. len = ((unsigned short*)(p)); /* attr val's len */
  121. *len = 0; /* init the len */
  122. p += 2;
  123. /* parse the whole url */
  124. do {
  125. /* extract a char from the encoded url */
  126. if (*url=='+') {
  127. /* substitute a blank for a plus */
  128. c=' ';
  129. url++;
  130. /* Look for a hex encoded character */
  131. } else if ( (*url=='%') && *(url+1) && *(url+2) ) {
  132. /* hex encoded - convert to a char */
  133. c = hex2int(url[1]);
  134. foo = hex2int(url[2]);
  135. if (c==-1 || foo==-1) {
  136. LM_ERR("non-ASCII escaped "
  137. "character in mail url [%.*s]\n", 3, url);
  138. goto error;
  139. }
  140. c = c<<4 | foo;
  141. url += 3;
  142. } else {
  143. /* normal character - just copy it without changing */
  144. c = *url;
  145. url++;
  146. }
  147. /* finally we got a character !! */
  148. switch (c) {
  149. case '?':
  150. switch (status) {
  151. case EMAIL_TO:
  152. if (*len==0) {
  153. LM_ERR("empty TO "
  154. "address found in MAIL node!\n");
  155. goto error;
  156. }
  157. if (((*len)&0x0001)==1) p++;
  158. *len = htons(*len);
  159. hdr_len = 0;
  160. status = EMAIL_HDR_NAME;
  161. break;
  162. default: goto parse_error;
  163. }
  164. break;
  165. case '=':
  166. switch (status) {
  167. case EMAIL_HDR_NAME:
  168. LM_DBG("hdr [%.*s] found\n",
  169. hdr_len,buf);
  170. if ( hdr_len==BODY_EMAILHDR_LEN &&
  171. strncasecmp(buf,BODY_EMAILHDR_STR,hdr_len)==0 ) {
  172. /* BODY hdr found */
  173. set_attr_type( p, BODY_ATTR, p_end, error);
  174. max_len = MAX_EMAIL_BODY_SIZE;
  175. } else if ( hdr_len==SUBJECT_EMAILHDR_LEN &&
  176. strncasecmp(buf,SUBJECT_EMAILHDR_STR,hdr_len)==0 ) {
  177. /* SUBJECT hdr found */
  178. set_attr_type( p, SUBJECT_ATTR, p_end, error);
  179. max_len = MAX_EMAIL_SUBJECT_SIZE;
  180. } else {
  181. LM_DBG("unknown hdr -> ignoring\n");
  182. status = EMAIL_UNKNOWN_HDR_BODY;
  183. break;
  184. }
  185. (*nr_attr) ++;
  186. len = ((unsigned short*)(p)); /* attr val's len */
  187. *len = 0; /* init the len */
  188. p += 2;
  189. status = EMAIL_KNOWN_HDR_BODY;
  190. break;
  191. default: goto parse_error;
  192. }
  193. break;
  194. case '&':
  195. switch (status) {
  196. case EMAIL_KNOWN_HDR_BODY:
  197. if (((*len)&0x0001)==1) p++;
  198. *len = htons(*len);
  199. case EMAIL_UNKNOWN_HDR_BODY:
  200. hdr_len = 0;
  201. status = EMAIL_HDR_NAME;
  202. break;
  203. default: goto parse_error;
  204. }
  205. break;
  206. case 0:
  207. switch (status) {
  208. case EMAIL_TO:
  209. if (*len==0) {
  210. LM_ERR("empty TO "
  211. "address found in MAIL node!\n");
  212. goto error;
  213. }
  214. case EMAIL_KNOWN_HDR_BODY:
  215. if (((*len)&0x0001)==1) p++;
  216. *len = htons(*len);
  217. case EMAIL_UNKNOWN_HDR_BODY:
  218. break;
  219. default: goto parse_error;
  220. }
  221. break;
  222. default:
  223. switch (status) {
  224. case EMAIL_TO:
  225. (*len)++;
  226. *(p++) = c;
  227. if (*len==URL_MAILTO_LEN &&
  228. !strncasecmp(p-(*len),URL_MAILTO_STR,(*len))) {
  229. LM_DBG("MAILTO: found at"
  230. " the beginning of TO -> removed\n");
  231. p -= (*len);
  232. *len = 0;
  233. }
  234. break;
  235. case EMAIL_KNOWN_HDR_BODY:
  236. if ((*len)<max_len) (*len)++;
  237. *(p++) = c;
  238. break;
  239. case EMAIL_HDR_NAME:
  240. if (hdr_len<MAX_EMAIL_HDR_SIZE) hdr_len++;
  241. buf[hdr_len-1] = c;
  242. break;
  243. case EMAIL_UNKNOWN_HDR_BODY:
  244. /* do nothing */
  245. break;
  246. default : goto parse_error;
  247. }
  248. }
  249. }while(c!=0);
  250. return p;
  251. parse_error:
  252. LM_ERR("unexpected char [%c] in state %d"
  253. " in email url \n",*url,status);
  254. error:
  255. return 0;
  256. }
  257. /* Attr. encoding for ADDRESS node:
  258. * | attr_t(2) attr_len(2) attr_val(2*x) | IS/CONTAINS/SUBDOMAIN_OF attr (NT)
  259. */
  260. static inline int encode_address_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  261. {
  262. xmlAttrPtr attr;
  263. char *p, *p_orig;
  264. unsigned char *nr_attr;
  265. str val;
  266. nr_attr = &(NR_OF_ATTR(node_ptr));
  267. *nr_attr = 0;
  268. p = p_orig = ATTR_PTR(node_ptr);
  269. FOR_ALL_ATTR(node,attr) {
  270. (*nr_attr)++;
  271. switch (attr->name[0]) {
  272. case 'i': case 'I':
  273. set_attr_type(p, IS_ATTR, buf_end, error);
  274. break;
  275. case 'c': case 'C':
  276. set_attr_type(p, CONTAINS_ATTR, buf_end, error);
  277. break;
  278. case 's': case 'S':
  279. set_attr_type(p, SUBDOMAIN_OF_ATTR, buf_end, error);
  280. break;
  281. default:
  282. LM_ERR("unknown attribute "
  283. "<%s>\n",attr->name);
  284. goto error;
  285. }
  286. /* get the value of the attribute */
  287. get_attr_val( attr->name , val, error);
  288. /* copy also the \0 from the end of string */
  289. val.len++;
  290. append_str_attr(p, val, buf_end, error);
  291. }
  292. return p-p_orig;
  293. error:
  294. return -1;
  295. }
  296. /* Attr. encoding for ADDRESS_SWITCH node:
  297. * | attr1_t(2) attr1_val(2) | FIELD attr
  298. * [| attr2_t(2) attr2_val(2) |]? SUBFILED attr
  299. */
  300. static inline int encode_address_switch_attr(xmlNodePtr node, char *node_ptr,
  301. char *buf_end)
  302. {
  303. xmlAttrPtr attr;
  304. char *p, *p_orig;
  305. unsigned char *nr_attr;
  306. str val;
  307. nr_attr = &(NR_OF_ATTR(node_ptr));
  308. *nr_attr = 0;
  309. p = p_orig = ATTR_PTR(node_ptr);
  310. FOR_ALL_ATTR(node,attr) {
  311. (*nr_attr)++;
  312. /* get the value of the attribute */
  313. get_attr_val( attr->name , val, error);
  314. switch(attr->name[0]) {
  315. case 'F': case 'f':
  316. set_attr_type(p, FIELD_ATTR, buf_end, error);
  317. if (val.s[0]=='D' || val.s[0]=='d')
  318. append_short_attr(p, DESTINATION_VAL, buf_end, error);
  319. else if (val.s[6]=='A' || val.s[6]=='a')
  320. append_short_attr(p,ORIGINAL_DESTINATION_VAL,buf_end,error);
  321. else if (!val.s[6])
  322. append_short_attr(p, ORIGIN_VAL, buf_end, error);
  323. else {
  324. LM_ERR("unknown"
  325. " value <%s> for FIELD attr\n",val.s);
  326. goto error;
  327. };
  328. break;
  329. case 'S': case 's':
  330. set_attr_type(p, SUBFIELD_ATTR, buf_end, error);
  331. switch (val.s[0]) {
  332. case 'u': case 'U':
  333. append_short_attr(p, USER_VAL, buf_end, error);
  334. break;
  335. case 'h': case 'H':
  336. append_short_attr(p, HOST_VAL, buf_end, error);
  337. break;
  338. case 'p': case 'P':
  339. append_short_attr(p, PORT_VAL, buf_end, error);
  340. break;
  341. case 't': case 'T':
  342. append_short_attr(p, TEL_VAL, buf_end, error);
  343. break;
  344. case 'd': case 'D':
  345. /*append_short_attr(p, DISPLAY_VAL, buf_end, error);
  346. break;*/ /* NOT YET SUPPORTED BY INTERPRETER */
  347. case 'a': case 'A':
  348. /*append_short_attr(p, ADDRESS_TYPE_VAL, buf_end,error);
  349. break;*/ /* NOT YET SUPPORTED BY INTERPRETER */
  350. default:
  351. LM_ERR("unknown value <%s> for SUBFIELD attr\n",val.s);
  352. goto error;
  353. }
  354. break;
  355. default:
  356. LM_ERR("unknown attribute <%s>\n",attr->name);
  357. goto error;
  358. }
  359. }
  360. return p-p_orig;
  361. error:
  362. return -1;
  363. }
  364. /* Attr. encoding for LANGUAGE node:
  365. * | attr_t(2) attr_len(2) attr_val(2*x) | MATCHES attr (NNT)
  366. */
  367. static inline int encode_lang_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  368. {
  369. xmlAttrPtr attr;
  370. char *p, *p_orig;
  371. unsigned char *nr_attr;
  372. char *end;
  373. char *val_bk;
  374. str val;
  375. nr_attr = &(NR_OF_ATTR(node_ptr));
  376. *nr_attr = 0;
  377. p = p_orig = ATTR_PTR(node_ptr);
  378. FOR_ALL_ATTR(node,attr) {
  379. /* there is only one attribute -> MATCHES */
  380. if (attr->name[0]!='M' && attr->name[0]!='m') {
  381. LM_ERR("unknown attribute "
  382. "<%s>\n",attr->name);
  383. goto error;
  384. }
  385. val.s = val_bk = (char*)xmlGetProp(node,attr->name);
  386. /* parse the language-tag */
  387. for(end=val.s,val.len=0;;end++) {
  388. /* trim all spaces from the beginning of the tag */
  389. if (!val.len && (*end==' ' || *end=='\t')) continue;
  390. /* we cannot have more than 2 attrs - LANG_TAG and LANG_SUBTAG */
  391. if ((*nr_attr)>=2) goto lang_error;
  392. if (((*end)|0x20)>='a' && ((*end)|0x20)<='z') {
  393. val.len++; continue;
  394. } else if (*end=='*' && val.len==0 && (*nr_attr)==0 &&
  395. (*end==' '|| *end=='\t' || *end==0)) {
  396. val.len++;
  397. set_attr_type(p, MATCHES_TAG_ATTR, buf_end, error);
  398. } else if (val.len && (*nr_attr)==0 && *end=='-' ) {
  399. set_attr_type(p, MATCHES_TAG_ATTR, buf_end, error);
  400. } else if (val.len && ((*nr_attr)==0 || (*nr_attr)==1) &&
  401. (*end==' '|| *end=='\t' || *end==0)) {
  402. set_attr_type(p,
  403. (!(*nr_attr))?MATCHES_TAG_ATTR:MATCHES_SUBTAG_ATTR,
  404. buf_end, error );
  405. } else goto lang_error;
  406. (*nr_attr)++;
  407. /*LM_DBG("----> language tag=%d; %d [%.*s]\n",*(p-1),
  408. val.len,val.len,end-val.len);*/
  409. val.s = end-val.len;
  410. append_str_attr(p, val, buf_end, error);
  411. val.len = 0;
  412. if (*end==0) break;
  413. }
  414. }
  415. return p-p_orig;
  416. lang_error:
  417. LM_ERR("bad value for language_tag <%s>\n",val_bk);
  418. error:
  419. return -1;
  420. }
  421. /* Attr. encoding for PRIORITY node:
  422. * | attr1_t(2) attr1_val(2) | LESS/GREATER/EQUAL attr
  423. * [| attr2_t(2) attr2_len(2) attr_val(2*x) |]? PRIOSTR attr (NT)
  424. */
  425. static inline int encode_priority_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  426. {
  427. xmlAttrPtr attr;
  428. char *p, *p_orig;
  429. unsigned char *nr_attr;
  430. str val;
  431. nr_attr = &(NR_OF_ATTR(node_ptr));
  432. *nr_attr = 0;
  433. p = p_orig = ATTR_PTR(node_ptr);
  434. FOR_ALL_ATTR(node,attr) {
  435. (*nr_attr)++;
  436. /* attribute's name */
  437. switch(attr->name[0]) {
  438. case 'L': case 'l':
  439. set_attr_type(p, LESS_ATTR, buf_end, error);
  440. break;
  441. case 'G': case 'g':
  442. set_attr_type(p, GREATER_ATTR, buf_end, error);
  443. break;
  444. case 'E': case 'e':
  445. set_attr_type(p, EQUAL_ATTR, buf_end, error);
  446. break;
  447. default:
  448. LM_ERR("unknown attribute <%s>\n",attr->name);
  449. goto error;
  450. }
  451. /* attribute's encoded value */
  452. get_attr_val( attr->name , val, error);
  453. if ( val.len==EMERGENCY_STR_LEN &&
  454. !strncasecmp(val.s,EMERGENCY_STR,val.len) ) {
  455. append_short_attr(p, EMERGENCY_VAL, buf_end, error);
  456. } else if ( val.len==URGENT_STR_LEN &&
  457. !strncasecmp(val.s,URGENT_STR,val.len) ) {
  458. append_short_attr(p, URGENT_VAL, buf_end, error);
  459. } else if ( val.len==NORMAL_STR_LEN &&
  460. !strncasecmp(val.s,NORMAL_STR,val.len) ) {
  461. append_short_attr(p, NORMAL_VAL, buf_end, error);
  462. } else if ( val.len==NON_URGENT_STR_LEN &&
  463. !strncasecmp(val.s,NON_URGENT_STR,val.len) ) {
  464. append_short_attr(p, NON_URGENT_VAL, buf_end, error);
  465. } else {
  466. append_short_attr(p, UNKNOWN_PRIO_VAL, buf_end, error);
  467. set_attr_type(p, PRIOSTR_ATTR, buf_end, error);
  468. val.len++; /* append \0 also */
  469. append_str_attr(p, val, buf_end, error);
  470. }
  471. }
  472. return p-p_orig;
  473. error:
  474. return -1;
  475. }
  476. /* Attr. encoding for STRING_SWITCH node:
  477. * [| attr1_t(2) attr1_len(2) attr_val(2*x) |]? IS attr (NT)
  478. * [| attr2_t(2) attr2_len(2) attr_val(2*x) |]? CONTAINS attr (NT)
  479. */
  480. static inline int encode_string_switch_attr(xmlNodePtr node, char *node_ptr,
  481. char *buf_end)
  482. {
  483. xmlAttrPtr attr;
  484. char *p, *p_orig;
  485. unsigned char *nr_attr;
  486. str val;
  487. nr_attr = &(NR_OF_ATTR(node_ptr));
  488. *nr_attr = 0;
  489. p = p_orig = ATTR_PTR(node_ptr);
  490. FOR_ALL_ATTR(node,attr) {
  491. (*nr_attr)++;
  492. /* there is only one attribute -> MATCHES */
  493. if (attr->name[0]!='F' && attr->name[0]!='f') {
  494. LM_ERR("unknown attribute <%s>\n",attr->name);
  495. goto error;
  496. }
  497. set_attr_type(p, FIELD_ATTR, buf_end, error);
  498. /* attribute's encoded value */
  499. get_attr_val( attr->name , val, error);
  500. switch (val.s[0]) {
  501. case 'S': case 's':
  502. append_short_attr(p, SUBJECT_VAL, buf_end, error);
  503. break;
  504. case 'O': case 'o':
  505. append_short_attr(p, ORGANIZATION_VAL, buf_end, error);
  506. break;
  507. case 'U': case 'u':
  508. append_short_attr(p, USER_AGENT_VAL, buf_end, error);
  509. break;
  510. case 'D': case 'd':
  511. append_short_attr(p, DISPLAY_VAL, buf_end, error);
  512. break;
  513. default:
  514. LM_ERR("unknown "
  515. "value <%s> for FIELD\n",attr->name);
  516. goto error;
  517. }
  518. }
  519. return p-p_orig;
  520. error:
  521. return -1;
  522. }
  523. /* Attr. encoding for STRING node:
  524. * [| attr1_t(2) attr1_len(2) attr_val(2*x) |]? IS attr (NT)
  525. * [| attr2_t(2) attr2_len(2) attr_val(2*x) |]? CONTAINS attr (NT)
  526. */
  527. static inline int encode_string_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  528. {
  529. xmlAttrPtr attr;
  530. char *p, *p_orig;
  531. unsigned char *nr_attr;
  532. str val;
  533. nr_attr = &(NR_OF_ATTR(node_ptr));
  534. *nr_attr = 0;
  535. p = p_orig = ATTR_PTR(node_ptr);
  536. FOR_ALL_ATTR(node,attr) {
  537. (*nr_attr)++;
  538. switch(attr->name[0]) {
  539. case 'I': case 'i':
  540. set_attr_type(p, IS_ATTR, buf_end, error);
  541. break;
  542. case 'C': case 'c':
  543. set_attr_type(p, CONTAINS_ATTR, buf_end, error);
  544. break;
  545. default:
  546. LM_ERR("unknown "
  547. "attribute <%s>\n",attr->name);
  548. goto error;
  549. }
  550. /* attribute's encoded value */
  551. get_attr_val( attr->name , val, error);
  552. val.len++; /* grab also the \0 */
  553. append_str_attr(p,val, buf_end, error);
  554. }
  555. return p-p_orig;
  556. error:
  557. return -1;
  558. }
  559. /* Attr. encoding for TIME_SWITCH node:
  560. * [| attr1_t(2) attr1_len(2) attr_val(2*x) |]? TZID attr (NT)
  561. * [| attr2_t(2) attr2_len(2) attr_val(2*x) |]? TZURL attr (NT)
  562. */
  563. static inline int encode_time_switch_attr(xmlNodePtr node, char *node_ptr,
  564. char *buf_end)
  565. {
  566. static str tz_str = {"TZ=",3};
  567. xmlAttrPtr attr;
  568. char *p, *p_orig;
  569. unsigned char *nr_attr;
  570. str val;
  571. nr_attr = &(NR_OF_ATTR(node_ptr));
  572. *nr_attr = 0;
  573. p = p_orig = ATTR_PTR(node_ptr);
  574. FOR_ALL_ATTR(node,attr) {
  575. (*nr_attr)++;
  576. switch(attr->name[2]) {
  577. case 'I': case 'i':
  578. set_attr_type(p, TZID_ATTR, buf_end, error);
  579. /* attribute's encoded value */
  580. get_attr_val( attr->name , val, error);
  581. val.len++; /* grab also the \0 */
  582. append_double_str_attr(p,tz_str,val, buf_end, error);
  583. break;
  584. case 'U': case 'u':
  585. /* set_attr_type(p, TZURL_ATTR, buf_end, error);
  586. * is a waste of space to copy the url - the interpreter doesn't
  587. * use it at all ;-) */
  588. break;
  589. default:
  590. LM_ERR("unknown attribute <%s>\n",attr->name);
  591. goto error;
  592. }
  593. }
  594. return p-p_orig;
  595. error:
  596. return -1;
  597. }
  598. /* Attr. encoding for TIME node:
  599. * | attr1_t(2) attr1_len(2) attr1_val(2*x) | DSTART attr (NT)
  600. * [| attr2_t(2) attr2_len(2) attr2_val(2*x) |]? DTEND attr (NT)
  601. * [| attr3_t(2) attr3_len(2) attr3_val(2*x) |]? DURATION attr (NT)
  602. * [| attr4_t(2) attr4_len(2) attr4_val(2*x) |]? FREQ attr (NT)
  603. * [| attr5_t(2) attr5_len(2) attr5_val(2*x) |]? WKST attr (NT)
  604. * [| attr6_t(2) attr6_len(2) attr6_val(2*x) |]? BYYEARDAY attr (NT)
  605. * [| attr7_t(2) attr7_len(2) attr7_val(2*x) |]? COUNT attr (NT)
  606. * [| attr8_t(2) attr8_len(2) attr8_val(2*x) |]? BYSETPOS attr (NT)
  607. * [| attr9_t(2) attr9_len(2) attr9_val(2*x) |]? BYMONTH attr (NT)
  608. * [| attr10_t(2) attr10_len(2) attr_val10(2*x) |]? BYMONTHDAY attr (NT)
  609. * [| attr11_t(2) attr11_len(2) attr_val11(2*x) |]? BYMINUTE attr (NT)
  610. * [| attr12_t(2) attr12_len(2) attr_val12(2*x) |]? INTERVAL attr (NT)
  611. * [| attr13_t(2) attr13_len(2) attr_val13(2*x) |]? UNTIL attr (NT)
  612. * [| attr14_t(2) attr14_len(2) attr_val14(2*x) |]? BYSECOND attr (NT)
  613. * [| attr15_t(2) attr15_len(2) attr_val15(2*x) |]? BYHOUR attr (NT)
  614. * [| attr16_t(2) attr16_len(2) attr_val16(2*x) |]? BYDAY attr (NT)
  615. * [| attr17_t(2) attr17_len(2) attr_val17(2*x) |]? BYWEEKNO attr (NT)
  616. */
  617. static inline int encode_time_attr(xmlNodePtr node, char *node_ptr,
  618. char *buf_end)
  619. {
  620. xmlAttrPtr attr;
  621. char *p, *p_orig;
  622. unsigned char *nr_attr;
  623. str val;
  624. nr_attr = &(NR_OF_ATTR(node_ptr));
  625. *nr_attr = 0;
  626. p = p_orig = ATTR_PTR(node_ptr);
  627. FOR_ALL_ATTR(node,attr) {
  628. (*nr_attr)++;
  629. switch (attr->name[4]) {
  630. case 0:
  631. if (attr->name[0]=='F' || attr->name[0]=='f')
  632. set_attr_type(p, FREQ_ATTR, buf_end, error);
  633. else if (attr->name[0]=='W' || attr->name[0]=='w')
  634. set_attr_type(p, WKST_ATTR, buf_end, error);
  635. break;
  636. case 'a': case 'A':
  637. if (attr->name[0]=='D' || attr->name[0]=='d')
  638. set_attr_type(p, DTSTART_ATTR, buf_end, error);
  639. else if (attr->name[0]=='B' || attr->name[0]=='b')
  640. set_attr_type(p, BYYEARDAY_ATTR, buf_end, error);
  641. break;
  642. case 't': case 'T':
  643. if (attr->name[0]=='D' || attr->name[0]=='d')
  644. set_attr_type(p, DURATION_ATTR, buf_end, error);
  645. else if (attr->name[0]=='C' || attr->name[0]=='c')
  646. set_attr_type(p, COUNT_ATTR, buf_end, error);
  647. else if (attr->name[0]=='B' || attr->name[0]=='b')
  648. set_attr_type(p, BYSETPOS_ATTR, buf_end, error);
  649. break;
  650. case 'n': case 'N':
  651. if (!attr->name[7])
  652. set_attr_type(p, BYMONTH_ATTR, buf_end, error);
  653. else if (attr->name[7]=='D' || attr->name[7]=='d')
  654. set_attr_type(p, BYMONTHDAY_ATTR, buf_end, error);
  655. else if (attr->name[7]=='e' || attr->name[7]=='E')
  656. set_attr_type(p, BYMINUTE_ATTR, buf_end, error);
  657. break;
  658. case 'd': case 'D':
  659. set_attr_type(p, DTEND_ATTR, buf_end, error);
  660. break;
  661. case 'r': case 'R':
  662. set_attr_type(p, INTERVAL_ATTR, buf_end, error);
  663. break;
  664. case 'l': case 'L':
  665. set_attr_type(p, UNTIL_ATTR, buf_end, error);
  666. break;
  667. case 'c': case 'C':
  668. set_attr_type(p, BYSECOND_ATTR, buf_end, error);
  669. break;
  670. case 'u': case 'U':
  671. set_attr_type(p, BYHOUR_ATTR, buf_end, error);
  672. break;
  673. case 'y': case 'Y':
  674. set_attr_type(p, BYDAY_ATTR, buf_end, error);
  675. break;
  676. case 'e': case 'E':
  677. set_attr_type(p, BYWEEKNO_ATTR, buf_end, error);
  678. break;
  679. default:
  680. LM_ERR("unknown attribute <%s>\n",attr->name);
  681. goto error;
  682. }
  683. /* attribute's encoded value */
  684. get_attr_val( attr->name , val, error);
  685. val.len++; /* grab also the \0 */
  686. append_str_attr(p,val, buf_end, error);
  687. }
  688. return p-p_orig;
  689. error:
  690. return -1;
  691. }
  692. /* Attr. encoding for LOOKUP node:
  693. * | attr1_t(2) attr1_len(2) attr1_val(2*x) | SOURCE attr (NT)
  694. * [| attr2_t(2) attr2_val(2) |]? CLEAR attr
  695. */
  696. static inline int encode_lookup_attr(xmlNodePtr node, char *node_ptr,
  697. char *buf_end)
  698. {
  699. xmlAttrPtr attr;
  700. char *p, *p_orig;
  701. unsigned char *nr_attr;
  702. str val;
  703. nr_attr = &(NR_OF_ATTR(node_ptr));
  704. *nr_attr = 0;
  705. p = p_orig = ATTR_PTR(node_ptr);
  706. FOR_ALL_ATTR(node,attr) {
  707. /* get attribute's value */
  708. get_attr_val( attr->name , val, error);
  709. if ( !strcasecmp((const char*)attr->name,"source") ) {
  710. /* this param will not be copied, since it has only one value ;-)*/
  711. if ( val.len!=SOURCE_REG_STR_LEN ||
  712. strncasecmp( val.s, SOURCE_REG_STR, val.len) ) {
  713. LM_ERR("unsupported value"
  714. " <%.*s> in SOURCE param\n",val.len,val.s);
  715. goto error;
  716. }
  717. } else if ( !strcasecmp((const char*)attr->name,"clear") ) {
  718. (*nr_attr)++;
  719. set_attr_type(p, CLEAR_ATTR, buf_end, error);
  720. if ( val.len==3 && !strncasecmp(val.s,"yes",3) )
  721. append_short_attr(p, YES_VAL, buf_end, error);
  722. else if ( val.len==2 && !strncasecmp(val.s,"no",2) )
  723. append_short_attr(p, NO_VAL, buf_end, error);
  724. else {
  725. LM_ERR("unknown value "
  726. "<%.*s> for attribute CLEAR\n",val.len,val.s);
  727. goto error;
  728. }
  729. } else if ( !strcasecmp((const char*)attr->name,"timeout") ) {
  730. LM_WARN("unsupported param TIMEOUT; skipping\n");
  731. } else {
  732. LM_ERR("unknown attribute <%s>\n",attr->name);
  733. goto error;
  734. }
  735. }
  736. return p-p_orig;
  737. error:
  738. return -1;
  739. }
  740. /* Attr. encoding for LOCATION node:
  741. * | attr1_t(2) attr1_len(2) attr1_val(2*x) | URL attr (NT)
  742. * [| attr2_t(2) attr2_val(2) |]? PRIORITY attr
  743. * [| attr3_t(2) attr3_val(2) |]? CLEAR attr
  744. */
  745. static inline int encode_location_attr(xmlNodePtr node, char *node_ptr,
  746. char *buf_end)
  747. {
  748. struct sip_uri uri;
  749. xmlAttrPtr attr;
  750. char *p, *p_orig;
  751. unsigned char *nr_attr;
  752. unsigned short nr;
  753. str val;
  754. nr_attr = &(NR_OF_ATTR(node_ptr));
  755. *nr_attr = 0;
  756. p = p_orig = ATTR_PTR(node_ptr);
  757. FOR_ALL_ATTR(node,attr) {
  758. (*nr_attr)++;
  759. /* get attribute's value */
  760. get_attr_val( attr->name , val, error);
  761. switch(attr->name[0]) {
  762. case 'U': case 'u':
  763. set_attr_type(p, URL_ATTR, buf_end, error);
  764. /* check if it's a valid SIP URL -> just call
  765. * parse uri function and see if returns error ;-) */
  766. if (parse_uri( val.s, val.len, &uri)!=0) {
  767. LM_ERR("<%s> is not a valid SIP URL\n",val.s);
  768. goto error;
  769. }
  770. val.len++; /*copy also the \0 */
  771. append_str_attr(p,val, buf_end, error);
  772. break;
  773. case 'P': case 'p':
  774. set_attr_type(p, PRIORITY_ATTR, buf_end, error);
  775. if (val.s[0]=='0') nr=0;
  776. else if (val.s[0]=='1') nr=10;
  777. else goto prio_error;
  778. if (val.s[1]!='.') goto prio_error;
  779. if (val.s[2]<'0' || val.s[2]>'9') goto prio_error;
  780. nr += val.s[2] - '0';
  781. if (nr>10)
  782. goto prio_error;
  783. append_short_attr(p, nr, buf_end, error);
  784. break;
  785. case 'C': case 'c':
  786. set_attr_type(p, CLEAR_ATTR, buf_end, error);
  787. if (val.s[0]=='y' || val.s[0]=='Y')
  788. append_short_attr(p, YES_VAL, buf_end, error);
  789. else
  790. append_short_attr(p, NO_VAL, buf_end, error);
  791. break;
  792. default:
  793. LM_ERR("unknown attribute <%s>\n",attr->name);
  794. goto error;
  795. }
  796. }
  797. return p-p_orig;
  798. prio_error:
  799. LM_ERR("invalid priority <%s>\n",val.s);
  800. error:
  801. return -1;
  802. }
  803. /* Attr. encoding for REMOVE_LOCATION node:
  804. * [| attr1_t(2) attr1_len(2) attr1_val(2*x) |]? LOCATION attr (NT)
  805. */
  806. static inline int encode_rmvloc_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  807. {
  808. struct sip_uri uri;
  809. xmlAttrPtr attr;
  810. char *p, *p_orig;
  811. unsigned char *nr_attr;
  812. str val;
  813. nr_attr = &(NR_OF_ATTR(node_ptr));
  814. *nr_attr = 0;
  815. p = p_orig = ATTR_PTR(node_ptr);
  816. FOR_ALL_ATTR(node,attr) {
  817. (*nr_attr)++;
  818. switch(attr->name[0]) {
  819. case 'L': case 'l':
  820. set_attr_type(p, LOCATION_ATTR, buf_end, error);
  821. /* get the value of the attribute */
  822. get_attr_val( attr->name , val, error);
  823. /* check if it's a valid SIP URL -> just call
  824. * parse uri function and see if returns error ;-) */
  825. if (parse_uri( val.s, val.len, &uri)!=0) {
  826. LM_ERR("<%s> is not a valid SIP URL\n",val.s);
  827. goto error;
  828. }
  829. val.len++; /*copy also the \0 */
  830. append_str_attr(p,val, buf_end, error);
  831. break;
  832. case 'P': case 'p':
  833. case 'V': case 'v':
  834. /* as the interpreter ignores PARAM and VALUE attributes, we will
  835. * do the same ;-) */
  836. break;
  837. default:
  838. LM_ERR("unknown attribute <%s>\n",attr->name);
  839. goto error;
  840. }
  841. }
  842. return p-p_orig;
  843. error:
  844. return -1;
  845. }
  846. /* Attr. encoding for PROXY node:
  847. * [| attr1_t(2) attr1_val(2) |]? RECURSE attr
  848. * [| attr2_t(2) attr2_val(2) |]? TIMEOUT attr
  849. * [| attr3_t(2) attr3_val(2) |]? ORDERING attr
  850. */
  851. static inline int encode_proxy_attr(xmlNodePtr node, char *node_ptr,
  852. char *buf_end)
  853. {
  854. xmlAttrPtr attr;
  855. char *p, *p_orig;
  856. unsigned char *nr_attr;
  857. unsigned int nr;
  858. str val;
  859. nr_attr = &(NR_OF_ATTR(node_ptr));
  860. *nr_attr = 0;
  861. p = p_orig = ATTR_PTR(node_ptr);
  862. FOR_ALL_ATTR(node,attr) {
  863. (*nr_attr)++;
  864. /* get the value of the attribute */
  865. get_attr_val( attr->name , val, error);
  866. switch(attr->name[0]) {
  867. case 'R': case 'r':
  868. set_attr_type(p, RECURSE_ATTR, buf_end, error);
  869. if (val.s[0]=='y' || val.s[0]=='Y')
  870. append_short_attr(p, YES_VAL, buf_end, error);
  871. else if (val.s[0]=='n' || val.s[0]=='N')
  872. append_short_attr(p, NO_VAL, buf_end, error);
  873. else {
  874. LM_ERR("unknown value "
  875. "<%s> for attribute RECURSE\n",val.s);
  876. goto error;
  877. }
  878. break;
  879. case 'T': case 't':
  880. set_attr_type(p, TIMEOUT_ATTR, buf_end, error);
  881. if (str2int(&val,&nr)==-1) {
  882. LM_ERR("bad value <%.*s>"
  883. " for attribute TIMEOUT\n",val.len,val.s);
  884. goto error;
  885. }
  886. append_short_attr(p, (unsigned short)nr, buf_end, error);
  887. break;
  888. case 'O': case 'o':
  889. set_attr_type(p, ORDERING_ATTR, buf_end, error);
  890. switch (val.s[0]) {
  891. case 'p': case'P':
  892. append_short_attr(p, PARALLEL_VAL, buf_end, error);
  893. break;
  894. case 'S': case 's':
  895. append_short_attr(p, SEQUENTIAL_VAL, buf_end, error);
  896. break;
  897. case 'F': case 'f':
  898. append_short_attr(p, FIRSTONLY_VAL, buf_end, error);
  899. break;
  900. default:
  901. LM_ERR("unknown "
  902. "value <%s> for attribute ORDERING\n",val.s);
  903. goto error;
  904. }
  905. break;
  906. default:
  907. LM_ERR("unknown attribute <%s>\n",attr->name);
  908. goto error;
  909. }
  910. }
  911. return p-p_orig;
  912. error:
  913. return -1;
  914. }
  915. /* Attr. encoding for REJECT node:
  916. * | attr1_t(2) attr1_val(2) | STATUS attr
  917. * [| attr2_t(2) attr2_len(2) attr2_val(2*x)|]? REASON attr (NT)
  918. */
  919. static inline int encode_reject_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  920. {
  921. xmlAttrPtr attr;
  922. char *p, *p_orig;
  923. unsigned char *nr_attr;
  924. unsigned int nr;
  925. str val;
  926. nr_attr = &(NR_OF_ATTR(node_ptr));
  927. *nr_attr = 0;
  928. p = p_orig = ATTR_PTR(node_ptr);
  929. FOR_ALL_ATTR(node,attr) {
  930. (*nr_attr)++;
  931. /* get the value of the attribute */
  932. get_attr_val( attr->name , val, error);
  933. switch(attr->name[0]) {
  934. case 'R': case 'r':
  935. set_attr_type(p, REASON_ATTR, buf_end, error);
  936. val.len++; /* grab also the /0 */
  937. append_str_attr(p, val, buf_end, error);
  938. break;
  939. case 'S': case 's':
  940. set_attr_type(p, STATUS_ATTR, buf_end, error);
  941. if (str2int(&val,&nr)==-1) {
  942. /*it was a non numeric value */
  943. if (val.len==BUSY_STR_LEN &&
  944. !strncasecmp(val.s,BUSY_STR,val.len)) {
  945. append_short_attr(p, BUSY_VAL, buf_end, error);
  946. } else if (val.len==NOTFOUND_STR_LEN &&
  947. !strncasecmp(val.s,NOTFOUND_STR,val.len)) {
  948. append_short_attr(p, NOTFOUND_VAL, buf_end, error);
  949. } else if (val.len==ERROR_STR_LEN &&
  950. !strncasecmp(val.s,ERROR_STR,val.len)) {
  951. append_short_attr(p, ERROR_VAL, buf_end, error);
  952. } else if (val.len==REJECT_STR_LEN &&
  953. !strncasecmp(val.s,REJECT_STR,val.len)) {
  954. append_short_attr(p, REJECT_VAL, buf_end, error);
  955. } else {
  956. LM_ERR("bad val. <%s> for STATUS\n",val.s);
  957. goto error;
  958. }
  959. } else if (nr<400 || nr>700) {
  960. LM_ERR("bad code <%d> for STATUS\n",nr);
  961. goto error;
  962. } else {
  963. append_short_attr(p, nr, buf_end, error);
  964. }
  965. break;
  966. default:
  967. LM_ERR("unknown attribute <%s>\n",attr->name);
  968. goto error;
  969. }
  970. }
  971. return p-p_orig;
  972. error:
  973. return -1;
  974. }
  975. /* Attr. encoding for REDIRECT node:
  976. * | attr1_t(2) attr1_val(2) | STATUS attr
  977. * [| attr2_t(2) attr2_len(2) attr2_val(2*x)|]? REASON attr (NT)
  978. */
  979. static inline int encode_redirect_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  980. {
  981. xmlAttrPtr attr;
  982. char *p, *p_orig;
  983. unsigned char *nr_attr;
  984. str val;
  985. nr_attr = &(NR_OF_ATTR(node_ptr));
  986. *nr_attr = 0;
  987. p = p_orig = ATTR_PTR(node_ptr);
  988. FOR_ALL_ATTR(node,attr) {
  989. (*nr_attr)++;
  990. if (attr->name[0]=='p' || attr->name[0]=='P') {
  991. set_attr_type(p, PERMANENT_ATTR, buf_end, error);
  992. /* get the value */
  993. get_attr_val( attr->name , val, error);
  994. if (val.s[0]=='y' || val.s[0]=='Y')
  995. append_short_attr( p, YES_VAL, buf_end, error);
  996. else if (val.s[0]=='n' || val.s[0]=='N')
  997. append_short_attr( p, NO_VAL, buf_end, error);
  998. else {
  999. LM_ERR("bad val. <%s> for PERMANENT\n",val.s);
  1000. goto error;
  1001. }
  1002. } else {
  1003. LM_ERR("unknown attribute <%s>\n",attr->name);
  1004. goto error;
  1005. }
  1006. }
  1007. return p-p_orig;
  1008. error:
  1009. return -1;
  1010. }
  1011. /* Attr. encoding for LOG node:
  1012. * [| attr1_t(2) attr1_len(2) attr1_val(2*x) |]? NAME attr (NT)
  1013. * [| attr2_t(2) attr2_len(2) attr2_val(2*x) |]? COMMENT attr (NT)
  1014. */
  1015. static inline int encode_log_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  1016. {
  1017. xmlAttrPtr attr;
  1018. char *p, *p_orig;
  1019. unsigned char *nr_attr;
  1020. str val;
  1021. nr_attr = &(NR_OF_ATTR(node_ptr));
  1022. *nr_attr = 0;
  1023. p = p_orig = ATTR_PTR(node_ptr);
  1024. FOR_ALL_ATTR(node,attr) {
  1025. (*nr_attr)++;
  1026. /* get the value of the attribute */
  1027. get_attr_val( attr->name , val, error);
  1028. switch (attr->name[0] ) {
  1029. case 'n': case 'N':
  1030. if (val.len>MAX_NAME_SIZE) val.len=MAX_NAME_SIZE;
  1031. set_attr_type(p, NAME_ATTR, buf_end, error);
  1032. break;
  1033. case 'c': case 'C':
  1034. if (val.len>MAX_COMMENT_SIZE) val.len=MAX_COMMENT_SIZE;
  1035. set_attr_type(p, COMMENT_ATTR, buf_end, error);
  1036. break;
  1037. default:
  1038. LM_ERR("unknown attribute <%s>\n",attr->name);
  1039. goto error;
  1040. }
  1041. /* be sure there is a \0 at the end of string */
  1042. val.s[val.len++]=0;
  1043. append_str_attr(p,val, buf_end, error);
  1044. }
  1045. return p-p_orig;
  1046. error:
  1047. return -1;
  1048. }
  1049. /* Attr. encoding for MAIL node:
  1050. * | attr1_t(2) attr1_len(2) attr1_val(2*x) | TO_ATTR attr (NNT)
  1051. * [| attr2_t(2) attr2_len(2) attr2_val(2*x) |]? SUBJECT_ATTR attr (NNT)
  1052. * [| attr3_t(2) attr3_len(2) attr3_val(2*x) |]? BODY_ATTR attr (NNT)
  1053. */
  1054. static inline int encode_mail_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  1055. {
  1056. xmlAttrPtr attr;
  1057. char *p, *p_orig;
  1058. unsigned char *nr_attr;
  1059. nr_attr = &(NR_OF_ATTR(node_ptr));
  1060. *nr_attr = 0;
  1061. p = p_orig = ATTR_PTR(node_ptr);
  1062. FOR_ALL_ATTR(node,attr) {
  1063. /* there is only one attribute -> URL */
  1064. if (attr->name[0]!='u' && attr->name[0]!='U') {
  1065. LM_ERR("unknown attribute <%s>\n",attr->name);
  1066. goto error;
  1067. }
  1068. p = decode_mail_url( p, buf_end,
  1069. (char*)xmlGetProp(node,attr->name), nr_attr);
  1070. if (p==0)
  1071. goto error;
  1072. }
  1073. return p-p_orig;
  1074. error:
  1075. return -1;
  1076. }
  1077. /* Attr. encoding for SUBACTION node:
  1078. */
  1079. static inline int encode_subaction_attr(xmlNodePtr node, char *node_ptr,
  1080. char *buf_end)
  1081. {
  1082. xmlAttrPtr attr;
  1083. str val;
  1084. FOR_ALL_ATTR(node,attr) {
  1085. /* there is only one attribute -> ID */
  1086. if ((attr->name[0]|0x20)=='i' && ((attr->name[1]|0x20)=='d') &&
  1087. attr->name[2]==0 ) {
  1088. /* get the value of the attribute */
  1089. get_attr_val( attr->name , val, error);
  1090. if ((list = append_to_list(list, node_ptr,val.s))==0) {
  1091. LM_ERR("failed to add "
  1092. "subaction into list -> pkg_malloc failed?\n");
  1093. goto error;
  1094. }
  1095. } else {
  1096. LM_ERR("unknown attribute <%s>\n",attr->name);
  1097. goto error;
  1098. }
  1099. }
  1100. return 0;
  1101. error:
  1102. return -1;
  1103. }
  1104. /* Attr. encoding for SUB node:
  1105. * | attr1_t(2) attr1_val(2) | REF_ATTR attr
  1106. */
  1107. static inline int encode_sub_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
  1108. {
  1109. xmlAttrPtr attr;
  1110. char *p, *p_orig;
  1111. unsigned char *nr_attr;
  1112. char *sub_ptr;
  1113. str val;
  1114. nr_attr = &(NR_OF_ATTR(node_ptr));
  1115. *nr_attr = 0;
  1116. p = p_orig = ATTR_PTR(node_ptr);
  1117. FOR_ALL_ATTR(node,attr) {
  1118. (*nr_attr)++;
  1119. /* there is only one attribute -> REF */
  1120. if ( strcasecmp("ref",(char*)attr->name)!=0 ) {
  1121. LM_ERR("unknown attribute <%s>\n",attr->name);
  1122. goto error;
  1123. }
  1124. set_attr_type(p, REF_ATTR, buf_end, error);
  1125. /* get the value of the attribute */
  1126. get_attr_val( attr->name , val, error);
  1127. if ( (sub_ptr=search_the_list(list, val.s))==0 ) {
  1128. LM_ERR("unable to find declaration "
  1129. "of subaction <%s>\n",val.s);
  1130. goto error;
  1131. }
  1132. append_short_attr(p,(unsigned short)(node_ptr-sub_ptr),buf_end,error);
  1133. }
  1134. return p-p_orig;
  1135. error:
  1136. return -1;
  1137. }
  1138. /* Returns : -1 - error
  1139. * >0 - subtree size of the given node
  1140. */
  1141. int encode_node( xmlNodePtr node, char *p, char *p_end)
  1142. {
  1143. xmlNodePtr kid;
  1144. unsigned short sub_tree_size;
  1145. int attr_size;
  1146. int kid_size;
  1147. int foo;
  1148. /* counting the kids */
  1149. for(kid=node->children,foo=0;kid;kid=kid->next)
  1150. if (kid->type==XML_ELEMENT_NODE) foo++;
  1151. check_overflow(p,GET_NODE_SIZE(foo),p_end,error);
  1152. NR_OF_KIDS(p) = foo;
  1153. /* size of the encoded attributes */
  1154. attr_size = 0;
  1155. /* init the number of attributes */
  1156. NR_OF_ATTR(p) = 0;
  1157. /* encode node name */
  1158. switch (node->name[0]) {
  1159. case 'a':case 'A':
  1160. switch (node->name[7]) {
  1161. case 0:
  1162. NODE_TYPE(p) = ADDRESS_NODE;
  1163. attr_size = encode_address_attr( node, p, p_end);
  1164. break;
  1165. case '-':
  1166. NODE_TYPE(p) = ADDRESS_SWITCH_NODE;
  1167. attr_size = encode_address_switch_attr( node, p, p_end);
  1168. break;
  1169. default:
  1170. NODE_TYPE(p) = ANCILLARY_NODE;
  1171. break;
  1172. }
  1173. break;
  1174. case 'B':case 'b':
  1175. NODE_TYPE(p) = BUSY_NODE;
  1176. break;
  1177. case 'c':case 'C':
  1178. NODE_TYPE(p) = CPL_NODE;
  1179. break;
  1180. case 'd':case 'D':
  1181. NODE_TYPE(p) = DEFAULT_NODE;
  1182. break;
  1183. case 'f':case 'F':
  1184. NODE_TYPE(p) = FAILURE_NODE;
  1185. break;
  1186. case 'i':case 'I':
  1187. NODE_TYPE(p) = INCOMING_NODE;
  1188. break;
  1189. case 'l':case 'L':
  1190. switch (node->name[2]) {
  1191. case 'g':case 'G':
  1192. NODE_TYPE(p) = LOG_NODE;
  1193. attr_size = encode_log_attr( node, p, p_end);
  1194. break;
  1195. case 'o':case 'O':
  1196. NODE_TYPE(p) = LOOKUP_NODE;
  1197. attr_size = encode_lookup_attr( node, p, p_end);
  1198. break;
  1199. case 'c':case 'C':
  1200. NODE_TYPE(p) = LOCATION_NODE;
  1201. attr_size = encode_location_attr( node, p, p_end);
  1202. break;
  1203. default:
  1204. if (node->name[8]) {
  1205. NODE_TYPE(p) = LANGUAGE_SWITCH_NODE;
  1206. } else {
  1207. NODE_TYPE(p) = LANGUAGE_NODE;
  1208. attr_size = encode_lang_attr( node, p, p_end);
  1209. }
  1210. break;
  1211. }
  1212. break;
  1213. case 'm':case 'M':
  1214. NODE_TYPE(p) = MAIL_NODE;
  1215. attr_size = encode_mail_attr( node, p, p_end);
  1216. break;
  1217. case 'n':case 'N':
  1218. switch (node->name[3]) {
  1219. case 'F':case 'f':
  1220. NODE_TYPE(p) = NOTFOUND_NODE;
  1221. break;
  1222. case 'N':case 'n':
  1223. NODE_TYPE(p) = NOANSWER_NODE;
  1224. break;
  1225. default:
  1226. NODE_TYPE(p) = NOT_PRESENT_NODE;
  1227. break;
  1228. }
  1229. break;
  1230. case 'o':case 'O':
  1231. if (node->name[1]=='t' || node->name[1]=='T') {
  1232. NODE_TYPE(p) = OTHERWISE_NODE;
  1233. } else {
  1234. NODE_TYPE(p) = OUTGOING_NODE;
  1235. }
  1236. break;
  1237. case 'p':case 'P':
  1238. if (node->name[2]=='o' || node->name[2]=='O') {
  1239. NODE_TYPE(p) = PROXY_NODE;
  1240. attr_size = encode_proxy_attr( node, p, p_end);
  1241. } else if (node->name[8]) {
  1242. NODE_TYPE(p) = PRIORITY_SWITCH_NODE;
  1243. } else {
  1244. NODE_TYPE(p) = PRIORITY_NODE;
  1245. attr_size = encode_priority_attr( node, p, p_end);
  1246. }
  1247. break;
  1248. case 'r':case 'R':
  1249. switch (node->name[2]) {
  1250. case 'j':case 'J':
  1251. NODE_TYPE(p) = REJECT_NODE;
  1252. attr_size = encode_reject_attr( node, p, p_end);
  1253. break;
  1254. case 'm':case 'M':
  1255. NODE_TYPE(p) = REMOVE_LOCATION_NODE;
  1256. attr_size = encode_rmvloc_attr( node, p, p_end);
  1257. break;
  1258. default:
  1259. if (node->name[8]) {
  1260. NODE_TYPE(p) = REDIRECTION_NODE;
  1261. } else {
  1262. NODE_TYPE(p) = REDIRECT_NODE;
  1263. attr_size = encode_redirect_attr( node, p, p_end);
  1264. }
  1265. break;
  1266. }
  1267. break;
  1268. case 's':case 'S':
  1269. switch (node->name[3]) {
  1270. case 0:
  1271. NODE_TYPE(p) = SUB_NODE;
  1272. attr_size = encode_sub_attr( node, p, p_end);
  1273. break;
  1274. case 'c':case 'C':
  1275. NODE_TYPE(p) = SUCCESS_NODE;
  1276. break;
  1277. case 'a':case 'A':
  1278. NODE_TYPE(p) = SUBACTION_NODE;
  1279. attr_size = encode_subaction_attr( node, p, p_end);
  1280. break;
  1281. default:
  1282. if (node->name[6]) {
  1283. NODE_TYPE(p) = STRING_SWITCH_NODE;
  1284. attr_size = encode_string_switch_attr( node, p, p_end);
  1285. } else {
  1286. NODE_TYPE(p) = STRING_NODE;
  1287. attr_size = encode_string_attr( node, p, p_end);
  1288. }
  1289. break;
  1290. }
  1291. break;
  1292. case 't':case 'T':
  1293. if (node->name[4]) {
  1294. NODE_TYPE(p) = TIME_SWITCH_NODE;
  1295. attr_size = encode_time_switch_attr( node, p, p_end);
  1296. } else {
  1297. NODE_TYPE(p) = TIME_NODE;
  1298. attr_size = encode_time_attr( node, p, p_end);
  1299. }
  1300. break;
  1301. default:
  1302. LM_ERR("unknown node <%s>\n",node->name);
  1303. goto error;
  1304. }
  1305. /* compute the total length of the node (including attributes) */
  1306. if (attr_size<0)
  1307. goto error;
  1308. sub_tree_size = SIMPLE_NODE_SIZE(p) + (unsigned short)attr_size;
  1309. /* encrypt all the kids */
  1310. for(kid = node->children,foo=0;kid;kid=kid->next) {
  1311. if (kid->type!=XML_ELEMENT_NODE) continue;
  1312. SET_KID_OFFSET( p, foo, sub_tree_size);
  1313. kid_size = encode_node( kid, p+sub_tree_size, p_end);
  1314. if (kid_size<=0)
  1315. goto error;
  1316. sub_tree_size += (unsigned short)kid_size;
  1317. foo++;
  1318. }
  1319. return sub_tree_size;
  1320. error:
  1321. return -1;
  1322. }
  1323. #define BAD_XML "CPL script is not a valid XML document"
  1324. #define BAD_XML_LEN (sizeof(BAD_XML)-1)
  1325. #define BAD_CPL "CPL script doesn't respect CPL grammar"
  1326. #define BAD_CPL_LEN (sizeof(BAD_CPL)-1)
  1327. #define NULL_CPL "Empty CPL script"
  1328. #define NULL_CPL_LEN (sizeof(NULL_CPL)-1)
  1329. #define ENC_ERR "Encoding of the CPL script failed"
  1330. #define ENC_ERR_LEN (sizeof(ENC_ERR)-1)
  1331. int encodeCPL( str *xml, str *bin, str *log)
  1332. {
  1333. static char buf[ENCONDING_BUFFER_SIZE];
  1334. xmlDocPtr doc;
  1335. xmlNodePtr cur;
  1336. doc = 0;
  1337. list = 0;
  1338. /* reset all the logs (if any) to catch some possible err/warn/notice
  1339. * from the parser/validater/encoder */
  1340. reset_logs();
  1341. /* parse the xml */
  1342. doc = xmlParseDoc( (unsigned char*)xml->s );
  1343. if (!doc) {
  1344. append_log( 1, MSG_ERR BAD_XML LF, MSG_ERR_LEN+BAD_XML_LEN+LF_LEN);
  1345. LM_ERR( BAD_XML "\n");
  1346. goto error;
  1347. }
  1348. /* check the xml against dtd */
  1349. if (xmlValidateDtd(&cvp, doc, dtd)!=1) {
  1350. append_log( 1, MSG_ERR BAD_CPL LF, MSG_ERR_LEN+BAD_CPL_LEN+LF_LEN);
  1351. LM_ERR( BAD_CPL "\n");
  1352. goto error;
  1353. }
  1354. cur = xmlDocGetRootElement(doc);
  1355. if (!cur) {
  1356. append_log( 1, MSG_ERR NULL_CPL LF, MSG_ERR_LEN+NULL_CPL_LEN+LF_LEN);
  1357. LM_ERR( NULL_CPL "\n");
  1358. goto error;
  1359. }
  1360. bin->len = encode_node( cur, buf, buf+ENCONDING_BUFFER_SIZE);
  1361. if (bin->len<0) {
  1362. append_log( 1, MSG_ERR ENC_ERR LF, MSG_ERR_LEN+ENC_ERR_LEN+LF_LEN);
  1363. LM_ERR( ENC_ERR "\n");
  1364. goto error;
  1365. }
  1366. xmlFreeDoc(doc);
  1367. if (list) delete_list(list);
  1368. /* compile the log buffer */
  1369. compile_logs( log );
  1370. bin->s = buf;
  1371. return 1;
  1372. error:
  1373. if (doc) xmlFreeDoc(doc);
  1374. if (list) delete_list(list);
  1375. /* compile the log buffer */
  1376. compile_logs( log );
  1377. return 0;
  1378. }
  1379. /* loads and parse the dtd file; a validating context is created */
  1380. int init_CPL_parser( char* DTD_filename )
  1381. {
  1382. dtd = xmlParseDTD( NULL, (unsigned char*)DTD_filename);
  1383. if (!dtd) {
  1384. LM_ERR("DTD not parsed successfully\n");
  1385. return -1;
  1386. }
  1387. cvp.userData = (void *) stderr;
  1388. cvp.error = (xmlValidityErrorFunc) /*err_print*/ fprintf;
  1389. cvp.warning = (xmlValidityWarningFunc) /*err_print*/ fprintf;
  1390. return 1;
  1391. }