rem: int xj_manage_jab(char *buf, int len, int *pos, str *sct, xj_jalias als, xj_jcon jbc)
add: int xj_manage_jab(char *buf, int len, int *pos, xj_jalias als, xj_jcon jbc)
context: int xj_manage_jab(char *buf, int len, int *pos, 		str *sct, xj_jalias als, xj_jcon jbc){	int i, err=0;	char *p, *to, *from, *msg, *type, *emsg, *ecode, lbuf[4096], fbuf[128];	xj_jconf jcf = NULL;	str ts, tf;	xode x, y, z;	str *sid;	xj_pres_cell prc = NULL;	if(!jbc)		return -1;	sid = jbc->jkey->id;		x = xode_from_strx(buf, len, &err, &i);	DBG("XJAB:xj_parse_jab: XODE ret:%d pos:%d\n", err, i);		if(err && pos != NULL)		*pos= i;	if(x == NULL)		return -1;		lbuf[0] = 0;	ecode = NULL;		if(!strncasecmp(xode_get_name(x), "message", 7))	{		DBG("XJAB:xj_manage_jab: jabber [message] received\n");		if((to = xode_get_attrib(x, "to")) == NULL)		{			DBG("XJAB:xj_manage_jab: missing 'to' attribute\n");			err = -1;			goto ready;		}		if((from = xode_get_attrib(x, "from")) == NULL)		{			DBG("XJAB:xj_manage_jab: missing 'from' attribute\n");			err = -1;			goto ready;		}		if((y = xode_get_tag(x, "body")) == NULL				|| (msg = xode_get_data(y)) == NULL)		{			DBG("XJAB:xj_manage_jab: missing 'body' of message\n");			err = -1;			goto ready;		}		type = xode_get_attrib(x, "type");		if(type != NULL && !strncasecmp(type, "error", 5))		{			if((y = xode_get_tag(x, "error")) == NULL					|| (emsg = xode_get_data(y)) == NULL)			{				strcpy(lbuf, "{Error sending following message} - ");			}			else			{				ecode = xode_get_attrib(y, "code");				if(ecode != NULL)					sprintf(lbuf, 						"{Error (%s/%s) when trying to send following messge}",						ecode, emsg);				else					sprintf(lbuf, 						"{Error (%s) when trying to send following messge}",						emsg);			}		}		// is from a conferece?!?!		if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)		{			if(lbuf[0] == 0)			{				p = from + strlen(from);				while(p>from && *p != '/')					p--;				if(*p == '/')				{					if(jcf->nick.len>0 						&& !strncasecmp(p+1, jcf->nick.s, jcf->nick.len))						goto ready;					sprintf(lbuf, "[%s] ", p+1);				}			}			else			{				jcf->status = XJ_JCONF_NULL;				xj_jcon_jconf_presence(jbc,jcf,NULL,"online");			}			strcat(lbuf, msg);			ts.s = lbuf;			ts.len = strlen(lbuf);				if(xj_send_sip_msg(sid, &jcf->uri, sct, &ts, &jbc->jkey->flag)<0)				DBG("XJAB:xj_manage_jab: ERROR SIP MESSAGE was not sent!\n");			else				DBG("XJAB:xj_manage_jab: SIP MESSAGE was sent!\n");			goto ready;		}		strcat(lbuf, msg);		ts.s = from;		ts.len = strlen(from);		tf.s = fbuf;		tf.len = 0;		if(xj_address_translation(&ts, &tf, als, XJ_ADDRTR_B2A) == 0)		{			ts.s = lbuf;			ts.len = strlen(lbuf);				if(xj_send_sip_msg(sid, &tf, sct, &ts, &jbc->jkey->flag) < 0)				DBG("XJAB:xj_manage_jab: ERROR SIP MESSAGE was not sent ...\n");			else				DBG("XJAB:xj_manage_jab: SIP MESSAGE was sent.\n");		}		goto ready;	} // end MESSAGE		/*** PRESENCE HANDLING ***/	if(!strncasecmp(xode_get_name(x), "presence", 8))	{		DBG("XJAB:xj_manage_jab: jabber [presence] received\n");		if(!jbc)			goto ready;		type = xode_get_attrib(x, "type");		from = xode_get_attrib(x, "from");		if(from == NULL)			goto ready;		ts.s = from;		p = from;		while(p<from + strlen(from) && *p != '/')					p++;		if(*p == '/')			ts.len = p - from;		else			ts.len = strlen(from);		if(type!=NULL && !strncasecmp(type, "error", 5))		{			if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)			{				tf.s = from;				tf.len = strlen(from);				if((y = xode_get_tag(x, "error")) == NULL)					goto ready;				if ((p = xode_get_attrib(y, "code")) != NULL						&& atoi(p) == 409)				{					xj_send_sip_msgz(sid, &tf, sct, XJ_DMSG_ERR_JCONFNICK,					&jbc->jkey->flag);					goto ready;				}				xj_send_sip_msgz(sid, &tf, sct, XJ_DMSG_ERR_JCONFREFUSED,						&jbc->jkey->flag);			}			goto ready;		}		if(type!=NULL && !strncasecmp(type, "subscribe", 9))		{			xj_jcon_send_presence(jbc, from, "subscribed", NULL, NULL);			goto ready;		}		if(type!=NULL && !strncasecmp(type, "unavailable", 11))		{			DBG("XJAB:xj_manage_jab: user <%s> is offline\n", from);			prc = xj_pres_list_check(jbc->plist, &ts);			if(prc)			{				prc->state = XJ_PRES_STATE_OFFLINE;				// call callback function				if(prc->cbf)				{					tf.s = fbuf;					tf.len = 0;					if(xj_address_translation(&ts,&tf,als,XJ_ADDRTR_B2A)==0)					{						DBG("XJAB:xj_manage_jab: calling CBF(%.*s,0)\n",							tf.len, tf.s);						(*(prc->cbf))(&tf, prc->state, prc->cbp);					}				}			}			goto ready;		}		if(type == NULL || !strncasecmp(type, "online", 6)			|| !strncasecmp(type, "available", 9))		{			if(strchr(from, '@') == NULL)			{				if(!strncasecmp(from, XJ_AIM_NAME, XJ_AIM_LEN))				{					jbc->ready |= XJ_NET_AIM;					DBG("XJAB:xj_manage_jab: AIM network ready\n");				}				else if(!strncasecmp(from, XJ_ICQ_NAME, XJ_ICQ_LEN))				{					jbc->ready |= XJ_NET_ICQ;					DBG("XJAB:xj_manage_jab: ICQ network ready\n");				}				else if(!strncasecmp(from, XJ_MSN_NAME, XJ_MSN_LEN))				{					jbc->ready |= XJ_NET_MSN;					DBG("XJAB:xj_manage_jab: MSN network ready\n");				}				else if(!strncasecmp(from, XJ_YAH_NAME, XJ_YAH_LEN))				{					jbc->ready |= XJ_NET_YAH;					DBG("XJAB:xj_manage_jab: YAHOO network ready\n");				}			}			else if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)			{				jcf->status = XJ_JCONF_READY;				DBG("XJAB:xj_manage_jab: %s conference ready\n", from);			}			else			{				DBG("XJAB:xj_manage_jab: user <%s> is online\n", from);				prc = xj_pres_list_check(jbc->plist, &ts);				if(prc)				{					prc->state = XJ_PRES_STATE_ONLINE;					// call callback function					if(prc->cbf)					{						tf.s = fbuf;						tf.len = 0;						if(xj_address_translation(&ts,&tf,als,XJ_ADDRTR_B2A)							==0)						{							DBG("XJAB:xj_manage_jab: calling CBF(%.*s,1)\n",								tf.len, tf.s);							(*(prc->cbf))(&tf, prc->state, prc->cbp);						}					}				}				else				{					DBG("XJAB:xj_manage_jab: user state received - creating"						" presence cell for [%.*s]\n", ts.len, ts.s);					prc = xj_pres_cell_new();					if(prc == NULL)					{						DBG("XJAB:xj_manage_jab: cannot create presence"							" cell for [%s]\n", from);						goto ready;					}					if(xj_pres_cell_init(prc, &ts, NULL, NULL)<0)					{						DBG("XJAB:xj_manage_jab: cannot init presence"							" cell for [%s]\n", from);						xj_pres_cell_free(prc);						goto ready;					}					prc = xj_pres_list_add(jbc->plist, prc);					if(prc)						prc->state = XJ_PRES_STATE_ONLINE;				}			}		}				goto ready;	} // end PRESENCE		if(!strncasecmp(xode_get_name(x), "iq", 2))	{		DBG("XJAB:xj_manage_jab: jabber [iq] received\n");		if(!jbc)			goto ready;		if(!strncasecmp(xode_get_attrib(x, "type"), "result", 6))		{			if((y = xode_get_tag(x, "query?xmlns=jabber:iq:roster")) == NULL)				goto ready;			z = xode_get_firstchild(y);			while(z)			{				if(!strncasecmp(xode_get_name(z), "item", 5)					&& (from = xode_get_attrib(z, "jid")) != NULL)				{					if(strchr(from, '@') == NULL)					{ // transports						if(!strncasecmp(from, XJ_AIM_NAME, XJ_AIM_LEN))						{							jbc->allowed |= XJ_NET_AIM;							DBG("XJAB:xj_manage_jab:AIM network available\n");						}						else if(!strncasecmp(from, XJ_ICQ_NAME, XJ_ICQ_LEN))						{							jbc->allowed |= XJ_NET_ICQ;							DBG("XJAB:xj_manage_jab:ICQ network available\n");						}						else if(!strncasecmp(from, XJ_MSN_NAME, XJ_MSN_LEN))						{							jbc->allowed |= XJ_NET_MSN;							DBG("XJAB:xj_manage_jab:MSN network available\n");						}						else if(!strncasecmp(from, XJ_YAH_NAME, XJ_YAH_LEN))						{							jbc->allowed |= XJ_NET_YAH;							DBG("XJAB:xj_manage_jab:YAHOO network available\n");						}						goto next_sibling;					}					/*** else					{ // user item						ts.s = from;						ts.len = strlen(from);						DBG("XJAB:xj_manage_jab:%s is in roster\n", from);						if(xj_pres_list_check(jbc->plist, &ts))						{							DBG("XJAB:xj_manage_jab:%s already in presence"								" list\n", from);							goto next_sibling;						}						prc = xj_pres_cell_new();						if(prc == NULL)						{							DBG("XJAB:xj_manage_jab: cannot create presence"								" cell for %s\n", from);							goto next_sibling;						}						if(xj_pres_cell_init(prc, &ts, NULL, NULL)<0)						{							DBG("XJAB:xj_manage_jab: cannot init presence"								" cell for %s\n", from);							xj_pres_cell_free(prc);							goto next_sibling;						}						prc = xj_pres_list_add(jbc->plist, prc);						if(prc)						{							p = xode_get_attrib(z, "subscription");							if(p && !strncasecmp(p, "none", 4))							{								DBG("XJAB:xj_manage_jab: wait for permission"									" from %s\n", from);								prc->status = XJ_PRES_STATUS_WAIT; 							}							else							{								DBG("XJAB:xj_manage_jab: permission granted"									" from %s\n", from);								prc->status = XJ_PRES_STATUS_SUBS;							}						}					} 					***/				}next_sibling:				z = xode_get_nextsibling(z);			}		}				goto ready;	} // end IQready:	xode_free(x);	return err;}