Browse code

XJAB module

Daniel-Constantin Mierla authored on 05/11/2002 13:25:13
Showing 7 changed files
... ...
@@ -86,25 +86,43 @@ int **pipes = NULL;
86 86
 
87 87
 static int mod_init(void);
88 88
 static int child_init(int rank);
89
-static int jab_send_message(struct sip_msg*, char*, char* );
89
+
90
+int xjab_manage_sipmsg(struct sip_msg *msg, int type);
91
+
92
+static int jab_send_message(struct sip_msg*, char*, char*);
93
+static int jab_send_bye(struct sip_msg*, char*, char*);
94
+static int jab_join_jconf(struct sip_msg*, char*, char*);
95
+static int jab_exit_jconf(struct sip_msg*, char*, char*);
96
+static int jab_go_online(struct sip_msg*, char*, char*);
97
+static int jab_go_offline(struct sip_msg*, char*, char*);
90 98
 
91 99
 void destroy(void);
92 100
 
93 101
 struct module_exports exports= {
94 102
 	"jabber",
95 103
 	(char*[]){
96
-		"jab_send_message"
104
+		"jab_send_message",
105
+		"jab_send_bye",
106
+		"jab_join_jconf",
107
+		"jab_exit_jconf",
108
+		"jab_go_online",
109
+		"jab_go_offline"
97 110
 	},
98 111
 	(cmd_function[]){
99
-		jab_send_message
112
+		jab_send_message,
113
+		jab_send_bye,
114
+		jab_join_jconf,
115
+		jab_exit_jconf,
116
+		jab_go_online,
117
+		jab_go_offline
100 118
 	},
101 119
 	(int[]){
102
-		0
120
+		0, 0, 0, 0, 0, 0
103 121
 	},
104 122
 	(fixup_function[]){
105
-		0
123
+		0, 0, 0, 0, 0, 0
106 124
 	},
107
-	1,
125
+	6,
108 126
 
109 127
 	(char*[]) {   /* Module parameter names */
110 128
 		"contact",
... ...
@@ -243,7 +261,8 @@ static int mod_init(void)
243 243
 			pipes[i][1]);
244 244
 	}
245 245
 	
246
-	if((jwl = xj_wlist_init(pipes, nrw, max_jobs)) == NULL)
246
+	if((jwl = xj_wlist_init(pipes,nrw,max_jobs,cache_time,sleep_time,
247
+				delay_time)) == NULL)
247 248
 	{
248 249
 		DBG("XJAB:mod_init: error initializing workers list\n");
249 250
 		return -1;
... ...
@@ -293,8 +312,7 @@ static int child_init(int rank)
293 293
 			if (pids[i] == 0)
294 294
 			{
295 295
 				close(pipes[i][1]);
296
-				xj_worker_process(jwl, jaddress, jport, pipes[i][0], max_jobs,
297
-					cache_time,	sleep_time, delay_time, db_con[i]);
296
+				xj_worker_process(jwl,jaddress,jport,pipes[i][0],db_con[i]);
298 297
 				exit(0);
299 298
 			}
300 299
 		}
... ...
@@ -317,22 +335,77 @@ static int child_init(int rank)
317 317
 }
318 318
 
319 319
 /**
320
- * send the SIP message through Jabber
320
+ * send the SIP MESSAGE through Jabber
321 321
  */
322 322
 static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
323 323
 {
324
-	str body, dst, /*host, user,*/ *p;
324
+	DBG("XJAB: processing SIP MESSAGE\n");
325
+	return xjab_manage_sipmsg(msg, XJ_SEND_MESSAGE);
326
+}
327
+
328
+/**
329
+ * send the SIP BYE through Jabber
330
+ */
331
+static int jab_send_bye(struct sip_msg *msg, char* foo1, char * foo2)
332
+{
333
+	DBG("XJAB: processing SIP BYE\n");
334
+	return xjab_manage_sipmsg(msg, XJ_SEND_BYE);
335
+}
336
+
337
+/**
338
+ * join a Jabber conference
339
+ */
340
+static int jab_join_jconf(struct sip_msg *msg, char* foo1, char * foo2)
341
+{
342
+	DBG("XJAB: join a Jabber conference\n");
343
+	return xjab_manage_sipmsg(msg, XJ_JOIN_JCONF);
344
+}
345
+
346
+/**
347
+ * exit from Jabber conference
348
+ */
349
+static int jab_exit_jconf(struct sip_msg *msg, char* foo1, char * foo2)
350
+{
351
+	DBG("XJAB: exit from a Jabber conference\n");
352
+	return xjab_manage_sipmsg(msg, XJ_EXIT_JCONF);
353
+}
354
+
355
+/**
356
+ * go online in Jabber network
357
+ */
358
+static int jab_go_online(struct sip_msg *msg, char* foo1, char * foo2)
359
+{
360
+	DBG("XJAB: go online in Jabber network\n");
361
+	return xjab_manage_sipmsg(msg, XJ_GO_ONLINE);
362
+}
363
+
364
+/**
365
+ * go offline in Jabber network
366
+ */
367
+static int jab_go_offline(struct sip_msg *msg, char* foo1, char * foo2)
368
+{
369
+	DBG("XJAB: go offline in Jabber network\n");
370
+	return xjab_manage_sipmsg(msg, XJ_GO_OFFLINE);
371
+}
372
+
373
+/**
374
+ * manage SIP message
375
+ */
376
+int xjab_manage_sipmsg(struct sip_msg *msg, int type)
377
+{
378
+	str body, dst;
325 379
 	xj_sipmsg jsmsg;
326 380
 	struct to_body to, from;
327 381
 	struct sip_uri _uri;
328 382
 	int pipe, fl;
329 383
 	struct to_param *foo,*bar;
330 384
 	char   *cp, *buf=0;
385
+	t_xj_jkey jkey, *p;
331 386
 
332 387
 	// extract message body - after that whole SIP MESSAGE is parsed
333
-	if ( imb.im_extract_body(msg,&body)==-1 )
388
+	if (type==XJ_SEND_MESSAGE && imb.im_extract_body(msg,&body)==-1 )
334 389
 	{
335
-		LOG(L_ERR,"ERROR:XJAB:xjab_send_message: cannot extract body"
390
+		LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR:cannot extract body"
336 391
 				" from sip msg!\n");
337 392
 		goto error;
338 393
 	}
... ...
@@ -341,7 +414,7 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
341 341
 	// check for FROM header
342 342
 	if(!msg->from)
343 343
 	{
344
-		LOG(L_ERR,"XJAB: xjab_send_message: cannot find FROM HEADER!\n");
344
+		LOG(L_ERR,"XJAB:xjab_manage_sipmsg: cannot find FROM HEADER!\n");
345 345
 		goto error;
346 346
 	}
347 347
 	
... ...
@@ -351,14 +424,14 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
351 351
 	buf = (char*)pkg_malloc(msg->from->body.len+1);
352 352
 	if (!buf) 
353 353
 	{
354
-		DBG("XJAB: xjab_send_message: error no free pkg memory\n");
354
+		DBG("XJAB:xjab_manage_sipmsg: error no free pkg memory\n");
355 355
 		goto error;
356 356
 	}
357 357
 	memcpy(buf,cp,msg->from->body.len+1);
358 358
 	parse_to(buf,buf+msg->from->body.len+1,&from);
359 359
 	if (from.error!=PARSE_OK ) 
360 360
 	{
361
-		DBG("XJAB: xjab_send_message: error cannot parse from header\n");
361
+		DBG("XJAB:xjab_manage_sipmsg: error cannot parse from header\n");
362 362
 		goto error;
363 363
 	}
364 364
 	/* we are not intrested in from param-> le's free them now*/
... ...
@@ -367,33 +440,55 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
367 367
 		bar = foo->next;
368 368
 		pkg_free(foo);
369 369
 	}
370
-	
370
+
371
+	jkey.hash = xj_get_hash(&from.uri, NULL);
372
+	jkey.id = &from.uri;
371 373
 	// get the communication pipe with the worker
372
-	if((pipe = xj_wlist_get(jwl, &from.uri, &p)) < 0)
374
+	switch(type)
373 375
 	{
374
-		DBG("XJAB: xjab_send_message: cannot find pipe of the worker!\n");
375
-		goto error;
376
+		case XJ_SEND_MESSAGE:
377
+		case XJ_JOIN_JCONF:
378
+		case XJ_GO_ONLINE:
379
+			if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0)
380
+			{
381
+				DBG("XJAB:xjab_manage_sipmsg: cannot find pipe of the worker!\n");
382
+				goto error;
383
+			}
384
+		break;
385
+		case XJ_SEND_BYE:
386
+		case XJ_EXIT_JCONF:
387
+		case XJ_GO_OFFLINE:
388
+			if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0)
389
+			{
390
+				DBG("XJAB:xjab_manage_sipmsg: no open Jabber session for"
391
+						" <%.*s>!\n", from.uri.len, from.uri.s);
392
+				goto error;
393
+			}
394
+		break;
395
+		default:
396
+			DBG("XJAB:xjab_manage_sipmsg: ERROR:strange SIP msg type!\n");
397
+			goto error;
376 398
 	}
377 399
 	
378 400
 	// determination of destination
379 401
 	dst.len = 0;
380 402
 	if( msg->new_uri.len > 0 )
381 403
 	{
382
-		DBG("XJAB: xjab_send_message: using NEW URI for destination\n");
404
+		DBG("XJAB:xjab_manage_sipmsg: using NEW URI for destination\n");
383 405
 		dst.s = msg->new_uri.s;
384 406
 		dst.len = msg->new_uri.len;
385 407
 	} else if ( msg->first_line.u.request.uri.len > 0 )
386 408
 	{
387
-		DBG("XJAB: xjab_send_message: parsing URI from first line\n");
409
+		DBG("XJAB:xjab_manage_sipmsg: parsing URI from first line\n");
388 410
 		if(parse_uri(msg->first_line.u.request.uri.s,
389 411
 					msg->first_line.u.request.uri.len, &_uri) < 0)
390 412
 		{
391
-			DBG("XJAB: xjab_send_message: ERROR parsing URI from first line\n");
413
+			DBG("XJAB:xjab_manage_sipmsg: ERROR parsing URI from first line\n");
392 414
 			goto error;
393 415
 		}
394 416
 		if(_uri.user.len > 0)
395 417
 		{
396
-			DBG("XJAB: xjab_send_message: using URI for destination\n");
418
+			DBG("XJAB:xjab_manage_sipmsg: using URI for destination\n");
397 419
 			dst.s = msg->first_line.u.request.uri.s;
398 420
 			dst.len = msg->first_line.u.request.uri.len;
399 421
 		}
... ...
@@ -406,20 +501,20 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
406 406
 				&to);
407 407
 		if(to.uri.len > 0) // to.error == PARSE_OK)
408 408
 		{
409
-			DBG("XJAB: xjab_send_message: TO parsed OK <%.*s>.\n",
409
+			DBG("XJAB:xjab_manage_sipmsg: TO parsed OK <%.*s>.\n",
410 410
 				to.uri.len, to.uri.s);
411 411
 			dst.s = to.uri.s;
412 412
 			dst.len = to.uri.len;
413 413
 		}
414 414
 		else
415 415
 		{
416
-			DBG("XJAB: xjab_send_message: TO NOT parsed\n");
416
+			DBG("XJAB:xjab_manage_sipmsg: TO NOT parsed\n");
417 417
 			goto error;
418 418
 		}
419 419
 	}
420 420
 	if(dst.len == 0)
421 421
 	{
422
-		DBG("XJAB: xjab_send_message: destination not found in SIP message\n");
422
+		DBG("XJAB:xjab_manage_sipmsg: destination not found in SIP message\n");
423 423
 		goto error;
424 424
 	}
425 425
 	
... ...
@@ -441,7 +536,7 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
441 441
 			dst.len += 3;
442 442
 		}
443 443
 		
444
-		DBG("XJAB: xjab_send_message: DESTINATION corrected <%.*s>.\n", 
444
+		DBG("XJAB:xjab_manage_sipmsg: DESTINATION corrected [%.*s].\n", 
445 445
 				dst.len, dst.s);
446 446
 	}
447 447
 	
... ...
@@ -449,33 +544,55 @@ static int jab_send_message(struct sip_msg *msg, char* foo1, char * foo2)
449 449
     jsmsg = (xj_sipmsg)shm_malloc(sizeof(t_xj_sipmsg));
450 450
     if(jsmsg == NULL)
451 451
     	return -1;
452
-	jsmsg->to.len = dst.len;
453
-	jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1);
454
-	if(jsmsg->to.s == NULL)
452
+	
453
+	switch(type)
455 454
 	{
456
-		shm_free(jsmsg);
457
-		goto error;
455
+		case XJ_SEND_MESSAGE:
456
+			jsmsg->msg.len = body.len;
457
+			if((jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1)) == NULL)
458
+			{
459
+				shm_free(jsmsg);
460
+				goto error;
461
+			}
462
+			strncpy(jsmsg->msg.s, body.s, jsmsg->msg.len);
463
+		break;
464
+		case XJ_SEND_BYE:
465
+		case XJ_JOIN_JCONF:
466
+		case XJ_EXIT_JCONF:
467
+		case XJ_GO_ONLINE:
468
+		case XJ_GO_OFFLINE:
469
+			jsmsg->msg.len = 0;
470
+			jsmsg->msg.s = NULL;
471
+		break;
472
+		default:
473
+			DBG("XJAB:xjab_manage_sipmsg: this SHOULD NOT appear\n");
474
+			shm_free(jsmsg);
475
+			goto error;
458 476
 	}
459
-	strncpy(jsmsg->to.s, dst.s, jsmsg->to.len);
460
-	
461
-	jsmsg->msg.len = body.len;
462
-	jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1);
463
-	if(jsmsg->msg.s == NULL)
477
+	jsmsg->to.len = dst.len;
478
+	if((jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1)) == NULL)
464 479
 	{
465
-		shm_free(jsmsg->to.s);
480
+		if(type == XJ_SEND_MESSAGE)
481
+			shm_free(jsmsg->msg.s);
466 482
 		shm_free(jsmsg);
467 483
 		goto error;
468 484
 	}
469
-	strncpy(jsmsg->msg.s, body.s, jsmsg->msg.len);
470
-	
471
-	jsmsg->from = p;
472
-	
473
-	DBG("XJAB: xjab_send_message:%d: sending <%p> to worker through <%d>\n",
485
+	strncpy(jsmsg->to.s, dst.s, jsmsg->to.len);
486
+
487
+	jsmsg->jkey = p;
488
+	jsmsg->type = type;
489
+	jsmsg->jkey->hash = jkey.hash;
490
+
491
+	DBG("XJAB:xjab_manage_sipmsg:%d: sending <%p> to worker through <%d>\n",
474 492
 			getpid(), jsmsg, pipe);
475 493
 	// sending the SHM pointer of SIP message to the worker
476 494
 	if(write(pipe, &jsmsg, sizeof(jsmsg)) != sizeof(jsmsg))
477 495
 	{
478
-		DBG("XJAB: xjab_send_message: error when writting to worker pipe!\n");
496
+		DBG("XJAB:xjab_manage_sipmsg: error when writting to worker pipe!\n");
497
+		if(type == XJ_SEND_MESSAGE)
498
+			shm_free(jsmsg->msg.s);
499
+		shm_free(jsmsg->to.s);
500
+		shm_free(jsmsg);
479 501
 		goto error;
480 502
 	}
481 503
 	
... ...
@@ -55,27 +55,44 @@
55 55
 
56 56
 #define JB_IQ_ROSTER_GET	"<iq type='get'><query xmlns='jabber:iq:roster'/></iq>"
57 57
 
58
+#define XJ_MAX_JCONF	12
59
+
58 60
 
59 61
 /**
60 62
  * init a JABBER connection
61 63
  */
62 64
 xj_jcon xj_jcon_init(char *hostname, int port)
63 65
 {
64
-	xj_jcon jbc = (xj_jcon)_M_MALLOC(sizeof(struct _xj_jcon));
66
+	xj_jcon jbc = NULL;
67
+	if(hostname==NULL || strlen(hostname)<=0)
68
+		return NULL;
69
+	
70
+	jbc = (xj_jcon)_M_MALLOC(sizeof(struct _xj_jcon));
65 71
 	if(jbc == NULL)
66 72
 		return NULL;
67 73
 	jbc->sock=-1;
68 74
     jbc->port = port;
69 75
     jbc->juid = -1;
70 76
 	jbc->seq_nr = 0;
71
-    jbc->hostname = (char*)_M_MALLOC(strlen(hostname));
77
+    jbc->hostname = (char*)_M_MALLOC(strlen(hostname)+1);
72 78
 	if(jbc->hostname == NULL)
73 79
 	{
74 80
 		_M_FREE(jbc);
75 81
 		return NULL;
76 82
 	}
83
+	if((jbc->close = (int*)_M_SHM_MALLOC(sizeof(int)))==NULL)
84
+	{
85
+		_M_FREE(jbc->hostname);
86
+		_M_FREE(jbc);
87
+		return NULL;
88
+
89
+	}
90
+	*jbc->close = 0;
77 91
     strcpy(jbc->hostname, hostname);
78 92
 	jbc->allowed = jbc->ready = XJ_NET_NUL;
93
+	jbc->jconf = NULL;
94
+	jbc->nrjconf = 0;
95
+
79 96
     return jbc;
80 97
 }
81 98
 
... ...
@@ -148,7 +165,7 @@ int xj_jcon_disconnect(xj_jcon jbc)
148 148
 		return -1;
149 149
 	DBG("XJAB:xj_jcon_disconnect: -----START-----\n");
150 150
     DBG("XJAB:xj_jcon_disconnect: socket [%d]\n", jbc->sock);
151
-	xj_jcon_send_presence(jbc, "unavailable", NULL, NULL);
151
+	xj_jcon_send_presence(jbc, NULL, "unavailable", NULL, NULL);
152 152
 	if(send(jbc->sock, "</stream:stream>", 16, 0) < 16)
153 153
 		DBG("XJAB:xj_jcon_disconnect: error closing stream\n");
154 154
 	if(close(jbc->sock) == -1)
... ...
@@ -305,7 +322,7 @@ int xj_jcon_user_auth(xj_jcon jbc, char *username, char *passwd,
305 305
 			strncasecmp(xode_get_attrib(x, "type"), "result", 6))
306 306
 		goto errorx;
307 307
 	
308
-	jbc->resource = (char*)_M_MALLOC(strlen(resource));
308
+	jbc->resource = (char*)_M_MALLOC(strlen(resource)+1);
309 309
 	strcpy(jbc->resource, resource);
310 310
 
311 311
 	jbc->allowed = XJ_NET_ALL;
... ...
@@ -334,7 +351,8 @@ int xj_jcon_get_roster(xj_jcon jbc)
334 334
  * send a message through a JABBER connection
335 335
  * params are pairs (buffer, len)
336 336
  */
337
-int xj_jcon_send_msg(xj_jcon jbc, char *to, int tol, char *msg, int msgl)
337
+int xj_jcon_send_msg(xj_jcon jbc, char *to, int tol, char *msg, 
338
+		int msgl, int type)
338 339
 {
339 340
 	char msg_buff[4096], *p;
340 341
 	int n;
... ...
@@ -350,7 +368,17 @@ int xj_jcon_send_msg(xj_jcon jbc, char *to, int tol, char *msg, int msgl)
350 350
 	strncpy(msg_buff, to, tol);
351 351
 	msg_buff[tol] = 0;
352 352
 	xode_put_attrib(x, "to", msg_buff);
353
-	xode_put_attrib(x, "type", "chat");
353
+	switch(type)
354
+	{
355
+		case XJ_JMSG_CHAT:
356
+			xode_put_attrib(x, "type", "chat");
357
+			break;
358
+		case XJ_JMSG_GROUPCHAT:
359
+			xode_put_attrib(x, "type", "groupchat");
360
+			break;
361
+		default:
362
+			xode_put_attrib(x, "type", "normal");
363
+	}
354 364
 
355 365
 	p = xode_to_str(x);
356 366
 	n = strlen(p);
... ...
@@ -386,7 +414,7 @@ int xj_jcon_recv_msg(xj_jcon jbc, char *from, char *msg)
386 386
  * status - "online", "away", "unavailable" ...
387 387
  * priority - "0", "1", ...
388 388
  */
389
-int xj_jcon_send_presence(xj_jcon jbc, char *type, char *status,
389
+int xj_jcon_send_presence(xj_jcon jbc, char *sto, char *type, char *status,
390 390
 				char *priority)
391 391
 {
392 392
 	char *p;
... ...
@@ -398,6 +426,8 @@ int xj_jcon_send_presence(xj_jcon jbc, char *type, char *status,
398 398
 	DBG("XJAB:xj_jcon_send_presence: -----START-----\n");
399 399
 	
400 400
 	x= xode_new_tag("presence");
401
+	if(sto != NULL)
402
+		xode_put_attrib(x, "to", sto);
401 403
 	if(type != NULL)
402 404
 		xode_put_attrib(x, "type", type);
403 405
 	if(status != NULL)
... ...
@@ -420,6 +450,7 @@ int xj_jcon_send_presence(xj_jcon jbc, char *type, char *status,
420 420
 		goto error;
421 421
 	}
422 422
 	xode_free(x);
423
+	DBG("XJAB:xj_jcon_send_presence: presence status was sent\n");
423 424
 	return 0;
424 425
 error:
425 426
 	xode_free(x);
... ...
@@ -431,6 +462,8 @@ error:
431 431
  */
432 432
 int xj_jcon_free(xj_jcon jbc)
433 433
 {
434
+	xj_jconf jcf;
435
+	
434 436
 	if(jbc == NULL)
435 437
 		return -1;
436 438
 	DBG("XJAB:xj_jcon_free: -----START-----\n");
... ...
@@ -441,15 +474,22 @@ int xj_jcon_free(xj_jcon jbc)
441 441
 		_M_FREE(jbc->hostname);
442 442
 	if(jbc->stream_id != NULL)
443 443
 		_M_FREE(jbc->stream_id);
444
-    /*******
445
-	if(jbc->username != NULL)
446
-		_M_FREE(jbc->username);
447
-	if(jbc->passwd != NULL)
448
-		_M_FREE(jbc->passwd);
449
-	*/
444
+	DBG("XJAB:xj_jcon_free: -----STEP A\n");	
445
+	if(jbc->close != NULL)
446
+	{
447
+		_M_SHM_FREE(jbc->close);
448
+		jbc->close = NULL;
449
+	}
450
+	DBG("XJAB:xj_jcon_free: -----STEP B\n");	
450 451
 	if(jbc->resource != NULL)
451 452
 		_M_FREE(jbc->resource);
452
-
453
+	DBG("XJAB:xj_jcon_free: %d conferences\n", jbc->nrjconf);
454
+	while(jbc->nrjconf > 0)
455
+	{
456
+		if((jcf=delpos234(jbc->jconf,0))!=NULL)
457
+			xj_jconf_free(jcf);
458
+		jbc->nrjconf--;
459
+	}
453 460
 	_M_FREE(jbc);
454 461
 	DBG("XJAB:xj_jcon_free: -----END-----\n");
455 462
 	return 0;
... ...
@@ -463,13 +503,13 @@ int xj_jcon_free(xj_jcon jbc)
463 463
  * - delay_time : time needed to became an active connection
464 464
  * #return : pointer to the structure or NULL on error
465 465
  */
466
-int xj_jcon_set_attrs(xj_jcon jbc, str *id, int cache_time, 
466
+int xj_jcon_set_attrs(xj_jcon jbc, xj_jkey jkey, int cache_time, 
467 467
 				int delay_time)
468 468
 {
469 469
 	int t;
470
-	if(jbc==NULL || id==NULL)
470
+	if(jbc==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
471 471
 		return -1;
472
-	jbc->id = id;
472
+	jbc->jkey = jkey;
473 473
 	t = get_ticks();
474 474
 	jbc->expire = t + cache_time;
475 475
 	jbc->ready = t + delay_time;
... ...
@@ -486,7 +526,8 @@ int xj_jcon_update(xj_jcon jbc, int cache_time)
486 486
 {
487 487
 	if(jbc == NULL)
488 488
 		return -1;
489
-	DBG("XJAB: xj_jcon_update -----START-----\n");
489
+	DBG("XJAB: xj_jcon_update [%.*s] %d\n", 
490
+			jbc->jkey->id->len, jbc->jkey->id->s, cache_time);
490 491
 	jbc->expire = get_ticks() + cache_time;
491 492
 	return 0;	
492 493
 }
... ...
@@ -494,9 +535,24 @@ int xj_jcon_update(xj_jcon jbc, int cache_time)
494 494
 int xj_jcon_is_ready(xj_jcon jbc, char *to, int tol)
495 495
 {
496 496
 	char *p;
497
+	str sto;
498
+	xj_jconf jcf = NULL;
497 499
 	if(!jbc || !to || tol <= 0)
498 500
 		return -1;
499 501
 	
502
+	sto.s = to;
503
+	sto.len = tol;
504
+	if(!xj_jconf_check_addr(&sto))
505
+	{
506
+		DBG("XJAB: xj_jcon_is_ready: destination=conference\n");
507
+		
508
+		if((jcf=xj_jcon_get_jconf(jbc, &sto))!=NULL)
509
+			return (jcf->status & XJ_JCONF_READY)?0:1;
510
+		
511
+		DBG("XJAB: xj_jcon_is_ready: conference does not exist\n");
512
+		return -1;
513
+	}
514
+	
500 515
 	p = to;
501 516
 	while(p < to+tol && *p!='@') 
502 517
 		p++;
... ...
@@ -514,10 +570,126 @@ int xj_jcon_is_ready(xj_jcon jbc, char *to, int tol)
514 514
 
515 515
 	if(!strncasecmp(p, XJ_YAH_NAME, XJ_YAH_LEN))
516 516
 		return (jbc->ready & XJ_NET_YAH)?0:((jbc->allowed & XJ_NET_YAH)?1:2);
517
-	
517
+
518
+	DBG("XJAB: xj_jcon_is_ready: destination=jabber\n");	
518 519
 	return 0;
519 520
 }
520 521
 
522
+xj_jconf  xj_jcon_get_jconf(xj_jcon jbc, str* sid)
523
+{
524
+	xj_jconf jcf = NULL, p;
525
+
526
+	if(!jbc || !sid || !sid->s || sid->len <= 0)
527
+		return NULL;
528
+	DBG("XJAB: xj_jcon_get_jconf: looking for conference\n");	
529
+	
530
+	if((jcf = xj_jconf_new(sid))==NULL)
531
+		return NULL;
532
+	if(xj_jconf_init_sip(jcf, jbc->jkey->id))
533
+		goto clean;
534
+	if(jbc->nrjconf && (p = find234(jbc->jconf, (void*)jcf, NULL)) != NULL)
535
+	{
536
+		DBG("XJAB: xj_jcon_get_jconf: conference found\n");
537
+		xj_jconf_free(jcf);
538
+		return p;
539
+	}
540
+	
541
+	if(jbc->nrjconf >= XJ_MAX_JCONF)
542
+		goto clean;
543
+
544
+	if(jbc->nrjconf==0)
545
+		if(jbc->jconf==NULL)
546
+			if((jbc->jconf = newtree234(xj_jconf_cmp)) == NULL)
547
+				goto clean;
548
+
549
+	if((p = add234(jbc->jconf, (void*)jcf)) != NULL)
550
+	{
551
+		DBG("XJAB: xj_jcon_get_jconf: new conference created\n");
552
+		jbc->nrjconf++;
553
+		return p;
554
+	}
555
+
556
+clean:
557
+	DBG("XJAB: xj_jcon_get_jconf: error looking for conference\n");
558
+	xj_jconf_free(jcf);
559
+	return NULL;
560
+}
561
+
562
+xj_jconf xj_jcon_check_jconf(xj_jcon jbc, char* id)
563
+{
564
+	str sid;
565
+	xj_jconf jcf = NULL, p = NULL;
566
+
567
+	if(!jbc || !id || !jbc->nrjconf)
568
+		return NULL;
569
+	DBG("XJAB: xj_jcon_get_jconf: looking for conference\n");	
570
+	
571
+	sid.s = id;
572
+	sid.len = strlen(id);
573
+	if((jcf = xj_jconf_new(&sid))==NULL)
574
+		return NULL;
575
+	if(xj_jconf_init_jab(jcf))
576
+		goto clean;
577
+	if((p = find234(jbc->jconf, (void*)jcf, NULL)) != NULL)
578
+	{
579
+		DBG("XJAB: xj_jcon_get_jconf: conference found\n");
580
+		xj_jconf_free(jcf);
581
+		return p;
582
+	}
583
+clean:
584
+	DBG("XJAB: xj_jcon_get_jconf: conference not found\n");
585
+	xj_jconf_free(jcf);
586
+	return NULL;	
587
+}
588
+
589
+int xj_jcon_jconf_presence(xj_jcon jbc, xj_jconf jcf, char* type, 
590
+		char* status)
591
+{
592
+	char buff[256];
593
+	
594
+	strncpy(buff, jcf->room.s, 
595
+			jcf->room.len + jcf->server.len +1);
596
+	buff[jcf->room.len + jcf->server.len +1] = '/';
597
+	buff[jcf->room.len + jcf->server.len +2] = 0;
598
+	buff[jcf->room.len] = '@';
599
+	strncat(buff, jcf->nick.s, jcf->nick.len);
600
+
601
+	return xj_jcon_send_presence(jbc,buff,type,status,NULL);
602
+}
603
+
604
+int  xj_jcon_del_jconf(xj_jcon jbc, str *sid, int flag)
605
+{
606
+	xj_jconf jcf = NULL, p = NULL;
607
+	
608
+	if(!jbc || !sid || !sid->s || sid->len <= 0)
609
+		return -1;
610
+	
611
+	DBG("XJAB: xj_jcon_del_jconf: deleting conference of <%.*s>\n",
612
+			sid->len, sid->s);
613
+	
614
+	if((jcf = xj_jconf_new(sid))==NULL)
615
+		return -1;
616
+	if(xj_jconf_init_sip(jcf, jbc->jkey->id))
617
+	{
618
+		xj_jconf_free(jcf);
619
+		return -1;
620
+	}
621
+	
622
+	p = del234(jbc->jconf, (void*)jcf);
623
+
624
+	if(p != NULL)
625
+	{
626
+		if(flag == XJ_JCMD_UNSUBSCRIBE)
627
+			xj_jcon_jconf_presence(jbc, jcf, "unavailable", NULL);
628
+		jbc->nrjconf--;
629
+		xj_jconf_free(p);
630
+		DBG("XJAB: xj_jcon_del_jconf: conference deleted\n");
631
+	}
632
+
633
+	xj_jconf_free(jcf);
634
+
635
+	return 0;
636
+}
521 637
 
522 638
 /**********    *********/
523 639
 
... ...
@@ -31,6 +31,9 @@
31 31
 #define _XJAB_JCON_H_
32 32
 
33 33
 #include "../../str.h"
34
+#include "xjab_jconf.h"
35
+#include "xjab_base.h"
36
+#include "tree234.h"
34 37
 
35 38
 #define XJ_NET_NUL	0
36 39
 #define XJ_NET_ALL	0xFFFFFFFF
... ...
@@ -49,6 +52,13 @@
49 49
 #define XJ_YAH_NAME "yahoo."
50 50
 #define XJ_YAH_LEN  6
51 51
 
52
+#define XJ_JMSG_NORMAL		1
53
+#define XJ_JMSG_CHAT		2
54
+#define XJ_JMSG_GROUPCHAT	4
55
+
56
+#define XJ_JCMD_SUBSCRIBE	1
57
+#define XJ_JCMD_UNSUBSCRIBE	2
58
+
52 59
 typedef struct _xj_jcon
53 60
 {
54 61
 	int sock;        // communication socket
... ...
@@ -58,17 +68,16 @@ typedef struct _xj_jcon
58 58
 	char *hostname;  // hosname of the Jabber server
59 59
 	char *stream_id; // stream id of the session
60 60
 
61
-	/****
62
-	char *username;
63
-	char *passwd;
64
-	*/
65 61
 	char *resource;  // resource ID
66 62
 
67
-	str *id;		// id of connection
63
+	xj_jkey jkey;		// id of connection
68 64
 	int expire;		// time when the open connection is expired
69 65
 	int allowed;	// allowed IM networks
70 66
 	int ready;		// time when the connection is ready for sending messages
71 67
 
68
+	int *close;		// t_uac callback parameter
69
+	int nrjconf;	// number of open conferences
70
+	tree234 *jconf; // open conferences
72 71
 } t_xj_jcon, *xj_jcon;
73 72
 
74 73
 /** --- **/
... ...
@@ -84,16 +93,21 @@ int  xj_jcon_get_juid(xj_jcon);
84 84
 int xj_jcon_get_roster(xj_jcon);
85 85
 
86 86
 int xj_jcon_user_auth(xj_jcon, char*, char*, char*);
87
-int xj_jcon_send_presence(xj_jcon, char*, char*, char*);
87
+int xj_jcon_send_presence(xj_jcon, char*, char*, char*, char*);
88 88
 
89
-int xj_jcon_send_msg(xj_jcon, char*, int, char*, int);
89
+int xj_jcon_send_msg(xj_jcon, char*, int, char*, int, int);
90 90
 int xj_jcon_send_sig_msg(xj_jcon, char*, int, char*, int, char*, int);
91 91
 
92 92
 int xj_jcon_is_ready(xj_jcon, char *, int);
93 93
 
94
+xj_jconf xj_jcon_get_jconf(xj_jcon, str*);
95
+xj_jconf xj_jcon_check_jconf(xj_jcon, char*);
96
+int xj_jcon_del_jconf(xj_jcon, str*, int);
97
+int xj_jcon_jconf_presence(xj_jcon, xj_jconf, char*, char*);
98
+
94 99
 /**********             ***/
95 100
 
96
-int xj_jcon_set_attrs(xj_jcon, str*, int, int);
101
+int xj_jcon_set_attrs(xj_jcon, xj_jkey, int, int);
97 102
 int xj_jcon_update(xj_jcon, int);
98 103
 
99 104
 /**********             ***/
... ...
@@ -65,20 +65,23 @@ xj_jcon_pool xj_jcon_pool_init(int size, int jlen, int ch)
65 65
 	jcp->jmqueue.len = jlen;
66 66
 	jcp->jmqueue.size = 0;
67 67
 	jcp->jmqueue.cache = (ch>0)?ch:90;
68
-	if((jcp->jmqueue.expire = (int*)_M_MALLOC(jlen*sizeof(int)))==NULL)
68
+	jcp->jmqueue.expire = (int*)_M_MALLOC(jlen*sizeof(int));
69
+	if(jcp->jmqueue.expire == NULL)
69 70
 	{
70 71
 		_M_FREE(jcp->ojc);
71 72
 		_M_FREE(jcp);
72 73
 		return NULL;
73 74
 	}
74
-	if((jcp->jmqueue.jsm=(xj_sipmsg*)_M_MALLOC(jlen*sizeof(xj_sipmsg)))==NULL)
75
+	jcp->jmqueue.jsm=(xj_sipmsg*)_M_MALLOC(jlen*sizeof(xj_sipmsg));
76
+	if(jcp->jmqueue.jsm == NULL)
75 77
 	{
76 78
 		_M_FREE(jcp->jmqueue.expire);
77 79
 		_M_FREE(jcp->ojc);
78 80
 		_M_FREE(jcp);
79 81
 		return NULL;
80 82
 	}
81
-	if((jcp->jmqueue.ojc = (xj_jcon*)_M_MALLOC(jlen*sizeof(xj_jcon)))==NULL)
83
+	jcp->jmqueue.ojc = (xj_jcon*)_M_MALLOC(jlen*sizeof(xj_jcon));
84
+	if(jcp->jmqueue.ojc == NULL)
82 85
 	{
83 86
 		_M_FREE(jcp->jmqueue.expire);
84 87
 		_M_FREE(jcp->jmqueue.jsm);
... ...
@@ -132,7 +135,7 @@ int xj_jcon_pool_del_jmsg(xj_jcon_pool jcp, int idx)
132 132
 {
133 133
 	if(jcp == NULL)
134 134
 		return -1;
135
-	if(jcp->jmqueue.size == 0)
135
+	if(jcp->jmqueue.size <= 0)
136 136
 		return -2;
137 137
 	jcp->jmqueue.size--;
138 138
 	jcp->jmqueue.jsm[idx] = NULL;
... ...
@@ -169,20 +172,20 @@ int xj_jcon_pool_add(xj_jcon_pool jcp, xj_jcon jc)
169 169
  * - id : id of the Jabber connection
170 170
  * #return : pointer to the open connection to Jabber structure or NULL on error
171 171
  */
172
-xj_jcon xj_jcon_pool_get(xj_jcon_pool jcp, str *id)
172
+xj_jcon xj_jcon_pool_get(xj_jcon_pool jcp, xj_jkey jkey)
173 173
 {
174 174
 	int i = 0;
175 175
 	xj_jcon _ojc;
176 176
 	
177
-	if(jcp == NULL || id == NULL)
177
+	if(jcp==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
178 178
 		return NULL;
179 179
 
180 180
 	DBG("XJAB:xj_jcon_pool_get: looking for the connection of <%.*s>"
181
-		" into the pool\n", id->len, id->s);
181
+		" into the pool\n", jkey->id->len, jkey->id->s);
182 182
 	while(i < jcp->len)
183 183
 	{
184
-	 	if((jcp->ojc[i]!=NULL) && (!strncmp(jcp->ojc[i]->id->s, id->s, 
185
-				id->len)))
184
+	 	if((jcp->ojc[i]!=NULL) && jcp->ojc[i]->jkey->hash==jkey->hash && 
185
+			(!strncmp(jcp->ojc[i]->jkey->id->s, jkey->id->s, jkey->id->len)))
186 186
 	 	{
187 187
 	 		_ojc = jcp->ojc[i];
188 188
 	 		//jcp->ojc[i] = NULL;
... ...
@@ -200,19 +203,19 @@ xj_jcon xj_jcon_pool_get(xj_jcon_pool jcp, str *id)
200 200
  * - id : id of the Jabber connection
201 201
  * #return : 0 on success or <0 on error
202 202
  */
203
-int xj_jcon_pool_del(xj_jcon_pool jcp, str *id)
203
+int xj_jcon_pool_del(xj_jcon_pool jcp, xj_jkey jkey)
204 204
 {
205 205
 	int i = 0;
206 206
 	
207
-	if(jcp == NULL)
207
+	if(jcp==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
208 208
 		return -1;
209 209
 
210 210
 	DBG("XJAB:xj_jcon_pool_del: removing a connection from the pool\n");
211 211
 
212 212
 	while(i < jcp->len)
213 213
 	{
214
-	 	if((jcp->ojc[i]!=NULL) && (!strncmp(jcp->ojc[i]->id->s, id->s,
215
-			id->len)))
214
+	 	if((jcp->ojc[i]!=NULL) && jcp->ojc[i]->jkey->hash==jkey->hash && 
215
+			(!strncmp(jcp->ojc[i]->jkey->id->s,jkey->id->s,jkey->id->len)))
216 216
 	 	{
217 217
 	 		xj_jcon_free(jcp->ojc[i]);
218 218
 	 		jcp->ojc[i] = NULL;
... ...
@@ -28,29 +28,11 @@
28 28
 
29 29
 
30 30
 #ifndef _XJAB_UTIL_H_
31
-#define _XHAB_UTIL_H_
32
-
33
-#include<sys/types.h>
34
-#include<sys/socket.h>
35
-#include<netinet/in.h>
36
-#include<netdb.h>
37
-#include<sys/un.h>
31
+#define _XJAB_UTIL_H_
38 32
 
33
+#include "xjab_base.h"
39 34
 #include "xjab_jcon.h"
40
-#include "tree234.h"
41 35
 #include "../../str.h"
42
-#include "../../db/db.h"
43
-#include "lock.h"
44
-#include "../tm/tm_load.h"
45
-
46
-/**********             ***/
47
-
48
-typedef struct _xj_sipmsg
49
-{
50
-	str *from; // pointer to FROM
51
-	str to;    // destination
52
-	str msg;   // message body
53
-} t_xj_sipmsg, *xj_sipmsg;
54 36
 
55 37
 /**********             ***/
56 38
 
... ...
@@ -77,8 +59,8 @@ typedef struct _xj_jcon_pool
77 77
 
78 78
 xj_jcon_pool xj_jcon_pool_init(int, int, int);
79 79
 int xj_jcon_pool_add(xj_jcon_pool, xj_jcon);
80
-xj_jcon xj_jcon_pool_get(xj_jcon_pool, str*);
81
-int xj_jcon_pool_del(xj_jcon_pool, str*);
80
+xj_jcon xj_jcon_pool_get(xj_jcon_pool, xj_jkey);
81
+int xj_jcon_pool_del(xj_jcon_pool, xj_jkey);
82 82
 void xj_jccon_pool_free(xj_jcon_pool);
83 83
 void xj_jcon_pool_print(xj_jcon_pool);
84 84
 int xj_jcon_pool_add_jmsg(xj_jcon_pool, xj_sipmsg, xj_jcon);
... ...
@@ -86,7 +68,5 @@ int xj_jcon_pool_del_jmsg(xj_jcon_pool, int);
86 86
 
87 87
 /**********             ***/
88 88
 
89
-char *shahash(const char *);
90
-
91 89
 #endif
92 90
 
... ...
@@ -34,13 +34,13 @@
34 34
 #include <sys/types.h>
35 35
 #include <fcntl.h>
36 36
 #include <errno.h>
37
+#include <signal.h>
37 38
 
38 39
 #include "../../dprint.h"
39 40
 #include "../../timer.h"
40 41
 #include "../../mem/mem.h"
41 42
 #include "../../mem/shm_mem.h"
42
-#include "../tm/t_funcs.h"
43
-#include "../tm/uac.h"
43
+#include "../tm/tm_load.h"
44 44
 
45 45
 #include "xjab_worker.h"
46 46
 #include "xjab_util.h"
... ...
@@ -51,60 +51,19 @@
51 51
 
52 52
 #define XJAB_RESOURCE "serXjab"
53 53
 
54
+#define XJ_ADDRTR_NUL	0
55
+#define XJ_ADDRTR_A2B	1
56
+#define XJ_ADDRTR_B2A	2
57
+#define XJ_ADDRTR_CON	4
58
+
59
+#define XJ_POOL_SIZE	10
60
+
54 61
 /** TM bind */
55 62
 extern struct tm_binds tmb;
56 63
 
57 64
 /** debug info */
58 65
 int _xj_pid = 0;
59
-
60
-/**
61
- * function used to compare two elements in B-Tree
62
- */
63
-int k_cmp(void *a, void *b)
64
-{
65
-	int n;
66
-	if(a == NULL)
67
-	    return -1;
68
-	if(a == NULL)
69
-	    return 1;
70
-	// DBG("JABBER: k_kmp: comparing <%.*s> / <%.*s>\n", ((str *)a)->len,
71
-	// 		((str *)a)->s, ((str *)b)->len, ((str *)b)->s);
72
-	if(((str *)a)->len != ((str *)b)->len)
73
-		return (((str *)a)->len < ((str *)b)->len)?-1:1;
74
-	n = strncmp(((str *)a)->s, ((str *)b)->s, ((str *)a)->len);
75
-	if(n!=0)
76
-		return (n<0)?-1:1;
77
-	return 0;
78
-}
79
-
80
-/**
81
- * free the information from a B-Tree node
82
- */
83
-void free_str_p(void *p)
84
-{
85
-	if(p == NULL)
86
-		return;
87
-	if(((str*)p)->s != NULL)
88
-		_M_SHM_FREE(((str*)p)->s);
89
-	_M_SHM_FREE(p);
90
-}
91
-
92
-/**
93
- * free a pointer to a t_jab_sipmsg structure
94
- * > element where points 'from' MUST be eliberated separated
95
- */
96
-void xj_sipmsg_free(xj_sipmsg jsmsg)
97
-{
98
-	if(jsmsg == NULL)
99
-		return;
100
-	if(jsmsg->to.s != NULL)
101
-		_M_SHM_FREE(jsmsg->to.s);
102
-//	if(jsmsg->from.s != NULL)
103
-//		_M_SHM_FREE(jsmsg->from.s);
104
-	if(jsmsg->msg.s != NULL)
105
-		_M_SHM_FREE(jsmsg->msg.s);
106
-	_M_SHM_FREE(jsmsg);
107
-}
66
+int main_loop = 1;
108 67
 
109 68
 /**
110 69
  * init a workers list
... ...
@@ -113,7 +72,8 @@ void xj_sipmsg_free(xj_sipmsg jsmsg)
113 113
  * - max : maximum number of jobs per worker
114 114
  * #return : pointer to workers list or NULL on error
115 115
  */
116
-xj_wlist xj_wlist_init(int **pipes, int size, int max)
116
+xj_wlist xj_wlist_init(int **pipes, int size, int max, int cache_time,
117
+		int sleep_time, int delay_time)
117 118
 {
118 119
 	int i;
119 120
 	xj_wlist jwl = NULL;
... ...
@@ -128,32 +88,48 @@ xj_wlist xj_wlist_init(int **pipes, int size, int max)
128 128
 		return NULL;
129 129
 	jwl->len = size;
130 130
 	jwl->maxj = max;
131
+	
132
+	jwl->cachet = cache_time;
133
+	jwl->delayt = delay_time;
134
+	jwl->sleept = sleep_time;
135
+
131 136
 	jwl->contact_h = NULL;
132 137
 	jwl->aliases = NULL;
138
+	jwl->sems = NULL;
139
+	i = 0;
133 140
 	if((jwl->sems = create_semaphores(size)) == NULL)
134
-	{
135
-		_M_SHM_FREE(jwl);
136
-		return NULL;
137
-	}
141
+		goto clean;
138 142
 	jwl->workers = (xj_worker)_M_SHM_MALLOC(size*sizeof(t_xj_worker));
139 143
 	if(jwl->workers == NULL)
140
-	{
141
-		_M_SHM_FREE(jwl);
142
-		return NULL;
143
-	}
144
+		goto clean;
144 145
 
145 146
 	for(i = 0; i < size; i++)
146 147
 	{
147 148
 		jwl->workers[i].nr = 0;
148 149
 		jwl->workers[i].pipe = pipes[i][1];
149
-		if((jwl->workers[i].sip_ids = newtree234(k_cmp)) == NULL)
150
-		{
151
-			_M_SHM_FREE(jwl);
152
-			return NULL;
153
-		}
150
+		if((jwl->workers[i].sip_ids = newtree234(xj_jkey_cmp)) == NULL)
151
+			goto clean;
154 152
 	}	
155 153
 
156 154
 	return jwl;
155
+
156
+clean:
157
+	DBG("XJAB:xj_wlist_init: error ocurred -> cleaning\n");
158
+	if(jwl->sems != NULL)
159
+		destroy_semaphores(jwl->sems);
160
+	if(jwl->workers != NULL)
161
+	{
162
+		while(i>=0)
163
+		{
164
+			if(jwl->workers[i].sip_ids == NULL)
165
+				free2tree234(jwl->workers[i].sip_ids, xj_jkey_free_p);
166
+			i--;
167
+		}
168
+		_M_SHM_FREE(jwl->workers);
169
+	}
170
+	_M_SHM_FREE(jwl);
171
+	return NULL;
172
+
157 173
 }
158 174
 
159 175
 /**
... ...
@@ -236,7 +212,7 @@ void xj_wlist_free(xj_wlist jwl)
236 236
 	if(jwl->workers != NULL)
237 237
 	{
238 238
 		for(i=0; i<jwl->len; i++)
239
-			free2tree234(jwl->workers[i].sip_ids, free_str_p);
239
+			free2tree234(jwl->workers[i].sip_ids, xj_jkey_free_p);
240 240
 		_M_SHM_FREE(jwl->workers);
241 241
 	}
242 242
 
... ...
@@ -266,34 +242,67 @@ void xj_wlist_free(xj_wlist jwl)
266 266
 
267 267
 /**
268 268
  * return communication pipe with the worker that will process the message for
269
+ * 		the id 'sid' only if it exsists, or -1 if error
270
+ * - jwl : pointer to the workers list
271
+ * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM
272
+ *   header of the incomming SIP message)
273
+ * - p : will point to the SHM location of the 'sid' in jwl
274
+ */
275
+int xj_wlist_check(xj_wlist jwl, xj_jkey jkey, xj_jkey *p)
276
+{
277
+	int i;
278
+	if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
279
+		return -1;
280
+	
281
+	i = 0;
282
+	*p = NULL;
283
+	while(i < jwl->len)
284
+	{
285
+		s_lock_at(jwl->sems, i);
286
+		if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL)) != NULL)
287
+		{
288
+			s_unlock_at(jwl->sems, i);
289
+			DBG("XJAB:xj_wlist_check: entry exists for <%.*s> in the"
290
+				" pool of <%d> [%d]\n",jkey->id->len, jkey->id->s,
291
+				jwl->workers[i].pid,i);
292
+			return jwl->workers[i].pipe;
293
+		}
294
+		s_unlock_at(jwl->sems, i);
295
+		i++;
296
+	}
297
+	DBG("XJAB:xj_wlist_check: entry does not exist for <%.*s>\n",
298
+			jkey->id->len, jkey->id->s);	
299
+	return -1;
300
+}
301
+
302
+/**
303
+ * return communication pipe with the worker that will process the message for
269 304
  * 		the id 'sid', or -1 if error
270 305
  * - jwl : pointer to the workers list
271 306
  * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM
272 307
  *   header of the incomming SIP message)
273 308
  * - p : will point to the SHM location of the 'sid' in jwl
274 309
  */
275
-int xj_wlist_get(xj_wlist jwl, str *sid, str **p)
310
+int xj_wlist_get(xj_wlist jwl, xj_jkey jkey, xj_jkey *p)
276 311
 {
277 312
 	int i = 0, pos = -1, min = 100000;
278
-	str *msid = NULL;
313
+	xj_jkey msid = NULL;
279 314
 	
280
-	if(jwl == NULL)
315
+	if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
281 316
 		return -1;
282
-	DBG("XJAB:xj_wlist_get: -----START-----\n");
283
-	//mutex_lock(jwl->semid);
284 317
 
285 318
 	*p = NULL;
286 319
 	while(i < jwl->len)
287 320
 	{
288 321
 		s_lock_at(jwl->sems, i);
289
-		if((*p = find234(jwl->workers[i].sip_ids, (void*)sid, NULL)) != NULL)
322
+		if((*p = find234(jwl->workers[i].sip_ids, (void*)jkey, NULL))!=NULL)
290 323
 		{
291
-			//mutex_unlock(jwl->semid);
292 324
 			if(pos >= 0)
293 325
 				s_unlock_at(jwl->sems, pos);
294 326
 			s_unlock_at(jwl->sems, i);
295 327
 			DBG("XJAB:xj_wlist_get: entry already exists for <%.*s> in the"
296
-				" pool of <%d> [%d]\n",sid->len, sid->s,jwl->workers[i].pid,i);
328
+				" pool of <%d> [%d]\n",jkey->id->len, jkey->id->s,
329
+				jwl->workers[i].pid,i);
297 330
 			return jwl->workers[i].pipe;
298 331
 		}
299 332
 		if(min > jwl->workers[i].nr)
... ...
@@ -311,26 +320,46 @@ int xj_wlist_get(xj_wlist jwl, str *sid, str **p)
311 311
 	{
312 312
 		jwl->workers[pos].nr++;
313 313
 
314
-		msid = (str*)_M_SHM_MALLOC(sizeof(str));
315
-		if((msid != NULL) &&
316
-			(*p = add234(jwl->workers[pos].sip_ids, msid)) != NULL)
314
+		msid = (xj_jkey)_M_SHM_MALLOC(sizeof(t_xj_jkey));
315
+		if(msid == NULL)
316
+			goto error;
317
+		msid->id = (str*)_M_SHM_MALLOC(sizeof(str));
318
+		if(msid->id == NULL)
319
+		{
320
+			_M_SHM_FREE(msid);
321
+			goto error;
322
+		}
323
+		
324
+		msid->id->s = (char*)_M_SHM_MALLOC(jkey->id->len);
325
+		if(msid->id == NULL)
326
+		{
327
+			_M_SHM_FREE(msid->id);
328
+			_M_SHM_FREE(msid);
329
+			goto error;
330
+		}
331
+		
332
+		if((*p = add234(jwl->workers[pos].sip_ids, msid)) != NULL)
317 333
 		{
318
-			msid->s = (char*)_M_SHM_MALLOC(sid->len);
319
-			msid->len = sid->len;
320
-			memcpy(msid->s, sid->s, sid->len);
321
-			s_unlock_at(jwl->sems, pos);
322
-			//mutex_unlock(jwl->semid);
334
+			msid->id->len = jkey->id->len;
335
+			memcpy(msid->id->s, jkey->id->s, jkey->id->len);
336
+			msid->hash = jkey->hash;
337
+						s_unlock_at(jwl->sems, pos);
323 338
 			DBG("XJAB:xj_wlist_get: new entry for <%.*s> in the pool of"
324
-				" <%d> - [%d]\n", sid->len, sid->s,
339
+				" <%d> - [%d]\n", jkey->id->len, jkey->id->s,
325 340
 				jwl->workers[pos].pid, pos);
326 341
 			return jwl->workers[pos].pipe;
327 342
 		}
343
+		_M_SHM_FREE(msid->id->s);
344
+		_M_SHM_FREE(msid->id);
345
+		_M_SHM_FREE(msid);
328 346
 	}
329 347
 
348
+error:
330 349
 	if(pos >= 0)
331 350
 		s_unlock_at(jwl->sems, pos);
332
-	//mutex_unlock(jwl->semid);
333 351
 
352
+	DBG("XJAB:xj_wlist_get: can not create a new entry for <%.*s>\n",
353
+				jkey->id->len, jkey->id->s);
334 354
 	return -1;
335 355
 }
336 356
 
... ...
@@ -453,11 +482,11 @@ clean:
453 453
  *   header of the incomming SIP message
454 454
  * - _pid : process id of the worker
455 455
  */
456
-void xj_wlist_del(xj_wlist jwl, str *sid, int _pid)
456
+void xj_wlist_del(xj_wlist jwl, xj_jkey jkey, int _pid)
457 457
 {
458 458
 	int i;
459 459
 	void *p;
460
-	if(jwl == NULL || sid == NULL)
460
+	if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
461 461
 		return;
462 462
 	for(i=0; i < jwl->len; i++)
463 463
 		if(jwl->workers[i].pid == _pid)
... ...
@@ -465,95 +494,28 @@ void xj_wlist_del(xj_wlist jwl, str *sid, int _pid)
465 465
 	if(i >= jwl->len)
466 466
 	{
467 467
 		DBG("XJAB:xj_wlist_del:%d: key <%.*s> not found in [%d]...\n",
468
-			_pid, sid->len, sid->s, i);
468
+			_pid, jkey->id->len, jkey->id->s, i);
469 469
 		return;
470 470
 	}
471 471
 	DBG("XJAB:xj_wlist_del:%d: trying to delete entry for <%.*s>...\n",
472
-		_pid, sid->len, sid->s);
472
+		_pid, jkey->id->len, jkey->id->s);
473 473
 
474 474
 	s_lock_at(jwl->sems, i);
475
-	p = del234(jwl->workers[i].sip_ids, (void*)sid);
475
+	p = del234(jwl->workers[i].sip_ids, (void*)jkey);
476 476
 
477 477
 	if(p != NULL)
478 478
 	{
479 479
 		jwl->workers[i].nr--;
480 480
 
481 481
 		DBG("XJAB:xj_wlist_del:%d: sip id <%.*s> deleted\n", _pid,
482
-			sid->len, sid->s);
483
-		free_str_p(p);
482
+			jkey->id->len, jkey->id->s);
483
+		xj_jkey_free_p(p);
484 484
 	}
485 485
 
486 486
 	s_unlock_at(jwl->sems, i);
487 487
 }
488 488
 
489 489
 /**
490
- * send a SIP MESSAGE message
491
- * - to : destination
492
- * - from : origin
493
- * - contact : contact header
494
- * - msg : body of the message
495
- * #return : 0 on success or <0 on error
496
- */
497
-int xj_send_sip_msg(str *to, str *from, str *contact, str *msg)
498
-{
499
-	str  msg_type = { "MESSAGE", 7};
500
-	char buf[512];
501
-	str  tfrom;
502
-	str  str_hdr;
503
-	char buf1[1024];
504
-
505
-	// from correction
506
-	strcpy(buf, "<sip:");
507
-	strncat(buf, from->s, from->len);
508
-	tfrom.len = from->len;
509
-	if(strstr(buf+5, "sip:") == NULL)
510
-	{
511
-		tfrom.len += 5;
512
-		buf[tfrom.len++] = '>';
513
-		tfrom.s = buf;
514
-	} else
515
-		tfrom.s = buf+5;
516
-	// building Contact and Content-Type
517
-	strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: ");
518
-	str_hdr.len = 24 + CRLF_LEN + 9;
519
-	if(contact != NULL && contact->len > 2) {
520
-		strncat(buf1,contact->s,contact->len);
521
-		str_hdr.len += contact->len;
522
-	} else {
523
-		strncat(buf1,tfrom.s,tfrom.len);
524
-		str_hdr.len += tfrom.len;
525
-	}
526
-	strcat(buf1, CRLF);
527
-	str_hdr.len += CRLF_LEN;
528
-	str_hdr.s = buf1;
529
-
530
-	return tmb.t_uac( &msg_type, to, &str_hdr , msg, &tfrom, 0 , 0, 0);
531
-}
532
-
533
-/**
534
- * send a SIP MESSAGE message
535
- * - to : destination
536
- * - from : origin
537
- * - contact : contact header
538
- * - msg : body of the message, string terminated by zero
539
- * #return : 0 on success or <0 on error
540
- */
541
-int xj_send_sip_msgz(str *to, str *from, str *contact, char *msg)
542
-{
543
-	str tstr;
544
-	int n;
545
-	tstr.s = msg;
546
-	tstr.len = strlen(msg);
547
-	if((n = xj_send_sip_msg(to, from, contact, &tstr)) < 0)
548
-		DBG("JABBER: jab_send_sip_msgz: ERROR SIP MESSAGE wasn't sent to"
549
-			" [%.*s]...\n", tstr.len, tstr.s);
550
-	else
551
-		DBG("JABBER: jab_send_sip_msgz: SIP MESSAGE was sent to [%.*s]...\n",
552
-			tstr.len, tstr.s);
553
-	return n;
554
-}
555
-
556
-/**
557 490
  * address corection
558 491
  * alias A~B: flag == 0 => A->B, otherwise B->A
559 492
  */
... ...
@@ -589,30 +551,55 @@ int xj_address_translation(str *src, str *dst, xj_jalias als, int flag)
589 589
 	DBG("XJAB:xj_address_translation:%d: - doing address corection\n", 
590 590
 			_xj_pid);	
591 591
 
592
-	if(!flag)
592
+	if(flag & XJ_ADDRTR_A2B)
593 593
 	{
594
-		if(!strncasecmp(p, als->jdm->s, als->jdm->len))
594
+		if(strncasecmp(p, als->jdm->s, als->jdm->len))
595
+		{
596
+			DBG("XJA:xj_address_translation:%d: - wrong Jabber"
597
+				" destination!\n", _xj_pid);
598
+			return -1;
599
+		}
600
+		if(flag & XJ_ADDRTR_CON)
595 601
 		{
596 602
 			DBG("XJAB:xj_address_translation:%d: - that is for"
597
-				" Jabber network\n", _xj_pid);
598
-			dst->len = p - src->s - 1;
599
-			strncpy(dst->s, src->s, dst->len);
603
+				" Jabber conference\n", _xj_pid);
604
+			p0 = p-1;
605
+			while(p0 > src->s && *p0 != '%')
606
+				p0--;
607
+			if(p0 <= src->s)
608
+				return -1;
609
+			p0--;
610
+			while(p0 > src->s && *p0 != '%')
611
+				p0--;
612
+			if(*p0 != '%')
613
+				return -1;
614
+			dst->len = p - p0 - 2;
615
+			strncpy(dst->s, p0+1, dst->len);
600 616
 			dst->s[dst->len]=0;
601
-			if((p = strchr(dst->s, '%')) != NULL)
617
+			p = dst->s;
618
+			while(p < (dst->s + dst->len) && *p!='%')
619
+				p++;
620
+			if(*p=='%')
602 621
 				*p = '@';
603
-			else
604
-			{
605
-				DBG("XJAB:xj_address_translation:%d: - wrong Jabber"
606
-				" destination\n", _xj_pid);
607
-				return -1;
608
-			}
609 622
 			return 0;
610 623
 		}
611
-		DBG("XJAB:xj_address_translation:%d: - wrong Jabber"
612
-			" destination!\n", _xj_pid);
613
-		return -1;		
624
+		
625
+		DBG("XJAB:xj_address_translation:%d: - that is for"
626
+			" Jabber network\n", _xj_pid);
627
+		dst->len = p - src->s - 1;
628
+		strncpy(dst->s, src->s, dst->len);
629
+		dst->s[dst->len]=0;
630
+		if((p = strchr(dst->s, '%')) != NULL)
631
+			*p = '@';
632
+		else
633
+		{
634
+			DBG("XJAB:xj_address_translation:%d: - wrong Jabber"
635
+			" destination\n", _xj_pid);
636
+			return -1;
637
+		}
638
+		return 0;
614 639
 	}
615
-	else
640
+	if(flag & XJ_ADDRTR_B2A)
616 641
 	{
617 642
 		*(p-1) = '%';
618 643
 		p0 = src->s + src->len;
... ...
@@ -653,65 +640,85 @@ done:
653 653
  * #return : 0 on success or <0 on error
654 654
  */
655 655
 int xj_worker_process(xj_wlist jwl, char* jaddress, int jport, int pipe,
656
-		int size, int ctime, int wtime, int dtime, db_con_t* db_con)
656
+		db_con_t* db_con)
657 657
 {
658
-	int ret, i, pos, maxfd;
658
+	int ret, i, pos, maxfd, flag;
659 659
 	xj_jcon_pool jcp;
660 660
 	struct timeval tmv;
661 661
 	fd_set set, mset;
662 662
 	xj_sipmsg jsmsg;
663 663
 	xj_jcon jbc;
664
+	xj_jconf jcf;
664 665
 	char *p, buff[1024], recv_buff[4096];
665 666
 	int flags, nr, ltime = 0;
666 667
 	str sto;
667 668
 	
668
-	db_key_t keys[] = {"sip_id"};
669
-	db_val_t vals[] = {{DB_STRING, 0, {.string_val = buff}}};
669
+	db_key_t keys[] = {"sip_id", "type"};
670
+	db_val_t vals[] = { {DB_STRING, 0, {.string_val = buff}},
671
+						{DB_INT, 0, {.int_val = 0}} };
670 672
 	db_key_t col[] = {"jab_id", "jab_passwd"};
671 673
 	db_res_t* res = NULL;
672 674
 
673 675
 	_xj_pid = getpid();
674 676
 	
677
+	signal(SIGTERM, xj_sig_handler);
678
+	signal(SIGINT, xj_sig_handler);
679
+	signal(SIGQUIT, xj_sig_handler);
680
+	
675 681
 	DBG("XJAB:xj_worker:%d: started - pipe=<%d> : 1st message delay"
676
-		" <%d>\n", _xj_pid, pipe, dtime);
682
+		" <%d>\n", _xj_pid, pipe, jwl->delayt);
677 683
 
678
-	if((jcp = xj_jcon_pool_init(size, 10, dtime)) == NULL)
684
+	if((jcp=xj_jcon_pool_init(jwl->maxj,XJ_POOL_SIZE,jwl->delayt))==NULL)
679 685
 	{
680 686
 		DBG("XJAB:xj_worker: cannot allocate the pool\n");
681 687
 		return -1;
682 688
 	}
683 689
 
684 690
 	maxfd = pipe;
685
-	tmv.tv_sec = wtime;
691
+	tmv.tv_sec = jwl->sleept;
686 692
 	tmv.tv_usec = 0;
687 693
 
688 694
 	FD_ZERO(&set);
689 695
 	FD_SET(pipe, &set);
690
-	while(1)
696
+	while(main_loop)
691 697
 	{
692 698
 		mset = set;