Example #1
0
static void irc_dccsend_send_connected(gpointer data, int source, PurpleInputCondition cond) {
    PurpleXfer *xfer = (PurpleXfer *) data;
    struct irc_xfer_send_data *xd = purple_xfer_get_protocol_data(xfer);
    int conn;

    conn = accept(xd->fd, NULL, 0);
    if (conn == -1) {
        /* Accepting the connection failed. This could just be related
         * to the nonblocking nature of the listening socket, so we'll
         * just try again next time */
        /* Let's print an error message anyway */
        purple_debug_warning("irc", "accept: %s\n", g_strerror(errno));
        return;
    }

    purple_input_remove(purple_xfer_get_watcher(xfer));
    purple_xfer_set_watcher(xfer, 0);
    close(xd->fd);
    xd->fd = -1;

    _purple_network_set_common_socket_flags(conn);

    xd->inpa = purple_input_add(conn, PURPLE_INPUT_READ, irc_dccsend_send_read, xfer);
    /* Start the transfer */
    purple_xfer_start(xfer, conn, NULL, 0);
}
Example #2
0
/**
 * This is the watcher callback for any listening socket that is
 * waiting for a peer to connect.  When a peer connects we set the
 * input watcher to start reading data from the peer.
 *
 * To make sure that the connection is with the intended person and
 * not with a malicious middle man, we don't send anything until we've
 * received a peer frame from the remote user and have verified that
 * the cookie in the peer frame matches the cookie that was exchanged
 * in the channel 2 ICBM.
 */
void
peer_connection_listen_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	PeerConnection *conn;
	struct sockaddr addr;
	socklen_t addrlen = sizeof(addr);

	conn = data;

	purple_debug_info("oscar", "Accepting connection on listener socket.\n");

	conn->fd = accept(conn->listenerfd, &addr, &addrlen);
	if (conn->fd < 0)
	{
		if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
			/* No connection yet--no worries */
			/* TODO: Hmm, but they SHOULD be connected if we're here, right? */
			return;

		peer_connection_trynext(conn);
		return;
	}

	if ((addr.sa_family != PF_INET) && (addr.sa_family != PF_INET6))
	{
		/* Invalid connection type?!  Continue waiting. */
		close(conn->fd);
		return;
	}

	_purple_network_set_common_socket_flags(conn->fd);

	purple_input_remove(conn->watcher_incoming);

	peer_connection_finalize_connection(conn);
}
Example #3
0
static void
bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleXfer *xfer = data;
	XepXfer *xf = xfer->data;
	int acceptfd;
	int len = 0;

	if(xf == NULL)
		return;

	purple_debug_info("bonjour", "bonjour_sock5_request_cb - req_state = 0x%x\n", xf->sock5_req_state);

	switch(xf->sock5_req_state){
	case 0x00:
		acceptfd = accept(source, NULL, 0);
		if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {

		} else if(acceptfd == -1) {
			/* This should cancel the ft */
			purple_debug_error("bonjour", "Error accepting incoming SOCKS5 connection. (%d)\n", errno);

			purple_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			purple_xfer_cancel_remote(xfer);
			return;
		} else {
			purple_debug_info("bonjour", "Accepted SOCKS5 ft connection - fd=%d\n", acceptfd);

			_purple_network_set_common_socket_flags(acceptfd);
			purple_input_remove(xfer->watcher);
			close(source);
			xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ,
							 bonjour_sock5_request_cb, xfer);
			xf->sock5_req_state++;
			xf->rxlen = 0;
		}
		break;
	case 0x01:
		xfer->fd = source;
		len = read(source, xf->rx_buf + xf->rxlen, 3);
		if(len < 0 && errno == EAGAIN)
			return;
		else if(len <= 0){
			purple_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			purple_xfer_cancel_remote(xfer);
			return;
		} else {
			purple_input_remove(xfer->watcher);
			xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
							 bonjour_sock5_request_cb, xfer);
			xf->sock5_req_state++;
			xf->rxlen = 0;
			bonjour_sock5_request_cb(xfer, source, PURPLE_INPUT_WRITE);
		}
		break;
	case 0x02:
		xf->tx_buf[0] = 0x05;
		xf->tx_buf[1] = 0x00;
		len = write(source, xf->tx_buf, 2);
		if (len < 0 && errno == EAGAIN)
			return;
		else if (len < 0) {
			purple_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			purple_xfer_cancel_remote(xfer);
			return;
		} else {
			purple_input_remove(xfer->watcher);
			xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
							 bonjour_sock5_request_cb, xfer);
			xf->sock5_req_state++;
			xf->rxlen = 0;
		}
		break;
	case 0x03:
		len = read(source, xf->rx_buf + xf->rxlen, 20);
		if(len<=0){
		} else {
			purple_input_remove(xfer->watcher);
			xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
							 bonjour_sock5_request_cb, xfer);
			xf->sock5_req_state++;
			xf->rxlen = 0;
			bonjour_sock5_request_cb(xfer, source, PURPLE_INPUT_WRITE);
		}
		break;
	case 0x04:
		xf->tx_buf[0] = 0x05;
		xf->tx_buf[1] = 0x00;
		xf->tx_buf[2] = 0x00;
		xf->tx_buf[3] = 0x03;
		xf->tx_buf[4] = strlen(xf->buddy_ip);
		memcpy(xf->tx_buf + 5, xf->buddy_ip, strlen(xf->buddy_ip));
		xf->tx_buf[5+strlen(xf->buddy_ip)] = 0x00;
		xf->tx_buf[6+strlen(xf->buddy_ip)] = 0x00;
		len = write(source, xf->tx_buf, 7 + strlen(xf->buddy_ip));
		if (len < 0 && errno == EAGAIN) {
			return;
		} else if (len < 0) {
			purple_input_remove(xfer->watcher);
			xfer->watcher = 0;
			close(source);
			purple_xfer_cancel_remote(xfer);
			return;
		} else {
			purple_input_remove(xfer->watcher);
			xfer->watcher = 0;
			xf->rxlen = 0;
			/*close(source);*/
			purple_xfer_start(xfer, source, NULL, -1);
		}
		break;
	default:
		break;
	}
	return;
}