| 432 | } |
| 433 | |
| 434 | int xmpp_server_child_process(int data_pipe) |
| 435 | { |
| 436 | int rv; |
| 437 | int listen_fd; |
| 438 | fd_set fdset; |
| 439 | struct xmpp_connection *conn; |
| 440 | |
| 441 | snprintf(local_secret, sizeof(local_secret), "%s", random_secret()); |
| 442 | |
| 443 | while ((listen_fd = net_listen(xmpp_domain, xmpp_port)) < 0) { |
| 444 | /* ugh. */ |
| 445 | sleep(3); |
| 446 | } |
| 447 | |
| 448 | while (1) { |
| 449 | FD_ZERO(&fdset); |
| 450 | FD_SET(data_pipe, &fdset); |
| 451 | FD_SET(listen_fd, &fdset); |
| 452 | |
| 453 | /* check for dead connections */ |
| 454 | for (conn = conn_list; conn; ) { |
| 455 | struct xmpp_connection *next = conn->next; |
| 456 | |
| 457 | if (conn->type == CONN_DEAD) |
| 458 | conn_free(conn); |
| 459 | conn = next; |
| 460 | } |
| 461 | |
| 462 | for (conn = conn_list; conn; conn = conn->next) { |
| 463 | /* check if we need to set up a connection */ |
| 464 | if (conn->type == CONN_OUTBOUND && conn->fd == -1) { |
| 465 | if ((conn->fd = net_connect(conn->domain, xmpp_port)) >= 0) |
| 466 | { |
| 467 | net_printf(conn->fd, |
| 468 | "<?xml version='1.0'?>" |
| 469 | "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' version='1.0' " |
| 470 | "xmlns:db='jabber:server:dialback' to='%s' from='%s'>", |
| 471 | conn->domain, xmpp_domain); |
| 472 | net_printf(conn->fd, |
| 473 | "<stream:features xmlns:stream='http://etherx.jabber.org/streams'/>"); |
| 474 | } else { |
| 475 | conn->type = CONN_DEAD; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | if (conn->fd != -1) |
| 480 | FD_SET(conn->fd, &fdset); |
| 481 | } |
| 482 | |
| 483 | rv = select(FD_SETSIZE, &fdset, NULL, NULL, NULL); |
| 484 | if (rv < 0) { |
| 485 | if (errno == EINTR) { |
| 486 | continue; |
| 487 | } |
| 488 | LM_ERR("select() failed: %s\n", strerror(errno)); |
| 489 | } else if (!rv) { |
| 490 | /* timeout */ |
| 491 | } else { |
no test coverage detected