📄 cpl_parser.c
字号:
/*it was a non numeric value */ if (val.len==BUSY_STR_LEN && !strncasecmp(val.s,BUSY_STR,val.len)) { append_short_attr(p, BUSY_VAL, buf_end, error); } else if (val.len==NOTFOUND_STR_LEN && !strncasecmp(val.s,NOTFOUND_STR,val.len)) { append_short_attr(p, NOTFOUND_VAL, buf_end, error); } else if (val.len==ERROR_STR_LEN && !strncasecmp(val.s,ERROR_STR,val.len)) { append_short_attr(p, ERROR_VAL, buf_end, error); } else if (val.len==REJECT_STR_LEN && !strncasecmp(val.s,REJECT_STR,val.len)) { append_short_attr(p, REJECT_VAL, buf_end, error); } else { LOG(L_ERR,"ERROR:cpl_c:encode_priority_attr: bad " "val. <%s> for STATUS\n",val.s); goto error; } } else if (nr<400 || nr>700) { LOG(L_ERR,"ERROR:cpl_c:encode_priority_attr: bad " "code <%d> for STATUS\n",nr); goto error; } else { append_short_attr(p, nr, buf_end, error); } break; default: LOG(L_ERR,"ERROR:cpl_c:encode_priority_attr: unknown attribute " "<%s>\n",attr->name); goto error; } } return p-p_orig;error: return -1;}/* Attr. encoding for REDIRECT node: * | attr1_t(2) attr1_val(2) | STATUS attr * [| attr2_t(2) attr2_len(2) attr2_val(2*x)|]? REASON attr (NT) */static inline int encode_redirect_attr(xmlNodePtr node, char *node_ptr, char *buf_end){ xmlAttrPtr attr; char *p, *p_orig; unsigned char *nr_attr; str val; nr_attr = &(NR_OF_ATTR(node_ptr)); *nr_attr = 0; p = p_orig = ATTR_PTR(node_ptr); FOR_ALL_ATTR(node,attr) { (*nr_attr)++; if (attr->name[0]=='p' || attr->name[0]=='P') { set_attr_type(p, PERMANENT_ATTR, buf_end, error); /* get the value */ get_attr_val( attr->name , val, error); if (val.s[0]=='y' || val.s[0]=='Y') append_short_attr( p, YES_VAL, buf_end, error); else if (val.s[0]=='n' || val.s[0]=='N') append_short_attr( p, NO_VAL, buf_end, error); else { LOG(L_ERR,"ERROR:cpl_c:encode_redirect_attr: bad " "val. <%s> for PERMANENT\n",val.s); goto error; } } else { LOG(L_ERR,"ERROR:cpl_c:encode_redirect_attr: unknown attribute " "<%s>\n",attr->name); goto error; } } return p-p_orig;error: return -1;}/* Attr. encoding for LOG node: * [| attr1_t(2) attr1_len(2) attr1_val(2*x) |]? NAME attr (NT) * [| attr2_t(2) attr2_len(2) attr2_val(2*x) |]? COMMENT attr (NT) */static inline int encode_log_attr(xmlNodePtr node, char *node_ptr, char *buf_end){ xmlAttrPtr attr; char *p, *p_orig; unsigned char *nr_attr; str val; nr_attr = &(NR_OF_ATTR(node_ptr)); *nr_attr = 0; p = p_orig = ATTR_PTR(node_ptr); FOR_ALL_ATTR(node,attr) { (*nr_attr)++; /* get the value of the attribute */ get_attr_val( attr->name , val, error); switch (attr->name[0] ) { case 'n': case 'N': if (val.len>MAX_NAME_SIZE) val.len=MAX_NAME_SIZE; set_attr_type(p, NAME_ATTR, buf_end, error); break; case 'c': case 'C': if (val.len>MAX_COMMENT_SIZE) val.len=MAX_COMMENT_SIZE; set_attr_type(p, COMMENT_ATTR, buf_end, error); break; default: LOG(L_ERR,"ERROR:cpl_c:encode_log_attr: unknown attribute " "<%s>\n",attr->name); goto error; } /* be sure there is a \0 at the end of string */ val.s[val.len++]=0; append_str_attr(p,val, buf_end, error); } return p-p_orig;error: return -1;}/* Attr. encoding for MAIL node: * | attr1_t(2) attr1_len(2) attr1_val(2*x) | TO_ATTR attr (NNT) * [| attr2_t(2) attr2_len(2) attr2_val(2*x) |]? SUBJECT_ATTR attr (NNT) * [| attr3_t(2) attr3_len(2) attr3_val(2*x) |]? BODY_ATTR attr (NNT) */static inline int encode_mail_attr(xmlNodePtr node, char *node_ptr, char *buf_end){ xmlAttrPtr attr; char *p, *p_orig; unsigned char *nr_attr; nr_attr = &(NR_OF_ATTR(node_ptr)); *nr_attr = 0; p = p_orig = ATTR_PTR(node_ptr); FOR_ALL_ATTR(node,attr) { /* there is only one attribute -> URL */ if (attr->name[0]!='u' && attr->name[0]!='U') { LOG(L_ERR,"ERROR:cpl_c:encode_node_attr: unknown attribute " "<%s>\n",attr->name); goto error; } p = decode_mail_url( p, buf_end, (char*)xmlGetProp(node,attr->name), nr_attr); if (p==0) goto error; } return p-p_orig;error: return -1;}/* Attr. encoding for SUBACTION node: */static inline int encode_subaction_attr(xmlNodePtr node, char *node_ptr, char *buf_end){ xmlAttrPtr attr; str val; FOR_ALL_ATTR(node,attr) { /* there is only one attribute -> ID */ if ((attr->name[0]|0x20)=='i' && ((attr->name[1]|0x20)=='d') && attr->name[2]==0 ) { /* get the value of the attribute */ get_attr_val( attr->name , val, error); if ((list = append_to_list(list, node_ptr,val.s))==0) { LOG(L_ERR,"ERROR:cpl_c:encode_subaction_attr: failed to add " "subaction into list -> pkg_malloc failed?\n"); goto error; } } else { LOG(L_ERR,"ERROR:cpl_c:encode_subaction_attr: unknown attribute " "<%s>\n",attr->name); goto error; } } return 0;error: return -1;}/* Attr. encoding for SUB node: * | attr1_t(2) attr1_val(2) | REF_ATTR attr */static inline int encode_sub_attr(xmlNodePtr node, char *node_ptr, char *buf_end){ xmlAttrPtr attr; char *p, *p_orig; unsigned char *nr_attr; char *sub_ptr; str val; nr_attr = &(NR_OF_ATTR(node_ptr)); *nr_attr = 0; p = p_orig = ATTR_PTR(node_ptr); FOR_ALL_ATTR(node,attr) { (*nr_attr)++; /* there is only one attribute -> REF */ if ( strcasecmp("ref",(char*)attr->name)!=0 ) { LOG(L_ERR,"ERROR:cpl_c:encode_sub_attr: unknown attribute " "<%s>\n",attr->name); goto error; } set_attr_type(p, REF_ATTR, buf_end, error); /* get the value of the attribute */ get_attr_val( attr->name , val, error); if ( (sub_ptr=search_the_list(list, val.s))==0 ) { LOG(L_ERR,"ERROR:cpl_c:encode_sub_attr: unable to find declaration " "of subaction <%s>\n",val.s); goto error; } append_short_attr(p,(unsigned short)(node_ptr-sub_ptr),buf_end,error); } return p-p_orig;error: return -1;}/* Returns : -1 - error * >0 - subtree size of the given node */int encode_node( xmlNodePtr node, char *p, char *p_end){ xmlNodePtr kid; unsigned short sub_tree_size; int attr_size; int kid_size; int foo; /* counting the kids */ for(kid=node->children,foo=0;kid;kid=kid->next) if (kid->type==XML_ELEMENT_NODE) foo++; check_overflow(p,GET_NODE_SIZE(foo),p_end,error); NR_OF_KIDS(p) = foo; /* size of the encoded attributes */ attr_size = 0; /* init the number of attributes */ NR_OF_ATTR(p) = 0; /* encode node name */ switch (node->name[0]) { case 'a':case 'A': switch (node->name[7]) { case 0: NODE_TYPE(p) = ADDRESS_NODE; attr_size = encode_address_attr( node, p, p_end); break; case '-': NODE_TYPE(p) = ADDRESS_SWITCH_NODE; attr_size = encode_address_switch_attr( node, p, p_end); break; default: NODE_TYPE(p) = ANCILLARY_NODE; break; } break; case 'B':case 'b': NODE_TYPE(p) = BUSY_NODE; break; case 'c':case 'C': NODE_TYPE(p) = CPL_NODE; break; case 'd':case 'D': NODE_TYPE(p) = DEFAULT_NODE; break; case 'f':case 'F': NODE_TYPE(p) = FAILURE_NODE; break; case 'i':case 'I': NODE_TYPE(p) = INCOMING_NODE; break; case 'l':case 'L': switch (node->name[2]) { case 'g':case 'G': NODE_TYPE(p) = LOG_NODE; attr_size = encode_log_attr( node, p, p_end); break; case 'o':case 'O': NODE_TYPE(p) = LOOKUP_NODE; attr_size = encode_lookup_attr( node, p, p_end); break; case 'c':case 'C': NODE_TYPE(p) = LOCATION_NODE; attr_size = encode_location_attr( node, p, p_end); break; default: if (node->name[8]) { NODE_TYPE(p) = LANGUAGE_SWITCH_NODE; } else { NODE_TYPE(p) = LANGUAGE_NODE; attr_size = encode_lang_attr( node, p, p_end); } break; } break; case 'm':case 'M': NODE_TYPE(p) = MAIL_NODE; attr_size = encode_mail_attr( node, p, p_end); break; case 'n':case 'N': switch (node->name[3]) { case 'F':case 'f': NODE_TYPE(p) = NOTFOUND_NODE; break; case 'N':case 'n': NODE_TYPE(p) = NOANSWER_NODE; break; default: NODE_TYPE(p) = NOT_PRESENT_NODE; break; } break; case 'o':case 'O': if (node->name[1]=='t' || node->name[1]=='T') { NODE_TYPE(p) = OTHERWISE_NODE; } else { NODE_TYPE(p) = OUTGOING_NODE; } break; case 'p':case 'P': if (node->name[2]=='o' || node->name[2]=='O') { NODE_TYPE(p) = PROXY_NODE; attr_size = encode_proxy_attr( node, p, p_end); } else if (node->name[8]) { NODE_TYPE(p) = PRIORITY_SWITCH_NODE; } else { NODE_TYPE(p) = PRIORITY_NODE; attr_size = encode_priority_attr( node, p, p_end); } break; case 'r':case 'R': switch (node->name[2]) { case 'j':case 'J': NODE_TYPE(p) = REJECT_NODE; attr_size = encode_reject_attr( node, p, p_end); break; case 'm':case 'M': NODE_TYPE(p) = REMOVE_LOCATION_NODE; attr_size = encode_rmvloc_attr( node, p, p_end); break; default: if (node->name[8]) { NODE_TYPE(p) = REDIRECTION_NODE; } else { NODE_TYPE(p) = REDIRECT_NODE; attr_size = encode_redirect_attr( node, p, p_end); } break; } break; case 's':case 'S': switch (node->name[3]) { case 0: NODE_TYPE(p) = SUB_NODE; attr_size = encode_sub_attr( node, p, p_end); break; case 'c':case 'C': NODE_TYPE(p) = SUCCESS_NODE; break; case 'a':case 'A': NODE_TYPE(p) = SUBACTION_NODE; attr_size = encode_subaction_attr( node, p, p_end); break; default: if (node->name[6]) { NODE_TYPE(p) = STRING_SWITCH_NODE; attr_size = encode_string_switch_attr( node, p, p_end); } else { NODE_TYPE(p) = STRING_NODE; attr_size = encode_string_attr( node, p, p_end); } break; } break; case 't':case 'T': if (node->name[4]) { NODE_TYPE(p) = TIME_SWITCH_NODE; attr_size = encode_time_switch_attr( node, p, p_end); } else { NODE_TYPE(p) = TIME_NODE; attr_size = encode_time_attr( node, p, p_end); } break; default: LOG(L_ERR,"ERROR:cpl-c:encode_node: unknown node <%s>\n", node->name); goto error; } /* compute the total length of the node (including attributes) */ if (attr_size<0) goto error; sub_tree_size = SIMPLE_NODE_SIZE(p) + (unsigned short)attr_size; /* encrypt all the kids */ for(kid = node->children,foo=0;kid;kid=kid->next) { if (kid->type!=XML_ELEMENT_NODE) continue; SET_KID_OFFSET( p, foo, sub_tree_size); kid_size = encode_node( kid, p+sub_tree_size, p_end); if (kid_size<=0) goto error; sub_tree_size += (unsigned short)kid_size; foo++; } return sub_tree_size;error: return -1;}#define BAD_XML "CPL script is not a valid XML document"#define BAD_XML_LEN (sizeof(BAD_XML)-1)#define BAD_CPL "CPL script doesn't respect CPL grammar"#define BAD_CPL_LEN (sizeof(BAD_CPL)-1)#define NULL_CPL "Empty CPL script"#define NULL_CPL_LEN (sizeof(NULL_CPL)-1)#define ENC_ERR "Encoding of the CPL script failed"#define ENC_ERR_LEN (sizeof(ENC_ERR)-1)int encodeCPL( str *xml, str *bin, str *log){ static char buf[ENCONDING_BUFFER_SIZE]; xmlDocPtr doc; xmlNodePtr cur; doc = 0; list = 0; /* reset all the logs (if any) to catch some possible err/warn/notice * from the parser/validater/encoder */ reset_logs(); /* parse the xml */ doc = xmlParseDoc( (unsigned char*)xml->s ); if (!doc) { append_log( 1, ERR BAD_XML LF, ERR_LEN+BAD_XML_LEN+LF_LEN); LOG(L_ERR,"ERROR:cpl:encodeCPL:" BAD_XML "\n"); goto error; } /* check the xml against dtd */ if (xmlValidateDtd(&cvp, doc, dtd)!=1) { append_log( 1, ERR BAD_CPL LF, ERR_LEN+BAD_CPL_LEN+LF_LEN); LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " BAD_CPL "\n"); goto error; } cur = xmlDocGetRootElement(doc); if (!cur) { append_log( 1, ERR NULL_CPL LF, ERR_LEN+NULL_CPL_LEN+LF_LEN); LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " NULL_CPL "\n"); goto error; } bin->len = encode_node( cur, buf, buf+ENCONDING_BUFFER_SIZE); if (bin->len<0) { append_log( 1, ERR ENC_ERR LF, ERR_LEN+ENC_ERR_LEN+LF_LEN); LOG(L_ERR,"ERROR:cpl-c:encodeCPL: " ENC_ERR "\n"); goto error; } xmlFreeDoc(doc); if (list) delete_list(list); /* compile the log buffer */ compile_logs( log ); bin->s = buf; return 1;error: if (doc) xmlFreeDoc(doc); if (list) delete_list(list); /* compile the log buffer */ compile_logs( log ); return 0;}#if 0static void err_print(void *ctx, const char *msg, ...){ va_list ap; //char *t; va_start( ap, msg); LOG(L_ERR,"->>>> my errr <%s>\n",msg); //while ( (t=va_arg(ap, char *))!=0) { // LOG(L_ERR," -> <%s>\n",t); //} vfprintf(stderr,msg,ap); //append_log( 2, ERR, ERR_LEN, msg, strlen(msg) ); va_end(ap);}#endif/* loads and parse the dtd file; a validating context is created */int init_CPL_parser( char* DTD_filename ){ dtd = xmlParseDTD( NULL, (unsigned char*)DTD_filename); if (!dtd) { LOG(L_ERR,"ERROR:cpl-c:init_CPL_parser: DTD not parsed successfully\n"); return -1; } cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) /*err_print*/ fprintf; cvp.warning = (xmlValidityWarningFunc) /*err_print*/ fprintf; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -