rem: if (new_msg->expires == 0) {
add: if (!HOOK_SET(expires)) {
context: struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len ){	unsigned int      len;	struct hdr_field  *hdr,*new_hdr,*last_hdr;	struct via_body   *via;	struct via_param  *prm;	struct to_param   *to_prm,*new_to_prm;	struct sip_msg    *new_msg;	struct lump_rpl   *rpl_lump, **rpl_lump_anchor;	char              *p;	/*computing the length of entire sip_msg structure*/	len = ROUND4(sizeof( struct sip_msg ));	/*we will keep only the original msg +ZT */	len += ROUND4(org_msg->len + 1);	/*the new uri (if any)*/	if (org_msg->new_uri.s && org_msg->new_uri.len)		len+= ROUND4(org_msg->new_uri.len);	/*all the headers*/	for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )	{		/*size of header struct*/		len += ROUND4(sizeof( struct hdr_field));		switch (hdr->type)		{			case HDR_VIA_T:				for (via=(struct via_body*)hdr->parsed;via;via=via->next)				{					len+=ROUND4(sizeof(struct via_body));					/*via param*/					for(prm=via->param_lst;prm;prm=prm->next)						len+=ROUND4(sizeof(struct via_param ));				}				break;			case HDR_TO_T:			case HDR_FROM_T:				/* From header might be unparsed */				if (hdr->parsed) {					len+=ROUND4(sizeof(struct to_body));					     /*to param*/					to_prm = ((struct to_body*)(hdr->parsed))->param_lst;					for(;to_prm;to_prm=to_prm->next)						len+=ROUND4(sizeof(struct to_param ));				}				break;			case HDR_CSEQ_T:				len+=ROUND4(sizeof(struct cseq_body));				break;			case HDR_AUTHORIZATION_T:			case HDR_PROXYAUTH_T:				if (hdr->parsed) {					len += ROUND4(AUTH_BODY_SIZE);				}				break;			case HDR_CALLID_T:			case HDR_CONTACT_T:			case HDR_MAXFORWARDS_T:			case HDR_ROUTE_T:			case HDR_RECORDROUTE_T:			case HDR_CONTENTTYPE_T:			case HDR_CONTENTLENGTH_T:			case HDR_EXPIRES_T:			case HDR_SUPPORTED_T:			case HDR_PROXYREQUIRE_T:			case HDR_UNSUPPORTED_T:			case HDR_ALLOW_T:			case HDR_EVENT_T:			case HDR_ACCEPT_T:			case HDR_ACCEPTLANGUAGE_T:			case HDR_ORGANIZATION_T:			case HDR_PRIORITY_T:			case HDR_SUBJECT_T:			case HDR_USERAGENT_T:			case HDR_ACCEPTDISPOSITION_T:			case HDR_CONTENTDISPOSITION_T:			case HDR_DIVERSION_T:			case HDR_RPID_T:			case HDR_REFER_TO_T:				/* we ignore them for now even if they have something parsed*/				break;			default:				if (hdr->parsed) {					LOG(L_WARN, "WARNING: sip_msg_cloner: "						"header body ignored: %d\n", hdr->type );				}				break;		}/*switch*/	}/*for all headers*/	/* length of the data lump structures */#define LUMP_LIST_LEN(len, list) \do { \        struct lump* tmp, *chain; \	chain = (list); \	while (chain) \	{ \		(len) += lump_len(chain); \		tmp = chain->before; \		while ( tmp ) \		{ \			(len) += lump_len( tmp ); \			tmp = tmp->before; \		} \		tmp = chain->after; \		while ( tmp ) \		{ \			(len) += lump_len( tmp ); \			tmp = tmp->after; \		} \		chain = chain->next; \	} \} while(0);	LUMP_LIST_LEN(len, org_msg->add_rm);	LUMP_LIST_LEN(len, org_msg->body_lumps);		/*length of reply lump structures*/	for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)			len+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len);	p=(char *)shm_malloc(len);	if (!p)	{		LOG(L_ERR , "ERROR: sip_msg_cloner: cannot allocate memory\n" );		return 0;	}	if (sip_msg_len)		*sip_msg_len = len;	/* filling up the new structure */	new_msg = (struct sip_msg*)p;	/* sip msg structure */	memcpy( new_msg , org_msg , sizeof(struct sip_msg) );	new_msg->msg_flags |= FL_SHM_CLONE;	p += ROUND4(sizeof(struct sip_msg));	new_msg->add_rm = 0;	new_msg->body_lumps = 0;	/* new_uri */	if (org_msg->new_uri.s && org_msg->new_uri.len)	{		new_msg->new_uri.s = p;		memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);		p += ROUND4(org_msg->new_uri.len);	}	/* message buffers(org and scratch pad) */	memcpy( p , org_msg->buf, org_msg->len);	/* ZT to be safer */	*(p+org_msg->len)=0;	new_msg->buf = p;	p += ROUND4(new_msg->len+1);	/* unparsed and eoh pointer */	new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,		org_msg->unparsed );	new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);	/* first line, updating the pointers*/	if ( org_msg->first_line.type==SIP_REQUEST )	{		new_msg->first_line.u.request.method.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.request.method.s );		new_msg->first_line.u.request.uri.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.request.uri.s );		new_msg->first_line.u.request.version.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.request.version.s );		uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);		uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);	}	else if ( org_msg->first_line.type==SIP_REPLY )	{		new_msg->first_line.u.reply.version.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.reply.version.s );		new_msg->first_line.u.reply.status.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.reply.status.s );		new_msg->first_line.u.reply.reason.s =			translate_pointer( new_msg->buf , org_msg->buf ,			org_msg->first_line.u.reply.reason.s );	}	/*headers list*/	new_msg->via1=0;	new_msg->via2=0;	for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )	{		new_hdr = (struct hdr_field*)p;		memcpy(new_hdr, hdr, sizeof(struct hdr_field) );		p += ROUND4(sizeof( struct hdr_field));		new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,			hdr->name.s);		new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,			hdr->body.s);		/* by default, we assume we don't understand this header in TM		   and better set it to zero; if we do, we will set a specific		   value in the following switch statement		*/		new_hdr->parsed=0;		switch (hdr->type)		{			case HDR_VIA_T:				/*fprintf(stderr,"prepare to clone via |%.*s|\n",					via_len((struct via_body*)hdr->parsed),					via_s((struct via_body*)hdr->parsed,org_msg));*/				if ( !new_msg->via1 )				{					new_msg->h_via1 = new_hdr;					new_msg->via1 = via_body_cloner(new_msg->buf,						org_msg->buf, (struct via_body*)hdr->parsed, &p);					new_hdr->parsed  = (void*)new_msg->via1;					/*fprintf(stderr,"setting via1 |%.*s|\n",						via_len(new_msg->via1),						via_s(new_msg->via1,new_msg));*/					if ( new_msg->via1->next )						new_msg->via2 = new_msg->via1->next;				}				else if ( !new_msg->via2 && new_msg->via1 )				{					new_msg->h_via2 = new_hdr;					if ( new_msg->via1->next )						new_hdr->parsed = (void*)new_msg->via1->next;					else{						new_msg->via2 = via_body_cloner( new_msg->buf,							org_msg->buf, (struct via_body*)hdr->parsed, &p);						new_hdr->parsed  = (void*)new_msg->via2;					}				}				else if ( new_msg->via2 && new_msg->via1 )				{					new_hdr->parsed =  						via_body_cloner( new_msg->buf , org_msg->buf ,						(struct via_body*)hdr->parsed , &p);				}				break;			case HDR_CSEQ_T:				new_hdr->parsed = p;				p +=ROUND4(sizeof(struct cseq_body));				memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));				((struct cseq_body*)new_hdr->parsed)->number.s =					translate_pointer(new_msg->buf ,org_msg->buf,					((struct cseq_body*)hdr->parsed)->number.s );				((struct cseq_body*)new_hdr->parsed)->method.s =					translate_pointer(new_msg->buf ,org_msg->buf,					((struct cseq_body*)hdr->parsed)->method.s );				if (new_msg->cseq == 0) new_msg->cseq = new_hdr;				break;			case HDR_TO_T:			case HDR_FROM_T:				if (hdr->type == HDR_TO_T) {					if (new_msg->to == 0) new_msg->to = new_hdr;				} else {					if (new_msg->from == 0) new_msg->from = new_hdr;				}				/* From header might be unparsed */				if (!hdr->parsed) break;				new_hdr->parsed = p;				p +=ROUND4(sizeof(struct to_body));				memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));				((struct to_body*)new_hdr->parsed)->body.s =					translate_pointer( new_msg->buf , org_msg->buf ,					((struct to_body*)hdr->parsed)->body.s );				((struct to_body*)new_hdr->parsed)->uri.s =					translate_pointer( new_msg->buf , org_msg->buf ,					((struct to_body*)hdr->parsed)->uri.s );				if ( ((struct to_body*)hdr->parsed)->tag_value.s )					((struct to_body*)new_hdr->parsed)->tag_value.s =						translate_pointer( new_msg->buf , org_msg->buf ,						((struct to_body*)hdr->parsed)->tag_value.s );				/*to params*/				to_prm = ((struct to_body*)(hdr->parsed))->param_lst;				for(;to_prm;to_prm=to_prm->next)				{					/*alloc*/					new_to_prm = (struct to_param*)p;					p +=ROUND4(sizeof(struct to_param ));					/*coping*/					memcpy( new_to_prm, to_prm, sizeof(struct to_param ));					((struct to_body*)new_hdr->parsed)->param_lst = 0;					new_to_prm->name.s = translate_pointer( new_msg->buf,						org_msg->buf , to_prm->name.s );					new_to_prm->value.s = translate_pointer( new_msg->buf,						org_msg->buf , to_prm->value.s );					/*linking*/					if ( !((struct to_body*)new_hdr->parsed)->param_lst )						((struct to_body*)new_hdr->parsed)->param_lst							= new_to_prm;					else						((struct to_body*)new_hdr->parsed)->last_param->next							= new_to_prm;					((struct to_body*)new_hdr->parsed)->last_param						= new_to_prm;				}				break;			case HDR_CALLID_T:				if (new_msg->callid == 0) {					new_msg->callid = new_hdr;				}				break;			case HDR_CONTACT_T:				if (new_msg->contact == 0) {					new_msg->contact = new_hdr;				}				break;			case HDR_MAXFORWARDS_T:				if (new_msg->maxforwards == 0) {					new_msg->maxforwards = new_hdr;				}				break;			case HDR_ROUTE_T:				if (new_msg->route == 0) {					new_msg->route = new_hdr;				}				break;			case HDR_RECORDROUTE_T:				if (new_msg->record_route == 0) {					new_msg->record_route = new_hdr;				}				break;			case HDR_CONTENTTYPE_T:				if (new_msg->content_type == 0) {					new_msg->content_type = new_hdr;					new_msg->content_type->parsed = hdr->parsed;				}				break;			case HDR_CONTENTLENGTH_T:				if (new_msg->content_length == 0) {					new_msg->content_length = new_hdr;					new_msg->content_length->parsed = hdr->parsed;				}				break;			case HDR_AUTHORIZATION_T:				if (new_msg->authorization == 0) {					new_msg->authorization = new_hdr;				}				if (hdr->parsed) {					new_hdr->parsed = auth_body_cloner(new_msg->buf ,						org_msg->buf , (struct auth_body*)hdr->parsed , &p);				}				break;			case HDR_EXPIRES_T:				if (new_msg->expires == 0) {					new_msg->expires = new_hdr;				}				break;			case HDR_PROXYAUTH_T:				if (new_msg->proxy_auth == 0) {					new_msg->proxy_auth = new_hdr;				}				if (hdr->parsed) {					new_hdr->parsed = auth_body_cloner(new_msg->buf ,						org_msg->buf , (struct auth_body*)hdr->parsed , &p);				}				break;			case HDR_SUPPORTED_T:				if (new_msg->supported == 0) {					new_msg->supported = new_hdr;				}				break;			case HDR_PROXYREQUIRE_T:				if (new_msg->proxy_require == 0) {					new_msg->proxy_require = new_hdr;				}				break;			case HDR_UNSUPPORTED_T:				if (new_msg->unsupported == 0) {					new_msg->unsupported = new_hdr;				}				break;			case HDR_ALLOW_T:				if (new_msg->allow == 0) {					new_msg->allow = new_hdr;				}				break;			case HDR_EVENT_T:				if (new_msg->event == 0) {					new_msg->event = new_hdr;				}				break;			case HDR_ACCEPT_T:				if (new_msg->accept == 0) {					new_msg->accept = new_hdr;				}				break;			case HDR_ACCEPTLANGUAGE_T:				if (new_msg->accept_language == 0) {					new_msg->accept_language = new_hdr;				}				break;			case HDR_ORGANIZATION_T:				if (new_msg->organization == 0) {					new_msg->organization = new_hdr;				}				break;			case HDR_PRIORITY_T:				if (new_msg->priority == 0) {					new_msg->priority = new_hdr;				}				break;			case HDR_SUBJECT_T:				if (new_msg->subject == 0) {					new_msg->subject = new_hdr;				}				break;			case HDR_USERAGENT_T:				if (new_msg->user_agent == 0) {					new_msg->user_agent = new_hdr;				}				break;			case HDR_ACCEPTDISPOSITION_T:				if (new_msg->accept_disposition == 0) {					new_msg->accept_disposition = new_hdr;				}				break;			case HDR_CONTENTDISPOSITION_T:				if (new_msg->content_disposition == 0) {					new_msg->content_disposition = new_hdr;				}				break;			default:				/* ignore the rest*/				;		}/*switch*/		if ( last_hdr )		{			last_hdr->next = new_hdr;			last_hdr=last_hdr->next;		}		else		{			last_hdr=new_hdr;			new_msg->headers =new_hdr;		}		last_hdr->next = 0;		new_msg->last_header = last_hdr;	}	/* cloning data lump */#define CLONE_LUMP_LIST(anchor, list) \do { \	struct lump* lump_tmp, *l; \	struct lump** lump_anchor2, **a; \	a = (anchor); \	l = (list); \	while (l) \	{ \		lump_clone( (*a) , l , p ); \		/*before list*/ \		lump_tmp = l->before; \		lump_anchor2 = &((*a)->before); \		while ( lump_tmp ) \		{ \			lump_clone( (*lump_anchor2) , lump_tmp , p ); \			lump_anchor2 = &((*lump_anchor2)->before); \			lump_tmp = lump_tmp->before; \		} \		/*after list*/ \		lump_tmp = l->after; \		lump_anchor2 = &((*a)->after); \		while ( lump_tmp ) \		{ \			lump_clone( (*lump_anchor2) , lump_tmp , p ); \			lump_anchor2 = &((*lump_anchor2)->after); \			lump_tmp = lump_tmp->after; \		} \		a = &((*a)->next); \		l = l->next; \	} \} while(0)	CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);	CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);	/*cloning reply lump structures*/	rpl_lump_anchor = &(new_msg->reply_lump);	for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)	{		*(rpl_lump_anchor)=(struct lump_rpl*)p;		p+=ROUND4(sizeof( struct lump_rpl ));		(*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM |			(rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE)));		(*rpl_lump_anchor)->text.len = rpl_lump->text.len;		(*rpl_lump_anchor)->text.s=p;		p+=ROUND4(rpl_lump->text.len);		memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len);		(*rpl_lump_anchor)->next=0;		rpl_lump_anchor = &((*rpl_lump_anchor)->next);	}	if (clone_authorized_hooks(new_msg, org_msg) < 0) {		shm_free(new_msg);		return 0;	}	return new_msg;}