- return 0;
-}
-
-static void
-start_io(struct Client *server)
-{
- unsigned char *iobuf;
- int c = 0;
- int linecount = 0;
- int linelen;
-
- iobuf = rb_malloc(256); /* XXX: This seems arbitrary. Perhaps make it IRCD_BUFSIZE? --nenolod */
-
- if(IsCapable(server, CAP_ZIP))
- {
- /* ziplink */
- iobuf[c++] = SLINKCMD_SET_ZIP_OUT_LEVEL;
- iobuf[c++] = 0; /* | */
- iobuf[c++] = 1; /* \ len is 1 */
- iobuf[c++] = ConfigFileEntry.compression_level;
- iobuf[c++] = SLINKCMD_START_ZIP_IN;
- iobuf[c++] = SLINKCMD_START_ZIP_OUT;
- }
-
- while (MyConnect(server))
- {
- linecount++;
-
- iobuf = rb_realloc(iobuf, (c + READBUF_SIZE + 64));
-
- /* store data in c+3 to allow for SLINKCMD_INJECT_RECVQ and len u16 */
- linelen = rb_linebuf_get(&server->localClient->buf_recvq, (char *) (iobuf + c + 3), READBUF_SIZE, LINEBUF_PARTIAL, LINEBUF_RAW); /* include partial lines */
-
- if(linelen)
- {
- iobuf[c++] = SLINKCMD_INJECT_RECVQ;
- iobuf[c++] = (linelen >> 8);
- iobuf[c++] = (linelen & 0xff);
- c += linelen;
- }
- else
- break;
- }
-
- while (MyConnect(server))
- {
- linecount++;
-
- iobuf = rb_realloc(iobuf, (c + BUF_DATA_SIZE + 64));
-
- /* store data in c+3 to allow for SLINKCMD_INJECT_RECVQ and len u16 */
- linelen = rb_linebuf_get(&server->localClient->buf_sendq,
- (char *) (iobuf + c + 3), READBUF_SIZE,
- LINEBUF_PARTIAL, LINEBUF_PARSED); /* include partial lines */
-
- if(linelen)
- {
- iobuf[c++] = SLINKCMD_INJECT_SENDQ;
- iobuf[c++] = (linelen >> 8);
- iobuf[c++] = (linelen & 0xff);
- c += linelen;
- }
- else
- break;
- }
-
- /* start io */
- iobuf[c++] = SLINKCMD_INIT;
-
- server->localClient->slinkq = iobuf;
- server->localClient->slinkq_ofs = 0;
- server->localClient->slinkq_len = c;
-
- /* schedule a write */
- send_queued_slink_write(server->localClient->ctrlF, server);
-}
-
-/*
- * fork_server
- *
- * inputs - struct Client *server
- * output - success: 0 / failure: -1
- * side effect - fork, and exec SERVLINK to handle this connection
- */
-static int
-fork_server(struct Client *server)
-{
- int ret;
- int i;
- int ctrl_fds[2];
- int data_fds[2];
-
- char fd_str[4][6];
- char *kid_argv[7];
- char slink[] = "-slink";
-
-
- /* ctrl */
-#ifdef HAVE_SOCKETPAIR
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, ctrl_fds) < 0)
-#else
- if(inet_socketpair(AF_INET,SOCK_STREAM, 0, ctrl_fds) < 0)
-#endif
- goto fork_error;
-
-
-
- /* data */
-#ifdef HAVE_SOCKETPAIR
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, data_fds) < 0)
-#else
- if(inet_socketpair(AF_INET,SOCK_STREAM, 0, data_fds) < 0)
-#endif
- goto fork_error;
-
-
-#ifdef __CYGWIN__
- if((ret = vfork()) < 0)
-#else
- if((ret = fork()) < 0)
-#endif
- goto fork_error;
- else if(ret == 0)
- {
- int maxconn = maxconnections;
-
- /* set our fds as non blocking and close everything else */
- for (i = 0; i < maxconn; i++)
- {
-
-
- if((i == ctrl_fds[1]) || (i == data_fds[1]) || (i == rb_get_fd(server->localClient->F)))
- {
- // XXX rb_set_nb(i);
- }
- else
- {
-#ifdef __CYGWIN__
- if(i > 2) /* don't close std* */
-#endif
- close(i);
- }
- }
-
- rb_snprintf(fd_str[0], sizeof(fd_str[0]), "%d", ctrl_fds[1]);
- rb_snprintf(fd_str[1], sizeof(fd_str[1]), "%d", data_fds[1]);
- rb_snprintf(fd_str[2], sizeof(fd_str[2]), "%d", rb_get_fd(server->localClient->F));
- kid_argv[0] = slink;
- kid_argv[1] = fd_str[0];
- kid_argv[2] = fd_str[1];
- kid_argv[3] = fd_str[2];
- kid_argv[4] = NULL;
-
- /* exec servlink program */
- execv(ConfigFileEntry.servlink_path, kid_argv);
-
- /* We're still here, abort. */
- _exit(1);
- }
- else
- {
- rb_close(server->localClient->F);
-
- /* close the childs end of the pipes */
- close(ctrl_fds[1]);
- close(data_fds[1]);
-
- s_assert(server->localClient);
- server->localClient->ctrlF = rb_open(ctrl_fds[0], RB_FD_PIPE, "servlink ctrl");
- server->localClient->F = rb_open(data_fds[0], RB_FD_PIPE, "servlink data");
-
- if(!rb_set_nb(server->localClient->ctrlF))
- {
- ilog_error("setting a slink fd nonblocking");
- }
-
- if(!rb_set_nb(server->localClient->F))
- {
- ilog_error("setting a slink fd nonblocking");
- }
-
- read_ctrl_packet(server->localClient->ctrlF, server);
- read_packet(server->localClient->F, server);
- }