diff options
Diffstat (limited to 'protocols/msn/invitation.c')
-rw-r--r-- | protocols/msn/invitation.c | 677 |
1 files changed, 360 insertions, 317 deletions
diff --git a/protocols/msn/invitation.c b/protocols/msn/invitation.c index 7bfec4aa..c386bdb9 100644 --- a/protocols/msn/invitation.c +++ b/protocols/msn/invitation.c @@ -12,12 +12,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License with the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; if not, write to the Free Software Foundation, Inc., 51 Franklin St., @@ -32,131 +32,134 @@ #ifdef debug #undef debug #endif -#define debug(msg...) log_message( LOGLVL_INFO, msg ) +#define debug(msg ...) log_message(LOGLVL_INFO, msg) -static void msn_ftp_free( file_transfer_t *file ); -static void msn_ftpr_accept( file_transfer_t *file ); -static void msn_ftp_finished( file_transfer_t *file ); -static void msn_ftp_canceled( file_transfer_t *file, char *reason ); -static gboolean msn_ftpr_write_request( file_transfer_t *file ); +static void msn_ftp_free(file_transfer_t *file); +static void msn_ftpr_accept(file_transfer_t *file); +static void msn_ftp_finished(file_transfer_t *file); +static void msn_ftp_canceled(file_transfer_t *file, char *reason); +static gboolean msn_ftpr_write_request(file_transfer_t *file); -static gboolean msn_ftp_connected( gpointer data, gint fd, b_input_condition cond ); -static gboolean msn_ftp_read( gpointer data, gint fd, b_input_condition cond ); -gboolean msn_ftps_write( file_transfer_t *file, char *buffer, unsigned int len ); +static gboolean msn_ftp_connected(gpointer data, gint fd, b_input_condition cond); +static gboolean msn_ftp_read(gpointer data, gint fd, b_input_condition cond); +gboolean msn_ftps_write(file_transfer_t *file, char *buffer, unsigned int len); /* * Vararg wrapper for imcb_file_canceled(). */ -gboolean msn_ftp_abort( file_transfer_t *file, char *format, ... ) +gboolean msn_ftp_abort(file_transfer_t *file, char *format, ...) { - va_list params; - va_start( params, format ); - char error[128]; - - if( vsnprintf( error, 128, format, params ) < 0 ) - sprintf( error, "internal error parsing error string (BUG)" ); - va_end( params ); - imcb_file_canceled( file, error ); + va_list params; + + va_start(params, format); + char error[128]; + + if (vsnprintf(error, 128, format, params) < 0) { + sprintf(error, "internal error parsing error string (BUG)"); + } + va_end(params); + imcb_file_canceled(file, error); return FALSE; } /* very useful */ #define ASSERTSOCKOP(op, msg) \ - if( (op) == -1 ) \ - return msn_ftp_abort( file , msg ": %s", strerror( errno ) ); + if ((op) == -1) { \ + return msn_ftp_abort(file, msg ": %s", strerror(errno)); } -void msn_ftp_invitation_cmd( struct im_connection *ic, char *who, int cookie, char *icmd, - char *trailer ) +void msn_ftp_invitation_cmd(struct im_connection *ic, char *who, int cookie, char *icmd, + char *trailer) { - struct msn_message *m = g_new0( struct msn_message, 1 ); - - m->text = g_strdup_printf( "%s" - "Invitation-Command: %s\r\n" - "Invitation-Cookie: %u\r\n" - "%s", - MSN_INVITE_HEADERS, - icmd, - cookie, - trailer); - - m->who = g_strdup( who ); - - msn_sb_write_msg( ic, m ); + struct msn_message *m = g_new0(struct msn_message, 1); + + m->text = g_strdup_printf("%s" + "Invitation-Command: %s\r\n" + "Invitation-Cookie: %u\r\n" + "%s", + MSN_INVITE_HEADERS, + icmd, + cookie, + trailer); + + m->who = g_strdup(who); + + msn_sb_write_msg(ic, m); } -void msn_ftp_cancel_invite( struct im_connection *ic, char *who, int cookie, char *code ) +void msn_ftp_cancel_invite(struct im_connection *ic, char *who, int cookie, char *code) { char buf[64]; - g_snprintf( buf, sizeof( buf ), "Cancel-Code: %s\r\n", code ); - msn_ftp_invitation_cmd( ic, who, cookie, "CANCEL", buf ); + g_snprintf(buf, sizeof(buf), "Cancel-Code: %s\r\n", code); + msn_ftp_invitation_cmd(ic, who, cookie, "CANCEL", buf); } -void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *file, char *who ) +void msn_ftp_transfer_request(struct im_connection *ic, file_transfer_t *file, char *who) { - unsigned int cookie = time( NULL ); /* TODO: randomize */ + unsigned int cookie = time(NULL); /* TODO: randomize */ char buf[2048]; - msn_filetransfer_t *msn_file = g_new0( msn_filetransfer_t, 1 ); + msn_filetransfer_t *msn_file = g_new0(msn_filetransfer_t, 1); + file->data = msn_file; file->free = msn_ftp_free; file->canceled = msn_ftp_canceled; file->write = msn_ftps_write; msn_file->md = ic->proto_data; msn_file->invite_cookie = cookie; - msn_file->handle = g_strdup( who ); + msn_file->handle = g_strdup(who); msn_file->dcc = file; - msn_file->md->filetransfers = g_slist_prepend( msn_file->md->filetransfers, msn_file->dcc ); + msn_file->md->filetransfers = g_slist_prepend(msn_file->md->filetransfers, msn_file->dcc); msn_file->fd = -1; msn_file->sbufpos = 3; - g_snprintf( buf, sizeof( buf ), - "Application-Name: File Transfer\r\n" - "Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\r\n" - "Application-File: %s\r\n" - "Application-FileSize: %zd\r\n", - file->file_name, - file->file_size); + g_snprintf(buf, sizeof(buf), + "Application-Name: File Transfer\r\n" + "Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\r\n" + "Application-File: %s\r\n" + "Application-FileSize: %zd\r\n", + file->file_name, + file->file_size); - msn_ftp_invitation_cmd( msn_file->md->ic, msn_file->handle, cookie, "INVITE", buf ); + msn_ftp_invitation_cmd(msn_file->md->ic, msn_file->handle, cookie, "INVITE", buf); - imcb_file_recv_start( file ); + imcb_file_recv_start(file); } -void msn_invitation_invite( struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen ) +void msn_invitation_invite(struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen) { - char *itype = msn_findheader( body, "Application-GUID:", blen ); + char *itype = msn_findheader(body, "Application-GUID:", blen); char *name, *size, *invitecookie, *reject = NULL; user_t *u; size_t isize; file_transfer_t *file; - - if( !itype || strcmp( itype, "{5D3E02AB-6190-11d3-BBBB-00C04F795683}" ) != 0 ) { + + if (!itype || strcmp(itype, "{5D3E02AB-6190-11d3-BBBB-00C04F795683}") != 0) { /* Don't know what that is - don't care */ - char *iname = msn_findheader( body, "Application-Name:", blen ); - imcb_log( sb->ic, "Received unknown MSN invitation %s (%s) from %s", - itype ? : "with no GUID", iname ? iname : "no application name", handle ); - g_free( iname ); + char *iname = msn_findheader(body, "Application-Name:", blen); + imcb_log(sb->ic, "Received unknown MSN invitation %s (%s) from %s", + itype ? : "with no GUID", iname ? iname : "no application name", handle); + g_free(iname); reject = "REJECT_NOT_INSTALLED"; - } else if ( - !( name = msn_findheader( body, "Application-File:", blen )) || - !( size = msn_findheader( body, "Application-FileSize:", blen )) || - !( invitecookie = msn_findheader( body, "Invitation-Cookie:", blen)) || - !( isize = atoll( size ) ) ) { - imcb_log( sb->ic, "Received corrupted transfer request from %s" - "(name=%s, size=%s, invitecookie=%s)", - handle, name, size, invitecookie ); + } else if ( + !(name = msn_findheader(body, "Application-File:", blen)) || + !(size = msn_findheader(body, "Application-FileSize:", blen)) || + !(invitecookie = msn_findheader(body, "Invitation-Cookie:", blen)) || + !(isize = atoll(size))) { + imcb_log(sb->ic, "Received corrupted transfer request from %s" + "(name=%s, size=%s, invitecookie=%s)", + handle, name, size, invitecookie); reject = "REJECT"; - } else if ( !( u = user_findhandle( sb->ic, handle ) ) ) { - imcb_log( sb->ic, "Error in parsing transfer request, User '%s'" - "is not in contact list", handle ); + } else if (!(u = user_findhandle(sb->ic, handle))) { + imcb_log(sb->ic, "Error in parsing transfer request, User '%s'" + "is not in contact list", handle); reject = "REJECT"; - } else if ( !( file = imcb_file_send_start( sb->ic, handle, name, isize ) ) ) { - imcb_log( sb->ic, "Error initiating transfer for request from %s for %s", - handle, name ); + } else if (!(file = imcb_file_send_start(sb->ic, handle, name, isize))) { + imcb_log(sb->ic, "Error initiating transfer for request from %s for %s", + handle, name); reject = "REJECT"; } else { - msn_filetransfer_t *msn_file = g_new0( msn_filetransfer_t, 1 ); + msn_filetransfer_t *msn_file = g_new0(msn_filetransfer_t, 1); file->data = msn_file; file->accept = msn_ftpr_accept; file->free = msn_ftp_free; @@ -165,230 +168,251 @@ void msn_invitation_invite( struct msn_switchboard *sb, char *handle, unsigned i file->write_request = msn_ftpr_write_request; msn_file->md = sb->ic->proto_data; msn_file->invite_cookie = cookie; - msn_file->handle = g_strdup( handle ); + msn_file->handle = g_strdup(handle); msn_file->dcc = file; - msn_file->md->filetransfers = g_slist_prepend( msn_file->md->filetransfers, msn_file->dcc ); + msn_file->md->filetransfers = g_slist_prepend(msn_file->md->filetransfers, msn_file->dcc); msn_file->fd = -1; } - if( reject ) - msn_ftp_cancel_invite( sb->ic, sb->who, cookie, reject ); + if (reject) { + msn_ftp_cancel_invite(sb->ic, sb->who, cookie, reject); + } - g_free( name ); - g_free( size ); - g_free( invitecookie ); - g_free( itype ); + g_free(name); + g_free(size); + g_free(invitecookie); + g_free(itype); } -msn_filetransfer_t* msn_find_filetransfer( struct msn_data *md, unsigned int cookie, char *handle ) +msn_filetransfer_t* msn_find_filetransfer(struct msn_data *md, unsigned int cookie, char *handle) { GSList *l; - - for( l = md->filetransfers; l; l = l->next ) { - msn_filetransfer_t *file = ( (file_transfer_t*) l->data )->data; - if( file->invite_cookie == cookie && strcmp( handle, file->handle ) == 0 ) { + + for (l = md->filetransfers; l; l = l->next) { + msn_filetransfer_t *file = ((file_transfer_t *) l->data)->data; + if (file->invite_cookie == cookie && strcmp(handle, file->handle) == 0) { return file; } } return NULL; } -gboolean msn_ftps_connected( gpointer data, gint fd, b_input_condition cond ) +gboolean msn_ftps_connected(gpointer data, gint fd, b_input_condition cond) { file_transfer_t *file = data; msn_filetransfer_t *msn_file = file->data; struct sockaddr_storage clt_addr; - socklen_t ssize = sizeof( clt_addr ); - - debug( "Connected to MSNFTP client" ); - - ASSERTSOCKOP( msn_file->fd = accept( fd, (struct sockaddr *) &clt_addr, &ssize ), "Accepting connection" ); + socklen_t ssize = sizeof(clt_addr); - closesocket( fd ); + debug("Connected to MSNFTP client"); + + ASSERTSOCKOP(msn_file->fd = accept(fd, (struct sockaddr *) &clt_addr, &ssize), "Accepting connection"); + + closesocket(fd); fd = msn_file->fd; - sock_make_nonblocking( fd ); + sock_make_nonblocking(fd); - msn_file->r_event_id = b_input_add( fd, B_EV_IO_READ, msn_ftp_read, file ); + msn_file->r_event_id = b_input_add(fd, B_EV_IO_READ, msn_ftp_read, file); return FALSE; } -void msn_invitations_accept( msn_filetransfer_t *msn_file, struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen ) +void msn_invitations_accept(msn_filetransfer_t *msn_file, struct msn_switchboard *sb, char *handle, unsigned int cookie, + char *body, int blen) { file_transfer_t *file = msn_file->dcc; char buf[1024]; - unsigned int acookie = time ( NULL ); - char host[HOST_NAME_MAX+1]; + unsigned int acookie = time(NULL); + char host[HOST_NAME_MAX + 1]; char port[6]; char *errmsg; msn_file->auth_cookie = acookie; - if( ( msn_file->fd = ft_listen( NULL, host, port, FALSE, &errmsg ) ) == -1 ) { - msn_ftp_abort( file, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", errmsg ); + if ((msn_file->fd = ft_listen(NULL, host, port, FALSE, &errmsg)) == -1) { + msn_ftp_abort(file, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", + errmsg); return; } - msn_file->r_event_id = b_input_add( msn_file->fd, B_EV_IO_READ, msn_ftps_connected, file ); + msn_file->r_event_id = b_input_add(msn_file->fd, B_EV_IO_READ, msn_ftps_connected, file); - g_snprintf( buf, sizeof( buf ), - "IP-Address: %s\r\n" - "Port: %s\r\n" - "AuthCookie: %d\r\n" - "Launch-Application: FALSE\r\n" - "Request-Data: IP-Address:\r\n\r\n", - host, - port, - msn_file->auth_cookie ); + g_snprintf(buf, sizeof(buf), + "IP-Address: %s\r\n" + "Port: %s\r\n" + "AuthCookie: %d\r\n" + "Launch-Application: FALSE\r\n" + "Request-Data: IP-Address:\r\n\r\n", + host, + port, + msn_file->auth_cookie); - msn_ftp_invitation_cmd( msn_file->md->ic, handle, msn_file->invite_cookie, "ACCEPT", buf ); + msn_ftp_invitation_cmd(msn_file->md->ic, handle, msn_file->invite_cookie, "ACCEPT", buf); } -void msn_invitationr_accept( msn_filetransfer_t *msn_file, struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen ) { +void msn_invitationr_accept(msn_filetransfer_t *msn_file, struct msn_switchboard *sb, char *handle, unsigned int cookie, + char *body, int blen) +{ file_transfer_t *file = msn_file->dcc; char *authcookie, *ip, *port; - if( !( authcookie = msn_findheader( body, "AuthCookie:", blen ) ) || - !( ip = msn_findheader( body, "IP-Address:", blen ) ) || - !( port = msn_findheader( body, "Port:", blen ) ) ) { - msn_ftp_abort( file, "Received invalid accept reply" ); - } else if( - ( msn_file->fd = proxy_connect( ip, atoi( port ), msn_ftp_connected, file ) ) - < 0 ) { - msn_ftp_abort( file, "Error connecting to MSN client" ); - } else - msn_file->auth_cookie = strtoul( authcookie, NULL, 10 ); - - g_free( authcookie ); - g_free( ip ); - g_free( port ); + if (!(authcookie = msn_findheader(body, "AuthCookie:", blen)) || + !(ip = msn_findheader(body, "IP-Address:", blen)) || + !(port = msn_findheader(body, "Port:", blen))) { + msn_ftp_abort(file, "Received invalid accept reply"); + } else if ( + (msn_file->fd = proxy_connect(ip, atoi(port), msn_ftp_connected, file)) + < 0) { + msn_ftp_abort(file, "Error connecting to MSN client"); + } else { + msn_file->auth_cookie = strtoul(authcookie, NULL, 10); + } + + g_free(authcookie); + g_free(ip); + g_free(port); } -void msn_invitation_accept( struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen ) +void msn_invitation_accept(struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen) { - msn_filetransfer_t *msn_file = msn_find_filetransfer( sb->ic->proto_data, cookie, handle ); + msn_filetransfer_t *msn_file = msn_find_filetransfer(sb->ic->proto_data, cookie, handle); file_transfer_t *file = msn_file ? msn_file->dcc : NULL; - - if( !msn_file ) - imcb_log( sb->ic, "Received invitation ACCEPT message for unknown invitation (already aborted?)" ); - else if( file->sending ) - msn_invitations_accept( msn_file, sb, handle, cookie, body, blen ); - else - msn_invitationr_accept( msn_file, sb, handle, cookie, body, blen ); + + if (!msn_file) { + imcb_log(sb->ic, "Received invitation ACCEPT message for unknown invitation (already aborted?)"); + } else if (file->sending) { + msn_invitations_accept(msn_file, sb, handle, cookie, body, blen); + } else { + msn_invitationr_accept(msn_file, sb, handle, cookie, body, blen); + } } -void msn_invitation_cancel( struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen ) +void msn_invitation_cancel(struct msn_switchboard *sb, char *handle, unsigned int cookie, char *body, int blen) { - msn_filetransfer_t *msn_file = msn_find_filetransfer( sb->ic->proto_data, cookie, handle ); - - if( !msn_file ) - imcb_log( sb->ic, "Received invitation CANCEL message for unknown invitation (already aborted?)" ); - else - msn_ftp_abort( msn_file->dcc, msn_findheader( body, "Cancel-Code:", blen ) ); + msn_filetransfer_t *msn_file = msn_find_filetransfer(sb->ic->proto_data, cookie, handle); + + if (!msn_file) { + imcb_log(sb->ic, "Received invitation CANCEL message for unknown invitation (already aborted?)"); + } else { + msn_ftp_abort(msn_file->dcc, msn_findheader(body, "Cancel-Code:", blen)); + } } -int msn_ftp_write( file_transfer_t *file, char *format, ... ) +int msn_ftp_write(file_transfer_t *file, char *format, ...) { msn_filetransfer_t *msn_file = file->data; va_list params; int st; char *s; - - va_start( params, format ); - s = g_strdup_vprintf( format, params ); - va_end( params ); - - st = write( msn_file->fd, s, strlen( s ) ); - if( st != strlen( s ) ) - return msn_ftp_abort( file, "Error sending data over MSNFTP connection: %s", - strerror( errno ) ); - - g_free( s ); + + va_start(params, format); + s = g_strdup_vprintf(format, params); + va_end(params); + + st = write(msn_file->fd, s, strlen(s)); + if (st != strlen(s)) { + return msn_ftp_abort(file, "Error sending data over MSNFTP connection: %s", + strerror(errno)); + } + + g_free(s); return 1; } -gboolean msn_ftp_connected( gpointer data, gint fd, b_input_condition cond ) +gboolean msn_ftp_connected(gpointer data, gint fd, b_input_condition cond) { file_transfer_t *file = data; msn_filetransfer_t *msn_file = file->data; - - debug( "Connected to MSNFTP server, starting authentication" ); - if( !msn_ftp_write( file, "VER MSNFTP\r\n" ) ) + + debug("Connected to MSNFTP server, starting authentication"); + if (!msn_ftp_write(file, "VER MSNFTP\r\n")) { return FALSE; - - sock_make_nonblocking( msn_file->fd ); - msn_file->r_event_id = b_input_add( msn_file->fd, B_EV_IO_READ, msn_ftp_read, file ); - + } + + sock_make_nonblocking(msn_file->fd); + msn_file->r_event_id = b_input_add(msn_file->fd, B_EV_IO_READ, msn_ftp_read, file); + return FALSE; } -gboolean msn_ftp_handle_command( file_transfer_t *file, char* line ) +gboolean msn_ftp_handle_command(file_transfer_t *file, char* line) { msn_filetransfer_t *msn_file = file->data; - char **cmd = msn_linesplit( line ); + char **cmd = msn_linesplit(line); int count = 0; - if( cmd[0] ) while( cmd[++count] ); - - if( count < 1 ) - return msn_ftp_abort( file, "Missing command in MSNFTP communication" ); - - if( strcmp( cmd[0], "VER" ) == 0 ) { - if( strcmp( cmd[1], "MSNFTP" ) != 0 ) - return msn_ftp_abort( file, "Unsupported filetransfer protocol: %s", cmd[1] ); - if( file->sending ) - msn_ftp_write( file, "VER MSNFTP\r\n" ); - else - msn_ftp_write( file, "USR %s %u\r\n", msn_file->md->ic->acc->user, msn_file->auth_cookie ); - } else if( strcmp( cmd[0], "FIL" ) == 0 ) { - if( strtoul( cmd[1], NULL, 10 ) != file->file_size ) - return msn_ftp_abort( file, "FIL reply contains a different file size than the size in the invitation" ); - msn_ftp_write( file, "TFR\r\n" ); + + if (cmd[0]) { + while (cmd[++count]) { + ; + } + } + + if (count < 1) { + return msn_ftp_abort(file, "Missing command in MSNFTP communication"); + } + + if (strcmp(cmd[0], "VER") == 0) { + if (strcmp(cmd[1], "MSNFTP") != 0) { + return msn_ftp_abort(file, "Unsupported filetransfer protocol: %s", cmd[1]); + } + if (file->sending) { + msn_ftp_write(file, "VER MSNFTP\r\n"); + } else { + msn_ftp_write(file, "USR %s %u\r\n", msn_file->md->ic->acc->user, msn_file->auth_cookie); + } + } else if (strcmp(cmd[0], "FIL") == 0) { + if (strtoul(cmd[1], NULL, 10) != file->file_size) { + return msn_ftp_abort(file, + "FIL reply contains a different file size than the size in the invitation"); + } + msn_ftp_write(file, "TFR\r\n"); msn_file->status |= MSN_TRANSFER_RECEIVING; - } else if( strcmp( cmd[0], "USR" ) == 0 ) { - if( ( strcmp( cmd[1], msn_file->handle ) != 0 ) || - ( strtoul( cmd[2], NULL, 10 ) != msn_file->auth_cookie ) ) - msn_ftp_abort( file, "Authentication failed. " - "Expected handle: %s (got %s), cookie: %u (got %s)", - msn_file->handle, cmd[1], - msn_file->auth_cookie, cmd[2] ); - msn_ftp_write( file, "FIL %zu\r\n", file->file_size); - } else if( strcmp( cmd[0], "TFR" ) == 0 ) { - file->write_request( file ); - } else if( strcmp( cmd[0], "BYE" ) == 0 ) { + } else if (strcmp(cmd[0], "USR") == 0) { + if ((strcmp(cmd[1], msn_file->handle) != 0) || + (strtoul(cmd[2], NULL, 10) != msn_file->auth_cookie)) { + msn_ftp_abort(file, "Authentication failed. " + "Expected handle: %s (got %s), cookie: %u (got %s)", + msn_file->handle, cmd[1], + msn_file->auth_cookie, cmd[2]); + } + msn_ftp_write(file, "FIL %zu\r\n", file->file_size); + } else if (strcmp(cmd[0], "TFR") == 0) { + file->write_request(file); + } else if (strcmp(cmd[0], "BYE") == 0) { unsigned int retcode = count > 1 ? atoi(cmd[1]) : 1; - if( ( retcode==16777989 ) || ( retcode==16777987 ) ) - imcb_file_finished( file ); - else if( retcode==2147942405 ) - imcb_file_canceled( file, "Failure: receiver is out of disk space" ); - else if( retcode==2164261682 ) - imcb_file_canceled( file, "Failure: receiver cancelled the transfer" ); - else if( retcode==2164261683 ) - imcb_file_canceled( file, "Failure: sender has cancelled the transfer" ); - else if( retcode==2164261694 ) - imcb_file_canceled( file, "Failure: connection is blocked" ); - else { + if ((retcode == 16777989) || (retcode == 16777987)) { + imcb_file_finished(file); + } else if (retcode == 2147942405) { + imcb_file_canceled(file, "Failure: receiver is out of disk space"); + } else if (retcode == 2164261682) { + imcb_file_canceled(file, "Failure: receiver cancelled the transfer"); + } else if (retcode == 2164261683) { + imcb_file_canceled(file, "Failure: sender has cancelled the transfer"); + } else if (retcode == 2164261694) { + imcb_file_canceled(file, "Failure: connection is blocked"); + } else { char buf[128]; - sprintf( buf, "Failure: unknown BYE code: %d", retcode); - imcb_file_canceled( file, buf ); + sprintf(buf, "Failure: unknown BYE code: %d", retcode); + imcb_file_canceled(file, buf); } - } else if( strcmp( cmd[0], "CCL" ) == 0 ) { - imcb_file_canceled( file, "Failure: receiver cancelled the transfer" ); + } else if (strcmp(cmd[0], "CCL") == 0) { + imcb_file_canceled(file, "Failure: receiver cancelled the transfer"); } else { - msn_ftp_abort( file, "Received invalid command %s from msn client", cmd[0] ); + msn_ftp_abort(file, "Received invalid command %s from msn client", cmd[0]); } return TRUE; } -gboolean msn_ftp_send( gpointer data, gint fd, b_input_condition cond ) +gboolean msn_ftp_send(gpointer data, gint fd, b_input_condition cond) { file_transfer_t *file = data; msn_filetransfer_t *msn_file = file->data; msn_file->w_event_id = 0; - file->write_request( file ); + file->write_request(file); return FALSE; } @@ -398,106 +422,115 @@ gboolean msn_ftp_send( gpointer data, gint fd, b_input_condition cond ) * Add a write watch so we can write more during the next cycle (if possible). * This got a bit complicated because (at least) amsn expects packets of size 2045. */ -gboolean msn_ftps_write( file_transfer_t *file, char *buffer, unsigned int len ) +gboolean msn_ftps_write(file_transfer_t *file, char *buffer, unsigned int len) { msn_filetransfer_t *msn_file = file->data; - int ret, overflow; + int ret, overflow; /* what we can't send now */ overflow = msn_file->sbufpos + len - MSNFTP_PSIZE; /* append what we can do the send buffer */ - memcpy( msn_file->sbuf + msn_file->sbufpos, buffer, MIN( len, MSNFTP_PSIZE - msn_file->sbufpos ) ); - msn_file->sbufpos += MIN( len, MSNFTP_PSIZE - msn_file->sbufpos ); + memcpy(msn_file->sbuf + msn_file->sbufpos, buffer, MIN(len, MSNFTP_PSIZE - msn_file->sbufpos)); + msn_file->sbufpos += MIN(len, MSNFTP_PSIZE - msn_file->sbufpos); /* if we don't have enough for a full packet and there's more wait for it */ - if( ( msn_file->sbufpos < MSNFTP_PSIZE ) && - ( msn_file->data_sent + msn_file->sbufpos - 3 < file->file_size ) ) { - if( !msn_file->w_event_id ) - msn_file->w_event_id = b_input_add( msn_file->fd, B_EV_IO_WRITE, msn_ftp_send, file ); + if ((msn_file->sbufpos < MSNFTP_PSIZE) && + (msn_file->data_sent + msn_file->sbufpos - 3 < file->file_size)) { + if (!msn_file->w_event_id) { + msn_file->w_event_id = b_input_add(msn_file->fd, B_EV_IO_WRITE, msn_ftp_send, file); + } return TRUE; } /* Accumulated enough data, lets send something out */ msn_file->sbuf[0] = 0; - msn_file->sbuf[1] = ( msn_file->sbufpos - 3 ) & 0xff; - msn_file->sbuf[2] = ( ( msn_file->sbufpos - 3 ) >> 8 ) & 0xff; + msn_file->sbuf[1] = (msn_file->sbufpos - 3) & 0xff; + msn_file->sbuf[2] = ((msn_file->sbufpos - 3) >> 8) & 0xff; - ASSERTSOCKOP( ret = send( msn_file->fd, msn_file->sbuf, msn_file->sbufpos, 0 ), "Sending" ); + ASSERTSOCKOP(ret = send(msn_file->fd, msn_file->sbuf, msn_file->sbufpos, 0), "Sending"); - msn_file->data_sent += ret - 3; + msn_file->data_sent += ret - 3; - /* TODO: this should really not be fatal */ - if( ret < msn_file->sbufpos ) - return msn_ftp_abort( file, "send() sent %d instead of %d (send buffer full!)", ret, msn_file->sbufpos ); + /* TODO: this should really not be fatal */ + if (ret < msn_file->sbufpos) { + return msn_ftp_abort(file, "send() sent %d instead of %d (send buffer full!)", ret, msn_file->sbufpos); + } msn_file->sbufpos = 3; - if( overflow > 0 ) { - while( overflow > ( MSNFTP_PSIZE - 3 ) ) { - if( !msn_ftps_write( file, buffer + len - overflow, MSNFTP_PSIZE - 3 ) ) + if (overflow > 0) { + while (overflow > (MSNFTP_PSIZE - 3)) { + if (!msn_ftps_write(file, buffer + len - overflow, MSNFTP_PSIZE - 3)) { return FALSE; + } overflow -= MSNFTP_PSIZE - 3; } - return msn_ftps_write( file, buffer + len - overflow, overflow ); + return msn_ftps_write(file, buffer + len - overflow, overflow); } - if( msn_file->data_sent == file->file_size ) { - if( msn_file->w_event_id ) { - b_event_remove( msn_file->w_event_id ); + if (msn_file->data_sent == file->file_size) { + if (msn_file->w_event_id) { + b_event_remove(msn_file->w_event_id); msn_file->w_event_id = 0; } } else { /* we might already be listening if this is data from an overflow */ - if( !msn_file->w_event_id ) - msn_file->w_event_id = b_input_add( msn_file->fd, B_EV_IO_WRITE, msn_ftp_send, file ); + if (!msn_file->w_event_id) { + msn_file->w_event_id = b_input_add(msn_file->fd, B_EV_IO_WRITE, msn_ftp_send, file); + } } - return TRUE; + return TRUE; } /* Binary part of the file transfer protocol */ -gboolean msn_ftpr_read( file_transfer_t *file ) +gboolean msn_ftpr_read(file_transfer_t *file) { msn_filetransfer_t *msn_file = file->data; int st; unsigned char buf[3]; - if( msn_file->data_remaining ) { + if (msn_file->data_remaining) { msn_file->r_event_id = 0; - ASSERTSOCKOP( st = read( msn_file->fd, file->buffer, MIN( sizeof( file->buffer ), msn_file->data_remaining ) ), "Receiving" ); + ASSERTSOCKOP(st = read(msn_file->fd, file->buffer, MIN(sizeof(file->buffer), + msn_file->data_remaining)), "Receiving"); - if( st == 0 ) - return msn_ftp_abort( file, "Remote end closed connection"); + if (st == 0) { + return msn_ftp_abort(file, "Remote end closed connection"); + } msn_file->data_sent += st; msn_file->data_remaining -= st; - file->write( file, file->buffer, st ); + file->write(file, file->buffer, st); - if( msn_file->data_sent >= file->file_size ) - imcb_file_finished( file ); + if (msn_file->data_sent >= file->file_size) { + imcb_file_finished(file); + } return FALSE; } else { - ASSERTSOCKOP( st = read( msn_file->fd, buf, 1 ), "Receiving" ); - if( st == 0 ) { - return msn_ftp_abort( file, "read returned EOF while reading data header from msn client" ); - } else if( buf[0] == '\r' || buf[0] == '\n' ) { - debug( "Discarding extraneous newline" ); - } else if( buf[0] != 0 ) { - msn_ftp_abort( file, "Remote end canceled the transfer"); + ASSERTSOCKOP(st = read(msn_file->fd, buf, 1), "Receiving"); + if (st == 0) { + return msn_ftp_abort(file, "read returned EOF while reading data header from msn client"); + } else if (buf[0] == '\r' || buf[0] == '\n') { + debug("Discarding extraneous newline"); + } else if (buf[0] != 0) { + msn_ftp_abort(file, "Remote end canceled the transfer"); /* don't really care about these last 2 (should be 0,0) */ - read( msn_file->fd, buf, 2 ); + read(msn_file->fd, buf, 2); return FALSE; } else { unsigned int size; - ASSERTSOCKOP( st = read( msn_file->fd, buf, 2 ), "Receiving" ); - if( st < 2 ) - return msn_ftp_abort( file, "read returned EOF while reading data header from msn client" ); + ASSERTSOCKOP(st = read(msn_file->fd, buf, 2), "Receiving"); + if (st < 2) { + return msn_ftp_abort(file, + "read returned EOF while reading data header from msn client"); + } size = buf[0] + ((unsigned int) buf[1] << 8); msn_file->data_remaining = size; @@ -507,116 +540,126 @@ gboolean msn_ftpr_read( file_transfer_t *file ) } /* Text mode part of the file transfer protocol */ -gboolean msn_ftp_txtproto( file_transfer_t *file ) +gboolean msn_ftp_txtproto(file_transfer_t *file) { msn_filetransfer_t *msn_file = file->data; int i = msn_file->tbufpos, st; char *tbuf = msn_file->tbuf; - ASSERTSOCKOP( st = read( msn_file->fd, - tbuf + msn_file->tbufpos, - sizeof( msn_file->tbuf ) - msn_file->tbufpos ), - "Receiving" ); + ASSERTSOCKOP(st = read(msn_file->fd, + tbuf + msn_file->tbufpos, + sizeof(msn_file->tbuf) - msn_file->tbufpos), + "Receiving"); - if( st == 0 ) - return msn_ftp_abort( file, "read returned EOF while reading text from msn client" ); + if (st == 0) { + return msn_ftp_abort(file, "read returned EOF while reading text from msn client"); + } msn_file->tbufpos += st; do { - for( ;i < msn_file->tbufpos; i++ ) { - if( tbuf[i] == '\n' || tbuf[i] == '\r' ) { + for (; i < msn_file->tbufpos; i++) { + if (tbuf[i] == '\n' || tbuf[i] == '\r') { tbuf[i] = '\0'; - if( i > 0 ) - msn_ftp_handle_command( file, tbuf ); - else - while( tbuf[i] == '\n' || tbuf[i] == '\r' ) i++; - memmove( tbuf, tbuf + i + 1, msn_file->tbufpos - i - 1 ); + if (i > 0) { + msn_ftp_handle_command(file, tbuf); + } else { + while (tbuf[i] == '\n' || tbuf[i] == '\r') { + i++; + } + } + memmove(tbuf, tbuf + i + 1, msn_file->tbufpos - i - 1); msn_file->tbufpos -= i + 1; i = 0; break; } } - } while ( i < msn_file->tbufpos ); + } while (i < msn_file->tbufpos); - if( msn_file->tbufpos == sizeof( msn_file->tbuf ) ) - return msn_ftp_abort( file, - "Line exceeded %d bytes in text protocol", - sizeof( msn_file->tbuf ) ); + if (msn_file->tbufpos == sizeof(msn_file->tbuf)) { + return msn_ftp_abort(file, + "Line exceeded %d bytes in text protocol", + sizeof(msn_file->tbuf)); + } return TRUE; } -gboolean msn_ftp_read( gpointer data, gint fd, b_input_condition cond ) +gboolean msn_ftp_read(gpointer data, gint fd, b_input_condition cond) { file_transfer_t *file = data; msn_filetransfer_t *msn_file = file->data; - - if( msn_file->status & MSN_TRANSFER_RECEIVING ) - return msn_ftpr_read( file ); - else - return msn_ftp_txtproto( file ); + + if (msn_file->status & MSN_TRANSFER_RECEIVING) { + return msn_ftpr_read(file); + } else { + return msn_ftp_txtproto(file); + } } -void msn_ftp_free( file_transfer_t *file ) +void msn_ftp_free(file_transfer_t *file) { msn_filetransfer_t *msn_file = file->data; - - if( msn_file->r_event_id ) - b_event_remove( msn_file->r_event_id ); - if( msn_file->w_event_id ) - b_event_remove( msn_file->w_event_id ); + if (msn_file->r_event_id) { + b_event_remove(msn_file->r_event_id); + } + + if (msn_file->w_event_id) { + b_event_remove(msn_file->w_event_id); + } + + if (msn_file->fd != -1) { + closesocket(msn_file->fd); + } + + msn_file->md->filetransfers = g_slist_remove(msn_file->md->filetransfers, msn_file->dcc); - if( msn_file->fd != -1 ) - closesocket( msn_file->fd ); + g_free(msn_file->handle); - msn_file->md->filetransfers = g_slist_remove( msn_file->md->filetransfers, msn_file->dcc ); - - g_free( msn_file->handle ); - - g_free( msn_file ); + g_free(msn_file); } -void msn_ftpr_accept( file_transfer_t *file ) +void msn_ftpr_accept(file_transfer_t *file) { msn_filetransfer_t *msn_file = file->data; - msn_ftp_invitation_cmd( msn_file->md->ic, msn_file->handle, msn_file->invite_cookie, "ACCEPT", - "Launch-Application: FALSE\r\n" - "Request-Data: IP-Address:\r\n"); + msn_ftp_invitation_cmd(msn_file->md->ic, msn_file->handle, msn_file->invite_cookie, "ACCEPT", + "Launch-Application: FALSE\r\n" + "Request-Data: IP-Address:\r\n"); } -void msn_ftp_finished( file_transfer_t *file ) +void msn_ftp_finished(file_transfer_t *file) { - msn_ftp_write( file, "BYE 16777989\r\n" ); + msn_ftp_write(file, "BYE 16777989\r\n"); } -void msn_ftp_canceled( file_transfer_t *file, char *reason ) +void msn_ftp_canceled(file_transfer_t *file, char *reason) { msn_filetransfer_t *msn_file = file->data; - msn_ftp_cancel_invite( msn_file->md->ic, msn_file->handle, - msn_file->invite_cookie, - file->status & FT_STATUS_TRANSFERRING ? - "FTTIMEOUT" : - "FAIL" ); + msn_ftp_cancel_invite(msn_file->md->ic, msn_file->handle, + msn_file->invite_cookie, + file->status & FT_STATUS_TRANSFERRING ? + "FTTIMEOUT" : + "FAIL"); - imcb_log( msn_file->md->ic, "File transfer aborted: %s", reason ); + imcb_log(msn_file->md->ic, "File transfer aborted: %s", reason); } -gboolean msn_ftpr_write_request( file_transfer_t *file ) +gboolean msn_ftpr_write_request(file_transfer_t *file) { msn_filetransfer_t *msn_file = file->data; - if( msn_file->r_event_id != 0 ) { - msn_ftp_abort( file, - "BUG in MSN file transfer:" - "write_request called when" - "already watching for input" ); + + if (msn_file->r_event_id != 0) { + msn_ftp_abort(file, + "BUG in MSN file transfer:" + "write_request called when" + "already watching for input"); return FALSE; } - msn_file->r_event_id = - b_input_add( msn_file->fd, B_EV_IO_READ, msn_ftp_read, file ); + msn_file->r_event_id = + b_input_add(msn_file->fd, B_EV_IO_READ, msn_ftp_read, file); return TRUE; } |