00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 #include <fcntl.h>
00029 #include <errno.h>
00030 #include <unistd.h>
00031 #include <libxml/xmlmemory.h>
00032 #include <libxml/parser.h>
00033
00034 #include "../../parser/parse_uri.h"
00035 #include "../../dprint.h"
00036 #include "../../str.h"
00037 #include "../../ut.h"
00038 #include "CPL_tree.h"
00039 #include "sub_list.h"
00040 #include "cpl_log.h"
00041
00042
00043
00044 static struct node *list = 0;
00045 static xmlDtdPtr dtd;
00046 static xmlValidCtxt cvp;
00047
00048
00049 typedef unsigned short length_type ;
00050 typedef length_type* length_type_ptr;
00051
00052 enum {EMAIL_TO,EMAIL_HDR_NAME,EMAIL_KNOWN_HDR_BODY,EMAIL_UNKNOWN_HDR_BODY};
00053
00054
00055 #define ENCONDING_BUFFER_SIZE 65536
00056
00057 #define FOR_ALL_ATTR(_node,_attr) \
00058 for( (_attr)=(_node)->properties ; (_attr) ; (_attr)=(_attr)->next)
00059
00060 #define check_overflow(_p_,_offset_,_end_,_error_) \
00061 do{\
00062 if ((_p_)+(_offset_)>=(_end_)) { \
00063 LM_ERR("%s:%d: overflow -> buffer to small\n",\
00064 __FILE__,__LINE__);\
00065 goto _error_;\
00066 }\
00067 }while(0)\
00068
00069 #define set_attr_type(_p_,_type_,_end_,_error_) \
00070 do{\
00071 check_overflow(_p_,sizeof(length_type),_end_,_error_);\
00072 *((length_type_ptr)(_p_)) = htons((length_type)(_type_));\
00073 (_p_) += sizeof(length_type);\
00074 }while(0)\
00075
00076 #define append_short_attr(_p_,_n_,_end_,_error_) \
00077 do{\
00078 check_overflow(_p_,sizeof(length_type),_end_,_error_);\
00079 *((length_type_ptr)(_p_)) = htons((length_type)(_n_));\
00080 (_p_) += sizeof(length_type);\
00081 }while(0)
00082
00083 #define append_str_attr(_p_,_s_,_end_,_error_) \
00084 do{\
00085 check_overflow(_p_,(_s_).len + 1*((((_s_).len)&0x0001)==1),\
00086 _end_,_error_);\
00087 *((length_type_ptr)(_p_)) = htons((length_type)(_s_).len);\
00088 (_p_) += sizeof(length_type);\
00089 memcpy( (_p_), (_s_).s, (_s_).len);\
00090 (_p_) += (_s_).len + 1*((((_s_).len)&0x0001)==1);\
00091 }while(0)
00092
00093 #define append_double_str_attr(_p_,_s1_,_s2_,_end_,_error_) \
00094 do{\
00095 check_overflow(_p_,(_s1_).len + (_s2_).len +\
00096 1*((((_s2_).len+(_s2_).len)&0x0001)==1), _end_, _error_);\
00097 *((length_type_ptr)(_p_))=htons((length_type)((_s1_).len)+(_s2_).len);\
00098 (_p_) += sizeof(length_type);\
00099 memcpy( (_p_), (_s1_).s, (_s1_).len);\
00100 (_p_) += (_s1_).len;\
00101 memcpy( (_p_), (_s2_).s, (_s2_).len);\
00102 (_p_) += (_s2_).len + 1*((((_s1_).len+(_s2_).len)&0x0001)==1);\
00103 }while(0)
00104
00105 #define get_attr_val(_attr_name_,_val_,_error_) \
00106 do { \
00107 (_val_).s = (char*)xmlGetProp(node,(_attr_name_));\
00108 (_val_).len = strlen((_val_).s);\
00109 \
00110 trim_spaces_lr( (_val_) );\
00111 if ((_val_).len==0) {\
00112 LM_ERR("%s:%d: attribute <%s> has an "\
00113 "empty value\n",__FILE__,__LINE__,(_attr_name_));\
00114 goto _error_;\
00115 }\
00116 }while(0)\
00117
00118
00119
00120 #define MAX_EMAIL_HDR_SIZE 7
00121 #define MAX_EMAIL_BODY_SIZE 512
00122 #define MAX_EMAIL_SUBJECT_SIZE 32
00123
00124 static inline char *decode_mail_url(char *p, char *p_end, char *url,
00125 unsigned char *nr_attr)
00126 {
00127 static char buf[ MAX_EMAIL_HDR_SIZE ];
00128 char c;
00129 char foo;
00130 unsigned short hdr_len;
00131 unsigned short *len;
00132 int max_len;
00133 int status;
00134
00135
00136 hdr_len = 0;
00137 max_len = 0;
00138 status = EMAIL_TO;
00139 (*nr_attr) ++;
00140 set_attr_type(p, TO_ATTR, p_end, error);
00141 len = ((unsigned short*)(p));
00142 *len = 0;
00143 p += 2;
00144
00145
00146 do {
00147
00148 if (*url=='+') {
00149
00150 c=' ';
00151 url++;
00152
00153 } else if ( (*url=='%') && *(url+1) && *(url+2) ) {
00154
00155 c = hex2int(url[1]);
00156 foo = hex2int(url[2]);
00157 if (c==-1 || foo==-1) {
00158 LM_ERR("non-ASCII escaped "
00159 "character in mail url [%.*s]\n", 3, url);
00160 goto error;
00161 }
00162 c = c<<4 | foo;
00163 url += 3;
00164 } else {
00165
00166 c = *url;
00167 url++;
00168 }
00169
00170
00171 switch (c) {
00172 case '?':
00173 switch (status) {
00174 case EMAIL_TO:
00175 if (*len==0) {
00176 LM_ERR("empty TO "
00177 "address found in MAIL node!\n");
00178 goto error;
00179 }
00180 if (((*len)&0x0001)==1) p++;
00181 *len = htons(*len);
00182 hdr_len = 0;
00183 status = EMAIL_HDR_NAME;
00184 break;
00185 default: goto parse_error;
00186 }
00187 break;
00188 case '=':
00189 switch (status) {
00190 case EMAIL_HDR_NAME:
00191 LM_DBG("hdr [%.*s] found\n",
00192 hdr_len,buf);
00193 if ( hdr_len==BODY_EMAILHDR_LEN &&
00194 strncasecmp(buf,BODY_EMAILHDR_STR,hdr_len)==0 ) {
00195
00196 set_attr_type( p, BODY_ATTR, p_end, error);
00197 max_len = MAX_EMAIL_BODY_SIZE;
00198 } else if ( hdr_len==SUBJECT_EMAILHDR_LEN &&
00199 strncasecmp(buf,SUBJECT_EMAILHDR_STR,hdr_len)==0 ) {
00200
00201 set_attr_type( p, SUBJECT_ATTR, p_end, error);
00202 max_len = MAX_EMAIL_SUBJECT_SIZE;
00203 } else {
00204 LM_DBG("unknown hdr -> ignoring\n");
00205 status = EMAIL_UNKNOWN_HDR_BODY;
00206 break;
00207 }
00208 (*nr_attr) ++;
00209 len = ((unsigned short*)(p));
00210 *len = 0;
00211 p += 2;
00212 status = EMAIL_KNOWN_HDR_BODY;
00213 break;
00214 default: goto parse_error;
00215 }
00216 break;
00217 case '&':
00218 switch (status) {
00219 case EMAIL_KNOWN_HDR_BODY:
00220 if (((*len)&0x0001)==1) p++;
00221 *len = htons(*len);
00222 case EMAIL_UNKNOWN_HDR_BODY:
00223 hdr_len = 0;
00224 status = EMAIL_HDR_NAME;
00225 break;
00226 default: goto parse_error;
00227 }
00228 break;
00229 case 0:
00230 switch (status) {
00231 case EMAIL_TO:
00232 if (*len==0) {
00233 LM_ERR("empty TO "
00234 "address found in MAIL node!\n");
00235 goto error;
00236 }
00237 case EMAIL_KNOWN_HDR_BODY:
00238 if (((*len)&0x0001)==1) p++;
00239 *len = htons(*len);
00240 case EMAIL_UNKNOWN_HDR_BODY:
00241 break;
00242 default: goto parse_error;
00243 }
00244 break;
00245 default:
00246 switch (status) {
00247 case EMAIL_TO:
00248 (*len)++;
00249 *(p++) = c;
00250 if (*len==URL_MAILTO_LEN &&
00251 !strncasecmp(p-(*len),URL_MAILTO_STR,(*len))) {
00252 LM_DBG("MAILTO: found at"
00253 " the beginning of TO -> removed\n");
00254 p -= (*len);
00255 *len = 0;
00256 }
00257 break;
00258 case EMAIL_KNOWN_HDR_BODY:
00259 if ((*len)<max_len) (*len)++;
00260 *(p++) = c;
00261 break;
00262 case EMAIL_HDR_NAME:
00263 if (hdr_len<MAX_EMAIL_HDR_SIZE) hdr_len++;
00264 buf[hdr_len-1] = c;
00265 break;
00266 case EMAIL_UNKNOWN_HDR_BODY:
00267
00268 break;
00269 default : goto parse_error;
00270 }
00271 }
00272 }while(c!=0);
00273
00274 return p;
00275 parse_error:
00276 LM_ERR("unexpected char [%c] in state %d"
00277 " in email url \n",*url,status);
00278 error:
00279 return 0;
00280 }
00281
00282
00283
00284
00285
00286
00287 static inline int encode_address_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
00288 {
00289 xmlAttrPtr attr;
00290 char *p, *p_orig;
00291 unsigned char *nr_attr;
00292 str val;
00293
00294 nr_attr = &(NR_OF_ATTR(node_ptr));
00295 *nr_attr = 0;
00296 p = p_orig = ATTR_PTR(node_ptr);
00297
00298 FOR_ALL_ATTR(node,attr) {
00299 (*nr_attr)++;
00300 switch (attr->name[0]) {
00301 case 'i': case 'I':
00302 set_attr_type(p, IS_ATTR, buf_end, error);
00303 break;
00304 case 'c': case 'C':
00305 set_attr_type(p, CONTAINS_ATTR, buf_end, error);
00306 break;
00307 case 's': case 'S':
00308 set_attr_type(p, SUBDOMAIN_OF_ATTR, buf_end, error);
00309 break;
00310 default:
00311 LM_ERR("unknown attribute "
00312 "<%s>\n",attr->name);
00313 goto error;
00314 }
00315
00316 get_attr_val( attr->name , val, error);
00317
00318 val.len++;
00319 append_str_attr(p, val, buf_end, error);
00320 }
00321
00322 return p-p_orig;
00323 error:
00324 return -1;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 static inline int encode_address_switch_attr(xmlNodePtr node, char *node_ptr,
00334 char *buf_end)
00335 {
00336 xmlAttrPtr attr;
00337 char *p, *p_orig;
00338 unsigned char *nr_attr;
00339 str val;
00340
00341 nr_attr = &(NR_OF_ATTR(node_ptr));
00342 *nr_attr = 0;
00343 p = p_orig = ATTR_PTR(node_ptr);
00344
00345 FOR_ALL_ATTR(node,attr) {
00346 (*nr_attr)++;
00347
00348 get_attr_val( attr->name , val, error);
00349 switch(attr->name[0]) {
00350 case 'F': case 'f':
00351 set_attr_type(p, FIELD_ATTR, buf_end, error);
00352 if (val.s[0]=='D' || val.s[0]=='d')
00353 append_short_attr(p, DESTINATION_VAL, buf_end, error);
00354 else if (val.s[6]=='A' || val.s[6]=='a')
00355 append_short_attr(p,ORIGINAL_DESTINATION_VAL,buf_end,error);
00356 else if (!val.s[6])
00357 append_short_attr(p, ORIGIN_VAL, buf_end, error);
00358 else {
00359 LM_ERR("unknown"
00360 " value <%s> for FIELD attr\n",val.s);
00361 goto error;
00362 };
00363 break;
00364 case 'S': case 's':
00365 set_attr_type(p, SUBFIELD_ATTR, buf_end, error);
00366 switch (val.s[0]) {
00367 case 'u': case 'U':
00368 append_short_attr(p, USER_VAL, buf_end, error);
00369 break;
00370 case 'h': case 'H':
00371 append_short_attr(p, HOST_VAL, buf_end, error);
00372 break;
00373 case 'p': case 'P':
00374 append_short_attr(p, PORT_VAL, buf_end, error);
00375 break;
00376 case 't': case 'T':
00377 append_short_attr(p, TEL_VAL, buf_end, error);
00378 break;
00379 case 'd': case 'D':
00380
00381
00382 case 'a': case 'A':
00383
00384
00385 default:
00386 LM_ERR("unknown value <%s> for SUBFIELD attr\n",val.s);
00387 goto error;
00388 }
00389 break;
00390 default:
00391 LM_ERR("unknown attribute <%s>\n",attr->name);
00392 goto error;
00393 }
00394 }
00395
00396 return p-p_orig;
00397 error:
00398 return -1;
00399 }
00400
00401
00402
00403
00404
00405
00406 static inline int encode_lang_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
00407
00408 {
00409 xmlAttrPtr attr;
00410 char *p, *p_orig;
00411 unsigned char *nr_attr;
00412 char *end;
00413 char *val_bk;
00414 str val;
00415
00416 nr_attr = &(NR_OF_ATTR(node_ptr));
00417 *nr_attr = 0;
00418 p = p_orig = ATTR_PTR(node_ptr);
00419
00420 FOR_ALL_ATTR(node,attr) {
00421
00422 if (attr->name[0]!='M' && attr->name[0]!='m') {
00423 LM_ERR("unknown attribute "
00424 "<%s>\n",attr->name);
00425 goto error;
00426 }
00427 val.s = val_bk = (char*)xmlGetProp(node,attr->name);
00428
00429 for(end=val.s,val.len=0;;end++) {
00430
00431 if (!val.len && (*end==' ' || *end=='\t')) continue;
00432
00433 if ((*nr_attr)>=2) goto lang_error;
00434 if (((*end)|0x20)>='a' && ((*end)|0x20)<='z') {
00435 val.len++; continue;
00436 } else if (*end=='*' && val.len==0 && (*nr_attr)==0 &&
00437 (*end==' '|| *end=='\t' || *end==0)) {
00438 val.len++;
00439 set_attr_type(p, MATCHES_TAG_ATTR, buf_end, error);
00440 } else if (val.len && (*nr_attr)==0 && *end=='-' ) {
00441 set_attr_type(p, MATCHES_TAG_ATTR, buf_end, error);
00442 } else if (val.len && ((*nr_attr)==0 || (*nr_attr)==1) &&
00443 (*end==' '|| *end=='\t' || *end==0)) {
00444 set_attr_type(p,
00445 (!(*nr_attr))?MATCHES_TAG_ATTR:MATCHES_SUBTAG_ATTR,
00446 buf_end, error );
00447 } else goto lang_error;
00448 (*nr_attr)++;
00449
00450
00451 val.s = end-val.len;
00452 append_str_attr(p, val, buf_end, error);
00453 val.len = 0;
00454 if (*end==0) break;
00455 }
00456 }
00457
00458 return p-p_orig;
00459 lang_error:
00460 LM_ERR("bad value for language_tag <%s>\n",val_bk);
00461 error:
00462 return -1;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471 static inline int encode_priority_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
00472 {
00473 xmlAttrPtr attr;
00474 char *p, *p_orig;
00475 unsigned char *nr_attr;
00476 str val;
00477
00478 nr_attr = &(NR_OF_ATTR(node_ptr));
00479 *nr_attr = 0;
00480 p = p_orig = ATTR_PTR(node_ptr);
00481
00482 FOR_ALL_ATTR(node,attr) {
00483 (*nr_attr)++;
00484
00485 switch(attr->name[0]) {
00486 case 'L': case 'l':
00487 set_attr_type(p, LESS_ATTR, buf_end, error);
00488 break;
00489 case 'G': case 'g':
00490 set_attr_type(p, GREATER_ATTR, buf_end, error);
00491 break;
00492 case 'E': case 'e':
00493 set_attr_type(p, EQUAL_ATTR, buf_end, error);
00494 break;
00495 default:
00496 LM_ERR("unknown attribute <%s>\n",attr->name);
00497 goto error;
00498 }
00499
00500 get_attr_val( attr->name , val, error);
00501 if ( val.len==EMERGENCY_STR_LEN &&
00502 !strncasecmp(val.s,EMERGENCY_STR,val.len) ) {
00503 append_short_attr(p, EMERGENCY_VAL, buf_end, error);
00504 } else if ( val.len==URGENT_STR_LEN &&
00505 !strncasecmp(val.s,URGENT_STR,val.len) ) {
00506 append_short_attr(p, URGENT_VAL, buf_end, error);
00507 } else if ( val.len==NORMAL_STR_LEN &&
00508 !strncasecmp(val.s,NORMAL_STR,val.len) ) {
00509 append_short_attr(p, NORMAL_VAL, buf_end, error);
00510 } else if ( val.len==NON_URGENT_STR_LEN &&
00511 !strncasecmp(val.s,NON_URGENT_STR,val.len) ) {
00512 append_short_attr(p, NON_URGENT_VAL, buf_end, error);
00513 } else {
00514 append_short_attr(p, UNKNOWN_PRIO_VAL, buf_end, error);
00515 set_attr_type(p, PRIOSTR_ATTR, buf_end, error);
00516 val.len++;
00517 append_str_attr(p, val, buf_end, error);
00518 }
00519 }
00520
00521 return p-p_orig;
00522 error:
00523 return -1;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532 static inline int encode_string_switch_attr(xmlNodePtr node, char *node_ptr,
00533 char *buf_end)
00534 {
00535 xmlAttrPtr attr;
00536 char *p, *p_orig;
00537 unsigned char *nr_attr;
00538 str val;
00539
00540 nr_attr = &(NR_OF_ATTR(node_ptr));
00541 *nr_attr = 0;
00542 p = p_orig = ATTR_PTR(node_ptr);
00543
00544 FOR_ALL_ATTR(node,attr) {
00545 (*nr_attr)++;
00546
00547 if (attr->name[0]!='F' && attr->name[0]!='f') {
00548 LM_ERR("unknown attribute <%s>\n",attr->name);
00549 goto error;
00550 }
00551 set_attr_type(p, FIELD_ATTR, buf_end, error);
00552
00553 get_attr_val( attr->name , val, error);
00554 switch (val.s[0]) {
00555 case 'S': case 's':
00556 append_short_attr(p, SUBJECT_VAL, buf_end, error);
00557 break;
00558 case 'O': case 'o':
00559 append_short_attr(p, ORGANIZATION_VAL, buf_end, error);
00560 break;
00561 case 'U': case 'u':
00562 append_short_attr(p, USER_AGENT_VAL, buf_end, error);
00563 break;
00564 case 'D': case 'd':
00565 append_short_attr(p, DISPLAY_VAL, buf_end, error);
00566 break;
00567 default:
00568 LM_ERR("unknown "
00569 "value <%s> for FIELD\n",attr->name);
00570 goto error;
00571 }
00572 }
00573
00574 return p-p_orig;
00575 error:
00576 return -1;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 static inline int encode_string_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
00586 {
00587 xmlAttrPtr attr;
00588 char *p, *p_orig;
00589 unsigned char *nr_attr;
00590 str val;
00591
00592 nr_attr = &(NR_OF_ATTR(node_ptr));
00593 *nr_attr = 0;
00594 p = p_orig = ATTR_PTR(node_ptr);
00595
00596 FOR_ALL_ATTR(node,attr) {
00597 (*nr_attr)++;
00598 switch(attr->name[0]) {
00599 case 'I': case 'i':
00600 set_attr_type(p, IS_ATTR, buf_end, error);
00601 break;
00602 case 'C': case 'c':
00603 set_attr_type(p, CONTAINS_ATTR, buf_end, error);
00604 break;
00605 default:
00606 LM_ERR("unknown "
00607 "attribute <%s>\n",attr->name);
00608 goto error;
00609 }
00610
00611 get_attr_val( attr->name , val, error);
00612 val.len++;
00613 append_str_attr(p,val, buf_end, error);
00614 }
00615
00616 return p-p_orig;
00617 error:
00618 return -1;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 static inline int encode_time_switch_attr(xmlNodePtr node, char *node_ptr,
00628 char *buf_end)
00629 {
00630 static str tz_str = {"TZ=",3};
00631 xmlAttrPtr attr;
00632 char *p, *p_orig;
00633 unsigned char *nr_attr;
00634 str val;
00635
00636 nr_attr = &(NR_OF_ATTR(node_ptr));
00637 *nr_attr = 0;
00638 p = p_orig = ATTR_PTR(node_ptr);
00639
00640 FOR_ALL_ATTR(node,attr) {
00641 (*nr_attr)++;
00642 switch(attr->name[2]) {
00643 case 'I': case 'i':
00644 set_attr_type(p, TZID_ATTR, buf_end, error);
00645
00646 get_attr_val( attr->name , val, error);
00647 val.len++;
00648 append_double_str_attr(p,tz_str,val, buf_end, error);
00649 break;
00650 case 'U': case 'u':
00651
00652
00653
00654 break;
00655 default:
00656 LM_ERR("unknown attribute <%s>\n",attr->name);
00657 goto error;
00658 }
00659 }
00660
00661 return p-p_orig;
00662 error:
00663 return -1;
00664 }
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 static inline int encode_time_attr(xmlNodePtr node, char *node_ptr,
00688 char *buf_end)
00689 {
00690 xmlAttrPtr attr;
00691 char *p, *p_orig;
00692 unsigned char *nr_attr;
00693 str val;
00694
00695 nr_attr = &(NR_OF_ATTR(node_ptr));
00696 *nr_attr = 0;
00697 p = p_orig = ATTR_PTR(node_ptr);
00698
00699 FOR_ALL_ATTR(node,attr) {
00700 (*nr_attr)++;
00701 switch (attr->name[4]) {
00702 case 0:
00703 if (attr->name[0]=='F' || attr->name[0]=='f')
00704 set_attr_type(p, FREQ_ATTR, buf_end, error);
00705 else if (attr->name[0]=='W' || attr->name[0]=='w')
00706 set_attr_type(p, WKST_ATTR, buf_end, error);
00707 break;
00708 case 'a': case 'A':
00709 if (attr->name[0]=='D' || attr->name[0]=='d')
00710 set_attr_type(p, DTSTART_ATTR, buf_end, error);
00711 else if (attr->name[0]=='B' || attr->name[0]=='b')
00712 set_attr_type(p, BYYEARDAY_ATTR, buf_end, error);
00713 break;
00714 case 't': case 'T':
00715 if (attr->name[0]=='D' || attr->name[0]=='d')
00716 set_attr_type(p, DURATION_ATTR, buf_end, error);
00717 else if (attr->name[0]=='C' || attr->name[0]=='c')
00718 set_attr_type(p, COUNT_ATTR, buf_end, error);
00719 else if (attr->name[0]=='B' || attr->name[0]=='b')
00720 set_attr_type(p, BYSETPOS_ATTR, buf_end, error);
00721 break;
00722 case 'n': case 'N':
00723 if (!attr->name[7])
00724 set_attr_type(p, BYMONTH_ATTR, buf_end, error);
00725 else if (attr->name[7]=='D' || attr->name[7]=='d')
00726 set_attr_type(p, BYMONTHDAY_ATTR, buf_end, error);
00727 else if (attr->name[7]=='e' || attr->name[7]=='E')
00728 set_attr_type(p, BYMINUTE_ATTR, buf_end, error);
00729 break;
00730 case 'd': case 'D':
00731 set_attr_type(p, DTEND_ATTR, buf_end, error);
00732 break;
00733 case 'r': case 'R':
00734 set_attr_type(p, INTERVAL_ATTR, buf_end, error);
00735 break;
00736 case 'l': case 'L':
00737 set_attr_type(p, UNTIL_ATTR, buf_end, error);
00738 break;
00739 case 'c': case 'C':
00740 set_attr_type(p, BYSECOND_ATTR, buf_end, error);
00741 break;
00742 case 'u': case 'U':
00743 set_attr_type(p, BYHOUR_ATTR, buf_end, error);
00744 break;
00745 case 'y': case 'Y':
00746 set_attr_type(p, BYDAY_ATTR, buf_end, error);
00747 break;
00748 case 'e': case 'E':
00749 set_attr_type(p, BYWEEKNO_ATTR, buf_end, error);
00750 break;
00751 default:
00752 LM_ERR("unknown attribute <%s>\n",attr->name);
00753 goto error;
00754 }
00755
00756 get_attr_val( attr->name , val, error);
00757 val.len++;
00758 append_str_attr(p,val, buf_end, error);
00759 }
00760
00761 return p-p_orig;
00762 error:
00763 return -1;
00764 }
00765
00766
00767
00768
00769
00770
00771
00772 static inline int encode_lookup_attr(xmlNodePtr node, char *node_ptr,
00773 char *buf_end)
00774 {
00775 xmlAttrPtr attr;
00776 char *p, *p_orig;
00777 unsigned char *nr_attr;
00778 str val;
00779
00780 nr_attr = &(NR_OF_ATTR(node_ptr));
00781 *nr_attr = 0;
00782 p = p_orig = ATTR_PTR(node_ptr);
00783
00784 FOR_ALL_ATTR(node,attr) {
00785
00786 get_attr_val( attr->name , val, error);
00787 if ( !strcasecmp((const char*)attr->name,"source") ) {
00788
00789 if ( val.len!=SOURCE_REG_STR_LEN ||
00790 strncasecmp( val.s, SOURCE_REG_STR, val.len) ) {
00791 LM_ERR("unsupported value"
00792 " <%.*s> in SOURCE param\n",val.len,val.s);
00793 goto error;
00794 }
00795 } else if ( !strcasecmp((const char*)attr->name,"clear") ) {
00796 (*nr_attr)++;
00797 set_attr_type(p, CLEAR_ATTR, buf_end, error);
00798 if ( val.len==3 && !strncasecmp(val.s,"yes",3) )
00799 append_short_attr(p, YES_VAL, buf_end, error);
00800 else if ( val.len==2 && !strncasecmp(val.s,"no",2) )
00801 append_short_attr(p, NO_VAL, buf_end, error);
00802 else {
00803 LM_ERR("unknown value "
00804 "<%.*s> for attribute CLEAR\n",val.len,val.s);
00805 goto error;
00806 }
00807 } else if ( !strcasecmp((const char*)attr->name,"timeout") ) {
00808 LM_WARN("unsupported param TIMEOUT; skipping\n");
00809 } else {
00810 LM_ERR("unknown attribute <%s>\n",attr->name);
00811 goto error;
00812 }
00813 }
00814
00815 return p-p_orig;
00816 error:
00817 return -1;
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 static inline int encode_location_attr(xmlNodePtr node, char *node_ptr,
00829 char *buf_end)
00830 {
00831 struct sip_uri uri;
00832 xmlAttrPtr attr;
00833 char *p, *p_orig;
00834 unsigned char *nr_attr;
00835 unsigned short nr;
00836 str val;
00837
00838 nr_attr = &(NR_OF_ATTR(node_ptr));
00839 *nr_attr = 0;
00840 p = p_orig = ATTR_PTR(node_ptr);
00841
00842 FOR_ALL_ATTR(node,attr) {
00843 (*nr_attr)++;
00844
00845 get_attr_val( attr->name , val, error);
00846 switch(attr->name[0]) {
00847 case 'U': case 'u':
00848 set_attr_type(p, URL_ATTR, buf_end, error);
00849
00850
00851 if (parse_uri( val.s, val.len, &uri)!=0) {
00852 LM_ERR("<%s> is not a valid SIP URL\n",val.s);
00853 goto error;
00854 }
00855 val.len++;
00856 append_str_attr(p,val, buf_end, error);
00857 break;
00858 case 'P': case 'p':
00859 set_attr_type(p, PRIORITY_ATTR, buf_end, error);
00860 if (val.s[0]=='0') nr=0;
00861 else if (val.s[0]=='1') nr=10;
00862 else goto prio_error;
00863 if (val.s[1]!='.') goto prio_error;
00864 if (val.s[2]<'0' || val.s[2]>'9') goto prio_error;
00865 nr += val.s[2] - '0';
00866 if (nr>10)
00867 goto prio_error;
00868 append_short_attr(p, nr, buf_end, error);
00869 break;
00870 case 'C': case 'c':
00871 set_attr_type(p, CLEAR_ATTR, buf_end, error);
00872 if (val.s[0]=='y' || val.s[0]=='Y')
00873 append_short_attr(p, YES_VAL, buf_end, error);
00874 else
00875 append_short_attr(p, NO_VAL, buf_end, error);
00876 break;
00877 default:
00878 LM_ERR("unknown attribute <%s>\n",attr->name);
00879 goto error;
00880 }
00881 }
00882
00883 return p-p_orig;
00884 prio_error:
00885 LM_ERR("invalid priority <%s>\n",val.s);
00886 error:
00887 return -1;
00888 }
00889
00890
00891
00892
00893
00894
00895 static inline int encode_rmvloc_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
00896 {
00897 struct sip_uri uri;
00898 xmlAttrPtr attr;
00899 char *p, *p_orig;
00900 unsigned char *nr_attr;
00901 str val;
00902
00903 nr_attr = &(NR_OF_ATTR(node_ptr));
00904 *nr_attr = 0;
00905 p = p_orig = ATTR_PTR(node_ptr);
00906
00907 FOR_ALL_ATTR(node,attr) {
00908 (*nr_attr)++;
00909 switch(attr->name[0]) {
00910 case 'L': case 'l':
00911 set_attr_type(p, LOCATION_ATTR, buf_end, error);
00912
00913 get_attr_val( attr->name , val, error);
00914
00915
00916 if (parse_uri( val.s, val.len, &uri)!=0) {
00917 LM_ERR("<%s> is not a valid SIP URL\n",val.s);
00918 goto error;
00919 }
00920 val.len++;
00921 append_str_attr(p,val, buf_end, error);
00922 break;
00923 case 'P': case 'p':
00924 case 'V': case 'v':
00925
00926
00927 break;
00928 default:
00929 LM_ERR("unknown attribute <%s>\n",attr->name);
00930 goto error;
00931 }
00932 }
00933
00934 return p-p_orig;
00935 error:
00936 return -1;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946 static inline int encode_proxy_attr(xmlNodePtr node, char *node_ptr,
00947 char *buf_end)
00948 {
00949 xmlAttrPtr attr;
00950 char *p, *p_orig;
00951 unsigned char *nr_attr;
00952 unsigned int nr;
00953 str val;
00954
00955 nr_attr = &(NR_OF_ATTR(node_ptr));
00956 *nr_attr = 0;
00957 p = p_orig = ATTR_PTR(node_ptr);
00958
00959 FOR_ALL_ATTR(node,attr) {
00960 (*nr_attr)++;
00961
00962 get_attr_val( attr->name , val, error);
00963 switch(attr->name[0]) {
00964 case 'R': case 'r':
00965 set_attr_type(p, RECURSE_ATTR, buf_end, error);
00966 if (val.s[0]=='y' || val.s[0]=='Y')
00967 append_short_attr(p, YES_VAL, buf_end, error);
00968 else if (val.s[0]=='n' || val.s[0]=='N')
00969 append_short_attr(p, NO_VAL, buf_end, error);
00970 else {
00971 LM_ERR("unknown value "
00972 "<%s> for attribute RECURSE\n",val.s);
00973 goto error;
00974 }
00975 break;
00976 case 'T': case 't':
00977 set_attr_type(p, TIMEOUT_ATTR, buf_end, error);
00978 if (str2int(&val,&nr)==-1) {
00979 LM_ERR("bad value <%.*s>"
00980 " for attribute TIMEOUT\n",val.len,val.s);
00981 goto error;
00982 }
00983 append_short_attr(p, (unsigned short)nr, buf_end, error);
00984 break;
00985 case 'O': case 'o':
00986 set_attr_type(p, ORDERING_ATTR, buf_end, error);
00987 switch (val.s[0]) {
00988 case 'p': case'P':
00989 append_short_attr(p, PARALLEL_VAL, buf_end, error);
00990 break;
00991 case 'S': case 's':
00992 append_short_attr(p, SEQUENTIAL_VAL, buf_end, error);
00993 break;
00994 case 'F': case 'f':
00995 append_short_attr(p, FIRSTONLY_VAL, buf_end, error);
00996 break;
00997 default:
00998 LM_ERR("unknown "
00999 "value <%s> for attribute ORDERING\n",val.s);
01000 goto error;
01001 }
01002 break;
01003 default:
01004 LM_ERR("unknown attribute <%s>\n",attr->name);
01005 goto error;
01006 }
01007 }
01008
01009 return p-p_orig;
01010 error:
01011 return -1;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020 static inline int encode_reject_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
01021 {
01022 xmlAttrPtr attr;
01023 char *p, *p_orig;
01024 unsigned char *nr_attr;
01025 unsigned int nr;
01026 str val;
01027
01028 nr_attr = &(NR_OF_ATTR(node_ptr));
01029 *nr_attr = 0;
01030 p = p_orig = ATTR_PTR(node_ptr);
01031
01032 FOR_ALL_ATTR(node,attr) {
01033 (*nr_attr)++;
01034
01035 get_attr_val( attr->name , val, error);
01036 switch(attr->name[0]) {
01037 case 'R': case 'r':
01038 set_attr_type(p, REASON_ATTR, buf_end, error);
01039 val.len++;
01040 append_str_attr(p, val, buf_end, error);
01041 break;
01042 case 'S': case 's':
01043 set_attr_type(p, STATUS_ATTR, buf_end, error);
01044 if (str2int(&val,&nr)==-1) {
01045
01046 if (val.len==BUSY_STR_LEN &&
01047 !strncasecmp(val.s,BUSY_STR,val.len)) {
01048 append_short_attr(p, BUSY_VAL, buf_end, error);
01049 } else if (val.len==NOTFOUND_STR_LEN &&
01050 !strncasecmp(val.s,NOTFOUND_STR,val.len)) {
01051 append_short_attr(p, NOTFOUND_VAL, buf_end, error);
01052 } else if (val.len==ERROR_STR_LEN &&
01053 !strncasecmp(val.s,ERROR_STR,val.len)) {
01054 append_short_attr(p, ERROR_VAL, buf_end, error);
01055 } else if (val.len==REJECT_STR_LEN &&
01056 !strncasecmp(val.s,REJECT_STR,val.len)) {
01057 append_short_attr(p, REJECT_VAL, buf_end, error);
01058 } else {
01059 LM_ERR("bad val. <%s> for STATUS\n",val.s);
01060 goto error;
01061 }
01062 } else if (nr<400 || nr>700) {
01063 LM_ERR("bad code <%d> for STATUS\n",nr);
01064 goto error;
01065 } else {
01066 append_short_attr(p, nr, buf_end, error);
01067 }
01068 break;
01069 default:
01070 LM_ERR("unknown attribute <%s>\n",attr->name);
01071 goto error;
01072 }
01073 }
01074
01075 return p-p_orig;
01076 error:
01077 return -1;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086 static inline int encode_redirect_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
01087 {
01088 xmlAttrPtr attr;
01089 char *p, *p_orig;
01090 unsigned char *nr_attr;
01091 str val;
01092
01093 nr_attr = &(NR_OF_ATTR(node_ptr));
01094 *nr_attr = 0;
01095 p = p_orig = ATTR_PTR(node_ptr);
01096
01097 FOR_ALL_ATTR(node,attr) {
01098 (*nr_attr)++;
01099 if (attr->name[0]=='p' || attr->name[0]=='P') {
01100 set_attr_type(p, PERMANENT_ATTR, buf_end, error);
01101
01102 get_attr_val( attr->name , val, error);
01103 if (val.s[0]=='y' || val.s[0]=='Y')
01104 append_short_attr( p, YES_VAL, buf_end, error);
01105 else if (val.s[0]=='n' || val.s[0]=='N')
01106 append_short_attr( p, NO_VAL, buf_end, error);
01107 else {
01108 LM_ERR("bad val. <%s> for PERMANENT\n",val.s);
01109 goto error;
01110 }
01111 } else {
01112 LM_ERR("unknown attribute <%s>\n",attr->name);
01113 goto error;
01114 }
01115 }
01116
01117 return p-p_orig;
01118 error:
01119 return -1;
01120 }
01121
01122
01123
01124
01125
01126
01127
01128 static inline int encode_log_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
01129 {
01130 xmlAttrPtr attr;
01131 char *p, *p_orig;
01132 unsigned char *nr_attr;
01133 str val;
01134
01135 nr_attr = &(NR_OF_ATTR(node_ptr));
01136 *nr_attr = 0;
01137 p = p_orig = ATTR_PTR(node_ptr);
01138
01139 FOR_ALL_ATTR(node,attr) {
01140 (*nr_attr)++;
01141
01142 get_attr_val( attr->name , val, error);
01143 switch (attr->name[0] ) {
01144 case 'n': case 'N':
01145 if (val.len>MAX_NAME_SIZE) val.len=MAX_NAME_SIZE;
01146 set_attr_type(p, NAME_ATTR, buf_end, error);
01147 break;
01148 case 'c': case 'C':
01149 if (val.len>MAX_COMMENT_SIZE) val.len=MAX_COMMENT_SIZE;
01150 set_attr_type(p, COMMENT_ATTR, buf_end, error);
01151 break;
01152 default:
01153 LM_ERR("unknown attribute <%s>\n",attr->name);
01154 goto error;
01155 }
01156
01157 val.s[val.len++]=0;
01158 append_str_attr(p,val, buf_end, error);
01159 }
01160
01161 return p-p_orig;
01162 error:
01163 return -1;
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173 static inline int encode_mail_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
01174 {
01175 xmlAttrPtr attr;
01176 char *p, *p_orig;
01177 unsigned char *nr_attr;
01178
01179 nr_attr = &(NR_OF_ATTR(node_ptr));
01180 *nr_attr = 0;
01181 p = p_orig = ATTR_PTR(node_ptr);
01182
01183 FOR_ALL_ATTR(node,attr) {
01184
01185 if (attr->name[0]!='u' && attr->name[0]!='U') {
01186 LM_ERR("unknown attribute <%s>\n",attr->name);
01187 goto error;
01188 }
01189 p = decode_mail_url( p, buf_end,
01190 (char*)xmlGetProp(node,attr->name), nr_attr);
01191 if (p==0)
01192 goto error;
01193 }
01194
01195 return p-p_orig;
01196 error:
01197 return -1;
01198 }
01199
01200
01201
01202
01203
01204 static inline int encode_subaction_attr(xmlNodePtr node, char *node_ptr,
01205 char *buf_end)
01206 {
01207 xmlAttrPtr attr;
01208 str val;
01209
01210 FOR_ALL_ATTR(node,attr) {
01211
01212 if ((attr->name[0]|0x20)=='i' && ((attr->name[1]|0x20)=='d') &&
01213 attr->name[2]==0 ) {
01214
01215 get_attr_val( attr->name , val, error);
01216 if ((list = append_to_list(list, node_ptr,val.s))==0) {
01217 LM_ERR("failed to add "
01218 "subaction into list -> pkg_malloc failed?\n");
01219 goto error;
01220 }
01221 } else {
01222 LM_ERR("unknown attribute <%s>\n",attr->name);
01223 goto error;
01224 }
01225 }
01226
01227 return 0;
01228 error:
01229 return -1;
01230 }
01231
01232
01233
01234
01235
01236
01237 static inline int encode_sub_attr(xmlNodePtr node, char *node_ptr, char *buf_end)
01238 {
01239 xmlAttrPtr attr;
01240 char *p, *p_orig;
01241 unsigned char *nr_attr;
01242 char *sub_ptr;
01243 str val;
01244
01245 nr_attr = &(NR_OF_ATTR(node_ptr));
01246 *nr_attr = 0;
01247 p = p_orig = ATTR_PTR(node_ptr);
01248
01249 FOR_ALL_ATTR(node,attr) {
01250 (*nr_attr)++;
01251
01252 if ( strcasecmp("ref",(char*)attr->name)!=0 ) {
01253 LM_ERR("unknown attribute <%s>\n",attr->name);
01254 goto error;
01255 }
01256 set_attr_type(p, REF_ATTR, buf_end, error);
01257
01258 get_attr_val( attr->name , val, error);
01259 if ( (sub_ptr=search_the_list(list, val.s))==0 ) {
01260 LM_ERR("unable to find declaration "
01261 "of subaction <%s>\n",val.s);
01262 goto error;
01263 }
01264 append_short_attr(p,(unsigned short)(node_ptr-sub_ptr),buf_end,error);
01265 }
01266
01267 return p-p_orig;
01268 error:
01269 return -1;
01270 }
01271
01272
01273
01274
01275
01276
01277 int encode_node( xmlNodePtr node, char *p, char *p_end)
01278 {
01279 xmlNodePtr kid;
01280 unsigned short sub_tree_size;
01281 int attr_size;
01282 int kid_size;
01283 int foo;
01284
01285
01286 for(kid=node->children,foo=0;kid;kid=kid->next)
01287 if (kid->type==XML_ELEMENT_NODE) foo++;
01288 check_overflow(p,GET_NODE_SIZE(foo),p_end,error);
01289 NR_OF_KIDS(p) = foo;
01290
01291
01292 attr_size = 0;
01293
01294
01295 NR_OF_ATTR(p) = 0;
01296
01297
01298 switch (node->name[0]) {
01299 case 'a':case 'A':
01300 switch (node->name[7]) {
01301 case 0:
01302 NODE_TYPE(p) = ADDRESS_NODE;
01303 attr_size = encode_address_attr( node, p, p_end);
01304 break;
01305 case '-':
01306 NODE_TYPE(p) = ADDRESS_SWITCH_NODE;
01307 attr_size = encode_address_switch_attr( node, p, p_end);
01308 break;
01309 default:
01310 NODE_TYPE(p) = ANCILLARY_NODE;
01311 break;
01312 }
01313 break;
01314 case 'B':case 'b':
01315 NODE_TYPE(p) = BUSY_NODE;
01316 break;
01317 case 'c':case 'C':
01318 NODE_TYPE(p) = CPL_NODE;
01319 break;
01320 case 'd':case 'D':
01321 NODE_TYPE(p) = DEFAULT_NODE;
01322 break;
01323 case 'f':case 'F':
01324 NODE_TYPE(p) = FAILURE_NODE;
01325 break;
01326 case 'i':case 'I':
01327 NODE_TYPE(p) = INCOMING_NODE;
01328 break;
01329 case 'l':case 'L':
01330 switch (node->name[2]) {
01331 case 'g':case 'G':
01332 NODE_TYPE(p) = LOG_NODE;
01333 attr_size = encode_log_attr( node, p, p_end);
01334 break;
01335 case 'o':case 'O':
01336 NODE_TYPE(p) = LOOKUP_NODE;
01337 attr_size = encode_lookup_attr( node, p, p_end);
01338 break;
01339 case 'c':case 'C':
01340 NODE_TYPE(p) = LOCATION_NODE;
01341 attr_size = encode_location_attr( node, p, p_end);
01342 break;
01343 default:
01344 if (node->name[8]) {
01345 NODE_TYPE(p) = LANGUAGE_SWITCH_NODE;
01346 } else {
01347 NODE_TYPE(p) = LANGUAGE_NODE;
01348 attr_size = encode_lang_attr( node, p, p_end);
01349 }
01350 break;
01351 }
01352 break;
01353 case 'm':case 'M':
01354 NODE_TYPE(p) = MAIL_NODE;
01355 attr_size = encode_mail_attr( node, p, p_end);
01356 break;
01357 case 'n':case 'N':
01358 switch (node->name[3]) {
01359 case 'F':case 'f':
01360 NODE_TYPE(p) = NOTFOUND_NODE;
01361 break;
01362 case 'N':case 'n':
01363 NODE_TYPE(p) = NOANSWER_NODE;
01364 break;
01365 default:
01366 NODE_TYPE(p) = NOT_PRESENT_NODE;
01367 break;
01368 }
01369 break;
01370 case 'o':case 'O':
01371 if (node->name[1]=='t' || node->name[1]=='T') {
01372 NODE_TYPE(p) = OTHERWISE_NODE;
01373 } else {
01374 NODE_TYPE(p) = OUTGOING_NODE;
01375 }
01376 break;
01377 case 'p':case 'P':
01378 if (node->name[2]=='o' || node->name[2]=='O') {
01379 NODE_TYPE(p) = PROXY_NODE;
01380 attr_size = encode_proxy_attr( node, p, p_end);
01381 } else if (node->name[8]) {
01382 NODE_TYPE(p) = PRIORITY_SWITCH_NODE;
01383 } else {
01384 NODE_TYPE(p) = PRIORITY_NODE;
01385 attr_size = encode_priority_attr( node, p, p_end);
01386 }
01387 break;
01388 case 'r':case 'R':
01389 switch (node->name[2]) {
01390 case 'j':case 'J':
01391 NODE_TYPE(p) = REJECT_NODE;
01392 attr_size = encode_reject_attr( node, p, p_end);
01393 break;
01394 case 'm':case 'M':
01395 NODE_TYPE(p) = REMOVE_LOCATION_NODE;
01396 attr_size = encode_rmvloc_attr( node, p, p_end);
01397 break;
01398 default:
01399 if (node->name[8]) {
01400 NODE_TYPE(p) = REDIRECTION_NODE;
01401 } else {
01402 NODE_TYPE(p) = REDIRECT_NODE;
01403 attr_size = encode_redirect_attr( node, p, p_end);
01404 }
01405 break;
01406 }
01407 break;
01408 case 's':case 'S':
01409 switch (node->name[3]) {
01410 case 0:
01411 NODE_TYPE(p) = SUB_NODE;
01412 attr_size = encode_sub_attr( node, p, p_end);
01413 break;
01414 case 'c':case 'C':
01415 NODE_TYPE(p) = SUCCESS_NODE;
01416 break;
01417 case 'a':case 'A':
01418 NODE_TYPE(p) = SUBACTION_NODE;
01419 attr_size = encode_subaction_attr( node, p, p_end);
01420 break;
01421 default:
01422 if (node->name[6]) {
01423 NODE_TYPE(p) = STRING_SWITCH_NODE;
01424 attr_size = encode_string_switch_attr( node, p, p_end);
01425 } else {
01426 NODE_TYPE(p) = STRING_NODE;
01427 attr_size = encode_string_attr( node, p, p_end);
01428 }
01429 break;
01430 }
01431 break;
01432 case 't':case 'T':
01433 if (node->name[4]) {
01434 NODE_TYPE(p) = TIME_SWITCH_NODE;
01435 attr_size = encode_time_switch_attr( node, p, p_end);
01436 } else {
01437 NODE_TYPE(p) = TIME_NODE;
01438 attr_size = encode_time_attr( node, p, p_end);
01439 }
01440 break;
01441 default:
01442 LM_ERR("unknown node <%s>\n",node->name);
01443 goto error;
01444 }
01445
01446
01447 if (attr_size<0)
01448 goto error;
01449 sub_tree_size = SIMPLE_NODE_SIZE(p) + (unsigned short)attr_size;
01450
01451
01452 for(kid = node->children,foo=0;kid;kid=kid->next) {
01453 if (kid->type!=XML_ELEMENT_NODE) continue;
01454 SET_KID_OFFSET( p, foo, sub_tree_size);
01455 kid_size = encode_node( kid, p+sub_tree_size, p_end);
01456 if (kid_size<=0)
01457 goto error;
01458 sub_tree_size += (unsigned short)kid_size;
01459 foo++;
01460 }
01461
01462 return sub_tree_size;
01463 error:
01464 return -1;
01465 }
01466
01467
01468
01469 #define BAD_XML "CPL script is not a valid XML document"
01470 #define BAD_XML_LEN (sizeof(BAD_XML)-1)
01471 #define BAD_CPL "CPL script doesn't respect CPL grammar"
01472 #define BAD_CPL_LEN (sizeof(BAD_CPL)-1)
01473 #define NULL_CPL "Empty CPL script"
01474 #define NULL_CPL_LEN (sizeof(NULL_CPL)-1)
01475 #define ENC_ERR "Encoding of the CPL script failed"
01476 #define ENC_ERR_LEN (sizeof(ENC_ERR)-1)
01477
01478 int encodeCPL( str *xml, str *bin, str *log)
01479 {
01480 static char buf[ENCONDING_BUFFER_SIZE];
01481 xmlDocPtr doc;
01482 xmlNodePtr cur;
01483
01484 doc = 0;
01485 list = 0;
01486
01487
01488
01489 reset_logs();
01490
01491
01492 doc = xmlParseDoc( (unsigned char*)xml->s );
01493 if (!doc) {
01494 append_log( 1, ERR BAD_XML LF, ERR_LEN+BAD_XML_LEN+LF_LEN);
01495 LM_ERR( BAD_XML "\n");
01496 goto error;
01497 }
01498
01499
01500 if (xmlValidateDtd(&cvp, doc, dtd)!=1) {
01501 append_log( 1, ERR BAD_CPL LF, ERR_LEN+BAD_CPL_LEN+LF_LEN);
01502 LM_ERR( BAD_CPL "\n");
01503 goto error;
01504 }
01505
01506 cur = xmlDocGetRootElement(doc);
01507 if (!cur) {
01508 append_log( 1, ERR NULL_CPL LF, ERR_LEN+NULL_CPL_LEN+LF_LEN);
01509 LM_ERR( NULL_CPL "\n");
01510 goto error;
01511 }
01512
01513 bin->len = encode_node( cur, buf, buf+ENCONDING_BUFFER_SIZE);
01514 if (bin->len<0) {
01515 append_log( 1, ERR ENC_ERR LF, ERR_LEN+ENC_ERR_LEN+LF_LEN);
01516 LM_ERR( ENC_ERR "\n");
01517 goto error;
01518 }
01519
01520 xmlFreeDoc(doc);
01521 if (list) delete_list(list);
01522
01523 compile_logs( log );
01524 bin->s = buf;
01525 return 1;
01526 error:
01527 if (doc) xmlFreeDoc(doc);
01528 if (list) delete_list(list);
01529
01530 compile_logs( log );
01531 return 0;
01532 }
01533
01534
01535
01536
01537 int init_CPL_parser( char* DTD_filename )
01538 {
01539 dtd = xmlParseDTD( NULL, (unsigned char*)DTD_filename);
01540 if (!dtd) {
01541 LM_ERR("DTD not parsed successfully\n");
01542 return -1;
01543 }
01544 cvp.userData = (void *) stderr;
01545 cvp.error = (xmlValidityErrorFunc) fprintf;
01546 cvp.warning = (xmlValidityWarningFunc) fprintf;
01547
01548 return 1;
01549 }
01550