Browse code

XJAB module - integration with PA

Daniel-Constantin Mierla authored on 16/01/2003 18:43:22
Showing 6 changed files
... ...
@@ -666,7 +666,7 @@ void destroy(void)
666 666
 /**
667 667
  * register a watcher function for a Jabber user' presence
668 668
  */
669
-void xj_register_watcher(str *dom,str *to,str *from,pa_callback_f cbf,void *pp)
669
+void xj_register_watcher(str *from, str *to, void *cbf, void *pp)
670 670
 {
671 671
 	xj_sipmsg jsmsg = NULL;
672 672
 	t_xj_jkey jkey, *jp;
... ...
@@ -675,6 +675,8 @@ void xj_register_watcher(str *dom,str *to,str *from,pa_callback_f cbf,void *pp)
675 675
 	if(!to || !from || !cbf)
676 676
 		return;
677 677
 
678
+	DBG("XJAB:xj_register_watcher: from=[%.*s] to=[%.*s]\n", from->len,
679
+			from->s, to->len, to->s);
678 680
 	jkey.hash = xj_get_hash(from, NULL);
679 681
 	jkey.id = from;
680 682
 
... ...
@@ -690,22 +692,8 @@ void xj_register_watcher(str *dom,str *to,str *from,pa_callback_f cbf,void *pp)
690 690
     if(jsmsg == NULL)
691 691
     	goto error;
692 692
 	
693
-	if(dom && dom->s && dom->len > 0)
694
-	{
695
-		jsmsg->msg.len = dom->len;
696
-		if((jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1)) == NULL)
697
-		{
698
-			shm_free(jsmsg);
699
-			goto error;
700
-		}
701
-		strncpy(jsmsg->msg.s, dom->s, jsmsg->msg.len);
702
-	}
703
-	else
704
-	{
705
-		jsmsg->msg.len = 0;
706
-		jsmsg->msg.s = NULL;
707
-
708
-	}
693
+	jsmsg->msg.len = 0;
694
+	jsmsg->msg.s = NULL;
709 695
 	
710 696
 	jsmsg->to.len = to->len;
711 697
 	if((jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1)) == NULL)
... ...
@@ -721,7 +709,7 @@ void xj_register_watcher(str *dom,str *to,str *from,pa_callback_f cbf,void *pp)
721 721
 	jsmsg->type = XJ_REG_WATCHER;
722 722
 	//jsmsg->jkey->hash = jkey.hash;
723 723
 	
724
-	jsmsg->cbf = cbf;
724
+	jsmsg->cbf = (pa_callback_f)cbf;
725 725
 	jsmsg->p = pp;
726 726
 
727 727
 	DBG("XJAB:xj_register_watcher:%d: sending <%p> to worker through <%d>\n",
... ...
@@ -745,7 +733,7 @@ error:
745 745
 /**
746 746
  * unregister a watcher for a Jabber user' presence
747 747
  */
748
-void xj_unregister_watcher(str *dom, str *to, str *from)
748
+void xj_unregister_watcher(str *from, str *to, void *cbf, void *pp)
749 749
 {
750 750
 	if(!to || !from)
751 751
 		return;
... ...
@@ -757,7 +745,7 @@ void xj_unregister_watcher(str *dom, str *to, str *from)
757 757
 void xjab_check_workers(int mpid)
758 758
 {
759 759
 	int i, n, stat;
760
-	DBG("XJAB:%d:xjab_check_workers: time=%d\n", mpid, get_ticks());
760
+	//DBG("XJAB:%d:xjab_check_workers: time=%d\n", mpid, get_ticks());
761 761
 	if(!jwl || jwl->len <= 0)
762 762
 		return;
763 763
 	for(i=0; i < jwl->len; i++)
... ...
@@ -148,8 +148,6 @@ void xj_sipmsg_free(xj_sipmsg jsmsg)
148 148
 //		_M_SHM_FREE(jsmsg->from->id->s);
149 149
 	if(jsmsg->msg.s != NULL)
150 150
 		_M_SHM_FREE(jsmsg->msg.s);
151
-	if(jsmsg->callid.s != NULL)
152
-		_M_SHM_FREE(jsmsg->callid.s);
153 151
 	_M_SHM_FREE(jsmsg);
154 152
 }
155 153
 
... ...
@@ -34,12 +34,15 @@
34 34
 
35 35
 #define XJ_NULL				0
36 36
 #define XJ_SEND_MESSAGE		1
37
-#define XJ_SEND_SUBSCRIBE	2
38
-#define XJ_SEND_BYE			4
39
-#define XJ_JOIN_JCONF		8
40
-#define XJ_EXIT_JCONF		16
41
-#define XJ_GO_ONLINE		32
42
-#define XJ_GO_OFFLINE		64
37
+#define XJ_JOIN_JCONF		2
38
+#define XJ_EXIT_JCONF		4
39
+#define XJ_GO_ONLINE		8
40
+#define XJ_GO_OFFLINE		16
41
+#define XJ_REG_WATCHER		32
42
+#define XJ_DEL_WATCHER		64
43
+
44
+
45
+typedef void (*pa_callback_f)(str* _user, int _state, void *p);
43 46
 
44 47
 /**********             ***/
45 48
 
... ...
@@ -54,11 +57,12 @@ typedef struct _xj_jkey
54 54
 
55 55
 typedef struct _xj_sipmsg
56 56
 {
57
-	int type;		// type of message
58
-	xj_jkey jkey;	// pointer to FROM
59
-	str to;			// destination
60
-	str msg;		// message body
61
-	str callid;		// call id of the message
57
+	int type;			// type of message
58
+	xj_jkey jkey;		// pointer to FROM
59
+	str to;				// destination
60
+	str msg;			// message body
61
+	pa_callback_f cbf;	// callback function
62
+	void *p;			// callback parameter
62 63
 } t_xj_sipmsg, *xj_sipmsg;
63 64
 
64 65
 /**********   LOOK AT IMPLEMENTATION OF FUNCTIONS FOR DESCRIPTION    ***/
... ...
@@ -84,7 +84,14 @@ xj_jcon xj_jcon_init(char *hostname, int port)
84 84
 	jbc->allowed = jbc->ready = XJ_NET_NUL;
85 85
 	jbc->jconf = NULL;
86 86
 	jbc->nrjconf = 0;
87
-
87
+	jbc->plist = xj_pres_list_init();
88
+	if(jbc->plist == NULL)
89
+	{
90
+		_M_FREE(jbc->hostname);
91
+		_M_FREE(jbc);
92
+		return NULL;
93
+	}
94
+			
88 95
     return jbc;
89 96
 }
90 97
 
... ...
@@ -204,6 +211,9 @@ int xj_jcon_user_auth(xj_jcon jbc, char *username, char *passwd,
204 204
 	sprintf(msg_buff, "%08X", jbc->seq_nr);
205 205
 	
206 206
 	x = xode_new_tag("iq");
207
+	if(!x)
208
+		return -1;
209
+
207 210
 	xode_put_attrib(x, "id", msg_buff);
208 211
 	xode_put_attrib(x, "type", "get");
209 212
 	y = xode_insert_tag(x, "query");
... ...
@@ -340,6 +350,51 @@ int xj_jcon_get_roster(xj_jcon jbc)
340 340
 }
341 341
 
342 342
 /**
343
+ * add a new contact in user's roster
344
+ */
345
+int xj_jcon_set_roster(xj_jcon jbc, char* jid, char *type)
346
+{
347
+	xode x;
348
+	char *p;
349
+	int n;
350
+	char buff[16];
351
+	
352
+	if(!jbc || !jid)
353
+		return -1;
354
+	
355
+	x = xode_new_tag("item");
356
+	if(!x)
357
+		return -1;
358
+	xode_put_attrib(x, "jid", jid);
359
+	if(type != NULL)
360
+		xode_put_attrib(x, "subscription", type);
361
+	
362
+	x = xode_wrap(x, "query");
363
+	xode_put_attrib(x, "xmlns", "jabber:iq:roster");
364
+
365
+	x = xode_wrap(x, "iq");
366
+	
367
+	xode_put_attrib(x, "type", "set");
368
+	jbc->seq_nr++;
369
+	sprintf(buff, "%08X", jbc->seq_nr);
370
+	xode_put_attrib(x, "id", buff);
371
+
372
+	p = xode_to_str(x);
373
+	n = strlen(p);
374
+	
375
+	if(send(jbc->sock, p, n, 0) != n)
376
+	{
377
+		DBG("XJAB:xj_jcon_set_roster: Error - item not sent\n");
378
+		goto error;
379
+	}
380
+	xode_free(x);
381
+	return 0;
382
+error:
383
+	xode_free(x);
384
+	return -1;
385
+}
386
+
387
+/**
343 388
  * send a message through a JABBER connection
344 389
  * params are pairs (buffer, len)
345 390
  */
... ...
@@ -354,6 +409,8 @@ int xj_jcon_send_msg(xj_jcon jbc, char *to, int tol, char *msg,
354 354
 		return -1;
355 355
 	
356 356
 	x = xode_new_tag("body");
357
+	if(!x)
358
+		return -1;
357 359
 	
358 360
 	xode_insert_cdata(x, msg, msgl);
359 361
 	x = xode_wrap(x, "message");
... ...
@@ -417,7 +474,10 @@ int xj_jcon_send_presence(xj_jcon jbc, char *sto, char *type, char *status,
417 417
 		return -1;
418 418
 	DBG("XJAB:xj_jcon_send_presence: -----START-----\n");
419 419
 	
420
-	x= xode_new_tag("presence");
420
+	x = xode_new_tag("presence");
421
+	if(!x)
422
+		return -1;
423
+	
421 424
 	if(sto != NULL)
422 425
 		xode_put_attrib(x, "to", sto);
423 426
 	if(type != NULL)
... ...
@@ -450,6 +510,44 @@ error:
450 450
 }
451 451
 
452 452
 /**
453
+ * send subscribe for user's presence
454
+ */
455
+int xj_jcon_send_subscribe(xj_jcon jbc, char *to, char *from, char *type)
456
+{
457
+	char *p;
458
+	int n;
459
+	xode x;
460
+	
461
+	if(!jbc || !to)
462
+		return -1;
463
+	
464
+	x = xode_new_tag("presence");
465
+	if(!x)
466
+		return -1;
467
+
468
+	xode_put_attrib(x, "to", to);
469
+	if(from != NULL)
470
+		xode_put_attrib(x, "from", from);
471
+	if(type != NULL)
472
+		xode_put_attrib(x, "type", type);
473
+
474
+	p = xode_to_str(x);
475
+	n = strlen(p);
476
+	
477
+	if(send(jbc->sock, p, n, 0) != n)
478
+	{
479
+		DBG("XJAB:xj_jcon_send_subscribe: Error - subscribe not sent\n");
480
+		goto error;
481
+	}
482
+	xode_free(x);
483
+	return 0;
484
+
485
+error:
486
+	xode_free(x);
487
+	return -1;
488
+}
489
+
490
+/**
453 491
  * free the allocated memory space of a JABBER connection
454 492
  */
455 493
 int xj_jcon_free(xj_jcon jbc)
... ...
@@ -476,6 +574,7 @@ int xj_jcon_free(xj_jcon jbc)
476 476
 			xj_jconf_free(jcf);
477 477
 		jbc->nrjconf--;
478 478
 	}
479
+	xj_pres_list_free(jbc->plist);
479 480
 	_M_FREE(jbc);
480 481
 	DBG("XJAB:xj_jcon_free: -----END-----\n");
481 482
 	return 0;
... ...
@@ -34,6 +34,7 @@
34 34
 #include "xjab_jconf.h"
35 35
 #include "xjab_base.h"
36 36
 #include "tree234.h"
37
+#include "xjab_presence.h"
37 38
 
38 39
 #define XJ_NET_NUL	0
39 40
 #define XJ_NET_ALL	0xFFFFFFFF
... ...
@@ -61,22 +62,23 @@
61 61
 
62 62
 typedef struct _xj_jcon
63 63
 {
64
-	int sock;        // communication socket
65
-	int port;        // port of the server
66
-	int juid;        // internal id of the Jabber user
67
-	int seq_nr;      // sequence number
68
-	char *hostname;  // hosname of the Jabber server
69
-	char *stream_id; // stream id of the session
64
+	int sock;			// communication socket
65
+	int port;			// port of the server
66
+	int juid;			// internal id of the Jabber user
67
+	int seq_nr;			// sequence number
68
+	char *hostname;		// hosname of the Jabber server
69
+	char *stream_id;	// stream id of the session
70 70
 
71
-	char *resource;  // resource ID
71
+	char *resource;		// resource ID
72 72
 
73 73
 	xj_jkey jkey;		// id of connection
74
-	int expire;		// time when the open connection is expired
75
-	int allowed;	// allowed IM networks
76
-	int ready;		// time when the connection is ready for sending messages
74
+	int expire;			// time when the open connection is expired
75
+	int allowed;		// allowed IM networks
76
+	int ready;			// time when the connection is ready for sending messages
77 77
 
78
-	int nrjconf;	// number of open conferences
79
-	tree234 *jconf; // open conferences
78
+	int nrjconf;		// number of open conferences
79
+	tree234 *jconf;		// open conferences
80
+	xj_pres_list plist;	// presence list
80 81
 } t_xj_jcon, *xj_jcon;
81 82
 
82 83
 /** --- **/
... ...
@@ -90,9 +92,11 @@ void xj_jcon_set_juid(xj_jcon, int);
90 90
 int  xj_jcon_get_juid(xj_jcon);
91 91
 
92 92
 int xj_jcon_get_roster(xj_jcon);
93
+int xj_jcon_set_roster(xj_jcon, char*, char*);
93 94
 
94 95
 int xj_jcon_user_auth(xj_jcon, char*, char*, char*);
95 96
 int xj_jcon_send_presence(xj_jcon, char*, char*, char*, char*);
97
+int xj_jcon_send_subscribe(xj_jcon, char*, char*, char*);
96 98
 
97 99
 int xj_jcon_send_msg(xj_jcon, char*, int, char*, int, int);
98 100
 int xj_jcon_send_sig_msg(xj_jcon, char*, int, char*, int, char*, int);
... ...
@@ -47,6 +47,7 @@
47 47
 #include "xjab_jcon.h"
48 48
 #include "xjab_dmsg.h"
49 49
 #include "xode.h"
50
+#include "xjab_presence.h"
50 51
 
51 52
 #include "mdefines.h"
52 53
 
... ...
@@ -234,6 +235,7 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
234 234
 	xj_jconf jcf = NULL;
235 235
 	char *p, buff[1024], recv_buff[4096];
236 236
 	int flags, nr, ltime = 0;
237
+	xj_pres_cell prc = NULL;
237 238
 	
238 239
 	db_key_t keys[] = {"sip_id", "type"};
239 240
 	db_val_t vals[] = { {DB_STRING, 0, {.string_val = buff}},
... ...
@@ -278,8 +280,8 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
278 278
 		mset = set;
279 279
 
280 280
 		tmv.tv_sec = (jcp->jmqueue.size == 0)?jwl->sleept:1;
281
-		DBG("XJAB:xj_worker[%d]:%d: select waiting %ds - queue=%d\n",rank,
282
-				_xj_pid, (int)tmv.tv_sec, jcp->jmqueue.size);
281
+		//DBG("XJAB:xj_worker[%d]:%d: select waiting %ds - queue=%d\n",rank,
282
+		//		_xj_pid, (int)tmv.tv_sec, jcp->jmqueue.size);
283 283
 		tmv.tv_usec = 0;
284 284
 
285 285
 		ret = select(maxfd+1, &mset, NULL, NULL, &tmv);
... ...
@@ -395,6 +397,7 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
395 395
 					goto step_w;
396 396
 				}
397 397
 				break;
398
+			case XJ_REG_WATCHER:
398 399
 			case XJ_JOIN_JCONF:
399 400
 			case XJ_GO_ONLINE:
400 401
 				break;
... ...
@@ -414,10 +417,9 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
414 414
 				if(jbc != NULL)
415 415
 					jbc->expire = ltime = -1;
416 416
 				goto step_w;
417
-			case XJ_SEND_SUBSCRIBE:
418
-			case XJ_SEND_BYE:
417
+			case XJ_DEL_WATCHER:
419 418
 			default:
420
-				break;
419
+				goto step_w;
421 420
 		}
422 421
 		
423 422
 		if(jbc != NULL)
... ...
@@ -495,7 +497,7 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
495 495
 		xj_jcon_get_roster(jbc);
496 496
 		xj_jcon_send_presence(jbc, NULL, NULL, "Online", "9");
497 497
 		
498
-		/** wait for a while - SER is tired */
498
+		/** wait for a while - the worker is tired */
499 499
 		//sleep(3);
500 500
 		
501 501
 		if ((res != NULL) && (db_free_query(db_con,res) < 0))
... ...
@@ -511,6 +513,56 @@ int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int rank,
511 511
 			goto step_w;
512 512
 		
513 513
 step_z:
514
+		if(jsmsg->type == XJ_REG_WATCHER)
515
+		{ // register a presence watcher
516
+			if(!xj_jconf_check_addr(&jsmsg->to, jwl->aliases->dlm))
517
+			{ // is for a conference - ignore?!?!
518
+				DBG("XJAB:xj_worker:%d: presence request for a conference.\n",
519
+					_xj_pid);
520
+				// set as offline
521
+				(*(jsmsg->cbf))(&jsmsg->to, 0, jsmsg->p);
522
+				goto step_w;
523
+			}
524
+			
525
+			sto.s = buff; 
526
+			sto.len = 0;
527
+
528
+			if(xj_address_translation(&jsmsg->to, &sto, jwl->aliases, 
529
+					XJ_ADDRTR_A2B) == 0)
530
+			{
531
+				prc = xj_pres_list_check(jbc->plist, &sto);
532
+				if(!prc)
533
+				{
534
+					prc = xj_pres_cell_new();
535
+					if(!prc)
536
+					{
537
+						DBG("XJAB:xj_worker:%d: cannot create a presence"
538
+							" cell for %.*s.\n", _xj_pid, sto.len, sto.s);
539
+						goto step_w;
540
+					}
541
+					if(xj_pres_cell_init(prc, &sto, jsmsg->cbf, jsmsg->p)<0)
542
+					{
543
+						xj_pres_cell_free(prc);
544
+						goto step_w;
545
+					}
546
+					if((prc = xj_pres_list_add(jbc->plist, prc))==NULL)
547
+					{
548
+						DBG("XJAB:xj_worker:%d: cannot add the presence"
549
+							" cell for %.*s.\n", _xj_pid, sto.len, sto.s);
550
+						goto step_w;
551
+					}
552
+					sto.s[sto.len] = 0;
553
+					if(!xj_jcon_send_subscribe(jbc, sto.s, NULL, "subscribe"))
554
+						prc->status = XJ_PRES_STATUS_WAIT; 
555
+				}
556
+				else
557
+				{
558
+					xj_pres_cell_update(prc, jsmsg->cbf, jsmsg->p);
559
+					(*(prc->cbf))(&jsmsg->to, prc->state, prc->cbp);
560
+				}
561
+			}
562
+			goto step_w;
563
+		}
514 564
 		flag = 0;
515 565
 		if(!xj_jconf_check_addr(&jsmsg->to, jwl->aliases->dlm))
516 566
 		{
... ...
@@ -601,8 +653,8 @@ step_z:
601 601
 				goto step_w;
602 602
 				
603 603
 			default:
604
-				xj_send_sip_msgz(jsmsg->jkey->id, &jsmsg->to,
605
-						jwl->contact_h, XJ_DMSG_ERR_SENDJMSG, &jbc->jkey->flag);
604
+				xj_send_sip_msgz(jsmsg->jkey->id, &jsmsg->to, jwl->contact_h,
605
+						XJ_DMSG_ERR_SENDJMSG, &jbc->jkey->flag);
606 606
 				goto step_w;
607 607
 		}
608 608
 
... ...
@@ -791,6 +843,7 @@ int xj_manage_jab(char *buf, int len, int *pos,
791 791
 	str ts, tf;
792 792
 	xode x, y, z;
793 793
 	str *sid;
794
+	xj_pres_cell prc = NULL;
794 795
 
795 796
 	if(!jbc)
796 797
 		return -1;
... ...
@@ -912,6 +965,14 @@ int xj_manage_jab(char *buf, int len, int *pos,
912 912
 		from = xode_get_attrib(x, "from");
913 913
 		if(from == NULL)
914 914
 			goto ready;
915
+		ts.s = from;
916
+		p = from;
917
+		while(p<from + strlen(from) && *p != '/')
918
+					p++;
919
+		if(*p == '/')
920
+			ts.len = p - from;
921
+		else
922
+			ts.len = strlen(from);
915 923
 		if(type!=NULL && !strncasecmp(type, "error", 5))
916 924
 		{
917 925
 			if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)
... ...
@@ -938,7 +999,30 @@ int xj_manage_jab(char *buf, int len, int *pos,
938 938
 			xj_jcon_send_presence(jbc, from, "subscribed", NULL, NULL);
939 939
 			goto ready;
940 940
 		}
941
-		if(type == NULL || !strncasecmp(type, "online", 6))
941
+		if(type!=NULL && !strncasecmp(type, "unavailable", 11))
942
+		{
943
+			DBG("XJAB:xj_manage_jab: user <%s> is offline\n", from);
944
+			prc = xj_pres_list_check(jbc->plist, &ts);
945
+			if(prc)
946
+			{
947
+				prc->state = XJ_PRES_STATE_OFFLINE;
948
+				// call callback function
949
+				if(prc->cbf)
950
+				{
951
+					tf.s = fbuf;
952
+					tf.len = 0;
953
+					if(xj_address_translation(&ts,&tf,als,XJ_ADDRTR_B2A)==0)
954
+					{
955
+						DBG("XJAB:xj_manage_jab: calling CBF(%.*s,0)\n",
956
+							tf.len, tf.s);
957
+						(*(prc->cbf))(&tf, prc->state, prc->cbp);
958
+					}
959
+				}
960
+			}
961
+			goto ready;
962
+		}
963
+		if(type == NULL || !strncasecmp(type, "online", 6)
964
+			|| !strncasecmp(type, "available", 9))
942 965
 		{
943 966
 			if(strchr(from, '@') == NULL)
944 967
 			{
... ...
@@ -968,6 +1052,50 @@ int xj_manage_jab(char *buf, int len, int *pos,
968 968
 				jcf->status = XJ_JCONF_READY;
969 969
 				DBG("XJAB:xj_manage_jab: %s conference ready\n", from);
970 970
 			}
971
+			else
972
+			{
973
+				DBG("XJAB:xj_manage_jab: user <%s> is online\n", from);
974
+				prc = xj_pres_list_check(jbc->plist, &ts);
975
+				if(prc)
976
+				{
977
+					prc->state = XJ_PRES_STATE_ONLINE;
978
+					// call callback function
979
+					if(prc->cbf)
980
+					{
981
+						tf.s = fbuf;
982
+						tf.len = 0;
983
+						if(xj_address_translation(&ts,&tf,als,XJ_ADDRTR_B2A)
984
+							==0)
985
+						{
986
+							DBG("XJAB:xj_manage_jab: calling CBF(%.*s,1)\n",
987
+								tf.len, tf.s);
988
+							(*(prc->cbf))(&tf, prc->state, prc->cbp);
989
+						}
990
+					}
991
+				}
992
+				else
993
+				{
994
+					DBG("XJAB:xj_manage_jab: creating presence"
995
+						" cell for [%.*s]\n", ts.len, ts.s);
996
+					prc = xj_pres_cell_new();
997
+					if(prc == NULL)
998
+					{
999
+						DBG("XJAB:xj_manage_jab: cannot create presence"
1000
+							" cell for [%s]\n", from);
1001
+						goto ready;
1002
+					}
1003
+					if(xj_pres_cell_init(prc, &ts, NULL, NULL)<0)
1004
+					{
1005
+						DBG("XJAB:xj_manage_jab: cannot init presence"
1006
+							" cell for [%s]\n", from);
1007
+						xj_pres_cell_free(prc);
1008
+						goto ready;
1009
+					}
1010
+					prc = xj_pres_list_add(jbc->plist, prc);
1011
+					if(prc)
1012
+						prc->state = XJ_PRES_STATE_ONLINE;
1013
+				}
1014
+			}
971 1015
 
972 1016
 		}
973 1017
 		
... ...
@@ -987,30 +1115,77 @@ int xj_manage_jab(char *buf, int len, int *pos,
987 987
 			while(z)
988 988
 			{
989 989
 				if(!strncasecmp(xode_get_name(z), "item", 5)
990
-					&& (type = xode_get_attrib(z, "jid")) != NULL
991
-					&& strchr(type, '@') == NULL)
990
+					&& (from = xode_get_attrib(z, "jid")) != NULL)
992 991
 				{
993
-					if(!strncasecmp(type, XJ_AIM_NAME, XJ_AIM_LEN))
994
-					{
995
-						jbc->allowed |= XJ_NET_AIM;
996
-						DBG("XJAB:xj_manage_jab: AIM network available\n");
997
-					}
998
-					else if(!strncasecmp(type, XJ_ICQ_NAME, XJ_ICQ_LEN))
999
-					{
1000
-						jbc->allowed |= XJ_NET_ICQ;
1001
-						DBG("XJAB:xj_manage_jab: ICQ network available\n");
992
+					if(strchr(from, '@') == NULL)
993
+					{ // transports
994
+						if(!strncasecmp(from, XJ_AIM_NAME, XJ_AIM_LEN))
995
+						{
996
+							jbc->allowed |= XJ_NET_AIM;
997
+							DBG("XJAB:xj_manage_jab:AIM network available\n");
998
+						}
999
+						else if(!strncasecmp(from, XJ_ICQ_NAME, XJ_ICQ_LEN))
1000
+						{
1001
+							jbc->allowed |= XJ_NET_ICQ;
1002
+							DBG("XJAB:xj_manage_jab:ICQ network available\n");
1003
+						}
1004
+						else if(!strncasecmp(from, XJ_MSN_NAME, XJ_MSN_LEN))
1005
+						{
1006
+							jbc->allowed |= XJ_NET_MSN;
1007
+							DBG("XJAB:xj_manage_jab:MSN network available\n");
1008
+						}
1009
+						else if(!strncasecmp(from, XJ_YAH_NAME, XJ_YAH_LEN))
1010
+						{
1011
+							jbc->allowed |= XJ_NET_YAH;
1012
+							DBG("XJAB:xj_manage_jab:YAHOO network available\n");
1013
+						} 
1002 1014
 					}
1003
-					else if(!strncasecmp(type, XJ_MSN_NAME, XJ_MSN_LEN))
1004
-					{
1005
-						jbc->allowed |= XJ_NET_MSN;
1006
-						DBG("XJAB:xj_manage_jab: MSN network available\n");
1015
+					else
1016
+					{ // user item
1017
+						ts.s = from;
1018
+						ts.len = strlen(from);
1019
+						DBG("XJAB:xj_manage_jab:%s is in roster\n", from);
1020
+						if(xj_pres_list_check(jbc->plist, &ts))
1021
+						{
1022
+							DBG("XJAB:xj_manage_jab:%s already in presence"
1023
+								" list\n", from);
1024
+							goto next_sibling;
1025
+						}
1026
+
1027
+						prc = xj_pres_cell_new();
1028
+						if(prc == NULL)
1029
+						{
1030
+							DBG("XJAB:xj_manage_jab: cannot create presence"
1031
+								" cell for %s\n", from);
1032
+							goto next_sibling;
1033
+						}
1034
+						if(xj_pres_cell_init(prc, &ts, NULL, NULL)<0)
1035
+						{
1036
+							DBG("XJAB:xj_manage_jab: cannot init presence"
1037
+								" cell for %s\n", from);
1038
+							xj_pres_cell_free(prc);
1039
+							goto next_sibling;
1040
+						}
1041
+						prc = xj_pres_list_add(jbc->plist, prc);
1042
+						if(prc)
1043
+						{
1044
+							p = xode_get_attrib(z, "subscription");
1045
+							if(p && !strncasecmp(p, "none", 4))
1046
+							{
1047
+								DBG("XJAB:xj_manage_jab: wait for permission"
1048
+									" from %s\n", from);
1049
+								prc->status = XJ_PRES_STATUS_WAIT; 
1050
+							}
1051
+							else
1052
+							{
1053
+								DBG("XJAB:xj_manage_jab: permission granted"
1054
+									" from %s\n", from);
1055
+								prc->status = XJ_PRES_STATUS_SUBS;
1056
+							}
1057
+						}
1007 1058
 					}
1008
-					else if(!strncasecmp(type, XJ_YAH_NAME, XJ_YAH_LEN))
1009
-					{
1010
-						jbc->allowed |= XJ_NET_YAH;
1011
-						DBG("XJAB:xj_manage_jab: YAHOO network available\n");
1012
-					} 
1013 1059
 				}
1060
+next_sibling:
1014 1061
 				z = xode_get_nextsibling(z);
1015 1062
 			}
1016 1063
 		}