Example #1
0
int	irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback)
{
	irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);

	if ( !dcc )
		return 1;

	if ( dcc->state != LIBIRC_STATE_INIT )
	{
		session->lasterror = LIBIRC_ERR_STATE;
		libirc_mutex_unlock (&session->mutex_dcc);
		return 1;
	}

	dcc->cb = callback;
	dcc->ctx = ctx;

	// Initiate the connect
    if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) )
	{
		libirc_dcc_destroy_nolock (session, dccid);
		libirc_mutex_unlock (&session->mutex_dcc);
		session->lasterror = LIBIRC_ERR_CONNECT;
		return 1;
	}

	dcc->state = LIBIRC_STATE_CONNECTING;
	libirc_mutex_unlock (&session->mutex_dcc);
	return 0;
}
Example #2
0
int irc_dcc_msg	(irc_session_t * session, irc_dcc_t dccid, const char * text)
{
	irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 1);

	if ( !dcc )
		return 1;

	if ( dcc->dccmode != LIBIRC_DCC_CHAT )
	{
		session->lasterror = LIBIRC_ERR_INVAL;
		libirc_mutex_unlock (&session->mutex_dcc);
		return 1;
	}

	if ( (strlen(text) + 2) >= (sizeof(dcc->outgoing_buf) - dcc->outgoing_offset) )
	{
		session->lasterror = LIBIRC_ERR_NOMEM;
		libirc_mutex_unlock (&session->mutex_dcc);
		return 1;
	}

	libirc_mutex_lock (&dcc->mutex_outbuf);

	strcpy (dcc->outgoing_buf + dcc->outgoing_offset, text);
	dcc->outgoing_offset += strlen (text);
	dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0D;
	dcc->outgoing_buf[dcc->outgoing_offset++] = 0x0A;

	libirc_mutex_unlock (&dcc->mutex_outbuf);
	libirc_mutex_unlock (&session->mutex_dcc);

	return 0;
}
Example #3
0
static void libirc_dcc_destroy_nolock (irc_session_t * session, irc_dcc_t dccid)
{
	irc_dcc_session_t * dcc = libirc_find_dcc_session (session, dccid, 0);

	if ( dcc )
	{
		if ( dcc->sock >= 0 )
			socket_close (&dcc->sock);

		dcc->state = LIBIRC_STATE_REMOVED;
	}
}
Example #4
0
int irc_dcc_decline(irc_session_t * session, irc_dcc_t dccid) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }

    libirc_dcc_destroy_nolock(session, dccid);
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;
}
Example #5
0
int irc_dcc_destroy(irc_session_t * session, irc_dcc_t dccid) {
    // This function doesn't actually destroy the session; it just changes
    // its state to "removed" and closes the socket. The memory is actually
    // freed after the processing loop.
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->sock >= 0)
        socket_close(&dcc->sock);

    dcc->state = LIBIRC_STATE_REMOVED;

    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;
}
Example #6
0
static void libirc_dcc_destroy_nolock(irc_session_t * session, irc_dcc_t dccid)
{
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 0);

    if (dcc == NULL) {
        return;
    }

#ifdef ENABLE_SSL
    if (dcc->ssl) {
        SSL_free(dcc->ssl_ctx);
    }
#endif

    if (dcc->sock >= 0) {
        socket_close(&dcc->sock);
    }

    dcc->state = LIBIRC_STATE_REMOVED;
}
Example #7
0
int irc_dcc_resume(irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback, const char *nick, irc_dcc_size_t filePosition) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }
    dcc->cb = callback;
    dcc->ctx = ctx;

    // ctcp msg to bot
    char buf[512];
    snprintf(buf, sizeof(buf), "DCC RESUME file.ext %hu %" IRC_DCC_SIZE_T_FORMAT "", ntohs(dcc->remote_addr.sin_port), filePosition);
    DBG_OK("%s", buf);
    irc_cmd_ctcp_request(session, nick, buf);
    dcc->state = LIBIRC_STATE_WAITING_FOR_RESUME_ACK;
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;

}
Example #8
0
int irc_dcc_accept(irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }

    dcc->cb = callback;
    dcc->ctx = ctx;

    DBG_OK("going to socket_connect!");

    // Initiate the connect

    if (socket_connect(&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof (dcc->remote_addr))) {
        libirc_dcc_destroy_nolock(session, dccid);
        libirc_mutex_unlock(&session->mutex_dcc);
        session->lasterror = LIBIRC_ERR_CONNECT;
        return 1;
    }
    
#ifdef ENABLE_SSL
    if (dcc->ssl == 1) {
        DBG_OK("using ssl!");

        while (1) {
            int err = SSL_connect(dcc->ssl_ctx);
            if (err <= 0) {
                int ssl_err = SSL_get_error(dcc->ssl_ctx, err);
                if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
                    continue;
                } else {
                    print_ssl_error_stack();
                    session->lasterror = LIBIRC_ERR_CONNECT;
                    return 1;
                }
            }
            DBG_OK("ssl_connect succeded!");
            break;
        }
        
        const char *ciphers_used = "None";
        ciphers_used = SSL_get_cipher_name(dcc->ssl_ctx);
        logprintf(LOG_INFO, "using cipher suite: %s for dcc connection", ciphers_used);
    }
#endif

    DBG_OK("connect succeded2!");

    dcc->state = LIBIRC_STATE_CONNECTING;
#ifdef ENABLE_SSL
    if (dcc->ssl) {
        dcc->state = LIBIRC_STATE_CONNECTED;
    }
#endif
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;
}