static int xmpp_send_pipe_cmd(enum xmpp_pipe_cmd_type type, str *from, str *to, str *body, str *id) { struct xmpp_pipe_cmd *cmd; /* todo: make shm allocation for one big chunk to include all fields */ cmd = (struct xmpp_pipe_cmd *) shm_malloc(sizeof(struct xmpp_pipe_cmd)); memset(cmd, 0, sizeof(struct xmpp_pipe_cmd)); cmd->type = type; cmd->from = shm_strdup(from); cmd->to = shm_strdup(to); cmd->body = shm_strdup(body); cmd->id = shm_strdup(id); if(pid == *xmpp_pid) /* if attempting to send from the xmpp extra process */ { LM_DBG("I am the XMPP extra process\n"); if(backend_mode == XMPP_COMP) { struct xmpp_private_data priv; priv.fd = curr_fd; priv.running = 1; xmpp_component_net_send(cmd, &priv); } else { xmpp_server_net_send(cmd); } } else { if (write(pipe_fds[1], &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to write to command pipe: %s\n", strerror(errno)); xmpp_free_pipe_cmd(cmd); return -1; } } return 0; }
int xmpp_component_child_process(int data_pipe) { int fd, maxfd, rv; fd_set fdset; xode_pool pool; xode_stream stream; struct xmpp_private_data priv; struct xmpp_pipe_cmd *cmd; while (1) { fd = net_connect(xmpp_host, xmpp_port); if (fd < 0) { sleep(3); continue; } curr_fd = fd; priv.fd = fd; priv.running = 1; pool = xode_pool_new(); stream = xode_stream_new(pool, stream_node_callback, &priv); net_printf(fd, "<?xml version='1.0'?>" "<stream:stream xmlns='jabber:component:accept' to='%s' " "version='1.0' xmlns:stream='http://etherx.jabber.org/streams'>", xmpp_domain); while (priv.running) { FD_ZERO(&fdset); FD_SET(data_pipe, &fdset); FD_SET(fd, &fdset); maxfd = fd > data_pipe ? fd : data_pipe; rv = select(maxfd + 1, &fdset, NULL, NULL, NULL); if (rv < 0) { if (errno == EINTR) { continue; } LM_ERR("select() failed: %s\n", strerror(errno)); } else if (!rv) { /* timeout */ } else if (FD_ISSET(fd, &fdset)) { char *buf = net_read_static(fd); if (!buf) /* connection closed */ break; LM_DBG("server read\n[%s]\n", buf); xode_stream_eat(stream, buf, strlen(buf)); } else if (FD_ISSET(data_pipe, &fdset)) { if (read(data_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) { LM_ERR("failed to read from command pipe: %s\n", strerror(errno)); } else { xmpp_component_net_send(cmd, &priv); } } } xode_pool_free(pool); close(fd); } return 0; }