rem: if(!rr_hdr->parsed && parse_rr(rr_hdr)){ LOG(L_ERR,"ERROR: vm: while parsing 'Record-Route:' header\n"); goto error; }  DBG("rr_hdr = 0x%X; rr_hdr->parsed = 0x%X\n",(unsigned int)rr_hdr,(unsigned int)rr_hdr->parsed);
add: if(rr_hdr && (!rr_hdr->parsed && parse_rr(rr_hdr))){ LOG(L_ERR,"ERROR: vm: while parsing 'Record-Route:' header\n"); goto error; }
context: static int vm_action(struct sip_msg* msg, char* vm_fifo, char* action){        str             body;        unsigned int    hash_index;        unsigned int    label;        contact_body_t* cb=0;        str*            str_uri=0;        str             email_query;        str             email;        db_res_t*       email_res=0;	contact_t*      c=0;	str             lines[VM_FIFO_PARAMS];	char            id_buf[IDBUF_LEN];	int             int_buflen, l;	char*           i2s;	char*           s;	rr_t*           record_route;	char            fproxy_lr;	//param_t*        route_param;	char            route_buffer[ROUTE_BUFFER_MAX];	str             route;	struct hdr_field* rr_hdr;	param_hooks_t     hooks;	str               tmp_str;	if(msg->first_line.type != SIP_REQUEST){	    LOG(L_ERR, "ERROR: vm() has been passed something else as a SIP request\n");	    goto error;	}	/* parse all -- we will need every header field for a UAS */	if (parse_headers(msg, HDR_EOH, 0)==-1) {		LOG(L_ERR, "ERROR: vm: parse_headers failed\n");		goto error;	}	/* find index and hash; (the transaction can be safely used due 	 * to refcounting till script completes)	 */        if( (*_tmb.t_get_trans_ident)(msg,&hash_index,&label) == -1 ) {		LOG(L_ERR,"ERROR: vm: t_get_trans_ident failed\n");		goto error;        }        if(parse_from_header(msg) == -1){		LOG(L_ERR,"ERROR: %s : vm: "				"while parsing <From:> header\n",exports.name);		goto error;        }	if (parse_sip_msg_uri(msg)<0) {  		LOG(L_ERR,"ERROR: %s : vm: uri has not been parsed\n",				exports.name);  		goto error;        }        if(msg->contact){		if(parse_contact(msg->contact) == -1){		    LOG(L_ERR,"ERROR: %s : vm: "			"while parsing <Contact:> header\n",exports.name);		    goto error;		}	#ifdef EXTRA_DEBUG		DBG("DEBUG: vm: ******* contacts: *******\n");#endif		cb = msg->contact->parsed;		if(cb && (c=cb->contacts)) {		    str_uri = &c->uri;#ifdef EXTRA_DEBUG		    /*print_contacts(c);*/		    for(; c; c=c->next)			DBG("DEBUG:           %.*s\n",c->uri.len,c->uri.s);#endif		}#ifdef EXTRA_DEBUG		DBG("DEBUG: vm: **** end of contacts ****\n");#endif        }	/* str_uri is taken from caller's contact or from is missing	 * for backwards compatibility with pre-3261 */        if(!str_uri || !str_uri->len)	    str_uri = &(get_from(msg)->uri);	//if(parse_nameaddr(str* _s, name_addr_t* _a)){	//    LOG(L_ERR,"ERROR: parse_nameaddr failed\n");	//}	route.s = route_buffer; route.len = 0;	s = route_buffer;	rr_hdr = msg->record_route;	if(!rr_hdr->parsed && parse_rr(rr_hdr)){	  LOG(L_ERR,"ERROR: vm: while parsing 'Record-Route:' header\n");	  goto error;	}	    	DBG("rr_hdr = 0x%X; rr_hdr->parsed = 0x%X\n",(unsigned int)rr_hdr,(unsigned int)rr_hdr->parsed);	record_route = rr_hdr ? rr_hdr->parsed : 0;		fproxy_lr = 0;	DBG("vm: ############# record route header ##############\n");	DBG("rr_hdr && record_route = %X && %X\n",(unsigned int)rr_hdr,(unsigned int)record_route);	if(rr_hdr && record_route){#define copy_route(s,len,rs,rlen) \   do {\     if(rlen+len+3 >= ROUTE_BUFFER_MAX){\       LOG(L_ERR,"vm: buffer overflow while copying new route");\       goto error;\     }\     if(len){\       append_str(s,",",1);len++;\     }\     append_str(s,"<",1);len++;\     append_str(s,rs,rlen);\     len += rlen; \     append_str(s,">",1);len++;\   } while(0);	  if(rr_hdr->body.len){	      	    /* Parse all parameters */	    DBG("record_route->nameaddr.uri (before parse_params): %.*s\n",record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);	    tmp_str = record_route->nameaddr.uri;	    if (parse_params(&tmp_str, CLASS_RR, &hooks, &record_route->params) < 0) {	      LOG(L_ERR, "vm: Error while parsing record route uri params\n");	      goto error;	    }	    	    //for(route_param=record_route->params; route_param; route_param=route_param->next)	    fproxy_lr = (hooks.rr.lr != 0);//|= (route_param->type == P_LR);	    	    DBG("record_route->nameaddr.uri: %.*s\n",record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);	    if(fproxy_lr){	      copy_route(s,route.len,record_route->nameaddr.uri.s,record_route->nameaddr.uri.len);	    }	  }	  rr_hdr = rr_hdr->next;	  for(;;rr_hdr = rr_hdr->next){	    if(rr_hdr && (rr_hdr->type == HDR_RECORDROUTE) && rr_hdr->body.len){	      	      if(!rr_hdr->parsed && parse_rr(rr_hdr)){		LOG(L_ERR,"ERROR: %s : vm: "		  "while parsing <Record-route:> header\n",exports.name);		goto error;	      }	      	      for(record_route = rr_hdr->parsed; record_route; record_route = record_route->next){		DBG("record_route->nameaddr.uri: %.*s\n",record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);		copy_route(s,route.len,record_route->nameaddr.uri.s,record_route->nameaddr.uri.len);	      }	    } 	    if(rr_hdr == msg->last_header)	      break;	  }	  if(!fproxy_lr){	    copy_route(s,route.len,str_uri->s,str_uri->len);	    str_uri = &((rr_t*)msg->record_route->parsed)->nameaddr.uri;	  }//  	const char* cur = route.c_str();//  	const char* end = cur + route.length();//  	bool is_uri=false;//  	while(cur<end){//  	    if(*cur == '<')//  		is_uri = true;//  	    else if(*cur == '>')//  		is_uri = false;//  	    else if(*cur == ';' && !is_uri) //  		break;//  	    cur++;//  	}//  	string first_route(route,0,cur-route.c_str());//  	if(first_route.find(";lr") >= first_route.length()) {//  	    // 1st proxy doesn't support loose-routing//  	    route = string(cur+1, route.length() + route.c_str() - (cur+1)) + ";" + ruri;//  	    ruri = first_route;//  	}	  	}	DBG("vm: route: %.*s\n",route.len,route.s);	DBG("vm: ############# record route header - end ##############\n");	/* 	if(msg->route) *//* 	    DBG("DEBUG: vm: route:%.*s\n", *//* 		msg->route->body.len,msg->route->body.s); */	email.s = 0; email.len = 0;	body.s = 0; body.len = 0;	if(!strcmp(action,VM_INVITE)){	    if( (body.s = get_body(msg)) == 0 ){		LOG(L_ERR, "ERROR: vm: get_body failed\n");		goto error;	    }	    body.len = strlen(body.s);#ifdef _OBSO	    if(vm_extract_body(msg,&body)==-1) {		LOG(L_ERR, "ERROR: vm: extract_body failed\n");		goto error;	    }#endif	    email_query.len = SQL_SELECT_LEN		+ strlen(email_column)		+ SQL_FROM_LEN		+ strlen(subscriber_table)		+ SQL_WHERE_LEN		+ strlen(user_column)		+ SQL_EQUAL_LEN		+ msg->parsed_uri.user.len + 2/* strlen("''") */#ifdef MULTI_DOMAIN		+ SQL_AND_LEN		+ strlen(domain_column)		+ SQL_EQUAL_LEN		+ msg->parsed_uri.host.len + 2/* strlen("''") */#endif		;	    	    email_query.s = malloc(email_query.len+1);	    if(!email_query.s){		LOG(L_ERR,"ERROR: %s: not enough memory\n",		    exports.name);		goto error;	    }	    s = email_query.s;	    append_str(s,SQL_SELECT,SQL_SELECT_LEN);	    append_str(s,email_column,strlen(email_column));	    append_str(s,SQL_FROM,SQL_FROM_LEN);	    append_str(s,subscriber_table,strlen(subscriber_table));	    append_str(s,SQL_WHERE,SQL_WHERE_LEN);	    append_str(s,user_column,strlen(user_column));	    append_str(s,SQL_EQUAL,SQL_EQUAL_LEN);	    *s = '\''; s++;	    append_str(s,msg->parsed_uri.user.s,msg->parsed_uri.user.len);	    *s = '\''; s++;#ifdef MULTI_DOMAIN	    append_str(s,SQL_AND,SQL_AND_LEN);	    append_str(s,domain_column,strlen(domain_column));	    append_str(s,SQL_EQUAL,SQL_EQUAL_LEN);	    *s = '\''; s++;	    append_str(s,msg->parsed_uri.host.s,msg->parsed_uri.host.len);	    *s = '\''; s++;#endif	    *s = '\0';	    	    	    (*db_raw_query)(db_handle,email_query.s,&email_res);	    free(email_query.s);	    	    if( (!email_res) || (email_res->n != 1) ){	    		if(email_res)		    (*db_free_query)(db_handle,email_res);				LOG( L_ERR,"ERROR: %s: no email for user '%.*s'",		     exports.name,		     msg->parsed_uri.user.len,msg->parsed_uri.user.s);		goto error;	    }	    	    email.s = strdup(VAL_STRING(&(email_res->rows[0].values[0])));	    email.len = strlen(email.s);	}	lines[0].s=action; lines[0].len=strlen(action); 	lines[1]=msg->parsed_uri.user;		/* user from r-uri */	lines[2]=email;			        /* email address from db */	lines[3].s=ip_addr2a(&msg->rcv.dst_ip);	/* dst ip */	lines[3].len=strlen(lines[3].s);	lines[4]=empty_param/*msg->first_line.u.request.uri*/;   /* r_uri ('Contact:' for next requests) */	lines[5]=*str_uri;			/* r_uri for subsequent requests */	lines[6]=get_from(msg)->body;		/* from */	lines[7]=msg->to->body;			/* to */	lines[8]=msg->callid->body;		/* callid */	lines[9]=get_from(msg)->tag_value;	/* from tag */	lines[10]=get_to(msg)->tag_value;	/* to tag */	lines[11]=get_cseq(msg)->number;	/* cseq number */	i2s=int2str(hash_index, &l);		/* hash:label */	if (l+1>=IDBUF_LEN) {		LOG(L_ERR, "ERROR: vm_start: too big hash\n");		goto error;	}	memcpy(id_buf, i2s, l);id_buf[l]=':';int_buflen=l+1;	i2s=int2str(label, &l);	if (l+1+int_buflen>=IDBUF_LEN) {		LOG(L_ERR, "ERROR: vm_start: too big label\n");		goto error;	}	memcpy(id_buf+int_buflen, i2s, l);int_buflen+=l;	lines[12].s=id_buf;lines[12].len=int_buflen;	lines[13]=route.len ? route : empty_param;	lines[14].s=body.s; lines[14].len=body.len;	if ( write_to_vm_fifo(vm_fifo, &lines[0], 			     body.len ? VM_FIFO_PARAMS : VM_FIFO_PARAMS-1)	     ==-1 ) {	    LOG(L_ERR, "ERROR: vm_start: write_to_fifo failed\n");	    goto error;	}	/* make sure that if voicemail does not initiate a reply	 * timely, a SIP timeout will be sent out */	if( (*_tmb.t_addblind)() == -1 ) {		LOG(L_ERR, "ERROR: vm_start: add_blind failed\n");		goto error;	}	return 1; error:	/* 0 would lead to immediate script exit -- -1 returns		with 'false' to script processing */	return -1;}