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; }
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; }
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; } }
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; }
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; }
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; }
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; }
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; }