static void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req) { char filenamebuf[256]; unsigned long ip, size; unsigned short port; if ( sscanf (req, "DCC CHAT chat %lu %hu", &ip, &port) == 2 ) { if ( session->callbacks.event_dcc_chat_req ) { irc_dcc_session_t * dcc; int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_CHAT, 0, &dcc); if ( err ) { session->lasterror = err; return; } (*session->callbacks.event_dcc_chat_req) (session, nick, inet_ntoa (dcc->remote_addr.sin_addr), dcc->id); } return; } else if ( sscanf (req, "DCC SEND %s %lu %hu %lu", filenamebuf, &ip, &port, &size) == 4 ) { if ( session->callbacks.event_dcc_send_req ) { irc_dcc_session_t * dcc; int err = libirc_new_dcc_session (session, ip, port, LIBIRC_DCC_RECVFILE, 0, &dcc); if ( err ) { session->lasterror = err; return; } (*session->callbacks.event_dcc_send_req) (session, nick, inet_ntoa (dcc->remote_addr.sin_addr), filenamebuf, size, dcc->id); dcc->received_file_size = size; } return; } #if defined (ENABLE_DEBUG) fprintf (stderr, "BUG: Unhandled DCC message: %s\n", req); abort(); #endif }
int irc_dcc_chat (irc_session_t * session, void * ctx, const char * nick, irc_dcc_callback_t callback, irc_dcc_t * dccid) { struct sockaddr_in saddr; socklen_t len = sizeof(saddr); char cmdbuf[128], notbuf[128]; irc_dcc_session_t * dcc; int err; if ( session->state != LIBIRC_STATE_CONNECTED ) { session->lasterror = LIBIRC_ERR_STATE; return 1; } err = libirc_new_dcc_session (session, 0, 0, LIBIRC_DCC_CHAT, ctx, &dcc); if ( err ) { session->lasterror = err; return 1; } if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 ) { session->lasterror = LIBIRC_ERR_SOCKET; libirc_remove_dcc_session (session, dcc, 1); return 1; } sprintf (notbuf, "DCC Chat (%s)", inet_ntoa (saddr.sin_addr)); sprintf (cmdbuf, "DCC CHAT chat %lu %u", (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs (saddr.sin_port)); if ( irc_cmd_notice (session, nick, notbuf) || irc_cmd_ctcp_request (session, nick, cmdbuf) ) { libirc_remove_dcc_session (session, dcc, 1); return 1; } *dccid = dcc->id; dcc->cb = callback; dcc->dccmode = LIBIRC_DCC_CHAT; return 0; }
static void accept_dcc_send(irc_session_t * session, const char * nick, const char * req, char *filename, unsigned long ip, irc_dcc_size_t size, unsigned short port, int ssl) { DBG_OK("---- got dcc send req: %s ---", req); if (session->callbacks.event_dcc_send_req) { irc_dcc_session_t * dcc; int err = libirc_new_dcc_session(session, ip, port, 0, &dcc, ssl); if (err) { session->lasterror = err; return; } (*session->callbacks.event_dcc_send_req) (session, nick, inet_ntoa(dcc->remote_addr.sin_addr), filename, size, dcc->id); dcc->received_file_size = size; } }
int irc_dcc_sendfile (irc_session_t * session, void * ctx, const char * nick, const char * filename, irc_dcc_callback_t callback, irc_dcc_t * dccid) { struct sockaddr_in saddr; socklen_t len = sizeof(saddr); char cmdbuf[128], notbuf[128]; irc_dcc_session_t * dcc; const char * p; int err; long filesize; if ( !session || !dccid || !filename || !callback ) { session->lasterror = LIBIRC_ERR_INVAL; return 1; } if ( session->state != LIBIRC_STATE_CONNECTED ) { session->lasterror = LIBIRC_ERR_STATE; return 1; } if ( (err = libirc_new_dcc_session (session, 0, 0, LIBIRC_DCC_SENDFILE, ctx, &dcc)) != 0 ) { session->lasterror = err; return 1; } if ( (dcc->dccsend_file_fp = fopen (filename, "rb")) == 0 ) { libirc_remove_dcc_session (session, dcc, 1); session->lasterror = LIBIRC_ERR_OPENFILE; return 1; } /* Get file length */ if ( fseek (dcc->dccsend_file_fp, 0, SEEK_END) || (filesize = ftell (dcc->dccsend_file_fp)) == -1 || fseek (dcc->dccsend_file_fp, 0, SEEK_SET) ) { libirc_remove_dcc_session (session, dcc, 1); session->lasterror = LIBIRC_ERR_NODCCSEND; return 1; } if ( getsockname (dcc->sock, (struct sockaddr*) &saddr, &len) < 0 ) { libirc_remove_dcc_session (session, dcc, 1); session->lasterror = LIBIRC_ERR_SOCKET; return 1; } // Remove path from the filename if ( (p = strrchr (filename, '\\')) == 0 && (p = strrchr (filename, '/')) == 0 ) p = filename; else p++; // skip directory slash sprintf (notbuf, "DCC Send %s (%s)", p, inet_ntoa (saddr.sin_addr)); sprintf (cmdbuf, "DCC SEND %s %lu %u %ld", p, (unsigned long) ntohl (saddr.sin_addr.s_addr), ntohs (saddr.sin_port), filesize); if ( irc_cmd_notice (session, nick, notbuf) || irc_cmd_ctcp_request (session, nick, cmdbuf) ) { libirc_remove_dcc_session (session, dcc, 1); return 1; } *dccid = dcc->id; dcc->cb = callback; return 0; }