diff options
author | Indent <please@skip.me> | 2015-02-19 02:47:20 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-02-20 19:50:54 -0300 |
commit | 5ebff60479fc7a9f7f50ac03b124c91d4e6ebe11 (patch) | |
tree | 9fc0d50cb1f4bc9768d9f00de94eafd876bb55b0 /protocols/msn | |
parent | af359b4316f9d392c6b752495a1b2ed631576ed8 (diff) |
Reindent everything to K&R style with tabs
Used uncrustify, with the configuration file in ./doc/uncrustify.cfg
Commit author set to "Indent <please@skip.me>" so that it's easier to
skip while doing git blame.
Diffstat (limited to 'protocols/msn')
-rw-r--r-- | protocols/msn/invitation.c | 677 | ||||
-rw-r--r-- | protocols/msn/invitation.h | 29 | ||||
-rw-r--r-- | protocols/msn/msn.c | 502 | ||||
-rw-r--r-- | protocols/msn/msn.h | 170 | ||||
-rw-r--r-- | protocols/msn/msn_util.c | 582 | ||||
-rw-r--r-- | protocols/msn/ns.c | 1303 | ||||
-rw-r--r-- | protocols/msn/sb.c | 1040 | ||||
-rw-r--r-- | protocols/msn/soap.c | 1034 | ||||
-rw-r--r-- | protocols/msn/soap.h | 492 | ||||
-rw-r--r-- | protocols/msn/tables.c | 71 |
10 files changed, 2892 insertions, 3008 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; } diff --git a/protocols/msn/invitation.h b/protocols/msn/invitation.h index 13bbf0d3..3e3bba0f 100644 --- a/protocols/msn/invitation.h +++ b/protocols/msn/invitation.h @@ -11,12 +11,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., @@ -28,20 +28,19 @@ #include "msn.h" -#define MSN_INVITE_HEADERS "MIME-Version: 1.0\r\n" \ - "Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n" \ - "\r\n" +#define MSN_INVITE_HEADERS "MIME-Version: 1.0\r\n" \ + "Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n" \ + "\r\n" #define MSNFTP_PSIZE 2048 typedef enum { - MSN_TRANSFER_RECEIVING = 1, - MSN_TRANSFER_SENDING = 2 + MSN_TRANSFER_RECEIVING = 1, + MSN_TRANSFER_SENDING = 2 } msn_filetransfer_status_t; -typedef struct msn_filetransfer -{ -/* Generic invitation data */ +typedef struct msn_filetransfer { +/* Generic invitation data */ /* msn_data instance this invitation was received with. */ struct msn_data *md; /* Cookie specifying this invitation. */ @@ -64,19 +63,19 @@ typedef struct msn_filetransfer /* Buffer containing received, but unprocessed text. */ char tbuf[256]; unsigned int tbufpos; - + unsigned int data_sent; gint r_event_id; gint w_event_id; - + unsigned char sbuf[2048]; int sbufpos; } msn_filetransfer_t; -void msn_invitation_invite( 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 ); -void msn_invitation_cancel( 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); +void msn_invitation_accept(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); #endif diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 65c19276..6ab35696 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2013 Wilmer van der Gaast and others * @@ -31,407 +31,409 @@ int msn_chat_id; GSList *msn_connections; GSList *msn_switchboards; -static char *set_eval_display_name( set_t *set, char *value ); +static char *set_eval_display_name(set_t *set, char *value); -static void msn_init( account_t *acc ) +static void msn_init(account_t *acc) { set_t *s; - - s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); + + s = set_add(&acc->set, "display_name", NULL, set_eval_display_name, acc); s->flags |= SET_NOSAVE | ACC_SET_ONLINE_ONLY; - - s = set_add( &acc->set, "server", MSN_NS_HOST, set_eval_account, acc ); + + s = set_add(&acc->set, "server", MSN_NS_HOST, set_eval_account, acc); s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY; - s = set_add( &acc->set, "port", MSN_NS_PORT, set_eval_int, acc ); + s = set_add(&acc->set, "port", MSN_NS_PORT, set_eval_int, acc); s->flags |= ACC_SET_OFFLINE_ONLY; - set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); - set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc ); - + set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc); + set_add(&acc->set, "switchboard_keepalives", "false", set_eval_bool, acc); + acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE | ACC_FLAG_HANDLE_DOMAINS; } -static void msn_login( account_t *acc ) +static void msn_login(account_t *acc) { - struct im_connection *ic = imcb_new( acc ); - struct msn_data *md = g_new0( struct msn_data, 1 ); - + struct im_connection *ic = imcb_new(acc); + struct msn_data *md = g_new0(struct msn_data, 1); + ic->proto_data = md; ic->flags |= OPT_PONGS | OPT_PONGED; - - if( strchr( acc->user, '@' ) == NULL ) - { - imcb_error( ic, "Invalid account name" ); - imc_logout( ic, FALSE ); + + if (strchr(acc->user, '@') == NULL) { + imcb_error(ic, "Invalid account name"); + imc_logout(ic, FALSE); return; } - + md->ic = ic; md->away_state = msn_away_state_list; - md->domaintree = g_tree_new( msn_domaintree_cmp ); + md->domaintree = g_tree_new(msn_domaintree_cmp); md->ns->fd = -1; - - msn_connections = g_slist_prepend( msn_connections, ic ); - - imcb_log( ic, "Connecting" ); - msn_ns_connect( ic, md->ns, - set_getstr( &ic->acc->set, "server" ), - set_getint( &ic->acc->set, "port" ) ); + + msn_connections = g_slist_prepend(msn_connections, ic); + + imcb_log(ic, "Connecting"); + msn_ns_connect(ic, md->ns, + set_getstr(&ic->acc->set, "server"), + set_getint(&ic->acc->set, "port")); } -static void msn_logout( struct im_connection *ic ) +static void msn_logout(struct im_connection *ic) { struct msn_data *md = ic->proto_data; GSList *l; int i; - - if( md ) - { + + if (md) { /** Disabling MSN ft support for now. while( md->filetransfers ) { - imcb_file_canceled( md->filetransfers->data, "Closing connection" ); + imcb_file_canceled( md->filetransfers->data, "Closing connection" ); } */ - - msn_ns_close( md->ns ); - - while( md->switchboards ) - msn_sb_destroy( md->switchboards->data ); - - msn_msgq_purge( ic, &md->msgq ); - msn_soapq_flush( ic, FALSE ); - - for( i = 0; i < sizeof( md->tokens ) / sizeof( md->tokens[0] ); i ++ ) - g_free( md->tokens[i] ); - g_free( md->lock_key ); - g_free( md->pp_policy ); - g_free( md->uuid ); - - while( md->groups ) - { + + msn_ns_close(md->ns); + + while (md->switchboards) { + msn_sb_destroy(md->switchboards->data); + } + + msn_msgq_purge(ic, &md->msgq); + msn_soapq_flush(ic, FALSE); + + for (i = 0; i < sizeof(md->tokens) / sizeof(md->tokens[0]); i++) { + g_free(md->tokens[i]); + } + g_free(md->lock_key); + g_free(md->pp_policy); + g_free(md->uuid); + + while (md->groups) { struct msn_group *mg = md->groups->data; - g_free( mg->id ); - g_free( mg->name ); - g_free( mg ); - md->groups = g_slist_remove( md->groups, mg ); + g_free(mg->id); + g_free(mg->name); + g_free(mg); + md->groups = g_slist_remove(md->groups, mg); + } + + g_free(md->profile_rid); + + if (md->domaintree) { + g_tree_destroy(md->domaintree); } - - g_free( md->profile_rid ); - - if( md->domaintree ) - g_tree_destroy( md->domaintree ); md->domaintree = NULL; - - while( md->grpq ) - { + + while (md->grpq) { struct msn_groupadd *ga = md->grpq->data; - g_free( ga->group ); - g_free( ga->who ); - g_free( ga ); - md->grpq = g_slist_remove( md->grpq, ga ); + g_free(ga->group); + g_free(ga->who); + g_free(ga); + md->grpq = g_slist_remove(md->grpq, ga); } - - g_free( md ); + + g_free(md); + } + + for (l = ic->permit; l; l = l->next) { + g_free(l->data); + } + g_slist_free(ic->permit); + + for (l = ic->deny; l; l = l->next) { + g_free(l->data); } - - for( l = ic->permit; l; l = l->next ) - g_free( l->data ); - g_slist_free( ic->permit ); - - for( l = ic->deny; l; l = l->next ) - g_free( l->data ); - g_slist_free( ic->deny ); - - msn_connections = g_slist_remove( msn_connections, ic ); + g_slist_free(ic->deny); + + msn_connections = g_slist_remove(msn_connections, ic); } -static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away ) +static int msn_buddy_msg(struct im_connection *ic, char *who, char *message, int away) { - struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who ); + struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who); struct msn_buddy_data *bd = bu ? bu->data : NULL; struct msn_switchboard *sb; - + #ifdef DEBUG - if( strcmp( who, "raw" ) == 0 ) - { - msn_ns_write( ic, -1, "%s\r\n", message ); - } - else + if (strcmp(who, "raw") == 0) { + msn_ns_write(ic, -1, "%s\r\n", message); + } else #endif - if( bd && bd->flags & MSN_BUDDY_FED ) - { - msn_ns_sendmessage( ic, bu, message ); - } - else if( ( sb = msn_sb_by_handle( ic, who ) ) ) - { - return( msn_sb_sendmessage( sb, message ) ); - } - else - { + if (bd && bd->flags & MSN_BUDDY_FED) { + msn_ns_sendmessage(ic, bu, message); + } else if ((sb = msn_sb_by_handle(ic, who))) { + return(msn_sb_sendmessage(sb, message)); + } else { struct msn_message *m; - + /* Create a message. We have to arrange a usable switchboard, and send the message later. */ - m = g_new0( struct msn_message, 1 ); - m->who = g_strdup( who ); - m->text = g_strdup( message ); - - return msn_sb_write_msg( ic, m ); + m = g_new0(struct msn_message, 1); + m->who = g_strdup(who); + m->text = g_strdup(message); + + return msn_sb_write_msg(ic, m); } - - return( 0 ); + + return(0); } -static GList *msn_away_states( struct im_connection *ic ) +static GList *msn_away_states(struct im_connection *ic) { static GList *l = NULL; int i; - - if( l == NULL ) - for( i = 0; *msn_away_state_list[i].code; i ++ ) - if( *msn_away_state_list[i].name ) - l = g_list_append( l, (void*) msn_away_state_list[i].name ); - + + if (l == NULL) { + for (i = 0; *msn_away_state_list[i].code; i++) { + if (*msn_away_state_list[i].name) { + l = g_list_append(l, (void *) msn_away_state_list[i].name); + } + } + } + return l; } -static void msn_set_away( struct im_connection *ic, char *state, char *message ) +static void msn_set_away(struct im_connection *ic, char *state, char *message) { char *uux; struct msn_data *md = ic->proto_data; - - if( state == NULL ) + + if (state == NULL) { md->away_state = msn_away_state_list; - else if( ( md->away_state = msn_away_state_by_name( state ) ) == NULL ) + } else if ((md->away_state = msn_away_state_by_name(state)) == NULL) { md->away_state = msn_away_state_list + 1; - - if( !msn_ns_write( ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2 ) ) + } + + if (!msn_ns_write(ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2)) { return; - - uux = g_markup_printf_escaped( "<EndpointData><Capabilities>%d:%02d" - "</Capabilities></EndpointData>", - MSN_CAP1, MSN_CAP2 ); - msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux ); - g_free( uux ); - - uux = g_markup_printf_escaped( "<PrivateEndpointData><EpName>%s</EpName>" - "<Idle>%s</Idle><ClientType>%d</ClientType>" - "<State>%s</State></PrivateEndpointData>", - md->uuid, - strcmp( md->away_state->code, "IDL" ) ? "false" : "true", - 1, /* ? */ - md->away_state->code ); - msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux ); - g_free( uux ); - - uux = g_markup_printf_escaped( "<Data><DDP></DDP><PSM>%s</PSM>" - "<CurrentMedia></CurrentMedia>" - "<MachineGuid>%s</MachineGuid></Data>", - message ? message : "", md->uuid ); - msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux ); - g_free( uux ); + } + + uux = g_markup_printf_escaped("<EndpointData><Capabilities>%d:%02d" + "</Capabilities></EndpointData>", + MSN_CAP1, MSN_CAP2); + msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux); + g_free(uux); + + uux = g_markup_printf_escaped("<PrivateEndpointData><EpName>%s</EpName>" + "<Idle>%s</Idle><ClientType>%d</ClientType>" + "<State>%s</State></PrivateEndpointData>", + md->uuid, + strcmp(md->away_state->code, "IDL") ? "false" : "true", + 1, /* ? */ + md->away_state->code); + msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux); + g_free(uux); + + uux = g_markup_printf_escaped("<Data><DDP></DDP><PSM>%s</PSM>" + "<CurrentMedia></CurrentMedia>" + "<MachineGuid>%s</MachineGuid></Data>", + message ? message : "", md->uuid); + msn_ns_write(ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen(uux), uux); + g_free(uux); } -static void msn_get_info(struct im_connection *ic, char *who) +static void msn_get_info(struct im_connection *ic, char *who) { /* Just make an URL and let the user fetch the info */ - imcb_log( ic, "%s\n%s: %s%s", _("User Info"), _("For now, fetch yourself"), PROFILE_URL, who ); + imcb_log(ic, "%s\n%s: %s%s", _("User Info"), _("For now, fetch yourself"), PROFILE_URL, who); } -static void msn_add_buddy( struct im_connection *ic, char *who, char *group ) +static void msn_add_buddy(struct im_connection *ic, char *who, char *group) { - struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who ); - - msn_buddy_list_add( ic, MSN_BUDDY_FL, who, who, group ); - if( bu && bu->group ) - msn_buddy_list_remove( ic, MSN_BUDDY_FL, who, bu->group->name ); + struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who); + + msn_buddy_list_add(ic, MSN_BUDDY_FL, who, who, group); + if (bu && bu->group) { + msn_buddy_list_remove(ic, MSN_BUDDY_FL, who, bu->group->name); + } } -static void msn_remove_buddy( struct im_connection *ic, char *who, char *group ) +static void msn_remove_buddy(struct im_connection *ic, char *who, char *group) { - msn_buddy_list_remove( ic, MSN_BUDDY_FL, who, NULL ); + msn_buddy_list_remove(ic, MSN_BUDDY_FL, who, NULL); } -static void msn_chat_msg( struct groupchat *c, char *message, int flags ) +static void msn_chat_msg(struct groupchat *c, char *message, int flags) { - struct msn_switchboard *sb = msn_sb_by_chat( c ); - - if( sb ) - msn_sb_sendmessage( sb, message ); + struct msn_switchboard *sb = msn_sb_by_chat(c); + + if (sb) { + msn_sb_sendmessage(sb, message); + } /* FIXME: Error handling (although this can't happen unless something's already severely broken) disappeared here! */ } -static void msn_chat_invite( struct groupchat *c, char *who, char *message ) +static void msn_chat_invite(struct groupchat *c, char *who, char *message) { - struct msn_switchboard *sb = msn_sb_by_chat( c ); - - if( sb ) - msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, who ); + struct msn_switchboard *sb = msn_sb_by_chat(c); + + if (sb) { + msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, who); + } } -static void msn_chat_leave( struct groupchat *c ) +static void msn_chat_leave(struct groupchat *c) { - struct msn_switchboard *sb = msn_sb_by_chat( c ); - - if( sb ) - msn_sb_write( sb, "OUT\r\n" ); + struct msn_switchboard *sb = msn_sb_by_chat(c); + + if (sb) { + msn_sb_write(sb, "OUT\r\n"); + } } -static struct groupchat *msn_chat_with( struct im_connection *ic, char *who ) +static struct groupchat *msn_chat_with(struct im_connection *ic, char *who) { struct msn_switchboard *sb; - struct groupchat *c = imcb_chat_new( ic, who ); - - if( ( sb = msn_sb_by_handle( ic, who ) ) ) - { - debug( "Converting existing switchboard to %s to a groupchat", who ); - return msn_sb_to_chat( sb ); - } - else - { + struct groupchat *c = imcb_chat_new(ic, who); + + if ((sb = msn_sb_by_handle(ic, who))) { + debug("Converting existing switchboard to %s to a groupchat", who); + return msn_sb_to_chat(sb); + } else { struct msn_message *m; - + /* Create a magic message. This is quite hackish, but who cares? :-P */ - m = g_new0( struct msn_message, 1 ); - m->who = g_strdup( who ); - m->text = g_strdup( GROUPCHAT_SWITCHBOARD_MESSAGE ); - - msn_sb_write_msg( ic, m ); + m = g_new0(struct msn_message, 1); + m->who = g_strdup(who); + m->text = g_strdup(GROUPCHAT_SWITCHBOARD_MESSAGE); + + msn_sb_write_msg(ic, m); return c; } } -static void msn_keepalive( struct im_connection *ic ) +static void msn_keepalive(struct im_connection *ic) { - msn_ns_write( ic, -1, "PNG\r\n" ); + msn_ns_write(ic, -1, "PNG\r\n"); } -static void msn_add_permit( struct im_connection *ic, char *who ) +static void msn_add_permit(struct im_connection *ic, char *who) { - msn_buddy_list_add( ic, MSN_BUDDY_AL, who, who, NULL ); + msn_buddy_list_add(ic, MSN_BUDDY_AL, who, who, NULL); } -static void msn_rem_permit( struct im_connection *ic, char *who ) +static void msn_rem_permit(struct im_connection *ic, char *who) { - msn_buddy_list_remove( ic, MSN_BUDDY_AL, who, NULL ); + msn_buddy_list_remove(ic, MSN_BUDDY_AL, who, NULL); } -static void msn_add_deny( struct im_connection *ic, char *who ) +static void msn_add_deny(struct im_connection *ic, char *who) { struct msn_switchboard *sb; - - msn_buddy_list_add( ic, MSN_BUDDY_BL, who, who, NULL ); - + + msn_buddy_list_add(ic, MSN_BUDDY_BL, who, who, NULL); + /* If there's still a conversation with this person, close it. */ - if( ( sb = msn_sb_by_handle( ic, who ) ) ) - { - msn_sb_destroy( sb ); + if ((sb = msn_sb_by_handle(ic, who))) { + msn_sb_destroy(sb); } } -static void msn_rem_deny( struct im_connection *ic, char *who ) +static void msn_rem_deny(struct im_connection *ic, char *who) { - msn_buddy_list_remove( ic, MSN_BUDDY_BL, who, NULL ); + msn_buddy_list_remove(ic, MSN_BUDDY_BL, who, NULL); } -static int msn_send_typing( struct im_connection *ic, char *who, int typing ) +static int msn_send_typing(struct im_connection *ic, char *who, int typing) { - struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who ); - - if( !( bu->flags & BEE_USER_ONLINE ) ) + struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who); + + if (!(bu->flags & BEE_USER_ONLINE)) { return 0; - else if( typing & OPT_TYPING ) - return( msn_buddy_msg( ic, who, TYPING_NOTIFICATION_MESSAGE, 0 ) ); - else + } else if (typing & OPT_TYPING) { + return(msn_buddy_msg(ic, who, TYPING_NOTIFICATION_MESSAGE, 0)); + } else { return 1; + } } -static char *set_eval_display_name( set_t *set, char *value ) +static char *set_eval_display_name(set_t *set, char *value) { account_t *acc = set->data; struct im_connection *ic = acc->ic; struct msn_data *md = ic->proto_data; - - if( md->flags & MSN_EMAIL_UNVERIFIED ) - imcb_log( ic, "Warning: Your e-mail address is unverified. MSN doesn't allow " - "changing your display name until your e-mail address is verified." ); - - if( md->flags & MSN_GOT_PROFILE_DN ) - msn_soap_profile_set_dn( ic, value ); - else - msn_soap_addressbook_set_display_name( ic, value ); - - return msn_ns_set_display_name( ic, value ) ? value : NULL; + + if (md->flags & MSN_EMAIL_UNVERIFIED) { + imcb_log(ic, "Warning: Your e-mail address is unverified. MSN doesn't allow " + "changing your display name until your e-mail address is verified."); + } + + if (md->flags & MSN_GOT_PROFILE_DN) { + msn_soap_profile_set_dn(ic, value); + } else { + msn_soap_addressbook_set_display_name(ic, value); + } + + return msn_ns_set_display_name(ic, value) ? value : NULL; } -static void msn_buddy_data_add( bee_user_t *bu ) +static void msn_buddy_data_add(bee_user_t *bu) { struct msn_data *md = bu->ic->proto_data; struct msn_buddy_data *bd; char *handle; - - bd = bu->data = g_new0( struct msn_buddy_data, 1 ); - g_tree_insert( md->domaintree, bu->handle, bu ); - - for( handle = bu->handle; g_ascii_isdigit( *handle ); handle ++ ); - if( *handle == ':' ) - { + + bd = bu->data = g_new0(struct msn_buddy_data, 1); + g_tree_insert(md->domaintree, bu->handle, bu); + + for (handle = bu->handle; g_ascii_isdigit(*handle); handle++) { + ; + } + if (*handle == ':') { /* Pass a nick hint so hopefully the stupid numeric prefix won't show up to the user. */ - char *s = strchr( ++handle, '@' ); - if( s ) - { - handle = g_strndup( handle, s - handle ); - imcb_buddy_nick_hint( bu->ic, bu->handle, handle ); - g_free( handle ); + char *s = strchr(++handle, '@'); + if (s) { + handle = g_strndup(handle, s - handle); + imcb_buddy_nick_hint(bu->ic, bu->handle, handle); + g_free(handle); } - + bd->flags |= MSN_BUDDY_FED; } } -static void msn_buddy_data_free( bee_user_t *bu ) +static void msn_buddy_data_free(bee_user_t *bu) { struct msn_data *md = bu->ic->proto_data; struct msn_buddy_data *bd = bu->data; - - g_free( bd->cid ); - g_free( bd ); - - g_tree_remove( md->domaintree, bu->handle ); + + g_free(bd->cid); + g_free(bd); + + g_tree_remove(md->domaintree, bu->handle); } -GList *msn_buddy_action_list( bee_user_t *bu ) +GList *msn_buddy_action_list(bee_user_t *bu) { static GList *ret = NULL; - - if( ret == NULL ) - { + + if (ret == NULL) { static const struct buddy_action ba[2] = { { "NUDGE", "Draw attention" }, }; - - ret = g_list_prepend( ret, (void*) ba + 0 ); + + ret = g_list_prepend(ret, (void *) ba + 0); } - + return ret; } -void *msn_buddy_action( struct bee_user *bu, const char *action, char * const args[], void *data ) +void *msn_buddy_action(struct bee_user *bu, const char *action, char * const args[], void *data) { - if( g_strcasecmp( action, "NUDGE" ) == 0 ) - msn_buddy_msg( bu->ic, bu->handle, NUDGE_MESSAGE, 0 ); - + if (g_strcasecmp(action, "NUDGE") == 0) { + msn_buddy_msg(bu->ic, bu->handle, NUDGE_MESSAGE, 0); + } + return NULL; } void msn_initmodule() { struct prpl *ret = g_new0(struct prpl, 1); - + ret->name = "msn"; ret->mms = 1409; /* this guess taken from libotr UPGRADING file */ ret->login = msn_login; @@ -458,7 +460,7 @@ void msn_initmodule() ret->buddy_data_free = msn_buddy_data_free; ret->buddy_action_list = msn_buddy_action_list; ret->buddy_action = msn_buddy_action; - + //ret->transfer_request = msn_ftp_transfer_request; register_protocol(ret); diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 438b2174..6022bc31 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -34,9 +34,9 @@ #define SB_KEEPALIVE_MESSAGE "\r\r\rDONT HANG UP ON ME!\r\r\r" #ifdef DEBUG_MSN -#define debug( text... ) imcb_log( ic, text ); +#define debug(text ...) imcb_log(ic, text); #else -#define debug( text... ) +#define debug(text ...) #endif /* This should be MSN Messenger 7.0.0813 @@ -68,30 +68,29 @@ #define MSN_CAP2 0x0000 #define MSN_MESSAGE_HEADERS "MIME-Version: 1.0\r\n" \ - "Content-Type: text/plain; charset=UTF-8\r\n" \ - "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ - "X-MMS-IM-Format: FN=MS%20Shell%20Dlg; EF=; CO=0; CS=0; PF=0\r\n" \ - "\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n" \ + "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ + "X-MMS-IM-Format: FN=MS%20Shell%20Dlg; EF=; CO=0; CS=0; PF=0\r\n" \ + "\r\n" #define MSN_TYPING_HEADERS "MIME-Version: 1.0\r\n" \ - "Content-Type: text/x-msmsgscontrol\r\n" \ - "TypingUser: %s\r\n" \ - "\r\n\r\n" + "Content-Type: text/x-msmsgscontrol\r\n" \ + "TypingUser: %s\r\n" \ + "\r\n\r\n" #define MSN_NUDGE_HEADERS "MIME-Version: 1.0\r\n" \ - "Content-Type: text/x-msnmsgr-datacast\r\n" \ - "\r\n" \ - "ID: 1\r\n" \ - "\r\n" + "Content-Type: text/x-msnmsgr-datacast\r\n" \ + "\r\n" \ + "ID: 1\r\n" \ + "\r\n" #define MSN_SB_KEEPALIVE_HEADERS "MIME-Version: 1.0\r\n" \ - "Content-Type: text/x-ping\r\n" \ - "\r\n\r\n" + "Content-Type: text/x-ping\r\n" \ + "\r\n\r\n" #define PROFILE_URL "http://members.msn.com/" -typedef enum -{ +typedef enum { MSN_GOT_PROFILE = 1, MSN_GOT_PROFILE_DN = 2, MSN_DONE_ADL = 4, @@ -99,43 +98,41 @@ typedef enum MSN_EMAIL_UNVERIFIED = 16, } msn_flags_t; -struct msn_handler_data -{ +struct msn_handler_data { int fd, inpa; int rxlen; char *rxq; - + int msglen; char *cmd_text; - + /* Either ic or sb */ gpointer data; - - int (*exec_command) ( struct msn_handler_data *handler, char **cmd, int count ); - int (*exec_message) ( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int count ); + + int (*exec_command) (struct msn_handler_data *handler, char **cmd, int count); + int (*exec_message) (struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int count); }; -struct msn_data -{ +struct msn_data { struct im_connection *ic; - + struct msn_handler_data ns[1]; msn_flags_t flags; - + int trId; char *tokens[4]; char *lock_key, *pp_policy; char *uuid; - + GSList *msgq, *grpq, *soapq; GSList *switchboards; int sb_failures; time_t first_sb_failure; - + const struct msn_away_state *away_state; GSList *groups; char *profile_rid; - + /* Mostly used for sending the ADL command; since MSNP13 the client is responsible for downloading the contact list and then sending it to the MSNP server. */ @@ -143,54 +140,48 @@ struct msn_data int adl_todo; }; -struct msn_switchboard -{ +struct msn_switchboard { struct im_connection *ic; - + /* The following two are also in the handler. TODO: Clean up. */ int fd; gint inp; struct msn_handler_data *handler; gint keepalive; - + int trId; int ready; - + int session; char *key; - + GSList *msgq; char *who; struct groupchat *chat; }; -struct msn_away_state -{ +struct msn_away_state { char code[4]; char name[16]; }; -struct msn_status_code -{ +struct msn_status_code { int number; char *text; int flags; }; -struct msn_message -{ +struct msn_message { char *who; char *text; }; -struct msn_groupadd -{ +struct msn_groupadd { char *who; char *group; }; -typedef enum -{ +typedef enum { MSN_BUDDY_FL = 1, /* Warning: FL,AL,BL *must* be 1,2,4. */ MSN_BUDDY_AL = 2, MSN_BUDDY_BL = 4, @@ -200,14 +191,12 @@ typedef enum MSN_BUDDY_FED = 512, } msn_buddy_flags_t; -struct msn_buddy_data -{ +struct msn_buddy_data { char *cid; msn_buddy_flags_t flags; }; -struct msn_group -{ +struct msn_group { char *name; char *id; }; @@ -215,8 +204,8 @@ struct msn_group /* Bitfield values for msn_status_code.flags */ #define STATUS_FATAL 1 #define STATUS_SB_FATAL 2 -#define STATUS_SB_IM_SPARE 4 /* Make one-to-one conversation switchboard available again, invite failed. */ -#define STATUS_SB_CHAT_SPARE 8 /* Same, but also for groupchats (not used yet). */ +#define STATUS_SB_IM_SPARE 4 /* Make one-to-one conversation switchboard available again, invite failed. */ +#define STATUS_SB_CHAT_SPARE 8 /* Same, but also for groupchats (not used yet). */ extern int msn_chat_id; extern const struct msn_away_state msn_away_state_list[]; @@ -231,47 +220,48 @@ extern GSList *msn_connections; extern GSList *msn_switchboards; /* ns.c */ -int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... ) G_GNUC_PRINTF( 3, 4 ); -gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port ); -void msn_ns_close( struct msn_handler_data *handler ); -void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error ); -void msn_auth_got_contact_list( struct im_connection *ic ); -int msn_ns_finish_login( struct im_connection *ic ); -int msn_ns_sendmessage( struct im_connection *ic, struct bee_user *bu, const char *text ); -void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq ); +int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...) G_GNUC_PRINTF(3, 4); +gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port); +void msn_ns_close(struct msn_handler_data *handler); +void msn_auth_got_passport_token(struct im_connection *ic, const char *token, const char *error); +void msn_auth_got_contact_list(struct im_connection *ic); +int msn_ns_finish_login(struct im_connection *ic); +int msn_ns_sendmessage(struct im_connection *ic, struct bee_user *bu, const char *text); +void msn_ns_oim_send_queue(struct im_connection *ic, GSList **msgq); /* msn_util.c */ -int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, const char *group ); -int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group ); -void msn_buddy_ask( bee_user_t *bu ); -char **msn_linesplit( char *line ); -int msn_handler( struct msn_handler_data *h ); -void msn_msgq_purge( struct im_connection *ic, GSList **list ); -char *msn_p11_challenge( char *challenge ); -gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ ); -struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name ); -struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id ); -int msn_ns_set_display_name( struct im_connection *ic, const char *value ); -const char *msn_normalize_handle( const char *handle ); +int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, + const char *group); +int msn_buddy_list_remove(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group); +void msn_buddy_ask(bee_user_t *bu); +char **msn_linesplit(char *line); +int msn_handler(struct msn_handler_data *h); +void msn_msgq_purge(struct im_connection *ic, GSList **list); +char *msn_p11_challenge(char *challenge); +gint msn_domaintree_cmp(gconstpointer a_, gconstpointer b_); +struct msn_group *msn_group_by_name(struct im_connection *ic, const char *name); +struct msn_group *msn_group_by_id(struct im_connection *ic, const char *id); +int msn_ns_set_display_name(struct im_connection *ic, const char *value); +const char *msn_normalize_handle(const char *handle); /* tables.c */ -const struct msn_away_state *msn_away_state_by_number( int number ); -const struct msn_away_state *msn_away_state_by_code( char *code ); -const struct msn_away_state *msn_away_state_by_name( char *name ); -const struct msn_status_code *msn_status_by_number( int number ); +const struct msn_away_state *msn_away_state_by_number(int number); +const struct msn_away_state *msn_away_state_by_code(char *code); +const struct msn_away_state *msn_away_state_by_name(char *name); +const struct msn_status_code *msn_status_by_number(int number); /* sb.c */ -int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... ) G_GNUC_PRINTF( 2, 3 );; -struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session ); -struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle ); -struct msn_switchboard *msn_sb_by_chat( struct groupchat *c ); -struct msn_switchboard *msn_sb_spare( struct im_connection *ic ); -int msn_sb_sendmessage( struct msn_switchboard *sb, char *text ); -struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb ); -void msn_sb_destroy( struct msn_switchboard *sb ); -gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); -int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); -void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ); -void msn_sb_stop_keepalives( struct msn_switchboard *sb ); +int msn_sb_write(struct msn_switchboard *sb, const char *fmt, ...) G_GNUC_PRINTF(2, 3);; +struct msn_switchboard *msn_sb_create(struct im_connection *ic, char *host, int port, char *key, int session); +struct msn_switchboard *msn_sb_by_handle(struct im_connection *ic, const char *handle); +struct msn_switchboard *msn_sb_by_chat(struct groupchat *c); +struct msn_switchboard *msn_sb_spare(struct im_connection *ic); +int msn_sb_sendmessage(struct msn_switchboard *sb, char *text); +struct groupchat *msn_sb_to_chat(struct msn_switchboard *sb); +void msn_sb_destroy(struct msn_switchboard *sb); +gboolean msn_sb_connected(gpointer data, gint source, b_input_condition cond); +int msn_sb_write_msg(struct im_connection *ic, struct msn_message *m); +void msn_sb_start_keepalives(struct msn_switchboard *sb, gboolean initial); +void msn_sb_stop_keepalives(struct msn_switchboard *sb); #endif //_MSN_H diff --git a/protocols/msn/msn_util.c b/protocols/msn/msn_util.c index f329ae03..8f929305 100644 --- a/protocols/msn/msn_util.c +++ b/protocols/msn/msn_util.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -29,68 +29,65 @@ #include "soap.h" #include <ctype.h> -static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list ) +static char *adlrml_entry(const char *handle_, msn_buddy_flags_t list) { - char *domain, handle[strlen(handle_)+1]; - - strcpy( handle, handle_ ); - if( ( domain = strchr( handle, '@' ) ) ) + char *domain, handle[strlen(handle_) + 1]; + + strcpy(handle, handle_); + if ((domain = strchr(handle, '@'))) { *(domain++) = '\0'; - else + } else { return NULL; - - return g_markup_printf_escaped( "<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>", - domain, handle, list ); + } + + return g_markup_printf_escaped("<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>", + domain, handle, list); } -int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group ) +int msn_buddy_list_add(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, + const char *group) { struct msn_data *md = ic->proto_data; char groupid[8]; bee_user_t *bu; struct msn_buddy_data *bd; char *adl; - + *groupid = '\0'; #if 0 - if( group ) - { + if (group) { int i; - for( i = 0; i < md->groupcount; i ++ ) - if( g_strcasecmp( md->grouplist[i], group ) == 0 ) - { - g_snprintf( groupid, sizeof( groupid ), " %d", i ); + for (i = 0; i < md->groupcount; i++) { + if (g_strcasecmp(md->grouplist[i], group) == 0) { + g_snprintf(groupid, sizeof(groupid), " %d", i); break; } - - if( *groupid == '\0' ) - { + } + + if (*groupid == '\0') { /* Have to create this group, it doesn't exist yet. */ struct msn_groupadd *ga; GSList *l; - - for( l = md->grpq; l; l = l->next ) - { + + for (l = md->grpq; l; l = l->next) { ga = l->data; - if( g_strcasecmp( ga->group, group ) == 0 ) + if (g_strcasecmp(ga->group, group) == 0) { break; + } } - - ga = g_new0( struct msn_groupadd, 1 ); - ga->who = g_strdup( who ); - ga->group = g_strdup( group ); - md->grpq = g_slist_prepend( md->grpq, ga ); - - if( l == NULL ) - { - char groupname[strlen(group)+1]; - strcpy( groupname, group ); - http_encode( groupname ); - g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); - return msn_write( ic, buf, strlen( buf ) ); - } - else - { + + ga = g_new0(struct msn_groupadd, 1); + ga->who = g_strdup(who); + ga->group = g_strdup(group); + md->grpq = g_slist_prepend(md->grpq, ga); + + if (l == NULL) { + char groupname[strlen(group) + 1]; + strcpy(groupname, group); + http_encode(groupname); + g_snprintf(buf, sizeof(buf), "ADG %d %s %d\r\n", ++md->trId, groupname, 0); + return msn_write(ic, buf, strlen(buf)); + } else { /* This can happen if the user's doing lots of adds to a new group at once; we're still waiting for the server to confirm group creation. */ @@ -99,155 +96,159 @@ int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const } } #endif - - if( !( ( bu = bee_user_by_handle( ic->bee, ic, who ) ) || - ( bu = bee_user_new( ic->bee, ic, who, 0 ) ) ) || - !( bd = bu->data ) || bd->flags & list ) + + if (!((bu = bee_user_by_handle(ic->bee, ic, who)) || + (bu = bee_user_new(ic->bee, ic, who, 0))) || + !(bd = bu->data) || bd->flags & list) { return 1; - + } + bd->flags |= list; - - if( list == MSN_BUDDY_FL ) - msn_soap_ab_contact_add( ic, bu ); - else - msn_soap_memlist_edit( ic, who, TRUE, list ); - - if( ( adl = adlrml_entry( who, list ) ) ) - { - int st = msn_ns_write( ic, -1, "ADL %d %zd\r\n%s", - ++md->trId, strlen( adl ), adl ); - g_free( adl ); - + + if (list == MSN_BUDDY_FL) { + msn_soap_ab_contact_add(ic, bu); + } else { + msn_soap_memlist_edit(ic, who, TRUE, list); + } + + if ((adl = adlrml_entry(who, list))) { + int st = msn_ns_write(ic, -1, "ADL %d %zd\r\n%s", + ++md->trId, strlen(adl), adl); + g_free(adl); + return st; } - + return 1; } -int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group ) +int msn_buddy_list_remove(struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group) { struct msn_data *md = ic->proto_data; char groupid[8]; bee_user_t *bu; struct msn_buddy_data *bd; char *adl; - + *groupid = '\0'; #if 0 - if( group ) - { + if (group) { int i; - for( i = 0; i < md->groupcount; i ++ ) - if( g_strcasecmp( md->grouplist[i], group ) == 0 ) - { - g_snprintf( groupid, sizeof( groupid ), " %d", i ); + for (i = 0; i < md->groupcount; i++) { + if (g_strcasecmp(md->grouplist[i], group) == 0) { + g_snprintf(groupid, sizeof(groupid), " %d", i); break; } + } } #endif - - if( !( bu = bee_user_by_handle( ic->bee, ic, who ) ) || - !( bd = bu->data ) || !( bd->flags & list ) ) + + if (!(bu = bee_user_by_handle(ic->bee, ic, who)) || + !(bd = bu->data) || !(bd->flags & list)) { return 1; - + } + bd->flags &= ~list; - - if( list == MSN_BUDDY_FL ) - msn_soap_ab_contact_del( ic, bu ); - else - msn_soap_memlist_edit( ic, who, FALSE, list ); - - if( ( adl = adlrml_entry( who, list ) ) ) - { - int st = msn_ns_write( ic, -1, "RML %d %zd\r\n%s", - ++md->trId, strlen( adl ), adl ); - g_free( adl ); - + + if (list == MSN_BUDDY_FL) { + msn_soap_ab_contact_del(ic, bu); + } else { + msn_soap_memlist_edit(ic, who, FALSE, list); + } + + if ((adl = adlrml_entry(who, list))) { + int st = msn_ns_write(ic, -1, "RML %d %zd\r\n%s", + ++md->trId, strlen(adl), adl); + g_free(adl); + return st; } - + return 1; } -struct msn_buddy_ask_data -{ +struct msn_buddy_ask_data { struct im_connection *ic; char *handle; char *realname; }; -static void msn_buddy_ask_yes( void *data ) +static void msn_buddy_ask_yes(void *data) { struct msn_buddy_ask_data *bla = data; - - msn_buddy_list_add( bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL ); - - imcb_ask_add( bla->ic, bla->handle, NULL ); - - g_free( bla->handle ); - g_free( bla->realname ); - g_free( bla ); + + msn_buddy_list_add(bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL); + + imcb_ask_add(bla->ic, bla->handle, NULL); + + g_free(bla->handle); + g_free(bla->realname); + g_free(bla); } -static void msn_buddy_ask_no( void *data ) +static void msn_buddy_ask_no(void *data) { struct msn_buddy_ask_data *bla = data; - - msn_buddy_list_add( bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL ); - - g_free( bla->handle ); - g_free( bla->realname ); - g_free( bla ); + + msn_buddy_list_add(bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL); + + g_free(bla->handle); + g_free(bla->realname); + g_free(bla); } -void msn_buddy_ask( bee_user_t *bu ) +void msn_buddy_ask(bee_user_t *bu) { struct msn_buddy_ask_data *bla; struct msn_buddy_data *bd = bu->data; char buf[1024]; - - if( !( bd->flags & MSN_BUDDY_PL ) ) + + if (!(bd->flags & MSN_BUDDY_PL)) { return; - - bla = g_new0( struct msn_buddy_ask_data, 1 ); + } + + bla = g_new0(struct msn_buddy_ask_data, 1); bla->ic = bu->ic; - bla->handle = g_strdup( bu->handle ); - bla->realname = g_strdup( bu->fullname ); - - g_snprintf( buf, sizeof( buf ), - "The user %s (%s) wants to add you to his/her buddy list.", - bu->handle, bu->fullname ); - imcb_ask( bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no ); + bla->handle = g_strdup(bu->handle); + bla->realname = g_strdup(bu->fullname); + + g_snprintf(buf, sizeof(buf), + "The user %s (%s) wants to add you to his/her buddy list.", + bu->handle, bu->fullname); + imcb_ask(bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no); } /* *NOT* thread-safe, but that's not a problem for now... */ -char **msn_linesplit( char *line ) +char **msn_linesplit(char *line) { static char **ret = NULL; static int size = 3; int i, n = 0; - - if( ret == NULL ) - ret = g_new0( char*, size ); - - for( i = 0; line[i] && line[i] == ' '; i ++ ); - if( line[i] ) - { + + if (ret == NULL) { + ret = g_new0(char*, size); + } + + for (i = 0; line[i] && line[i] == ' '; i++) { + ; + } + if (line[i]) { ret[n++] = line + i; - for( i ++; line[i]; i ++ ) - { - if( line[i] == ' ' ) + for (i++; line[i]; i++) { + if (line[i] == ' ') { line[i] = 0; - else if( line[i] != ' ' && !line[i-1] ) + } else if (line[i] != ' ' && !line[i - 1]) { ret[n++] = line + i; - - if( n >= size ) - ret = g_renew( char*, ret, size += 2 ); + } + + if (n >= size) { + ret = g_renew(char*, ret, size += 2); + } } } ret[n] = NULL; - - return( ret ); + + return(ret); } /* This one handles input from a MSN Messenger server. Both the NS and SB servers usually give @@ -258,152 +259,154 @@ char **msn_linesplit( char *line ) 0: Command reported error; Abort *immediately*. (The connection does not exist anymore) 1: OK */ -int msn_handler( struct msn_handler_data *h ) +int msn_handler(struct msn_handler_data *h) { int st; - - h->rxq = g_renew( char, h->rxq, h->rxlen + 1024 ); - st = read( h->fd, h->rxq + h->rxlen, 1024 ); + + h->rxq = g_renew(char, h->rxq, h->rxlen + 1024); + st = read(h->fd, h->rxq + h->rxlen, 1024); h->rxlen += st; - - if( st <= 0 ) - return( -1 ); - - if( getenv( "BITLBEE_DEBUG" ) ) - { - write( 2, "->C:", 4 ); - write( 2, h->rxq + h->rxlen - st, st ); + + if (st <= 0) { + return(-1); + } + + if (getenv("BITLBEE_DEBUG")) { + write(2, "->C:", 4); + write(2, h->rxq + h->rxlen - st, st); } - - while( st ) - { + + while (st) { int i; - - if( h->msglen == 0 ) - { - for( i = 0; i < h->rxlen; i ++ ) - { - if( h->rxq[i] == '\r' || h->rxq[i] == '\n' ) - { + + if (h->msglen == 0) { + for (i = 0; i < h->rxlen; i++) { + if (h->rxq[i] == '\r' || h->rxq[i] == '\n') { char *cmd_text, **cmd; int count; - - cmd_text = g_strndup( h->rxq, i ); - cmd = msn_linesplit( cmd_text ); - for( count = 0; cmd[count]; count ++ ); - st = h->exec_command( h, cmd, count ); - g_free( cmd_text ); - + + cmd_text = g_strndup(h->rxq, i); + cmd = msn_linesplit(cmd_text); + for (count = 0; cmd[count]; count++) { + ; + } + st = h->exec_command(h, cmd, count); + g_free(cmd_text); + /* If the connection broke, don't continue. We don't even exist anymore. */ - if( !st ) - return( 0 ); - - if( h->msglen ) - h->cmd_text = g_strndup( h->rxq, i ); - + if (!st) { + return(0); + } + + if (h->msglen) { + h->cmd_text = g_strndup(h->rxq, i); + } + /* Skip to the next non-emptyline */ - while( i < h->rxlen && ( h->rxq[i] == '\r' || h->rxq[i] == '\n' ) ) i ++; - + while (i < h->rxlen && (h->rxq[i] == '\r' || h->rxq[i] == '\n')) { + i++; + } + break; } } - + /* If we reached the end of the buffer, there's still an incomplete command there. Return and wait for more data. */ - if( i == h->rxlen && h->rxq[i-1] != '\r' && h->rxq[i-1] != '\n' ) + if (i == h->rxlen && h->rxq[i - 1] != '\r' && h->rxq[i - 1] != '\n') { break; - } - else - { + } + } else { char *msg, **cmd; int count; - + /* Do we have the complete message already? */ - if( h->msglen > h->rxlen ) + if (h->msglen > h->rxlen) { break; - - msg = g_strndup( h->rxq, h->msglen ); - cmd = msn_linesplit( h->cmd_text ); - for( count = 0; cmd[count]; count ++ ); - - st = h->exec_message( h, msg, h->msglen, cmd, count ); - g_free( msg ); - g_free( h->cmd_text ); + } + + msg = g_strndup(h->rxq, h->msglen); + cmd = msn_linesplit(h->cmd_text); + for (count = 0; cmd[count]; count++) { + ; + } + + st = h->exec_message(h, msg, h->msglen, cmd, count); + g_free(msg); + g_free(h->cmd_text); h->cmd_text = NULL; - - if( !st ) - return( 0 ); - + + if (!st) { + return(0); + } + i = h->msglen; h->msglen = 0; } - + /* More data after this block? */ - if( i < h->rxlen ) - { + if (i < h->rxlen) { char *tmp; - - tmp = g_memdup( h->rxq + i, h->rxlen - i ); - g_free( h->rxq ); + + tmp = g_memdup(h->rxq + i, h->rxlen - i); + g_free(h->rxq); h->rxq = tmp; h->rxlen -= i; i = 0; - } - else - /* If not, reset the rx queue and get lost. */ - { - g_free( h->rxq ); - h->rxq = g_new0( char, 1 ); + } else { + /* If not, reset the rx queue and get lost. */ + g_free(h->rxq); + h->rxq = g_new0(char, 1); h->rxlen = 0; - return( 1 ); + return(1); } } - - return( 1 ); + + return(1); } -void msn_msgq_purge( struct im_connection *ic, GSList **list ) +void msn_msgq_purge(struct im_connection *ic, GSList **list) { struct msn_message *m; GString *ret; GSList *l; int n = 0; - + l = *list; - if( l == NULL ) + if (l == NULL) { return; - + } + m = l->data; - ret = g_string_sized_new( 1024 ); - g_string_printf( ret, "Warning: Cleaning up MSN (switchboard) connection with unsent " - "messages to %s:", m->who ? m->who : "unknown recipient" ); - - while( l ) - { + ret = g_string_sized_new(1024); + g_string_printf(ret, "Warning: Cleaning up MSN (switchboard) connection with unsent " + "messages to %s:", m->who ? m->who : "unknown recipient"); + + while (l) { m = l->data; - - if( strncmp( m->text, "\r\r\r", 3 ) != 0 ) - { - g_string_append_printf( ret, "\n%s", m->text ); - n ++; + + if (strncmp(m->text, "\r\r\r", 3) != 0) { + g_string_append_printf(ret, "\n%s", m->text); + n++; } - - g_free( m->who ); - g_free( m->text ); - g_free( m ); - + + g_free(m->who); + g_free(m->text); + g_free(m); + l = l->next; } - g_slist_free( *list ); + g_slist_free(*list); *list = NULL; - - if( n > 0 ) - imcb_log( ic, "%s", ret->str ); - g_string_free( ret, TRUE ); + + if (n > 0) { + imcb_log(ic, "%s", ret->str); + } + g_string_free(ret, TRUE); } /* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */ -char *msn_p11_challenge( char *challenge ) +char *msn_p11_challenge(char *challenge) { char *output, buf[256]; md5_state_t md5c; @@ -414,126 +417,133 @@ char *msn_p11_challenge( char *challenge ) /* Create the MD5 hash */ md5_init(&md5c); - md5_append(&md5c, (unsigned char*) challenge, strlen(challenge)); - md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY)); + md5_append(&md5c, (unsigned char *) challenge, strlen(challenge)); + md5_append(&md5c, (unsigned char *) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY)); md5_finish(&md5c, md5Hash); /* Split it into four integers */ - md5Parts = (unsigned int *)md5Hash; - for (i = 0; i < 4; i ++) - { + md5Parts = (unsigned int *) md5Hash; + for (i = 0; i < 4; i++) { md5Parts[i] = GUINT32_TO_LE(md5Parts[i]); - + /* & each integer with 0x7FFFFFFF */ /* and save one unmodified array for later */ newHashParts[i] = md5Parts[i]; md5Parts[i] &= 0x7FFFFFFF; } - + /* make a new string and pad with '0' */ - n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID); + n = g_snprintf(buf, sizeof(buf) - 5, "%s%s00000000", challenge, MSNP11_PROD_ID); /* truncate at an 8-byte boundary */ - buf[n&=~7] = '\0'; - + buf[n &= ~7] = '\0'; + /* split into integers */ - chlStringParts = (unsigned int *)buf; - + chlStringParts = (unsigned int *) buf; + /* this is magic */ - for (i = 0; i < (n / 4) - 1; i += 2) - { + for (i = 0; i < (n / 4) - 1; i += 2) { long long temp; chlStringParts[i] = GUINT32_TO_LE(chlStringParts[i]); - chlStringParts[i+1] = GUINT32_TO_LE(chlStringParts[i+1]); + chlStringParts[i + 1] = GUINT32_TO_LE(chlStringParts[i + 1]); - temp = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF; - nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF; + temp = + (md5Parts[0] * + (((0x0E79A9C1 * + (long long) chlStringParts[i]) % 0x7FFFFFFF) + nHigh) + md5Parts[1]) % 0x7FFFFFFF; + nHigh = + (md5Parts[2] * + (((long long) chlStringParts[i + 1] + temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF; nLow = nLow + nHigh + temp; } - nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF; - nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF; - + nHigh = (nHigh + md5Parts[1]) % 0x7FFFFFFF; + nLow = (nLow + md5Parts[3]) % 0x7FFFFFFF; + newHashParts[0] ^= nHigh; newHashParts[1] ^= nLow; newHashParts[2] ^= nHigh; newHashParts[3] ^= nLow; - + /* swap more bytes if big endian */ - for (i = 0; i < 4; i ++) - newHashParts[i] = GUINT32_TO_LE(newHashParts[i]); - + for (i = 0; i < 4; i++) { + newHashParts[i] = GUINT32_TO_LE(newHashParts[i]); + } + /* make a string of the parts */ - newHash = (unsigned char *)newHashParts; - + newHash = (unsigned char *) newHashParts; + /* convert to hexadecimal */ output = g_new(char, 33); - for (i = 0; i < 16; i ++) + for (i = 0; i < 16; i++) { sprintf(output + i * 2, "%02x", newHash[i]); - + } + return output; } -gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ ) +gint msn_domaintree_cmp(gconstpointer a_, gconstpointer b_) { const char *a = a_, *b = b_; gint ret; - - if( !( a = strchr( a, '@' ) ) || !( b = strchr( b, '@' ) ) || - ( ret = strcmp( a, b ) ) == 0 ) - ret = strcmp( a_, b_ ); - + + if (!(a = strchr(a, '@')) || !(b = strchr(b, '@')) || + (ret = strcmp(a, b)) == 0) { + ret = strcmp(a_, b_); + } + return ret; } -struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name ) +struct msn_group *msn_group_by_name(struct im_connection *ic, const char *name) { struct msn_data *md = ic->proto_data; GSList *l; - - for( l = md->groups; l; l = l->next ) - { + + for (l = md->groups; l; l = l->next) { struct msn_group *mg = l->data; - - if( g_strcasecmp( mg->name, name ) == 0 ) + + if (g_strcasecmp(mg->name, name) == 0) { return mg; + } } - + return NULL; } -struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id ) +struct msn_group *msn_group_by_id(struct im_connection *ic, const char *id) { struct msn_data *md = ic->proto_data; GSList *l; - - for( l = md->groups; l; l = l->next ) - { + + for (l = md->groups; l; l = l->next) { struct msn_group *mg = l->data; - - if( g_strcasecmp( mg->id, id ) == 0 ) + + if (g_strcasecmp(mg->id, id) == 0) { return mg; + } } - + return NULL; } -int msn_ns_set_display_name( struct im_connection *ic, const char *value ) +int msn_ns_set_display_name(struct im_connection *ic, const char *value) { struct msn_data *md = ic->proto_data; - char fn[strlen(value)*3+1]; - - strcpy( fn, value ); - http_encode( fn ); - + char fn[strlen(value) * 3 + 1]; + + strcpy(fn, value); + http_encode(fn); + /* Note: We don't actually know if the server accepted the new name, and won't give proper feedback yet if it doesn't. */ - return msn_ns_write( ic, -1, "PRP %d MFN %s\r\n", ++md->trId, fn ); + return msn_ns_write(ic, -1, "PRP %d MFN %s\r\n", ++md->trId, fn); } -const char *msn_normalize_handle( const char *handle ) +const char *msn_normalize_handle(const char *handle) { - if( strncmp( handle, "1:", 2 ) == 0 ) + if (strncmp(handle, "1:", 2) == 0) { return handle + 2; - else + } else { return handle; + } } diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 7646e237..f6c553a8 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -32,849 +32,753 @@ #include "soap.h" #include "xmltree.h" -static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ); -static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond ); -static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num_parts ); -static int msn_ns_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts ); +static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond); +static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond); +static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts); +static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts); -static void msn_ns_send_adl_start( struct im_connection *ic ); -static void msn_ns_send_adl( struct im_connection *ic ); +static void msn_ns_send_adl_start(struct im_connection *ic); +static void msn_ns_send_adl(struct im_connection *ic); -int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... ) +int msn_ns_write(struct im_connection *ic, int fd, const char *fmt, ...) { struct msn_data *md = ic->proto_data; va_list params; char *out; size_t len; int st; - - va_start( params, fmt ); - out = g_strdup_vprintf( fmt, params ); - va_end( params ); - - if( fd < 0 ) + + va_start(params, fmt); + out = g_strdup_vprintf(fmt, params); + va_end(params); + + if (fd < 0) { fd = md->ns->fd; - - if( getenv( "BITLBEE_DEBUG" ) ) - fprintf( stderr, "->NS%d:%s\n", fd, out ); - - len = strlen( out ); - st = write( fd, out, len ); - g_free( out ); - if( st != len ) - { - imcb_error( ic, "Short write() to main server" ); - imc_logout( ic, TRUE ); + } + + if (getenv("BITLBEE_DEBUG")) { + fprintf(stderr, "->NS%d:%s\n", fd, out); + } + + len = strlen(out); + st = write(fd, out, len); + g_free(out); + if (st != len) { + imcb_error(ic, "Short write() to main server"); + imc_logout(ic, TRUE); return 0; } - + return 1; } -gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port ) +gboolean msn_ns_connect(struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port) { - if( handler->fd >= 0 ) - closesocket( handler->fd ); - + if (handler->fd >= 0) { + closesocket(handler->fd); + } + handler->exec_command = msn_ns_command; handler->exec_message = msn_ns_message; handler->data = ic; - handler->fd = proxy_connect( host, port, msn_ns_connected, handler ); - if( handler->fd < 0 ) - { - imcb_error( ic, "Could not connect to server" ); - imc_logout( ic, TRUE ); + handler->fd = proxy_connect(host, port, msn_ns_connected, handler); + if (handler->fd < 0) { + imcb_error(ic, "Could not connect to server"); + imc_logout(ic, TRUE); return FALSE; } - + return TRUE; } -static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) +static gboolean msn_ns_connected(gpointer data, gint source, b_input_condition cond) { struct msn_handler_data *handler = data; struct im_connection *ic = handler->data; struct msn_data *md; - - if( !g_slist_find( msn_connections, ic ) ) + + if (!g_slist_find(msn_connections, ic)) { return FALSE; - + } + md = ic->proto_data; - - if( source == -1 ) - { - imcb_error( ic, "Could not connect to server" ); - imc_logout( ic, TRUE ); + + if (source == -1) { + imcb_error(ic, "Could not connect to server"); + imc_logout(ic, TRUE); return FALSE; } - - g_free( handler->rxq ); + + g_free(handler->rxq); handler->rxlen = 0; - handler->rxq = g_new0( char, 1 ); - - if( md->uuid == NULL ) - { + handler->rxq = g_new0(char, 1); + + if (md->uuid == NULL) { struct utsname name; sha1_state_t sha[1]; - + /* UUID == SHA1("BitlBee" + my hostname + MSN username) */ - sha1_init( sha ); - sha1_append( sha, (void*) "BitlBee", 7 ); - if( uname( &name ) == 0 ) - { - sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) ); + sha1_init(sha); + sha1_append(sha, (void *) "BitlBee", 7); + if (uname(&name) == 0) { + sha1_append(sha, (void *) name.nodename, strlen(name.nodename)); } - sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) ); - md->uuid = sha1_random_uuid( sha ); - memcpy( md->uuid, "b171be3e", 8 ); /* :-P */ + sha1_append(sha, (void *) ic->acc->user, strlen(ic->acc->user)); + md->uuid = sha1_random_uuid(sha); + memcpy(md->uuid, "b171be3e", 8); /* :-P */ } - - if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) ) - { - handler->inpa = b_input_add( handler->fd, B_EV_IO_READ, msn_ns_callback, handler ); - imcb_log( ic, "Connected to server, waiting for reply" ); + + if (msn_ns_write(ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER)) { + handler->inpa = b_input_add(handler->fd, B_EV_IO_READ, msn_ns_callback, handler); + imcb_log(ic, "Connected to server, waiting for reply"); } - + return FALSE; } -void msn_ns_close( struct msn_handler_data *handler ) +void msn_ns_close(struct msn_handler_data *handler) { - if( handler->fd >= 0 ) - { - closesocket( handler->fd ); - b_event_remove( handler->inpa ); + if (handler->fd >= 0) { + closesocket(handler->fd); + b_event_remove(handler->inpa); } - + handler->fd = handler->inpa = -1; - g_free( handler->rxq ); - g_free( handler->cmd_text ); - + g_free(handler->rxq); + g_free(handler->cmd_text); + handler->rxlen = 0; handler->rxq = NULL; handler->cmd_text = NULL; } -static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond ) +static gboolean msn_ns_callback(gpointer data, gint source, b_input_condition cond) { struct msn_handler_data *handler = data; struct im_connection *ic = handler->data; - - if( msn_handler( handler ) == -1 ) /* Don't do this on ret == 0, it's already done then. */ - { - imcb_error( ic, "Error while reading from server" ); - imc_logout( ic, TRUE ); - + + if (msn_handler(handler) == -1) { /* Don't do this on ret == 0, it's already done then. */ + imcb_error(ic, "Error while reading from server"); + imc_logout(ic, TRUE); + return FALSE; - } - else + } else { return TRUE; + } } -static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num_parts ) +static int msn_ns_command(struct msn_handler_data *handler, char **cmd, int num_parts) { struct im_connection *ic = handler->data; struct msn_data *md = ic->proto_data; - - if( num_parts == 0 ) - { + + if (num_parts == 0) { /* Hrrm... Empty command...? Ignore? */ - return( 1 ); + return(1); } - - if( strcmp( cmd[0], "VER" ) == 0 ) - { - if( cmd[2] && strncmp( cmd[2], MSNP_VER, 5 ) != 0 ) - { - imcb_error( ic, "Unsupported protocol" ); - imc_logout( ic, FALSE ); - return( 0 ); + + if (strcmp(cmd[0], "VER") == 0) { + if (cmd[2] && strncmp(cmd[2], MSNP_VER, 5) != 0) { + imcb_error(ic, "Unsupported protocol"); + imc_logout(ic, FALSE); + return(0); } - - return( msn_ns_write( ic, handler->fd, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s\r\n", - ++md->trId, ic->acc->user ) ); - } - else if( strcmp( cmd[0], "CVR" ) == 0 ) - { + + return(msn_ns_write(ic, handler->fd, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s\r\n", + ++md->trId, ic->acc->user)); + } else if (strcmp(cmd[0], "CVR") == 0) { /* We don't give a damn about the information we just received */ - return msn_ns_write( ic, handler->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user ); - } - else if( strcmp( cmd[0], "XFR" ) == 0 ) - { + return msn_ns_write(ic, handler->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user); + } else if (strcmp(cmd[0], "XFR") == 0) { char *server; int port; - - if( num_parts >= 6 && strcmp( cmd[2], "NS" ) == 0 ) - { - b_event_remove( handler->inpa ); + + if (num_parts >= 6 && strcmp(cmd[2], "NS") == 0) { + b_event_remove(handler->inpa); handler->inpa = -1; - - server = strchr( cmd[3], ':' ); - if( !server ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + server = strchr(cmd[3], ':'); + if (!server) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } *server = 0; - port = atoi( server + 1 ); + port = atoi(server + 1); server = cmd[3]; - - imcb_log( ic, "Transferring to other server" ); - return msn_ns_connect( ic, handler, server, port ); - } - else if( num_parts >= 6 && strcmp( cmd[2], "SB" ) == 0 ) - { + + imcb_log(ic, "Transferring to other server"); + return msn_ns_connect(ic, handler, server, port); + } else if (num_parts >= 6 && strcmp(cmd[2], "SB") == 0) { struct msn_switchboard *sb; - - server = strchr( cmd[3], ':' ); - if( !server ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + server = strchr(cmd[3], ':'); + if (!server) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } *server = 0; - port = atoi( server + 1 ); + port = atoi(server + 1); server = cmd[3]; - - if( strcmp( cmd[4], "CKI" ) != 0 ) - { - imcb_error( ic, "Unknown authentication method for switchboard" ); - imc_logout( ic, TRUE ); - return( 0 ); + + if (strcmp(cmd[4], "CKI") != 0) { + imcb_error(ic, "Unknown authentication method for switchboard"); + imc_logout(ic, TRUE); + return(0); } - - debug( "Connecting to a new switchboard with key %s", cmd[5] ); - if( ( sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ) ) == NULL ) - { + debug("Connecting to a new switchboard with key %s", cmd[5]); + + if ((sb = msn_sb_create(ic, server, port, cmd[5], MSN_SB_NEW)) == NULL) { /* Although this isn't strictly fatal for the NS connection, it's definitely something serious (we ran out of file descriptors?). */ - imcb_error( ic, "Could not create new switchboard" ); - imc_logout( ic, TRUE ); - return( 0 ); + imcb_error(ic, "Could not create new switchboard"); + imc_logout(ic, TRUE); + return(0); } - - if( md->msgq ) - { + + if (md->msgq) { struct msn_message *m = md->msgq->data; GSList *l; - - sb->who = g_strdup( m->who ); - + + sb->who = g_strdup(m->who); + /* Move all the messages to the first user in the message queue to the switchboard message queue. */ l = md->msgq; - while( l ) - { + while (l) { m = l->data; l = l->next; - if( strcmp( m->who, sb->who ) == 0 ) - { - sb->msgq = g_slist_append( sb->msgq, m ); - md->msgq = g_slist_remove( md->msgq, m ); + if (strcmp(m->who, sb->who) == 0) { + sb->msgq = g_slist_append(sb->msgq, m); + md->msgq = g_slist_remove(md->msgq, m); } } } - } - else - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); - } - } - else if( strcmp( cmd[0], "USR" ) == 0 ) - { - if( num_parts >= 6 && strcmp( cmd[2], "SSO" ) == 0 && - strcmp( cmd[3], "S" ) == 0 ) - { - g_free( md->pp_policy ); - md->pp_policy = g_strdup( cmd[4] ); - msn_soap_passport_sso_request( ic, cmd[5] ); - } - else if( strcmp( cmd[2], "OK" ) == 0 ) - { + } else { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); + } + } else if (strcmp(cmd[0], "USR") == 0) { + if (num_parts >= 6 && strcmp(cmd[2], "SSO") == 0 && + strcmp(cmd[3], "S") == 0) { + g_free(md->pp_policy); + md->pp_policy = g_strdup(cmd[4]); + msn_soap_passport_sso_request(ic, cmd[5]); + } else if (strcmp(cmd[2], "OK") == 0) { /* If the number after the handle is 0, the e-mail address is unverified, which means we can't change the display name. */ - if( cmd[4][0] == '0' ) + if (cmd[4][0] == '0') { md->flags |= MSN_EMAIL_UNVERIFIED; - - imcb_log( ic, "Authenticated, getting buddy list" ); - msn_soap_memlist_request( ic ); - } - else - { - imcb_error( ic, "Unknown authentication type" ); - imc_logout( ic, FALSE ); - return( 0 ); - } - } - else if( strcmp( cmd[0], "MSG" ) == 0 ) - { - if( num_parts < 4 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); - } - - handler->msglen = atoi( cmd[3] ); - - if( handler->msglen <= 0 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); - } - } - else if( strcmp( cmd[0], "BLP" ) == 0 ) - { - msn_ns_send_adl_start( ic ); - return msn_ns_finish_login( ic ); - } - else if( strcmp( cmd[0], "ADL" ) == 0 ) - { - if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 ) - { - msn_ns_send_adl( ic ); - return msn_ns_finish_login( ic ); - } - else if( num_parts >= 3 ) - { - handler->msglen = atoi( cmd[2] ); + } + + imcb_log(ic, "Authenticated, getting buddy list"); + msn_soap_memlist_request(ic); + } else { + imcb_error(ic, "Unknown authentication type"); + imc_logout(ic, FALSE); + return(0); + } + } else if (strcmp(cmd[0], "MSG") == 0) { + if (num_parts < 4) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } - } - else if( strcmp( cmd[0], "PRP" ) == 0 ) - { - imcb_connected( ic ); - } - else if( strcmp( cmd[0], "CHL" ) == 0 ) - { + + handler->msglen = atoi(cmd[3]); + + if (handler->msglen <= 0) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); + } + } else if (strcmp(cmd[0], "BLP") == 0) { + msn_ns_send_adl_start(ic); + return msn_ns_finish_login(ic); + } else if (strcmp(cmd[0], "ADL") == 0) { + if (num_parts >= 3 && strcmp(cmd[2], "OK") == 0) { + msn_ns_send_adl(ic); + return msn_ns_finish_login(ic); + } else if (num_parts >= 3) { + handler->msglen = atoi(cmd[2]); + } + } else if (strcmp(cmd[0], "PRP") == 0) { + imcb_connected(ic); + } else if (strcmp(cmd[0], "CHL") == 0) { char *resp; int st; - - if( num_parts < 3 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + if (num_parts < 3) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } - - resp = msn_p11_challenge( cmd[2] ); - - st = msn_ns_write( ic, -1, "QRY %d %s %zd\r\n%s", - ++md->trId, MSNP11_PROD_ID, - strlen( resp ), resp ); - g_free( resp ); + + resp = msn_p11_challenge(cmd[2]); + + st = msn_ns_write(ic, -1, "QRY %d %s %zd\r\n%s", + ++md->trId, MSNP11_PROD_ID, + strlen(resp), resp); + g_free(resp); return st; - } - else if( strcmp( cmd[0], "ILN" ) == 0 || strcmp( cmd[0], "NLN" ) == 0 ) - { + } else if (strcmp(cmd[0], "ILN") == 0 || strcmp(cmd[0], "NLN") == 0) { const struct msn_away_state *st; const char *handle; int cap = 0; - - if( num_parts < 6 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + if (num_parts < 6) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } /* ILN and NLN are more or less the same, except ILN has a trId - at the start, and NLN has a capability field at the end. + at the start, and NLN has a capability field at the end. Does ILN still exist BTW? */ - if( cmd[0][1] == 'I' ) - cmd ++; - else - cap = atoi( cmd[4] ); + if (cmd[0][1] == 'I') { + cmd++; + } else { + cap = atoi(cmd[4]); + } - handle = msn_normalize_handle( cmd[2] ); - if( strcmp( handle, ic->acc->user ) == 0 ) + handle = msn_normalize_handle(cmd[2]); + if (strcmp(handle, ic->acc->user) == 0) { return 1; /* That's me! */ - - http_decode( cmd[3] ); - imcb_rename_buddy( ic, handle, cmd[3] ); - - st = msn_away_state_by_code( cmd[1] ); - if( !st ) - { + + } + http_decode(cmd[3]); + imcb_rename_buddy(ic, handle, cmd[3]); + + st = msn_away_state_by_code(cmd[1]); + if (!st) { /* FIXME: Warn/Bomb about unknown away state? */ st = msn_away_state_list + 1; } - - imcb_buddy_status( ic, handle, OPT_LOGGED_IN | - ( st != msn_away_state_list ? OPT_AWAY : 0 ) | - ( cap & 1 ? OPT_MOBILE : 0 ), - st->name, NULL ); - - msn_sb_stop_keepalives( msn_sb_by_handle( ic, handle ) ); - } - else if( strcmp( cmd[0], "FLN" ) == 0 ) - { + + imcb_buddy_status(ic, handle, OPT_LOGGED_IN | + (st != msn_away_state_list ? OPT_AWAY : 0) | + (cap & 1 ? OPT_MOBILE : 0), + st->name, NULL); + + msn_sb_stop_keepalives(msn_sb_by_handle(ic, handle)); + } else if (strcmp(cmd[0], "FLN") == 0) { const char *handle; - - if( cmd[1] == NULL ) + + if (cmd[1] == NULL) { return 1; - - handle = msn_normalize_handle( cmd[1] ); - imcb_buddy_status( ic, handle, 0, NULL, NULL ); - msn_sb_start_keepalives( msn_sb_by_handle( ic, handle ), TRUE ); - } - else if( strcmp( cmd[0], "RNG" ) == 0 ) - { + } + + handle = msn_normalize_handle(cmd[1]); + imcb_buddy_status(ic, handle, 0, NULL, NULL); + msn_sb_start_keepalives(msn_sb_by_handle(ic, handle), TRUE); + } else if (strcmp(cmd[0], "RNG") == 0) { struct msn_switchboard *sb; char *server; int session, port; - - if( num_parts < 7 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + if (num_parts < 7) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } - - session = atoi( cmd[1] ); - - server = strchr( cmd[2], ':' ); - if( !server ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + session = atoi(cmd[1]); + + server = strchr(cmd[2], ':'); + if (!server) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } *server = 0; - port = atoi( server + 1 ); + port = atoi(server + 1); server = cmd[2]; - - if( strcmp( cmd[3], "CKI" ) != 0 ) - { - imcb_error( ic, "Unknown authentication method for switchboard" ); - imc_logout( ic, TRUE ); - return( 0 ); + + if (strcmp(cmd[3], "CKI") != 0) { + imcb_error(ic, "Unknown authentication method for switchboard"); + imc_logout(ic, TRUE); + return(0); } - - debug( "Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4] ); - - if( ( sb = msn_sb_create( ic, server, port, cmd[4], session ) ) == NULL ) - { + + debug("Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4]); + + if ((sb = msn_sb_create(ic, server, port, cmd[4], session)) == NULL) { /* Although this isn't strictly fatal for the NS connection, it's definitely something serious (we ran out of file descriptors?). */ - imcb_error( ic, "Could not create new switchboard" ); - imc_logout( ic, TRUE ); - return( 0 ); - } - else - { - sb->who = g_strdup( msn_normalize_handle( cmd[5] ) ); + imcb_error(ic, "Could not create new switchboard"); + imc_logout(ic, TRUE); + return(0); + } else { + sb->who = g_strdup(msn_normalize_handle(cmd[5])); } - } - else if( strcmp( cmd[0], "OUT" ) == 0 ) - { + } else if (strcmp(cmd[0], "OUT") == 0) { int allow_reconnect = TRUE; - - if( cmd[1] && strcmp( cmd[1], "OTH" ) == 0 ) - { - imcb_error( ic, "Someone else logged in with your account" ); + + if (cmd[1] && strcmp(cmd[1], "OTH") == 0) { + imcb_error(ic, "Someone else logged in with your account"); allow_reconnect = FALSE; + } else if (cmd[1] && strcmp(cmd[1], "SSD") == 0) { + imcb_error(ic, "Terminating session because of server shutdown"); + } else { + imcb_error(ic, "Session terminated by remote server (%s)", + cmd[1] ? cmd[1] : "reason unknown)"); } - else if( cmd[1] && strcmp( cmd[1], "SSD" ) == 0 ) - { - imcb_error( ic, "Terminating session because of server shutdown" ); - } - else - { - imcb_error( ic, "Session terminated by remote server (%s)", - cmd[1] ? cmd[1] : "reason unknown)" ); - } - - imc_logout( ic, allow_reconnect ); - return( 0 ); - } - else if( strcmp( cmd[0], "IPG" ) == 0 ) - { - imcb_error( ic, "Received IPG command, we don't handle them yet." ); - - handler->msglen = atoi( cmd[1] ); - - if( handler->msglen <= 0 ) - { - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); - return( 0 ); + + imc_logout(ic, allow_reconnect); + return(0); + } else if (strcmp(cmd[0], "IPG") == 0) { + imcb_error(ic, "Received IPG command, we don't handle them yet."); + + handler->msglen = atoi(cmd[1]); + + if (handler->msglen <= 0) { + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); + return(0); } } #if 0 - else if( strcmp( cmd[0], "ADG" ) == 0 ) - { - char *group = g_strdup( cmd[3] ); + else if (strcmp(cmd[0], "ADG") == 0) { + char *group = g_strdup(cmd[3]); int groupnum, i; GSList *l, *next; - - http_decode( group ); - if( sscanf( cmd[4], "%d", &groupnum ) == 1 ) - { - if( groupnum >= md->groupcount ) - { - md->grouplist = g_renew( char *, md->grouplist, groupnum + 1 ); - for( i = md->groupcount; i <= groupnum; i ++ ) + + http_decode(group); + if (sscanf(cmd[4], "%d", &groupnum) == 1) { + if (groupnum >= md->groupcount) { + md->grouplist = g_renew(char *, md->grouplist, groupnum + 1); + for (i = md->groupcount; i <= groupnum; i++) { md->grouplist[i] = NULL; + } md->groupcount = groupnum + 1; } - g_free( md->grouplist[groupnum] ); + g_free(md->grouplist[groupnum]); md->grouplist[groupnum] = group; - } - else - { + } else { /* Shouldn't happen, but if it does, give up on the group. */ - g_free( group ); - imcb_error( ic, "Syntax error" ); - imc_logout( ic, TRUE ); + g_free(group); + imcb_error(ic, "Syntax error"); + imc_logout(ic, TRUE); return 0; } - - for( l = md->grpq; l; l = next ) - { + + for (l = md->grpq; l; l = next) { struct msn_groupadd *ga = l->data; next = l->next; - if( g_strcasecmp( ga->group, group ) == 0 ) - { - if( !msn_buddy_list_add( ic, "FL", ga->who, ga->who, group ) ) + if (g_strcasecmp(ga->group, group) == 0) { + if (!msn_buddy_list_add(ic, "FL", ga->who, ga->who, group)) { return 0; - - g_free( ga->group ); - g_free( ga->who ); - g_free( ga ); - md->grpq = g_slist_remove( md->grpq, ga ); + } + + g_free(ga->group); + g_free(ga->who); + g_free(ga); + md->grpq = g_slist_remove(md->grpq, ga); } } } #endif - else if( strcmp( cmd[0], "GCF" ) == 0 ) - { + else if (strcmp(cmd[0], "GCF") == 0) { /* Coming up is cmd[2] bytes of stuff we're supposed to censore. Meh. */ - handler->msglen = atoi( cmd[2] ); - } - else if( strcmp( cmd[0], "UBX" ) == 0 ) - { + handler->msglen = atoi(cmd[2]); + } else if (strcmp(cmd[0], "UBX") == 0) { /* Status message. */ - if( num_parts >= 3 ) - handler->msglen = atoi( cmd[2] ); - } - else if( strcmp( cmd[0], "NOT" ) == 0 ) - { + if (num_parts >= 3) { + handler->msglen = atoi(cmd[2]); + } + } else if (strcmp(cmd[0], "NOT") == 0) { /* Some kind of notification, poorly documented but apparently used to announce address book changes. */ - if( num_parts >= 2 ) - handler->msglen = atoi( cmd[1] ); - } - else if( strcmp( cmd[0], "UBM" ) == 0 ) - { - if( num_parts >= 7 ) - handler->msglen = atoi( cmd[6] ); - } - else if( strcmp( cmd[0], "QNG" ) == 0 ) - { + if (num_parts >= 2) { + handler->msglen = atoi(cmd[1]); + } + } else if (strcmp(cmd[0], "UBM") == 0) { + if (num_parts >= 7) { + handler->msglen = atoi(cmd[6]); + } + } else if (strcmp(cmd[0], "QNG") == 0) { ic->flags |= OPT_PONGED; - } - else if( g_ascii_isdigit( cmd[0][0] ) ) - { - int num = atoi( cmd[0] ); - const struct msn_status_code *err = msn_status_by_number( num ); - - imcb_error( ic, "Error reported by MSN server: %s", err->text ); - - if( err->flags & STATUS_FATAL ) - { - imc_logout( ic, TRUE ); - return( 0 ); + } else if (g_ascii_isdigit(cmd[0][0])) { + int num = atoi(cmd[0]); + const struct msn_status_code *err = msn_status_by_number(num); + + imcb_error(ic, "Error reported by MSN server: %s", err->text); + + if (err->flags & STATUS_FATAL) { + imc_logout(ic, TRUE); + return(0); } - + /* Oh yes, errors can have payloads too now. Discard them for now. */ - if( num_parts >= 3 ) - handler->msglen = atoi( cmd[2] ); - } - else - { + if (num_parts >= 3) { + handler->msglen = atoi(cmd[2]); + } + } else { /* debug( "Received unknown command from main server: %s", cmd[0] ); */ } - - return( 1 ); + + return(1); } -static int msn_ns_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts ) +static int msn_ns_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts) { struct im_connection *ic = handler->data; char *body; int blen = 0; - - if( !num_parts ) - return( 1 ); - - if( ( body = strstr( msg, "\r\n\r\n" ) ) ) - { + + if (!num_parts) { + return(1); + } + + if ((body = strstr(msg, "\r\n\r\n"))) { body += 4; - blen = msglen - ( body - msg ); + blen = msglen - (body - msg); } - - if( strcmp( cmd[0], "MSG" ) == 0 ) - { - if( g_strcasecmp( cmd[1], "Hotmail" ) == 0 ) - { - char *ct = get_rfc822_header( msg, "Content-Type:", msglen ); - - if( !ct ) - return( 1 ); - - if( g_strncasecmp( ct, "application/x-msmsgssystemmessage", 33 ) == 0 ) - { + + if (strcmp(cmd[0], "MSG") == 0) { + if (g_strcasecmp(cmd[1], "Hotmail") == 0) { + char *ct = get_rfc822_header(msg, "Content-Type:", msglen); + + if (!ct) { + return(1); + } + + if (g_strncasecmp(ct, "application/x-msmsgssystemmessage", 33) == 0) { char *mtype; char *arg1; - - if( !body ) - return( 1 ); - - mtype = get_rfc822_header( body, "Type:", blen ); - arg1 = get_rfc822_header( body, "Arg1:", blen ); - - if( mtype && strcmp( mtype, "1" ) == 0 ) - { - if( arg1 ) - imcb_log( ic, "The server is going down for maintenance in %s minutes.", arg1 ); + + if (!body) { + return(1); } - - g_free( arg1 ); - g_free( mtype ); - } - else if( g_strncasecmp( ct, "text/x-msmsgsprofile", 20 ) == 0 ) - { + + mtype = get_rfc822_header(body, "Type:", blen); + arg1 = get_rfc822_header(body, "Arg1:", blen); + + if (mtype && strcmp(mtype, "1") == 0) { + if (arg1) { + imcb_log(ic, "The server is going down for maintenance in %s minutes.", + arg1); + } + } + + g_free(arg1); + g_free(mtype); + } else if (g_strncasecmp(ct, "text/x-msmsgsprofile", 20) == 0) { /* We don't care about this profile for now... */ - } - else if( g_strncasecmp( ct, "text/x-msmsgsinitialemailnotification", 37 ) == 0 ) - { - if( set_getbool( &ic->acc->set, "mail_notifications" ) ) - { - char *inbox = get_rfc822_header( body, "Inbox-Unread:", blen ); - char *folders = get_rfc822_header( body, "Folders-Unread:", blen ); - - if( inbox && folders ) - imcb_log( ic, "INBOX contains %s new messages, plus %s messages in other folders.", inbox, folders ); - - g_free( inbox ); - g_free( folders ); + } else if (g_strncasecmp(ct, "text/x-msmsgsinitialemailnotification", 37) == 0) { + if (set_getbool(&ic->acc->set, "mail_notifications")) { + char *inbox = get_rfc822_header(body, "Inbox-Unread:", blen); + char *folders = get_rfc822_header(body, "Folders-Unread:", blen); + + if (inbox && folders) { + imcb_log(ic, + "INBOX contains %s new messages, plus %s messages in other folders.", inbox, + folders); + } + + g_free(inbox); + g_free(folders); } - } - else if( g_strncasecmp( ct, "text/x-msmsgsemailnotification", 30 ) == 0 ) - { - if( set_getbool( &ic->acc->set, "mail_notifications" ) ) - { - char *from = get_rfc822_header( body, "From-Addr:", blen ); - char *fromname = get_rfc822_header( body, "From:", blen ); - - if( from && fromname ) - imcb_log( ic, "Received an e-mail message from %s <%s>.", fromname, from ); - - g_free( from ); - g_free( fromname ); + } else if (g_strncasecmp(ct, "text/x-msmsgsemailnotification", 30) == 0) { + if (set_getbool(&ic->acc->set, "mail_notifications")) { + char *from = get_rfc822_header(body, "From-Addr:", blen); + char *fromname = get_rfc822_header(body, "From:", blen); + + if (from && fromname) { + imcb_log(ic, "Received an e-mail message from %s <%s>.", fromname, + from); + } + + g_free(from); + g_free(fromname); } - } - else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 ) - { - } - else if( g_strncasecmp( ct, "text/x-msmsgsinitialmdatanotification", 37 ) == 0 || - g_strncasecmp( ct, "text/x-msmsgsoimnotification", 28 ) == 0 ) - { + } else if (g_strncasecmp(ct, "text/x-msmsgsactivemailnotification", 35) == 0) { + } else if (g_strncasecmp(ct, "text/x-msmsgsinitialmdatanotification", 37) == 0 || + g_strncasecmp(ct, "text/x-msmsgsoimnotification", 28) == 0) { /* We received an offline message. Or at least notification that there is one waiting for us. Fetching the message(s) and purging them from the server is a lot of SOAPy work not worth doing IMHO. Also I thought it was possible to have the notification server send them directly, I was pretty sure I saw Pidgin do it.. - + At least give a notification for now, seems like a reasonable thing to do. Only problem is, they'll keep coming back at login time until you read them using a different client. :-( */ - - char *xml = get_rfc822_header( body, "Mail-Data:", blen ); + + char *xml = get_rfc822_header(body, "Mail-Data:", blen); struct xt_node *md, *m; - - if( !xml ) + + if (!xml) { return 1; - md = xt_from_string( xml, 0 ); - if( !md ) + } + md = xt_from_string(xml, 0); + if (!md) { return 1; - - for( m = md->children; ( m = xt_find_node( m, "M" ) ); m = m->next ) - { - struct xt_node *e = xt_find_node( m->children, "E" ); - struct xt_node *rt = xt_find_node( m->children, "RT" ); + } + + for (m = md->children; (m = xt_find_node(m, "M")); m = m->next) { + struct xt_node *e = xt_find_node(m->children, "E"); + struct xt_node *rt = xt_find_node(m->children, "RT"); struct tm tp; time_t msgtime = 0; - - if( !e || !e->text ) + + if (!e || !e->text) { continue; - - memset( &tp, 0, sizeof( tp ) ); - if( rt && rt->text && - sscanf( rt->text, "%4d-%2d-%2dT%2d:%2d:%2d.", - &tp.tm_year, &tp.tm_mon, &tp.tm_mday, - &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) == 6 ) - { + } + + memset(&tp, 0, sizeof(tp)); + if (rt && rt->text && + sscanf(rt->text, "%4d-%2d-%2dT%2d:%2d:%2d.", + &tp.tm_year, &tp.tm_mon, &tp.tm_mday, + &tp.tm_hour, &tp.tm_min, &tp.tm_sec) == 6) { tp.tm_year -= 1900; - tp.tm_mon --; - msgtime = mktime_utc( &tp ); - + tp.tm_mon--; + msgtime = mktime_utc(&tp); + } - imcb_buddy_msg( ic, e->text, "<< \002BitlBee\002 - Received offline message. BitlBee can't show these. >>", 0, msgtime ); + imcb_buddy_msg(ic, e->text, + "<< \002BitlBee\002 - Received offline message. BitlBee can't show these. >>", 0, + msgtime); } - - g_free( xml ); - xt_free_node( md ); - } - else - { - debug( "Can't handle %s packet from notification server", ct ); + + g_free(xml); + xt_free_node(md); + } else { + debug("Can't handle %s packet from notification server", ct); } - - g_free( ct ); + + g_free(ct); } - } - else if( strcmp( cmd[0], "UBX" ) == 0 ) - { + } else if (strcmp(cmd[0], "UBX") == 0) { struct xt_node *ubx, *psm; char *psm_text = NULL; - - ubx = xt_from_string( msg, msglen ); - if( ubx && strcmp( ubx->name, "Data" ) == 0 && - ( psm = xt_find_node( ubx->children, "PSM" ) ) ) + + ubx = xt_from_string(msg, msglen); + if (ubx && strcmp(ubx->name, "Data") == 0 && + (psm = xt_find_node(ubx->children, "PSM"))) { psm_text = psm->text; - - imcb_buddy_status_msg( ic, msn_normalize_handle( cmd[1] ), psm_text ); - xt_free_node( ubx ); - } - else if( strcmp( cmd[0], "ADL" ) == 0 ) - { + } + + imcb_buddy_status_msg(ic, msn_normalize_handle(cmd[1]), psm_text); + xt_free_node(ubx); + } else if (strcmp(cmd[0], "ADL") == 0) { struct xt_node *adl, *d, *c; - - if( !( adl = xt_from_string( msg, msglen ) ) ) + + if (!(adl = xt_from_string(msg, msglen))) { return 1; - - for( d = adl->children; d; d = d->next ) - { + } + + for (d = adl->children; d; d = d->next) { char *dn; - if( strcmp( d->name, "d" ) != 0 || - ( dn = xt_find_attr( d, "n" ) ) == NULL ) + if (strcmp(d->name, "d") != 0 || + (dn = xt_find_attr(d, "n")) == NULL) { continue; - for( c = d->children; c; c = c->next ) - { + } + for (c = d->children; c; c = c->next) { bee_user_t *bu; struct msn_buddy_data *bd; char *cn, *handle, *f, *l; int flags; - - if( strcmp( c->name, "c" ) != 0 || - ( l = xt_find_attr( c, "l" ) ) == NULL || - ( cn = xt_find_attr( c, "n" ) ) == NULL ) + + if (strcmp(c->name, "c") != 0 || + (l = xt_find_attr(c, "l")) == NULL || + (cn = xt_find_attr(c, "n")) == NULL) { continue; - + } + /* FIXME: Use "t" here, guess I should just add it as a prefix like elsewhere in the protocol. */ - handle = g_strdup_printf( "%s@%s", cn, dn ); - if( !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) || - ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) ) - { - g_free( handle ); + handle = g_strdup_printf("%s@%s", cn, dn); + if (!((bu = bee_user_by_handle(ic->bee, ic, handle)) || + (bu = bee_user_new(ic->bee, ic, handle, 0)))) { + g_free(handle); continue; } - g_free( handle ); + g_free(handle); bd = bu->data; - - if( ( f = xt_find_attr( c, "f" ) ) ) - { - http_decode( f ); - imcb_rename_buddy( ic, bu->handle, f ); + + if ((f = xt_find_attr(c, "f"))) { + http_decode(f); + imcb_rename_buddy(ic, bu->handle, f); } - - flags = atoi( l ) & 15; - if( bd->flags != flags ) - { + + flags = atoi(l) & 15; + if (bd->flags != flags) { bd->flags = flags; - msn_buddy_ask( bu ); + msn_buddy_ask(bu); } } } - } - else if( strcmp( cmd[0], "UBM" ) == 0 ) - { + } else if (strcmp(cmd[0], "UBM") == 0) { /* This one will give us msgs from federated networks. Technically it should also get us offline messages, but I don't know how I can signal MSN servers to use it. */ char *ct, *handle; - - if( strcmp( cmd[1], ic->acc->user ) == 0 ) - { + + if (strcmp(cmd[1], ic->acc->user) == 0) { /* With MPOP, you'll get copies of your own msgs from other sessions. Discard those at least for now. */ return 1; } - - ct = get_rfc822_header( msg, "Content-Type", msglen ); - if( strncmp( ct, "text/plain", 10 ) != 0 ) - { + + ct = get_rfc822_header(msg, "Content-Type", msglen); + if (strncmp(ct, "text/plain", 10) != 0) { /* Typing notification or something? */ - g_free( ct ); + g_free(ct); return 1; } - if( strcmp( cmd[2], "1" ) != 0 ) - handle = g_strdup_printf( "%s:%s", cmd[2], cmd[1] ); - else - handle = g_strdup( cmd[1] ); - - imcb_buddy_msg( ic, handle, body, 0, 0 ); - g_free( handle ); + if (strcmp(cmd[2], "1") != 0) { + handle = g_strdup_printf("%s:%s", cmd[2], cmd[1]); + } else { + handle = g_strdup(cmd[1]); + } + + imcb_buddy_msg(ic, handle, body, 0, 0); + g_free(handle); } - + return 1; } -void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error ) +void msn_auth_got_passport_token(struct im_connection *ic, const char *token, const char *error) { struct msn_data *md; - + /* Dead connection? */ - if( g_slist_find( msn_connections, ic ) == NULL ) + if (g_slist_find(msn_connections, ic) == NULL) { return; - - md = ic->proto_data; - - if( token ) - { - msn_ns_write( ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid ); } - else - { - imcb_error( ic, "Error during Passport authentication: %s", error ); - imc_logout( ic, TRUE ); + + md = ic->proto_data; + + if (token) { + msn_ns_write(ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid); + } else { + imcb_error(ic, "Error during Passport authentication: %s", error); + imc_logout(ic, TRUE); } } -void msn_auth_got_contact_list( struct im_connection *ic ) +void msn_auth_got_contact_list(struct im_connection *ic) { struct msn_data *md; - + /* Dead connection? */ - if( g_slist_find( msn_connections, ic ) == NULL ) + if (g_slist_find(msn_connections, ic) == NULL) { return; - + } + md = ic->proto_data; - msn_ns_write( ic, -1, "BLP %d %s\r\n", ++md->trId, "BL" ); + msn_ns_write(ic, -1, "BLP %d %s\r\n", ++md->trId, "BL"); } -static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data ) +static gboolean msn_ns_send_adl_1(gpointer key, gpointer value, gpointer data) { struct xt_node *adl = data, *d, *c; struct bee_user *bu = value; @@ -883,159 +787,166 @@ static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data ) char handle[strlen(bu->handle) + 1]; char *domain; char l[4]; - - if( ( bd->flags & 7 ) == 0 || ( bd->flags & MSN_BUDDY_ADL_SYNCED ) ) + + if ((bd->flags & 7) == 0 || (bd->flags & MSN_BUDDY_ADL_SYNCED)) { + return FALSE; + } + + strcpy(handle, bu->handle); + if ((domain = strchr(handle, '@')) == NULL) { /* WTF */ return FALSE; - - strcpy( handle, bu->handle ); - if( ( domain = strchr( handle, '@' ) ) == NULL ) /* WTF */ - return FALSE; + } *domain = '\0'; - domain ++; - - if( ( d = adl->children ) == NULL || - g_strcasecmp( xt_find_attr( d, "n" ), domain ) != 0 ) - { - d = xt_new_node( "d", NULL, NULL ); - xt_add_attr( d, "n", domain ); - xt_insert_child( adl, d ); + domain++; + + if ((d = adl->children) == NULL || + g_strcasecmp(xt_find_attr(d, "n"), domain) != 0) { + d = xt_new_node("d", NULL, NULL); + xt_add_attr(d, "n", domain); + xt_insert_child(adl, d); } - - g_snprintf( l, sizeof( l ), "%d", bd->flags & 7 ); - c = xt_new_node( "c", NULL, NULL ); - xt_add_attr( c, "n", handle ); - xt_add_attr( c, "l", l ); - xt_add_attr( c, "t", "1" ); /* FIXME: Network type, i.e. 32 for Y!MSG */ - xt_insert_child( d, c ); - + + g_snprintf(l, sizeof(l), "%d", bd->flags & 7); + c = xt_new_node("c", NULL, NULL); + xt_add_attr(c, "n", handle); + xt_add_attr(c, "l", l); + xt_add_attr(c, "t", "1"); /* FIXME: Network type, i.e. 32 for Y!MSG */ + xt_insert_child(d, c); + /* Do this in batches of 100. */ bd->flags |= MSN_BUDDY_ADL_SYNCED; return (--md->adl_todo % 140) == 0; } -static void msn_ns_send_adl( struct im_connection *ic ) +static void msn_ns_send_adl(struct im_connection *ic) { struct xt_node *adl; struct msn_data *md = ic->proto_data; char *adls; - - adl = xt_new_node( "ml", NULL, NULL ); - xt_add_attr( adl, "l", "1" ); - g_tree_foreach( md->domaintree, msn_ns_send_adl_1, adl ); - if( adl->children == NULL ) - { + + adl = xt_new_node("ml", NULL, NULL); + xt_add_attr(adl, "l", "1"); + g_tree_foreach(md->domaintree, msn_ns_send_adl_1, adl); + if (adl->children == NULL) { /* This tells the caller that we're done now. */ md->adl_todo = -1; - xt_free_node( adl ); + xt_free_node(adl); return; } - - adls = xt_to_string( adl ); - xt_free_node( adl ); - msn_ns_write( ic, -1, "ADL %d %zd\r\n%s", ++md->trId, strlen( adls ), adls ); - g_free( adls ); + + adls = xt_to_string(adl); + xt_free_node(adl); + msn_ns_write(ic, -1, "ADL %d %zd\r\n%s", ++md->trId, strlen(adls), adls); + g_free(adls); } -static void msn_ns_send_adl_start( struct im_connection *ic ) +static void msn_ns_send_adl_start(struct im_connection *ic) { struct msn_data *md; GSList *l; - + /* Dead connection? */ - if( g_slist_find( msn_connections, ic ) == NULL ) + if (g_slist_find(msn_connections, ic) == NULL) { return; - + } + md = ic->proto_data; md->adl_todo = 0; - for( l = ic->bee->users; l; l = l->next ) - { + for (l = ic->bee->users; l; l = l->next) { bee_user_t *bu = l->data; struct msn_buddy_data *bd = bu->data; - - if( bu->ic != ic || ( bd->flags & 7 ) == 0 ) + + if (bu->ic != ic || (bd->flags & 7) == 0) { continue; - + } + bd->flags &= ~MSN_BUDDY_ADL_SYNCED; md->adl_todo++; } - - msn_ns_send_adl( ic ); + + msn_ns_send_adl(ic); } -int msn_ns_finish_login( struct im_connection *ic ) +int msn_ns_finish_login(struct im_connection *ic) { struct msn_data *md = ic->proto_data; - - if( ic->flags & OPT_LOGGED_IN ) + + if (ic->flags & OPT_LOGGED_IN) { return 1; - - if( md->adl_todo < 0 ) + } + + if (md->adl_todo < 0) { md->flags |= MSN_DONE_ADL; - - if( ( md->flags & MSN_DONE_ADL ) && ( md->flags & MSN_GOT_PROFILE ) ) - { - if( md->flags & MSN_EMAIL_UNVERIFIED ) - imcb_connected( ic ); - else - return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) ); } - + + if ((md->flags & MSN_DONE_ADL) && (md->flags & MSN_GOT_PROFILE)) { + if (md->flags & MSN_EMAIL_UNVERIFIED) { + imcb_connected(ic); + } else { + return msn_ns_set_display_name(ic, set_getstr(&ic->acc->set, "display_name")); + } + } + return 1; } -int msn_ns_sendmessage( struct im_connection *ic, bee_user_t *bu, const char *text ) +int msn_ns_sendmessage(struct im_connection *ic, bee_user_t *bu, const char *text) { struct msn_data *md = ic->proto_data; int type = 0; char *buf, *handle; - - if( strncmp( text, "\r\r\r", 3 ) == 0 ) + + if (strncmp(text, "\r\r\r", 3) == 0) { /* Err. Shouldn't happen but I guess it can. Don't send others any of the "SHAKE THAT THING" messages. :-D */ return 1; - + } + /* This might be a federated contact. Get its network number, prefixed to bu->handle with a colon. Default is 1. */ - for( handle = bu->handle; g_ascii_isdigit( *handle ); handle ++ ) + for (handle = bu->handle; g_ascii_isdigit(*handle); handle++) { type = type * 10 + *handle - '0'; - if( *handle == ':' ) - handle ++; - else + } + if (*handle == ':') { + handle++; + } else { type = 1; - - buf = g_strdup_printf( "%s%s", MSN_MESSAGE_HEADERS, text ); - - if( msn_ns_write( ic, -1, "UUM %d %s %d %d %zd\r\n%s", - ++md->trId, handle, type, - 1, /* type == IM (not nudge/typing) */ - strlen( buf ), buf ) ) + } + + buf = g_strdup_printf("%s%s", MSN_MESSAGE_HEADERS, text); + + if (msn_ns_write(ic, -1, "UUM %d %s %d %d %zd\r\n%s", + ++md->trId, handle, type, + 1, /* type == IM (not nudge/typing) */ + strlen(buf), buf)) { return 1; - else + } else { return 0; + } } -void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq ) +void msn_ns_oim_send_queue(struct im_connection *ic, GSList **msgq) { GSList *l; - - for( l = *msgq; l; l = l->next ) - { + + for (l = *msgq; l; l = l->next) { struct msn_message *m = l->data; - bee_user_t *bu = bee_user_by_handle( ic->bee, ic, m->who ); - - if( bu ) - if( !msn_ns_sendmessage( ic, bu, m->text ) ) + bee_user_t *bu = bee_user_by_handle(ic->bee, ic, m->who); + + if (bu) { + if (!msn_ns_sendmessage(ic, bu, m->text)) { return; + } + } } - - while( *msgq != NULL ) - { + + while (*msgq != NULL) { struct msn_message *m = (*msgq)->data; - - g_free( m->who ); - g_free( m->text ); - g_free( m ); - - *msgq = g_slist_remove( *msgq, m ); + + g_free(m->who); + g_free(m->text); + g_free(m); + + *msgq = g_slist_remove(*msgq, m); } } diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index 40e4e00d..d0412961 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -30,336 +30,328 @@ #include "soap.h" #include "invitation.h" -static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond ); -static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts ); -static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts ); +static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond); +static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts); +static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts); -int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... ) +int msn_sb_write(struct msn_switchboard *sb, const char *fmt, ...) { va_list params; char *out; size_t len; int st; - - va_start( params, fmt ); - out = g_strdup_vprintf( fmt, params ); - va_end( params ); - - if( getenv( "BITLBEE_DEBUG" ) ) - fprintf( stderr, "->SB%d:%s\n", sb->fd, out ); - - len = strlen( out ); - st = write( sb->fd, out, len ); - g_free( out ); - if( st != len ) - { - msn_sb_destroy( sb ); + + va_start(params, fmt); + out = g_strdup_vprintf(fmt, params); + va_end(params); + + if (getenv("BITLBEE_DEBUG")) { + fprintf(stderr, "->SB%d:%s\n", sb->fd, out); + } + + len = strlen(out); + st = write(sb->fd, out, len); + g_free(out); + if (st != len) { + msn_sb_destroy(sb); return 0; } - + return 1; } -int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ) +int msn_sb_write_msg(struct im_connection *ic, struct msn_message *m) { struct msn_data *md = ic->proto_data; struct msn_switchboard *sb; /* FIXME: *CHECK* the reliability of using spare sb's! */ - if( ( sb = msn_sb_spare( ic ) ) ) - { - debug( "Trying to use a spare switchboard to message %s", m->who ); - - sb->who = g_strdup( m->who ); - if( msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, m->who ) ) - { + if ((sb = msn_sb_spare(ic))) { + debug("Trying to use a spare switchboard to message %s", m->who); + + sb->who = g_strdup(m->who); + if (msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, m->who)) { /* He/She should join the switchboard soon, let's queue the message. */ - sb->msgq = g_slist_append( sb->msgq, m ); - return( 1 ); + sb->msgq = g_slist_append(sb->msgq, m); + return(1); } } - - debug( "Creating a new switchboard to message %s", m->who ); - + + debug("Creating a new switchboard to message %s", m->who); + /* If we reach this line, there was no spare switchboard, so let's make one. */ - if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) ) - { - g_free( m->who ); - g_free( m->text ); - g_free( m ); - - return( 0 ); + if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) { + g_free(m->who); + g_free(m->text); + g_free(m); + + return(0); } - + /* And queue the message to md. We'll pick it up when the switchboard comes up. */ - md->msgq = g_slist_append( md->msgq, m ); - + md->msgq = g_slist_append(md->msgq, m); + /* FIXME: If the switchboard creation fails, the message will not be sent. */ - - return( 1 ); + + return(1); } -struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session ) +struct msn_switchboard *msn_sb_create(struct im_connection *ic, char *host, int port, char *key, int session) { struct msn_data *md = ic->proto_data; - struct msn_switchboard *sb = g_new0( struct msn_switchboard, 1 ); - - sb->fd = proxy_connect( host, port, msn_sb_connected, sb ); - if( sb->fd < 0 ) - { - g_free( sb ); - return( NULL ); + struct msn_switchboard *sb = g_new0(struct msn_switchboard, 1); + + sb->fd = proxy_connect(host, port, msn_sb_connected, sb); + if (sb->fd < 0) { + g_free(sb); + return(NULL); } - + sb->ic = ic; - sb->key = g_strdup( key ); + sb->key = g_strdup(key); sb->session = session; - - msn_switchboards = g_slist_append( msn_switchboards, sb ); - md->switchboards = g_slist_append( md->switchboards, sb ); - - return( sb ); + + msn_switchboards = g_slist_append(msn_switchboards, sb); + md->switchboards = g_slist_append(md->switchboards, sb); + + return(sb); } -struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle ) +struct msn_switchboard *msn_sb_by_handle(struct im_connection *ic, const char *handle) { struct msn_data *md = ic->proto_data; struct msn_switchboard *sb; GSList *l; - - for( l = md->switchboards; l; l = l->next ) - { + + for (l = md->switchboards; l; l = l->next) { sb = l->data; - if( sb->who && strcmp( sb->who, handle ) == 0 ) - return( sb ); + if (sb->who && strcmp(sb->who, handle) == 0) { + return(sb); + } } - - return( NULL ); + + return(NULL); } -struct msn_switchboard *msn_sb_by_chat( struct groupchat *c ) +struct msn_switchboard *msn_sb_by_chat(struct groupchat *c) { struct msn_data *md = c->ic->proto_data; struct msn_switchboard *sb; GSList *l; - - for( l = md->switchboards; l; l = l->next ) - { + + for (l = md->switchboards; l; l = l->next) { sb = l->data; - if( sb->chat == c ) - return( sb ); + if (sb->chat == c) { + return(sb); + } } - - return( NULL ); + + return(NULL); } -struct msn_switchboard *msn_sb_spare( struct im_connection *ic ) +struct msn_switchboard *msn_sb_spare(struct im_connection *ic) { struct msn_data *md = ic->proto_data; struct msn_switchboard *sb; GSList *l; - - for( l = md->switchboards; l; l = l->next ) - { + + for (l = md->switchboards; l; l = l->next) { sb = l->data; - if( !sb->who && !sb->chat ) - return( sb ); + if (!sb->who && !sb->chat) { + return(sb); + } } - - return( NULL ); + + return(NULL); } -int msn_sb_sendmessage( struct msn_switchboard *sb, char *text ) +int msn_sb_sendmessage(struct msn_switchboard *sb, char *text) { - if( sb->ready ) - { + if (sb->ready) { char *buf; int i, j; - + /* Build the message. Convert LF to CR-LF for normal messages. */ - if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) == 0 ) - { - i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user ); - buf = g_new0( char, i ); - i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user ); - } - else if( strcmp( text, NUDGE_MESSAGE ) == 0 ) - { - buf = g_strdup( MSN_NUDGE_HEADERS ); - i = strlen( buf ); - } - else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 ) - { - buf = g_strdup( MSN_SB_KEEPALIVE_HEADERS ); - i = strlen( buf ); - } - else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 ) - { - buf = g_strdup( text ); - i = strlen( buf ); - } - else - { - buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 ); - i = strlen( MSN_MESSAGE_HEADERS ); - - strcpy( buf, MSN_MESSAGE_HEADERS ); - for( j = 0; text[j]; j ++ ) - { - if( text[j] == '\n' ) + if (strcmp(text, TYPING_NOTIFICATION_MESSAGE) == 0) { + i = strlen(MSN_TYPING_HEADERS) + strlen(sb->ic->acc->user); + buf = g_new0(char, i); + i = g_snprintf(buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user); + } else if (strcmp(text, NUDGE_MESSAGE) == 0) { + buf = g_strdup(MSN_NUDGE_HEADERS); + i = strlen(buf); + } else if (strcmp(text, SB_KEEPALIVE_MESSAGE) == 0) { + buf = g_strdup(MSN_SB_KEEPALIVE_HEADERS); + i = strlen(buf); + } else if (strncmp(text, MSN_INVITE_HEADERS, sizeof(MSN_INVITE_HEADERS) - 1) == 0) { + buf = g_strdup(text); + i = strlen(buf); + } else { + buf = g_new0(char, sizeof(MSN_MESSAGE_HEADERS) + strlen(text) * 2 + 1); + i = strlen(MSN_MESSAGE_HEADERS); + + strcpy(buf, MSN_MESSAGE_HEADERS); + for (j = 0; text[j]; j++) { + if (text[j] == '\n') { buf[i++] = '\r'; - + } + buf[i++] = text[j]; } } - + /* Build the final packet (MSG command + the message). */ - if( msn_sb_write( sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf ) ) - { - g_free( buf ); + if (msn_sb_write(sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf)) { + g_free(buf); return 1; - } - else - { - g_free( buf ); + } else { + g_free(buf); return 0; } - } - else if( sb->who ) - { - struct msn_message *m = g_new0( struct msn_message, 1 ); - - m->who = g_strdup( "" ); - m->text = g_strdup( text ); - sb->msgq = g_slist_append( sb->msgq, m ); - - return( 1 ); - } - else - { - return( 0 ); + } else if (sb->who) { + struct msn_message *m = g_new0(struct msn_message, 1); + + m->who = g_strdup(""); + m->text = g_strdup(text); + sb->msgq = g_slist_append(sb->msgq, m); + + return(1); + } else { + return(0); } } -struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb ) +struct groupchat *msn_sb_to_chat(struct msn_switchboard *sb) { struct im_connection *ic = sb->ic; struct groupchat *c = NULL; char buf[1024]; - + /* Create the groupchat structure. */ - g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session ); - if( sb->who ) - c = bee_chat_by_title( ic->bee, ic, sb->who ); - if( c && !msn_sb_by_chat( c ) ) + g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session); + if (sb->who) { + c = bee_chat_by_title(ic->bee, ic, sb->who); + } + if (c && !msn_sb_by_chat(c)) { sb->chat = c; - else - sb->chat = imcb_chat_new( ic, buf ); - + } else { + sb->chat = imcb_chat_new(ic, buf); + } + /* Populate the channel. */ - if( sb->who ) imcb_chat_add_buddy( sb->chat, sb->who ); - imcb_chat_add_buddy( sb->chat, ic->acc->user ); - + if (sb->who) { + imcb_chat_add_buddy(sb->chat, sb->who); + } + imcb_chat_add_buddy(sb->chat, ic->acc->user); + /* And make sure the switchboard doesn't look like a regular chat anymore. */ - if( sb->who ) - { - g_free( sb->who ); + if (sb->who) { + g_free(sb->who); sb->who = NULL; } - + return sb->chat; } -void msn_sb_destroy( struct msn_switchboard *sb ) +void msn_sb_destroy(struct msn_switchboard *sb) { struct im_connection *ic = sb->ic; struct msn_data *md = ic->proto_data; - - debug( "Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "" ); - - msn_msgq_purge( ic, &sb->msgq ); - msn_sb_stop_keepalives( sb ); - - if( sb->key ) g_free( sb->key ); - if( sb->who ) g_free( sb->who ); - - if( sb->chat ) - { - imcb_chat_free( sb->chat ); + + debug("Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : ""); + + msn_msgq_purge(ic, &sb->msgq); + msn_sb_stop_keepalives(sb); + + if (sb->key) { + g_free(sb->key); + } + if (sb->who) { + g_free(sb->who); } - - if( sb->handler ) - { - if( sb->handler->rxq ) g_free( sb->handler->rxq ); - if( sb->handler->cmd_text ) g_free( sb->handler->cmd_text ); - g_free( sb->handler ); + + if (sb->chat) { + imcb_chat_free(sb->chat); } - - if( sb->inp ) b_event_remove( sb->inp ); - closesocket( sb->fd ); - - msn_switchboards = g_slist_remove( msn_switchboards, sb ); - md->switchboards = g_slist_remove( md->switchboards, sb ); - g_free( sb ); + + if (sb->handler) { + if (sb->handler->rxq) { + g_free(sb->handler->rxq); + } + if (sb->handler->cmd_text) { + g_free(sb->handler->cmd_text); + } + g_free(sb->handler); + } + + if (sb->inp) { + b_event_remove(sb->inp); + } + closesocket(sb->fd); + + msn_switchboards = g_slist_remove(msn_switchboards, sb); + md->switchboards = g_slist_remove(md->switchboards, sb); + g_free(sb); } -gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ) +gboolean msn_sb_connected(gpointer data, gint source, b_input_condition cond) { struct msn_switchboard *sb = data; struct im_connection *ic; struct msn_data *md; char buf[1024]; - + /* Are we still alive? */ - if( !g_slist_find( msn_switchboards, sb ) ) + if (!g_slist_find(msn_switchboards, sb)) { return FALSE; - + } + ic = sb->ic; md = ic->proto_data; - - if( source != sb->fd ) - { - debug( "Error %d while connecting to switchboard server", 1 ); - msn_sb_destroy( sb ); + + if (source != sb->fd) { + debug("Error %d while connecting to switchboard server", 1); + msn_sb_destroy(sb); return FALSE; } - + /* Prepare the callback */ - sb->handler = g_new0( struct msn_handler_data, 1 ); + sb->handler = g_new0(struct msn_handler_data, 1); sb->handler->fd = sb->fd; - sb->handler->rxq = g_new0( char, 1 ); + sb->handler->rxq = g_new0(char, 1); sb->handler->data = sb; sb->handler->exec_command = msn_sb_command; sb->handler->exec_message = msn_sb_message; - - if( sb->session == MSN_SB_NEW ) - g_snprintf( buf, sizeof( buf ), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key ); - else - g_snprintf( buf, sizeof( buf ), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key, sb->session ); - - if( msn_sb_write( sb, "%s", buf ) ) - sb->inp = b_input_add( sb->fd, B_EV_IO_READ, msn_sb_callback, sb ); - else - debug( "Error %d while connecting to switchboard server", 2 ); - + + if (sb->session == MSN_SB_NEW) { + g_snprintf(buf, sizeof(buf), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key); + } else { + g_snprintf(buf, sizeof(buf), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key, + sb->session); + } + + if (msn_sb_write(sb, "%s", buf)) { + sb->inp = b_input_add(sb->fd, B_EV_IO_READ, msn_sb_callback, sb); + } else { + debug("Error %d while connecting to switchboard server", 2); + } + return FALSE; } -static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond ) +static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond) { struct msn_switchboard *sb = data; struct im_connection *ic = sb->ic; struct msn_data *md = ic->proto_data; - - if( msn_handler( sb->handler ) != -1 ) + + if (msn_handler(sb->handler) != -1) { return TRUE; - - if( sb->msgq != NULL ) - { - time_t now = time( NULL ); - - if( now - md->first_sb_failure > 600 ) - { + } + + if (sb->msgq != NULL) { + time_t now = time(NULL); + + if (now - md->first_sb_failure > 600) { /* It's not really the first one, but the start of this "series". With this, the warning below will be shown only if this happens at least three times in ten minutes. This algorithm isn't @@ -367,457 +359,393 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c md->first_sb_failure = now; md->sb_failures = 0; } - - debug( "Error: Switchboard died" ); - if( ++ md->sb_failures >= 3 ) - imcb_log( ic, "Warning: Many switchboard failures on MSN connection. " - "There might be problems delivering your messages." ); - - if( md->msgq == NULL ) - { - md->msgq = sb->msgq; + + debug("Error: Switchboard died"); + if (++md->sb_failures >= 3) { + imcb_log(ic, "Warning: Many switchboard failures on MSN connection. " + "There might be problems delivering your messages."); } - else - { + + if (md->msgq == NULL) { + md->msgq = sb->msgq; + } else { GSList *l; - - for( l = md->msgq; l->next; l = l->next ); + + for (l = md->msgq; l->next; l = l->next) { + ; + } l->next = sb->msgq; } sb->msgq = NULL; - - debug( "Moved queued messages back to the main queue, " - "creating a new switchboard to retry." ); - if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) ) + + debug("Moved queued messages back to the main queue, " + "creating a new switchboard to retry."); + if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) { return FALSE; + } } - - msn_sb_destroy( sb ); + + msn_sb_destroy(sb); return FALSE; } -static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts ) +static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts) { struct msn_switchboard *sb = handler->data; struct im_connection *ic = sb->ic; - - if( !num_parts ) - { + + if (!num_parts) { /* Hrrm... Empty command...? Ignore? */ - return( 1 ); - } - - if( strcmp( cmd[0], "XFR" ) == 0 ) - { - imcb_error( ic, "Received an XFR from a switchboard server, unable to comply! This is likely to be a bug, please report it!" ); - imc_logout( ic, TRUE ); - return( 0 ); - } - else if( strcmp( cmd[0], "USR" ) == 0 ) - { - if( num_parts < 5 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - if( strcmp( cmd[2], "OK" ) != 0 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - if( sb->who ) - return msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, sb->who ); - else - debug( "Just created a switchboard, but I don't know what to do with it." ); + return(1); } - else if( strcmp( cmd[0], "IRO" ) == 0 ) - { + + if (strcmp(cmd[0], "XFR") == 0) { + imcb_error(ic, + "Received an XFR from a switchboard server, unable to comply! This is likely to be a bug, please report it!"); + imc_logout(ic, TRUE); + return(0); + } else if (strcmp(cmd[0], "USR") == 0) { + if (num_parts < 5) { + msn_sb_destroy(sb); + return(0); + } + + if (strcmp(cmd[2], "OK") != 0) { + msn_sb_destroy(sb); + return(0); + } + + if (sb->who) { + return msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, sb->who); + } else { + debug("Just created a switchboard, but I don't know what to do with it."); + } + } else if (strcmp(cmd[0], "IRO") == 0) { int num, tot; - - if( num_parts < 6 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - num = atoi( cmd[2] ); - tot = atoi( cmd[3] ); - - if( tot <= 0 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - else if( tot > 1 ) - { + + if (num_parts < 6) { + msn_sb_destroy(sb); + return(0); + } + + num = atoi(cmd[2]); + tot = atoi(cmd[3]); + + if (tot <= 0) { + msn_sb_destroy(sb); + return(0); + } else if (tot > 1) { char buf[1024]; - + /* For as much as I understand this MPOP stuff now, a switchboard has two (or more) roster entries per participant. One "bare JID" and one JID;UUID. Ignore the latter. */ - if( !strchr( cmd[4], ';' ) ) - { + if (!strchr(cmd[4], ';')) { /* HACK: Since even 1:1 chats now have >2 participants (ourselves included) it gets hard to tell them apart from rooms. Let's hope this is enough: */ - if( sb->chat == NULL && num != tot ) - { - g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session ); - sb->chat = imcb_chat_new( ic, buf ); - - g_free( sb->who ); + if (sb->chat == NULL && num != tot) { + g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session); + sb->chat = imcb_chat_new(ic, buf); + + g_free(sb->who); sb->who = NULL; } - - if( sb->chat ) - imcb_chat_add_buddy( sb->chat, cmd[4] ); + + if (sb->chat) { + imcb_chat_add_buddy(sb->chat, cmd[4]); + } } - + /* We have the full roster, start showing the channel to the user. */ - if( num == tot && sb->chat ) - { - imcb_chat_add_buddy( sb->chat, ic->acc->user ); + if (num == tot && sb->chat) { + imcb_chat_add_buddy(sb->chat, ic->acc->user); } } - } - else if( strcmp( cmd[0], "ANS" ) == 0 ) - { - if( num_parts < 3 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - if( strcmp( cmd[2], "OK" ) != 0 ) - { - debug( "Switchboard server sent a negative ANS reply" ); - msn_sb_destroy( sb ); - return( 0 ); - } - + } else if (strcmp(cmd[0], "ANS") == 0) { + if (num_parts < 3) { + msn_sb_destroy(sb); + return(0); + } + + if (strcmp(cmd[2], "OK") != 0) { + debug("Switchboard server sent a negative ANS reply"); + msn_sb_destroy(sb); + return(0); + } + sb->ready = 1; - - msn_sb_start_keepalives( sb, FALSE ); - } - else if( strcmp( cmd[0], "CAL" ) == 0 ) - { - if( num_parts < 4 || !g_ascii_isdigit( cmd[3][0] ) ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - sb->session = atoi( cmd[3] ); - } - else if( strcmp( cmd[0], "JOI" ) == 0 ) - { - if( num_parts < 3 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - + + msn_sb_start_keepalives(sb, FALSE); + } else if (strcmp(cmd[0], "CAL") == 0) { + if (num_parts < 4 || !g_ascii_isdigit(cmd[3][0])) { + msn_sb_destroy(sb); + return(0); + } + + sb->session = atoi(cmd[3]); + } else if (strcmp(cmd[0], "JOI") == 0) { + if (num_parts < 3) { + msn_sb_destroy(sb); + return(0); + } + /* See IRO above. Handle "bare JIDs" only. */ - if( strchr( cmd[1], ';' ) ) + if (strchr(cmd[1], ';')) { return 1; - - if( sb->who && g_strcasecmp( cmd[1], sb->who ) == 0 ) - { + } + + if (sb->who && g_strcasecmp(cmd[1], sb->who) == 0) { /* The user we wanted to talk to is finally there, let's send the queued messages then. */ struct msn_message *m; GSList *l; int st = 1; - - debug( "%s arrived in the switchboard session, now sending queued message(s)", cmd[1] ); - + + debug("%s arrived in the switchboard session, now sending queued message(s)", cmd[1]); + /* Without this, sendmessage() will put everything back on the queue... */ sb->ready = 1; - - while( ( l = sb->msgq ) ) - { + + while ((l = sb->msgq)) { m = l->data; - if( st ) - { + if (st) { /* This hack is meant to convert a regular new chat into a groupchat */ - if( strcmp( m->text, GROUPCHAT_SWITCHBOARD_MESSAGE ) == 0 ) - msn_sb_to_chat( sb ); - else - st = msn_sb_sendmessage( sb, m->text ); + if (strcmp(m->text, GROUPCHAT_SWITCHBOARD_MESSAGE) == 0) { + msn_sb_to_chat(sb); + } else { + st = msn_sb_sendmessage(sb, m->text); + } } - g_free( m->text ); - g_free( m->who ); - g_free( m ); - - sb->msgq = g_slist_remove( sb->msgq, m ); + g_free(m->text); + g_free(m->who); + g_free(m); + + sb->msgq = g_slist_remove(sb->msgq, m); } - - msn_sb_start_keepalives( sb, FALSE ); - - return( st ); - } - else if( strcmp( cmd[1], ic->acc->user ) == 0 ) - { + + msn_sb_start_keepalives(sb, FALSE); + + return(st); + } else if (strcmp(cmd[1], ic->acc->user) == 0) { /* Well, gee thanks. Thanks for letting me know I've arrived.. */ - } - else if( sb->who ) - { - debug( "Converting chat with %s to a groupchat because %s joined the session.", sb->who, cmd[1] ); - + } else if (sb->who) { + debug("Converting chat with %s to a groupchat because %s joined the session.", sb->who, cmd[1]); + /* This SB is a one-to-one chat right now, but someone else is joining. */ - msn_sb_to_chat( sb ); - - imcb_chat_add_buddy( sb->chat, cmd[1] ); - } - else if( sb->chat ) - { - imcb_chat_add_buddy( sb->chat, cmd[1] ); + msn_sb_to_chat(sb); + + imcb_chat_add_buddy(sb->chat, cmd[1]); + } else if (sb->chat) { + imcb_chat_add_buddy(sb->chat, cmd[1]); sb->ready = 1; - } - else - { + } else { /* PANIC! */ } - } - else if( strcmp( cmd[0], "MSG" ) == 0 ) - { - if( num_parts < 4 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - - sb->handler->msglen = atoi( cmd[3] ); - - if( sb->handler->msglen <= 0 ) - { - debug( "Received a corrupted message on the switchboard, the switchboard will be closed" ); - msn_sb_destroy( sb ); - return( 0 ); - } - } - else if( strcmp( cmd[0], "NAK" ) == 0 ) - { - if( sb->who ) - { - imcb_log( ic, "The MSN servers could not deliver one of your messages to %s.", sb->who ); + } else if (strcmp(cmd[0], "MSG") == 0) { + if (num_parts < 4) { + msn_sb_destroy(sb); + return(0); } - else - { - imcb_log( ic, "The MSN servers could not deliver one of your groupchat messages to all participants." ); + + sb->handler->msglen = atoi(cmd[3]); + + if (sb->handler->msglen <= 0) { + debug("Received a corrupted message on the switchboard, the switchboard will be closed"); + msn_sb_destroy(sb); + return(0); + } + } else if (strcmp(cmd[0], "NAK") == 0) { + if (sb->who) { + imcb_log(ic, "The MSN servers could not deliver one of your messages to %s.", sb->who); + } else { + imcb_log(ic, + "The MSN servers could not deliver one of your groupchat messages to all participants."); + } + } else if (strcmp(cmd[0], "BYE") == 0) { + if (num_parts < 2) { + msn_sb_destroy(sb); + return(0); } - } - else if( strcmp( cmd[0], "BYE" ) == 0 ) - { - if( num_parts < 2 ) - { - msn_sb_destroy( sb ); - return( 0 ); - } - + /* if( cmd[2] && *cmd[2] == '1' ) -=> Chat is being cleaned up because of idleness */ - - if( sb->who ) - { - msn_sb_stop_keepalives( sb ); - + + if (sb->who) { + msn_sb_stop_keepalives(sb); + /* This is a single-person chat, and the other person is leaving. */ - g_free( sb->who ); + g_free(sb->who); sb->who = NULL; sb->ready = 0; - - debug( "Person %s left the one-to-one switchboard connection. Keeping it around as a spare...", cmd[1] ); - + + debug("Person %s left the one-to-one switchboard connection. Keeping it around as a spare...", + cmd[1]); + /* We could clean up the switchboard now, but keeping it around as a spare for a next conversation sounds more sane to me. The server will clean it up when it's idle for too long. */ - } - else if( sb->chat && !strchr( cmd[1], ';' ) ) - { - imcb_chat_remove_buddy( sb->chat, cmd[1], "" ); - } - else - { + } else if (sb->chat && !strchr(cmd[1], ';')) { + imcb_chat_remove_buddy(sb->chat, cmd[1], ""); + } else { /* PANIC! */ } - } - else if( g_ascii_isdigit( cmd[0][0] ) ) - { - int num = atoi( cmd[0] ); - const struct msn_status_code *err = msn_status_by_number( num ); - + } else if (g_ascii_isdigit(cmd[0][0])) { + int num = atoi(cmd[0]); + const struct msn_status_code *err = msn_status_by_number(num); + /* If the person is offline, send an offline message instead, and don't report an error. */ - if( num == 217 ) - msn_ns_oim_send_queue( ic, &sb->msgq ); - else - imcb_error( ic, "Error reported by switchboard server: %s", err->text ); - - if( err->flags & STATUS_SB_FATAL ) - { - msn_sb_destroy( sb ); - return 0; + if (num == 217) { + msn_ns_oim_send_queue(ic, &sb->msgq); + } else { + imcb_error(ic, "Error reported by switchboard server: %s", err->text); } - else if( err->flags & STATUS_FATAL ) - { - imc_logout( ic, TRUE ); + + if (err->flags & STATUS_SB_FATAL) { + msn_sb_destroy(sb); return 0; - } - else if( err->flags & STATUS_SB_IM_SPARE ) - { - if( sb->who ) - { + } else if (err->flags & STATUS_FATAL) { + imc_logout(ic, TRUE); + return 0; + } else if (err->flags & STATUS_SB_IM_SPARE) { + if (sb->who) { /* Apparently some invitation failed. We might want to use this board later, so keep it as a spare. */ - g_free( sb->who ); + g_free(sb->who); sb->who = NULL; - + /* Also clear the msgq, otherwise someone else might get them. */ - msn_msgq_purge( ic, &sb->msgq ); + msn_msgq_purge(ic, &sb->msgq); } - + /* Do NOT return 0 here, we want to keep this sb. */ } - } - else - { + } else { /* debug( "Received unknown command from switchboard server: %s", cmd[0] ); */ } - - return( 1 ); + + return(1); } -static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts ) +static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts) { struct msn_switchboard *sb = handler->data; struct im_connection *ic = sb->ic; char *body; - - if( !num_parts ) - return( 1 ); - - if( ( body = strstr( msg, "\r\n\r\n" ) ) ) + + if (!num_parts) { + return(1); + } + + if ((body = strstr(msg, "\r\n\r\n"))) { body += 4; - - if( strcmp( cmd[0], "MSG" ) == 0 ) - { - char *ct = get_rfc822_header( msg, "Content-Type:", msglen ); - - if( !ct ) - return( 1 ); - - if( g_strncasecmp( ct, "text/plain", 10 ) == 0 ) - { - g_free( ct ); - - if( !body ) - return( 1 ); - - if( sb->who ) - { - imcb_buddy_msg( ic, cmd[1], body, 0, 0 ); - } - else if( sb->chat ) - { - imcb_chat_msg( sb->chat, cmd[1], body, 0, 0 ); + } + + if (strcmp(cmd[0], "MSG") == 0) { + char *ct = get_rfc822_header(msg, "Content-Type:", msglen); + + if (!ct) { + return(1); + } + + if (g_strncasecmp(ct, "text/plain", 10) == 0) { + g_free(ct); + + if (!body) { + return(1); } - else - { + + if (sb->who) { + imcb_buddy_msg(ic, cmd[1], body, 0, 0); + } else if (sb->chat) { + imcb_chat_msg(sb->chat, cmd[1], body, 0, 0); + } else { /* PANIC! */ } } #if 0 // Disable MSN ft support for now. - else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) - { - char *command = get_rfc822_header( body, "Invitation-Command:", blen ); - char *cookie = get_rfc822_header( body, "Invitation-Cookie:", blen ); + else if (g_strncasecmp(ct, "text/x-msmsgsinvite", 19) == 0) { + char *command = get_rfc822_header(body, "Invitation-Command:", blen); + char *cookie = get_rfc822_header(body, "Invitation-Cookie:", blen); unsigned int icookie; - - g_free( ct ); - + + g_free(ct); + /* Every invite should have both a Command and Cookie header */ - if( !command || !cookie ) { - g_free( command ); - g_free( cookie ); - imcb_log( ic, "Warning: No command or cookie from %s", sb->who ); + if (!command || !cookie) { + g_free(command); + g_free(cookie); + imcb_log(ic, "Warning: No command or cookie from %s", sb->who); return 1; } - - icookie = strtoul( cookie, NULL, 10 ); - g_free( cookie ); - - if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) { - msn_invitation_invite( sb, cmd[1], icookie, body, blen ); - } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) { - msn_invitation_accept( sb, cmd[1], icookie, body, blen ); - } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) { - msn_invitation_cancel( sb, cmd[1], icookie, body, blen ); + + icookie = strtoul(cookie, NULL, 10); + g_free(cookie); + + if (g_strncasecmp(command, "INVITE", 6) == 0) { + msn_invitation_invite(sb, cmd[1], icookie, body, blen); + } else if (g_strncasecmp(command, "ACCEPT", 6) == 0) { + msn_invitation_accept(sb, cmd[1], icookie, body, blen); + } else if (g_strncasecmp(command, "CANCEL", 6) == 0) { + msn_invitation_cancel(sb, cmd[1], icookie, body, blen); } else { - imcb_log( ic, "Warning: Received invalid invitation with " - "command %s from %s", command, sb->who ); + imcb_log(ic, "Warning: Received invalid invitation with " + "command %s from %s", command, sb->who); } - - g_free( command ); + + g_free(command); } #endif - else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) - { + else if (g_strncasecmp(ct, "application/x-msnmsgrp2p", 24) == 0) { /* Not currently implemented. Don't warn about it since this seems to be used for avatars now. */ - g_free( ct ); - } - else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 ) - { - char *who = get_rfc822_header( msg, "TypingUser:", msglen ); - - if( who ) - { - imcb_buddy_typing( ic, who, OPT_TYPING ); - g_free( who ); + g_free(ct); + } else if (g_strncasecmp(ct, "text/x-msmsgscontrol", 20) == 0) { + char *who = get_rfc822_header(msg, "TypingUser:", msglen); + + if (who) { + imcb_buddy_typing(ic, who, OPT_TYPING); + g_free(who); } - - g_free( ct ); - } - else - { - g_free( ct ); + + g_free(ct); + } else { + g_free(ct); } } - - return( 1 ); + + return(1); } -static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ) +static gboolean msn_sb_keepalive(gpointer data, gint source, b_input_condition cond) { struct msn_switchboard *sb = data; - return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE ); + + return sb->ready && msn_sb_sendmessage(sb, SB_KEEPALIVE_MESSAGE); } -void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ) +void msn_sb_start_keepalives(struct msn_switchboard *sb, gboolean initial) { bee_user_t *bu; - - if( sb && sb->who && sb->keepalive == 0 && - ( bu = bee_user_by_handle( sb->ic->bee, sb->ic, sb->who ) ) && - !( bu->flags & BEE_USER_ONLINE ) && - set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) ) - { - if( initial ) - msn_sb_keepalive( sb, 0, 0 ); - - sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb ); + + if (sb && sb->who && sb->keepalive == 0 && + (bu = bee_user_by_handle(sb->ic->bee, sb->ic, sb->who)) && + !(bu->flags & BEE_USER_ONLINE) && + set_getbool(&sb->ic->acc->set, "switchboard_keepalives")) { + if (initial) { + msn_sb_keepalive(sb, 0, 0); + } + + sb->keepalive = b_timeout_add(20000, msn_sb_keepalive, sb); } } -void msn_sb_stop_keepalives( struct msn_switchboard *sb ) +void msn_sb_stop_keepalives(struct msn_switchboard *sb) { - if( sb && sb->keepalive > 0 ) - { - b_event_remove( sb->keepalive ); + if (sb && sb->keepalive > 0) { + b_event_remove(sb->keepalive); sb->keepalive = 0; } } diff --git a/protocols/msn/soap.c b/protocols/msn/soap.c index 175b4546..f948decb 100644 --- a/protocols/msn/soap.c +++ b/protocols/msn/soap.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -43,8 +43,7 @@ parts of the response, and a function to run when the full response was received and parsed. See the various examples below. */ -typedef enum -{ +typedef enum { MSN_SOAP_OK, MSN_SOAP_RETRY, MSN_SOAP_REAUTH, @@ -52,35 +51,34 @@ typedef enum } msn_soap_result_t; struct msn_soap_req_data; -typedef int (*msn_soap_func) ( struct msn_soap_req_data * ); +typedef int (*msn_soap_func) (struct msn_soap_req_data *); -struct msn_soap_req_data -{ +struct msn_soap_req_data { void *data; struct im_connection *ic; int ttl; char *error; - + char *url, *action, *payload; struct http_request *http_req; - + const struct xt_handler_entry *xml_parser; msn_soap_func build_request, handle_response, free_data; }; -static int msn_soap_send_request( struct msn_soap_req_data *req ); -static void msn_soap_free( struct msn_soap_req_data *soap_req ); -static void msn_soap_debug_print( const char *headers, const char *payload ); +static int msn_soap_send_request(struct msn_soap_req_data *req); +static void msn_soap_free(struct msn_soap_req_data *soap_req); +static void msn_soap_debug_print(const char *headers, const char *payload); -static int msn_soap_start( struct im_connection *ic, - void *data, - msn_soap_func build_request, - const struct xt_handler_entry *xml_parser, - msn_soap_func handle_response, - msn_soap_func free_data ) +static int msn_soap_start(struct im_connection *ic, + void *data, + msn_soap_func build_request, + const struct xt_handler_entry *xml_parser, + msn_soap_func handle_response, + msn_soap_func free_data) { - struct msn_soap_req_data *req = g_new0( struct msn_soap_req_data, 1 ); - + struct msn_soap_req_data *req = g_new0(struct msn_soap_req_data, 1); + req->ic = ic; req->data = data; req->xml_parser = xml_parser; @@ -88,199 +86,190 @@ static int msn_soap_start( struct im_connection *ic, req->handle_response = handle_response; req->free_data = free_data; req->ttl = 3; - - return msn_soap_send_request( req ); + + return msn_soap_send_request(req); } -static void msn_soap_handle_response( struct http_request *http_req ); +static void msn_soap_handle_response(struct http_request *http_req); -static int msn_soap_send_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_send_request(struct msn_soap_req_data *soap_req) { char *http_req; char *soap_action = NULL; url_t url; - - soap_req->build_request( soap_req ); - - if( soap_req->action ) - soap_action = g_strdup_printf( "SOAPAction: \"%s\"\r\n", soap_req->action ); - - url_set( &url, soap_req->url ); - http_req = g_strdup_printf( SOAP_HTTP_REQUEST, url.file, url.host, - soap_action ? soap_action : "", - strlen( soap_req->payload ), soap_req->payload ); - - msn_soap_debug_print( http_req, soap_req->payload ); - - soap_req->http_req = http_dorequest( url.host, url.port, url.proto == PROTO_HTTPS, - http_req, msn_soap_handle_response, soap_req ); - - g_free( http_req ); - g_free( soap_action ); - + + soap_req->build_request(soap_req); + + if (soap_req->action) { + soap_action = g_strdup_printf("SOAPAction: \"%s\"\r\n", soap_req->action); + } + + url_set(&url, soap_req->url); + http_req = g_strdup_printf(SOAP_HTTP_REQUEST, url.file, url.host, + soap_action ? soap_action : "", + strlen(soap_req->payload), soap_req->payload); + + msn_soap_debug_print(http_req, soap_req->payload); + + soap_req->http_req = http_dorequest(url.host, url.port, url.proto == PROTO_HTTPS, + http_req, msn_soap_handle_response, soap_req); + + g_free(http_req); + g_free(soap_action); + return soap_req->http_req != NULL; } -static void msn_soap_handle_response( struct http_request *http_req ) +static void msn_soap_handle_response(struct http_request *http_req) { struct msn_soap_req_data *soap_req = http_req->data; int st; - - if( g_slist_find( msn_connections, soap_req->ic ) == NULL ) - { - msn_soap_free( soap_req ); + + if (g_slist_find(msn_connections, soap_req->ic) == NULL) { + msn_soap_free(soap_req); return; } - - msn_soap_debug_print( http_req->reply_headers, http_req->reply_body ); - - if( http_req->body_size > 0 ) - { + + msn_soap_debug_print(http_req->reply_headers, http_req->reply_body); + + if (http_req->body_size > 0) { struct xt_parser *parser; struct xt_node *err; - - parser = xt_new( soap_req->xml_parser, soap_req ); - xt_feed( parser, http_req->reply_body, http_req->body_size ); - if( http_req->status_code == 500 && - ( err = xt_find_path( parser->root, "soap:Body/soap:Fault/detail/errorcode" ) ) && - err->text_len > 0 ) - { - if( strcmp( err->text, "PassportAuthFail" ) == 0 ) - { - xt_free( parser ); + + parser = xt_new(soap_req->xml_parser, soap_req); + xt_feed(parser, http_req->reply_body, http_req->body_size); + if (http_req->status_code == 500 && + (err = xt_find_path(parser->root, "soap:Body/soap:Fault/detail/errorcode")) && + err->text_len > 0) { + if (strcmp(err->text, "PassportAuthFail") == 0) { + xt_free(parser); st = MSN_SOAP_REAUTH; goto fail; } /* TODO: Handle/report other errors. */ } - - xt_handle( parser, NULL, -1 ); - xt_free( parser ); + + xt_handle(parser, NULL, -1); + xt_free(parser); } - - if( http_req->status_code != 200 ) - soap_req->error = g_strdup( http_req->status_string ); - - st = soap_req->handle_response( soap_req ); - -fail: - g_free( soap_req->url ); - g_free( soap_req->action ); - g_free( soap_req->payload ); - g_free( soap_req->error ); - soap_req->url = soap_req->action = soap_req->payload = soap_req->error = NULL; - - if( st == MSN_SOAP_RETRY && --soap_req->ttl ) - { - msn_soap_send_request( soap_req ); + + if (http_req->status_code != 200) { + soap_req->error = g_strdup(http_req->status_string); } - else if( st == MSN_SOAP_REAUTH ) - { + + st = soap_req->handle_response(soap_req); + +fail: + g_free(soap_req->url); + g_free(soap_req->action); + g_free(soap_req->payload); + g_free(soap_req->error); + soap_req->url = soap_req->action = soap_req->payload = soap_req->error = NULL; + + if (st == MSN_SOAP_RETRY && --soap_req->ttl) { + msn_soap_send_request(soap_req); + } else if (st == MSN_SOAP_REAUTH) { struct msn_data *md = soap_req->ic->proto_data; - - if( !( md->flags & MSN_REAUTHING ) ) - { + + if (!(md->flags & MSN_REAUTHING)) { /* Nonce shouldn't actually be touched for re-auths. */ - msn_soap_passport_sso_request( soap_req->ic, "blaataap" ); - md->flags |= MSN_REAUTHING; + msn_soap_passport_sso_request(soap_req->ic, "blaataap"); + md->flags |= MSN_REAUTHING; } - md->soapq = g_slist_append( md->soapq, soap_req ); - } - else - { - soap_req->free_data( soap_req ); - g_free( soap_req ); + md->soapq = g_slist_append(md->soapq, soap_req); + } else { + soap_req->free_data(soap_req); + g_free(soap_req); } } -static char *msn_soap_abservice_build( const char *body_fmt, const char *scenario, const char *ticket, ... ) +static char *msn_soap_abservice_build(const char *body_fmt, const char *scenario, const char *ticket, ...) { va_list params; char *ret, *format, *body; - - format = g_markup_printf_escaped( SOAP_ABSERVICE_PAYLOAD, scenario, ticket ); - - va_start( params, ticket ); - body = g_strdup_vprintf( body_fmt, params ); - va_end( params ); - - ret = g_strdup_printf( format, body ); - g_free( body ); - g_free( format ); - + + format = g_markup_printf_escaped(SOAP_ABSERVICE_PAYLOAD, scenario, ticket); + + va_start(params, ticket); + body = g_strdup_vprintf(body_fmt, params); + va_end(params); + + ret = g_strdup_printf(format, body); + g_free(body); + g_free(format); + return ret; } -static void msn_soap_debug_print( const char *headers, const char *payload ) +static void msn_soap_debug_print(const char *headers, const char *payload) { char *s; - - if( !getenv( "BITLBEE_DEBUG" ) ) + + if (!getenv("BITLBEE_DEBUG")) { return; - - if( headers ) - { - if( ( s = strstr( headers, "\r\n\r\n" ) ) ) - write( 2, headers, s - headers + 4 ); - else - write( 2, headers, strlen( headers ) ); } - - if( payload ) - { - struct xt_node *xt = xt_from_string( payload, 0 ); - if( xt ) - xt_print( xt ); - xt_free_node( xt ); + + if (headers) { + if ((s = strstr(headers, "\r\n\r\n"))) { + write(2, headers, s - headers + 4); + } else { + write(2, headers, strlen(headers)); + } + } + + if (payload) { + struct xt_node *xt = xt_from_string(payload, 0); + if (xt) { + xt_print(xt); + } + xt_free_node(xt); } } -int msn_soapq_flush( struct im_connection *ic, gboolean resend ) +int msn_soapq_flush(struct im_connection *ic, gboolean resend) { struct msn_data *md = ic->proto_data; - - while( md->soapq ) - { - if( resend ) - msn_soap_send_request( (struct msn_soap_req_data*) md->soapq->data ); - else - msn_soap_free( (struct msn_soap_req_data*) md->soapq->data ); - md->soapq = g_slist_remove( md->soapq, md->soapq->data ); + + while (md->soapq) { + if (resend) { + msn_soap_send_request((struct msn_soap_req_data*) md->soapq->data); + } else { + msn_soap_free((struct msn_soap_req_data*) md->soapq->data); + } + md->soapq = g_slist_remove(md->soapq, md->soapq->data); } - + return MSN_SOAP_OK; } -static void msn_soap_free( struct msn_soap_req_data *soap_req ) +static void msn_soap_free(struct msn_soap_req_data *soap_req) { - soap_req->free_data( soap_req ); - g_free( soap_req->url ); - g_free( soap_req->action ); - g_free( soap_req->payload ); - g_free( soap_req->error ); - g_free( soap_req ); + soap_req->free_data(soap_req); + g_free(soap_req->url); + g_free(soap_req->action); + g_free(soap_req->payload); + g_free(soap_req->error); + g_free(soap_req); } /* passport_sso: Authentication MSNP15+ */ -struct msn_soap_passport_sso_data -{ +struct msn_soap_passport_sso_data { char *nonce; char *secret; char *error; char *redirect; }; -static int msn_soap_passport_sso_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_passport_sso_build_request(struct msn_soap_req_data *soap_req) { struct msn_soap_passport_sso_data *sd = soap_req->data; struct im_connection *ic = soap_req->ic; struct msn_data *md = ic->proto_data; - char pass[MAX_PASSPORT_PWLEN+1]; - - if( sd->redirect ) - { + char pass[MAX_PASSPORT_PWLEN + 1]; + + if (sd->redirect) { soap_req->url = sd->redirect; sd->redirect = NULL; } @@ -288,63 +277,66 @@ static int msn_soap_passport_sso_build_request( struct msn_soap_req_data *soap_r one works, forwarding us to a msn.com URL that works. Takes an extra second, but that's better than not being able to log in at all. :-/ else if( g_str_has_suffix( ic->acc->user, "@msn.com" ) ) - soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL_MSN ); + soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL_MSN ); */ - else - soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL ); - - strncpy( pass, ic->acc->pass, MAX_PASSPORT_PWLEN ); + else { + soap_req->url = g_strdup(SOAP_PASSPORT_SSO_URL); + } + + strncpy(pass, ic->acc->pass, MAX_PASSPORT_PWLEN); pass[MAX_PASSPORT_PWLEN] = '\0'; - soap_req->payload = g_markup_printf_escaped( SOAP_PASSPORT_SSO_PAYLOAD, - ic->acc->user, pass, md->pp_policy ); - + soap_req->payload = g_markup_printf_escaped(SOAP_PASSPORT_SSO_PAYLOAD, + ic->acc->user, pass, md->pp_policy); + return MSN_SOAP_OK; } -static xt_status msn_soap_passport_sso_token( struct xt_node *node, gpointer data ) +static xt_status msn_soap_passport_sso_token(struct xt_node *node, gpointer data) { struct msn_soap_req_data *soap_req = data; struct msn_soap_passport_sso_data *sd = soap_req->data; struct msn_data *md = soap_req->ic->proto_data; struct xt_node *p; char *id; - - if( ( id = xt_find_attr( node, "Id" ) ) == NULL ) + + if ((id = xt_find_attr(node, "Id")) == NULL) { return XT_HANDLED; - id += strlen( id ) - 1; - if( *id == '1' && - ( p = xt_find_path( node, "../../wst:RequestedProofToken/wst:BinarySecret" ) ) && - p->text ) - sd->secret = g_strdup( p->text ); - + } + id += strlen(id) - 1; + if (*id == '1' && + (p = xt_find_path(node, "../../wst:RequestedProofToken/wst:BinarySecret")) && + p->text) { + sd->secret = g_strdup(p->text); + } + *id -= '1'; - if( *id >= 0 && *id < sizeof( md->tokens ) / sizeof( md->tokens[0] ) ) - { - g_free( md->tokens[(int)*id] ); - md->tokens[(int)*id] = g_strdup( node->text ); + if (*id >= 0 && *id < sizeof(md->tokens) / sizeof(md->tokens[0])) { + g_free(md->tokens[(int) *id]); + md->tokens[(int) *id] = g_strdup(node->text); } - + return XT_HANDLED; } -static xt_status msn_soap_passport_failure( struct xt_node *node, gpointer data ) +static xt_status msn_soap_passport_failure(struct xt_node *node, gpointer data) { struct msn_soap_req_data *soap_req = data; struct msn_soap_passport_sso_data *sd = soap_req->data; - struct xt_node *code = xt_find_node( node->children, "faultcode" ); - struct xt_node *string = xt_find_node( node->children, "faultstring" ); + struct xt_node *code = xt_find_node(node->children, "faultcode"); + struct xt_node *string = xt_find_node(node->children, "faultstring"); struct xt_node *url; - - if( code == NULL || code->text_len == 0 ) - sd->error = g_strdup( "Unknown error" ); - else if( strcmp( code->text, "psf:Redirect" ) == 0 && - ( url = xt_find_node( node->children, "psf:redirectUrl" ) ) && - url->text_len > 0 ) - sd->redirect = g_strdup( url->text ); - else - sd->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ? - string->text : "no description available" ); - + + if (code == NULL || code->text_len == 0) { + sd->error = g_strdup("Unknown error"); + } else if (strcmp(code->text, "psf:Redirect") == 0 && + (url = xt_find_node(node->children, "psf:redirectUrl")) && + url->text_len > 0) { + sd->redirect = g_strdup(url->text); + } else { + sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ? + string->text : "no description available"); + } + return XT_HANDLED; } @@ -354,27 +346,27 @@ static const struct xt_handler_entry msn_soap_passport_sso_parser[] = { { NULL, NULL, NULL } }; -static char *msn_key_fuckery( char *key, int key_len, char *type ) +static char *msn_key_fuckery(char *key, int key_len, char *type) { - unsigned char hash1[20+strlen(type)+1]; + unsigned char hash1[20 + strlen(type) + 1]; unsigned char hash2[20]; char *ret; - - sha1_hmac( key, key_len, type, 0, hash1 ); - strcpy( (char*) hash1 + 20, type ); - sha1_hmac( key, key_len, (char*) hash1, sizeof( hash1 ) - 1, hash2 ); - + + sha1_hmac(key, key_len, type, 0, hash1); + strcpy((char *) hash1 + 20, type); + sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash2); + /* This is okay as hash1 is read completely before it's overwritten. */ - sha1_hmac( key, key_len, (char*) hash1, 20, hash1 ); - sha1_hmac( key, key_len, (char*) hash1, sizeof( hash1 ) - 1, hash1 ); - - ret = g_malloc( 24 ); - memcpy( ret, hash2, 20 ); - memcpy( ret + 20, hash1, 4 ); + sha1_hmac(key, key_len, (char *) hash1, 20, hash1); + sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash1); + + ret = g_malloc(24); + memcpy(ret, hash2, 20); + memcpy(ret + 20, hash1, 4); return ret; } -static int msn_soap_passport_sso_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_passport_sso_handle_response(struct msn_soap_req_data *soap_req) { struct msn_soap_passport_sso_data *sd = soap_req->data; struct im_connection *ic = soap_req->ic; @@ -382,8 +374,8 @@ static int msn_soap_passport_sso_handle_response( struct msn_soap_req_data *soap char *key1, *key2, *key3, *blurb64; int key1_len; unsigned char *padnonce, *des3res; - struct - { + + struct { unsigned int uStructHeaderSize; // 28. Does not count data unsigned int uCryptMode; // CRYPT_MODE_CBC (1) unsigned int uCipherType; // TripleDES (0x6603) @@ -395,98 +387,97 @@ static int msn_soap_passport_sso_handle_response( struct msn_soap_req_data *soap unsigned char hash[20]; unsigned char cipherbytes[72]; } blurb = { - GUINT32_TO_LE( 28 ), - GUINT32_TO_LE( 1 ), - GUINT32_TO_LE( 0x6603 ), - GUINT32_TO_LE( 0x8004 ), - GUINT32_TO_LE( 8 ), - GUINT32_TO_LE( 20 ), - GUINT32_TO_LE( 72 ), + GUINT32_TO_LE(28), + GUINT32_TO_LE(1), + GUINT32_TO_LE(0x6603), + GUINT32_TO_LE(0x8004), + GUINT32_TO_LE(8), + GUINT32_TO_LE(20), + GUINT32_TO_LE(72), }; - - if( sd->redirect ) + + if (sd->redirect) { return MSN_SOAP_RETRY; - - if( md->soapq ) - { - md->flags &= ~MSN_REAUTHING; - return msn_soapq_flush( ic, TRUE ); } - - if( sd->secret == NULL ) - { - msn_auth_got_passport_token( ic, NULL, sd->error ? sd->error : soap_req->error ); + + if (md->soapq) { + md->flags &= ~MSN_REAUTHING; + return msn_soapq_flush(ic, TRUE); + } + + if (sd->secret == NULL) { + msn_auth_got_passport_token(ic, NULL, sd->error ? sd->error : soap_req->error); return MSN_SOAP_OK; } - key1_len = base64_decode( sd->secret, (unsigned char**) &key1 ); - - key2 = msn_key_fuckery( key1, key1_len, "WS-SecureConversationSESSION KEY HASH" ); - key3 = msn_key_fuckery( key1, key1_len, "WS-SecureConversationSESSION KEY ENCRYPTION" ); - - sha1_hmac( key2, 24, sd->nonce, 0, blurb.hash ); - padnonce = g_malloc( strlen( sd->nonce ) + 8 ); - strcpy( (char*) padnonce, sd->nonce ); - memset( padnonce + strlen( sd->nonce ), 8, 8 ); - - random_bytes( blurb.iv, 8 ); - - ssl_des3_encrypt( (unsigned char*) key3, 24, padnonce, strlen( sd->nonce ) + 8, blurb.iv, &des3res ); - memcpy( blurb.cipherbytes, des3res, 72 ); - - blurb64 = base64_encode( (unsigned char*) &blurb, sizeof( blurb ) ); - msn_auth_got_passport_token( ic, blurb64, NULL ); - - g_free( padnonce ); - g_free( blurb64 ); - g_free( des3res ); - g_free( key1 ); - g_free( key2 ); - g_free( key3 ); - + key1_len = base64_decode(sd->secret, (unsigned char **) &key1); + + key2 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY HASH"); + key3 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY ENCRYPTION"); + + sha1_hmac(key2, 24, sd->nonce, 0, blurb.hash); + padnonce = g_malloc(strlen(sd->nonce) + 8); + strcpy((char *) padnonce, sd->nonce); + memset(padnonce + strlen(sd->nonce), 8, 8); + + random_bytes(blurb.iv, 8); + + ssl_des3_encrypt((unsigned char *) key3, 24, padnonce, strlen(sd->nonce) + 8, blurb.iv, &des3res); + memcpy(blurb.cipherbytes, des3res, 72); + + blurb64 = base64_encode((unsigned char *) &blurb, sizeof(blurb)); + msn_auth_got_passport_token(ic, blurb64, NULL); + + g_free(padnonce); + g_free(blurb64); + g_free(des3res); + g_free(key1); + g_free(key2); + g_free(key3); + return MSN_SOAP_OK; } -static int msn_soap_passport_sso_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_passport_sso_free_data(struct msn_soap_req_data *soap_req) { struct msn_soap_passport_sso_data *sd = soap_req->data; - - g_free( sd->nonce ); - g_free( sd->secret ); - g_free( sd->error ); - g_free( sd->redirect ); - g_free( sd ); - + + g_free(sd->nonce); + g_free(sd->secret); + g_free(sd->error); + g_free(sd->redirect); + g_free(sd); + return MSN_SOAP_OK; } -int msn_soap_passport_sso_request( struct im_connection *ic, const char *nonce ) +int msn_soap_passport_sso_request(struct im_connection *ic, const char *nonce) { - struct msn_soap_passport_sso_data *sd = g_new0( struct msn_soap_passport_sso_data, 1 ); - - sd->nonce = g_strdup( nonce ); - - return msn_soap_start( ic, sd, msn_soap_passport_sso_build_request, - msn_soap_passport_sso_parser, - msn_soap_passport_sso_handle_response, - msn_soap_passport_sso_free_data ); + struct msn_soap_passport_sso_data *sd = g_new0(struct msn_soap_passport_sso_data, 1); + + sd->nonce = g_strdup(nonce); + + return msn_soap_start(ic, sd, msn_soap_passport_sso_build_request, + msn_soap_passport_sso_parser, + msn_soap_passport_sso_handle_response, + msn_soap_passport_sso_free_data); } /* memlist: Fetching the membership list (NOT address book) */ -static int msn_soap_memlist_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - - soap_req->url = g_strdup( SOAP_MEMLIST_URL ); - soap_req->action = g_strdup( SOAP_MEMLIST_ACTION ); - soap_req->payload = msn_soap_abservice_build( SOAP_MEMLIST_PAYLOAD, "Initial", md->tokens[1] ); - + + soap_req->url = g_strdup(SOAP_MEMLIST_URL); + soap_req->action = g_strdup(SOAP_MEMLIST_ACTION); + soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_PAYLOAD, "Initial", md->tokens[1]); + return 1; } -static xt_status msn_soap_memlist_member( struct xt_node *node, gpointer data ) +static xt_status msn_soap_memlist_member(struct xt_node *node, gpointer data) { bee_user_t *bu; struct msn_buddy_data *bd; @@ -494,37 +485,38 @@ static xt_status msn_soap_memlist_member( struct xt_node *node, gpointer data ) char *role = NULL, *handle = NULL; struct msn_soap_req_data *soap_req = data; struct im_connection *ic = soap_req->ic; - - if( ( p = xt_find_path( node, "../../MemberRole" ) ) ) + + if ((p = xt_find_path(node, "../../MemberRole"))) { role = p->text; - - if( ( p = xt_find_node( node->children, "PassportName" ) ) ) + } + + if ((p = xt_find_node(node->children, "PassportName"))) { handle = p->text; - - if( !role || !handle || - !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) || - ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) ) + } + + if (!role || !handle || + !((bu = bee_user_by_handle(ic->bee, ic, handle)) || + (bu = bee_user_new(ic->bee, ic, handle, 0)))) { return XT_HANDLED; - + } + bd = bu->data; - if( strcmp( role, "Allow" ) == 0 ) - { + if (strcmp(role, "Allow") == 0) { bd->flags |= MSN_BUDDY_AL; - ic->permit = g_slist_prepend( ic->permit, g_strdup( handle ) ); - } - else if( strcmp( role, "Block" ) == 0 ) - { + ic->permit = g_slist_prepend(ic->permit, g_strdup(handle)); + } else if (strcmp(role, "Block") == 0) { bd->flags |= MSN_BUDDY_BL; - ic->deny = g_slist_prepend( ic->deny, g_strdup( handle ) ); - } - else if( strcmp( role, "Reverse" ) == 0 ) + ic->deny = g_slist_prepend(ic->deny, g_strdup(handle)); + } else if (strcmp(role, "Reverse") == 0) { bd->flags |= MSN_BUDDY_RL; - else if( strcmp( role, "Pending" ) == 0 ) + } else if (strcmp(role, "Pending") == 0) { bd->flags |= MSN_BUDDY_PL; - - if( getenv( "BITLBEE_DEBUG" ) ) - fprintf( stderr, "%p %s %d\n", bu, handle, bd->flags ); - + } + + if (getenv("BITLBEE_DEBUG")) { + fprintf(stderr, "%p %s %d\n", bu, handle, bd->flags); + } + return XT_HANDLED; } @@ -533,53 +525,48 @@ static const struct xt_handler_entry msn_soap_memlist_parser[] = { { NULL, NULL, NULL } }; -static int msn_soap_memlist_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_handle_response(struct msn_soap_req_data *soap_req) { - msn_soap_addressbook_request( soap_req->ic ); - + msn_soap_addressbook_request(soap_req->ic); + return MSN_SOAP_OK; } -static int msn_soap_memlist_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_free_data(struct msn_soap_req_data *soap_req) { return 0; } -int msn_soap_memlist_request( struct im_connection *ic ) +int msn_soap_memlist_request(struct im_connection *ic) { - return msn_soap_start( ic, NULL, msn_soap_memlist_build_request, - msn_soap_memlist_parser, - msn_soap_memlist_handle_response, - msn_soap_memlist_free_data ); + return msn_soap_start(ic, NULL, msn_soap_memlist_build_request, + msn_soap_memlist_parser, + msn_soap_memlist_handle_response, + msn_soap_memlist_free_data); } /* Variant: Adding/Removing people */ -struct msn_soap_memlist_edit_data -{ +struct msn_soap_memlist_edit_data { char *handle; gboolean add; msn_buddy_flags_t list; }; -static int msn_soap_memlist_edit_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_edit_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; struct msn_soap_memlist_edit_data *med = soap_req->data; char *add, *scenario, *list; - - soap_req->url = g_strdup( SOAP_MEMLIST_URL ); - if( med->add ) - { - soap_req->action = g_strdup( SOAP_MEMLIST_ADD_ACTION ); + + soap_req->url = g_strdup(SOAP_MEMLIST_URL); + if (med->add) { + soap_req->action = g_strdup(SOAP_MEMLIST_ADD_ACTION); add = "Add"; - } - else - { - soap_req->action = g_strdup( SOAP_MEMLIST_DEL_ACTION ); + } else { + soap_req->action = g_strdup(SOAP_MEMLIST_DEL_ACTION); add = "Delete"; } - switch( med->list ) - { + switch (med->list) { case MSN_BUDDY_AL: scenario = "BlockUnblock"; list = "Allow"; @@ -598,141 +585,153 @@ static int msn_soap_memlist_edit_build_request( struct msn_soap_req_data *soap_r list = "Pending"; break; } - soap_req->payload = msn_soap_abservice_build( SOAP_MEMLIST_EDIT_PAYLOAD, - scenario, md->tokens[1], add, list, med->handle, add ); - + soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_EDIT_PAYLOAD, + scenario, md->tokens[1], add, list, med->handle, add); + return 1; } -static int msn_soap_memlist_edit_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_edit_handle_response(struct msn_soap_req_data *soap_req) { return MSN_SOAP_OK; } -static int msn_soap_memlist_edit_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_memlist_edit_free_data(struct msn_soap_req_data *soap_req) { struct msn_soap_memlist_edit_data *med = soap_req->data; - - g_free( med->handle ); - g_free( med ); - + + g_free(med->handle); + g_free(med); + return 0; } -int msn_soap_memlist_edit( struct im_connection *ic, const char *handle, gboolean add, int list ) +int msn_soap_memlist_edit(struct im_connection *ic, const char *handle, gboolean add, int list) { struct msn_soap_memlist_edit_data *med; - - med = g_new0( struct msn_soap_memlist_edit_data, 1 ); - med->handle = g_strdup( handle ); + + med = g_new0(struct msn_soap_memlist_edit_data, 1); + med->handle = g_strdup(handle); med->add = add; med->list = list; - - return msn_soap_start( ic, med, msn_soap_memlist_edit_build_request, - NULL, - msn_soap_memlist_edit_handle_response, - msn_soap_memlist_edit_free_data ); + + return msn_soap_start(ic, med, msn_soap_memlist_edit_build_request, + NULL, + msn_soap_memlist_edit_handle_response, + msn_soap_memlist_edit_free_data); } /* addressbook: Fetching the membership list (NOT address book) */ -static int msn_soap_addressbook_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_addressbook_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - - soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); - soap_req->action = g_strdup( SOAP_ADDRESSBOOK_ACTION ); - soap_req->payload = msn_soap_abservice_build( SOAP_ADDRESSBOOK_PAYLOAD, "Initial", md->tokens[1] ); - + + soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); + soap_req->action = g_strdup(SOAP_ADDRESSBOOK_ACTION); + soap_req->payload = msn_soap_abservice_build(SOAP_ADDRESSBOOK_PAYLOAD, "Initial", md->tokens[1]); + return 1; } -static xt_status msn_soap_addressbook_group( struct xt_node *node, gpointer data ) +static xt_status msn_soap_addressbook_group(struct xt_node *node, gpointer data) { struct xt_node *p; char *id = NULL, *name = NULL; struct msn_soap_req_data *soap_req = data; struct msn_data *md = soap_req->ic->proto_data; - - if( ( p = xt_find_path( node, "../groupId" ) ) ) + + if ((p = xt_find_path(node, "../groupId"))) { id = p->text; - - if( ( p = xt_find_node( node->children, "name" ) ) ) + } + + if ((p = xt_find_node(node->children, "name"))) { name = p->text; - - if( id && name ) - { - struct msn_group *mg = g_new0( struct msn_group, 1 ); - mg->id = g_strdup( id ); - mg->name = g_strdup( name ); - md->groups = g_slist_prepend( md->groups, mg ); } - - if( getenv( "BITLBEE_DEBUG" ) ) - fprintf( stderr, "%s %s\n", id, name ); - + + if (id && name) { + struct msn_group *mg = g_new0(struct msn_group, 1); + mg->id = g_strdup(id); + mg->name = g_strdup(name); + md->groups = g_slist_prepend(md->groups, mg); + } + + if (getenv("BITLBEE_DEBUG")) { + fprintf(stderr, "%s %s\n", id, name); + } + return XT_HANDLED; } -static xt_status msn_soap_addressbook_contact( struct xt_node *node, gpointer data ) +static xt_status msn_soap_addressbook_contact(struct xt_node *node, gpointer data) { bee_user_t *bu; struct msn_buddy_data *bd; struct xt_node *p; char *id = NULL, *type = NULL, *handle = NULL, *is_msgr = "false", - *display_name = NULL, *group_id = NULL; + *display_name = NULL, *group_id = NULL; struct msn_soap_req_data *soap_req = data; struct im_connection *ic = soap_req->ic; struct msn_group *group; - - if( ( p = xt_find_path( node, "../contactId" ) ) ) + + if ((p = xt_find_path(node, "../contactId"))) { id = p->text; - if( ( p = xt_find_node( node->children, "contactType" ) ) ) + } + if ((p = xt_find_node(node->children, "contactType"))) { type = p->text; - if( ( p = xt_find_node( node->children, "passportName" ) ) ) + } + if ((p = xt_find_node(node->children, "passportName"))) { handle = p->text; - if( ( p = xt_find_node( node->children, "displayName" ) ) ) + } + if ((p = xt_find_node(node->children, "displayName"))) { display_name = p->text; - if( ( p = xt_find_node( node->children, "isMessengerUser" ) ) ) + } + if ((p = xt_find_node(node->children, "isMessengerUser"))) { is_msgr = p->text; - if( ( p = xt_find_path( node, "groupIds/guid" ) ) ) + } + if ((p = xt_find_path(node, "groupIds/guid"))) { group_id = p->text; - - if( type && g_strcasecmp( type, "me" ) == 0 ) - { - set_t *set = set_find( &ic->acc->set, "display_name" ); - g_free( set->value ); - set->value = g_strdup( display_name ); - + } + + if (type && g_strcasecmp(type, "me") == 0) { + set_t *set = set_find(&ic->acc->set, "display_name"); + g_free(set->value); + set->value = g_strdup(display_name); + /* Try to fetch the profile; if the user has one, that's where we can find the persistent display_name. */ - if( ( p = xt_find_node( node->children, "CID" ) ) && p->text ) - msn_soap_profile_get( ic, p->text ); - + if ((p = xt_find_node(node->children, "CID")) && p->text) { + msn_soap_profile_get(ic, p->text); + } + return XT_HANDLED; } - - if( !bool2int( is_msgr ) || handle == NULL ) + + if (!bool2int(is_msgr) || handle == NULL) { return XT_HANDLED; - - if( !( bu = bee_user_by_handle( ic->bee, ic, handle ) ) && - !( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) + } + + if (!(bu = bee_user_by_handle(ic->bee, ic, handle)) && + !(bu = bee_user_new(ic->bee, ic, handle, 0))) { return XT_HANDLED; - + } + bd = bu->data; bd->flags |= MSN_BUDDY_FL; - g_free( bd->cid ); - bd->cid = g_strdup( id ); - - imcb_rename_buddy( ic, handle, display_name ); - - if( group_id && ( group = msn_group_by_id( ic, group_id ) ) ) - imcb_add_buddy( ic, handle, group->name ); - - if( getenv( "BITLBEE_DEBUG" ) ) - fprintf( stderr, "%s %s %s %s\n", id, type, handle, display_name ); - + g_free(bd->cid); + bd->cid = g_strdup(id); + + imcb_rename_buddy(ic, handle, display_name); + + if (group_id && (group = msn_group_by_id(ic, group_id))) { + imcb_add_buddy(ic, handle, group->name); + } + + if (getenv("BITLBEE_DEBUG")) { + fprintf(stderr, "%s %s %s %s\n", id, type, handle, display_name); + } + return XT_HANDLED; } @@ -742,118 +741,116 @@ static const struct xt_handler_entry msn_soap_addressbook_parser[] = { { NULL, NULL, NULL } }; -static int msn_soap_addressbook_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_addressbook_handle_response(struct msn_soap_req_data *soap_req) { GSList *l; int wtf = 0; - - for( l = soap_req->ic->bee->users; l; l = l->next ) - { + + for (l = soap_req->ic->bee->users; l; l = l->next) { struct bee_user *bu = l->data; struct msn_buddy_data *bd = bu->data; - - if( bu->ic == soap_req->ic && bd ) - { - msn_buddy_ask( bu ); - - if( ( bd->flags & ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) == - ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) - { + + if (bu->ic == soap_req->ic && bd) { + msn_buddy_ask(bu); + + if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) == + (MSN_BUDDY_AL | MSN_BUDDY_BL)) { /* both allow and block, delete block, add wtf */ bd->flags &= ~MSN_BUDDY_BL; wtf++; } - if( ( bd->flags & ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) == 0 ) - { + if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) == 0) { /* neither allow or block, add allow */ bd->flags |= MSN_BUDDY_AL; } } } - - if( wtf ) - imcb_log( soap_req->ic, "Warning: %d contacts were in both your " - "block and your allow list. Assuming they're all " - "allowed. Use the official WLM client once to fix " - "this.", wtf ); - - msn_auth_got_contact_list( soap_req->ic ); - + + if (wtf) { + imcb_log(soap_req->ic, "Warning: %d contacts were in both your " + "block and your allow list. Assuming they're all " + "allowed. Use the official WLM client once to fix " + "this.", wtf); + } + + msn_auth_got_contact_list(soap_req->ic); + return MSN_SOAP_OK; } -static int msn_soap_addressbook_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_addressbook_free_data(struct msn_soap_req_data *soap_req) { return 0; } -int msn_soap_addressbook_request( struct im_connection *ic ) +int msn_soap_addressbook_request(struct im_connection *ic) { - return msn_soap_start( ic, NULL, msn_soap_addressbook_build_request, - msn_soap_addressbook_parser, - msn_soap_addressbook_handle_response, - msn_soap_addressbook_free_data ); + return msn_soap_start(ic, NULL, msn_soap_addressbook_build_request, + msn_soap_addressbook_parser, + msn_soap_addressbook_handle_response, + msn_soap_addressbook_free_data); } /* Variant: Change our display name. */ -static int msn_soap_ab_namechange_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_namechange_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - - soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); - soap_req->action = g_strdup( SOAP_AB_NAMECHANGE_ACTION ); - soap_req->payload = msn_soap_abservice_build( SOAP_AB_NAMECHANGE_PAYLOAD, - "Timer", md->tokens[1], (char *) soap_req->data ); - + + soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); + soap_req->action = g_strdup(SOAP_AB_NAMECHANGE_ACTION); + soap_req->payload = msn_soap_abservice_build(SOAP_AB_NAMECHANGE_PAYLOAD, + "Timer", md->tokens[1], (char *) soap_req->data); + return 1; } -static int msn_soap_ab_namechange_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_namechange_handle_response(struct msn_soap_req_data *soap_req) { /* TODO: Ack the change? Not sure what the NAKs look like.. */ return MSN_SOAP_OK; } -static int msn_soap_ab_namechange_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_namechange_free_data(struct msn_soap_req_data *soap_req) { - g_free( soap_req->data ); + g_free(soap_req->data); return 0; } -int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new ) +int msn_soap_addressbook_set_display_name(struct im_connection *ic, const char *new) { - return msn_soap_start( ic, g_strdup( new ), - msn_soap_ab_namechange_build_request, - NULL, - msn_soap_ab_namechange_handle_response, - msn_soap_ab_namechange_free_data ); + return msn_soap_start(ic, g_strdup(new), + msn_soap_ab_namechange_build_request, + NULL, + msn_soap_ab_namechange_handle_response, + msn_soap_ab_namechange_free_data); } /* Add a contact. */ -static int msn_soap_ab_contact_add_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_add_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; bee_user_t *bu = soap_req->data; - - soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); - soap_req->action = g_strdup( SOAP_AB_CONTACT_ADD_ACTION ); - soap_req->payload = msn_soap_abservice_build( SOAP_AB_CONTACT_ADD_PAYLOAD, - "ContactSave", md->tokens[1], bu->handle, bu->fullname ? bu->fullname : bu->handle ); - + + soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); + soap_req->action = g_strdup(SOAP_AB_CONTACT_ADD_ACTION); + soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_ADD_PAYLOAD, + "ContactSave", md->tokens[1], bu->handle, + bu->fullname ? bu->fullname : bu->handle); + return 1; } -static xt_status msn_soap_ab_contact_add_cid( struct xt_node *node, gpointer data ) +static xt_status msn_soap_ab_contact_add_cid(struct xt_node *node, gpointer data) { struct msn_soap_req_data *soap_req = data; bee_user_t *bu = soap_req->data; struct msn_buddy_data *bd = bu->data; - - g_free( bd->cid ); - bd->cid = g_strdup( node->text ); - + + g_free(bd->cid); + bd->cid = g_strdup(node->text); + return XT_HANDLED; } @@ -862,105 +859,104 @@ static const struct xt_handler_entry msn_soap_ab_contact_add_parser[] = { { NULL, NULL, NULL } }; -static int msn_soap_ab_contact_add_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_add_handle_response(struct msn_soap_req_data *soap_req) { /* TODO: Ack the change? Not sure what the NAKs look like.. */ return MSN_SOAP_OK; } -static int msn_soap_ab_contact_add_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_add_free_data(struct msn_soap_req_data *soap_req) { return 0; } -int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu ) +int msn_soap_ab_contact_add(struct im_connection *ic, bee_user_t *bu) { - return msn_soap_start( ic, bu, - msn_soap_ab_contact_add_build_request, - msn_soap_ab_contact_add_parser, - msn_soap_ab_contact_add_handle_response, - msn_soap_ab_contact_add_free_data ); + return msn_soap_start(ic, bu, + msn_soap_ab_contact_add_build_request, + msn_soap_ab_contact_add_parser, + msn_soap_ab_contact_add_handle_response, + msn_soap_ab_contact_add_free_data); } /* Remove a contact. */ -static int msn_soap_ab_contact_del_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_del_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; const char *cid = soap_req->data; - - soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); - soap_req->action = g_strdup( SOAP_AB_CONTACT_DEL_ACTION ); - soap_req->payload = msn_soap_abservice_build( SOAP_AB_CONTACT_DEL_PAYLOAD, - "Timer", md->tokens[1], cid ); - + + soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); + soap_req->action = g_strdup(SOAP_AB_CONTACT_DEL_ACTION); + soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_DEL_PAYLOAD, + "Timer", md->tokens[1], cid); + return 1; } -static int msn_soap_ab_contact_del_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_del_handle_response(struct msn_soap_req_data *soap_req) { /* TODO: Ack the change? Not sure what the NAKs look like.. */ return MSN_SOAP_OK; } -static int msn_soap_ab_contact_del_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_ab_contact_del_free_data(struct msn_soap_req_data *soap_req) { - g_free( soap_req->data ); + g_free(soap_req->data); return 0; } -int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ) +int msn_soap_ab_contact_del(struct im_connection *ic, bee_user_t *bu) { struct msn_buddy_data *bd = bu->data; - - return msn_soap_start( ic, g_strdup( bd->cid ), - msn_soap_ab_contact_del_build_request, - NULL, - msn_soap_ab_contact_del_handle_response, - msn_soap_ab_contact_del_free_data ); + + return msn_soap_start(ic, g_strdup(bd->cid), + msn_soap_ab_contact_del_build_request, + NULL, + msn_soap_ab_contact_del_handle_response, + msn_soap_ab_contact_del_free_data); } /* Storage stuff: Fetch profile. */ -static int msn_soap_profile_get_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_get_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - - soap_req->url = g_strdup( SOAP_STORAGE_URL ); - soap_req->action = g_strdup( SOAP_PROFILE_GET_ACTION ); - soap_req->payload = g_markup_printf_escaped( SOAP_PROFILE_GET_PAYLOAD, - md->tokens[3], (char*) soap_req->data ); - + + soap_req->url = g_strdup(SOAP_STORAGE_URL); + soap_req->action = g_strdup(SOAP_PROFILE_GET_ACTION); + soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_GET_PAYLOAD, + md->tokens[3], (char *) soap_req->data); + return 1; } -static xt_status msn_soap_profile_get_result( struct xt_node *node, gpointer data ) +static xt_status msn_soap_profile_get_result(struct xt_node *node, gpointer data) { struct msn_soap_req_data *soap_req = data; struct im_connection *ic = soap_req->ic; struct msn_data *md = soap_req->ic->proto_data; struct xt_node *dn; - - if( ( dn = xt_find_node( node->children, "DisplayName" ) ) && dn->text ) - { - set_t *set = set_find( &ic->acc->set, "display_name" ); - g_free( set->value ); - set->value = g_strdup( dn->text ); - + + if ((dn = xt_find_node(node->children, "DisplayName")) && dn->text) { + set_t *set = set_find(&ic->acc->set, "display_name"); + g_free(set->value); + set->value = g_strdup(dn->text); + md->flags |= MSN_GOT_PROFILE_DN; } - + return XT_HANDLED; } -static xt_status msn_soap_profile_get_rid( struct xt_node *node, gpointer data ) +static xt_status msn_soap_profile_get_rid(struct xt_node *node, gpointer data) { struct msn_soap_req_data *soap_req = data; struct msn_data *md = soap_req->ic->proto_data; - - g_free( md->profile_rid ); - md->profile_rid = g_strdup( node->text ); - + + g_free(md->profile_rid); + md->profile_rid = g_strdup(node->text); + return XT_HANDLED; } @@ -970,41 +966,41 @@ static const struct xt_handler_entry msn_soap_profile_get_parser[] = { { NULL, NULL, NULL } }; -static int msn_soap_profile_get_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_get_handle_response(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - + md->flags |= MSN_GOT_PROFILE; - msn_ns_finish_login( soap_req->ic ); - + msn_ns_finish_login(soap_req->ic); + return MSN_SOAP_OK; } -static int msn_soap_profile_get_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_get_free_data(struct msn_soap_req_data *soap_req) { - g_free( soap_req->data ); + g_free(soap_req->data); return 0; } -int msn_soap_profile_get( struct im_connection *ic, const char *cid ) +int msn_soap_profile_get(struct im_connection *ic, const char *cid) { - return msn_soap_start( ic, g_strdup( cid ), - msn_soap_profile_get_build_request, - msn_soap_profile_get_parser, - msn_soap_profile_get_handle_response, - msn_soap_profile_get_free_data ); + return msn_soap_start(ic, g_strdup(cid), + msn_soap_profile_get_build_request, + msn_soap_profile_get_parser, + msn_soap_profile_get_handle_response, + msn_soap_profile_get_free_data); } /* Update profile (display name). */ -static int msn_soap_profile_set_dn_build_request( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_set_dn_build_request(struct msn_soap_req_data *soap_req) { struct msn_data *md = soap_req->ic->proto_data; - - soap_req->url = g_strdup( SOAP_STORAGE_URL ); - soap_req->action = g_strdup( SOAP_PROFILE_SET_DN_ACTION ); - soap_req->payload = g_markup_printf_escaped( SOAP_PROFILE_SET_DN_PAYLOAD, - md->tokens[3], md->profile_rid, (char*) soap_req->data ); - + + soap_req->url = g_strdup(SOAP_STORAGE_URL); + soap_req->action = g_strdup(SOAP_PROFILE_SET_DN_ACTION); + soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_SET_DN_PAYLOAD, + md->tokens[3], md->profile_rid, (char *) soap_req->data); + return 1; } @@ -1012,22 +1008,22 @@ static const struct xt_handler_entry msn_soap_profile_set_dn_parser[] = { { NULL, NULL, NULL } }; -static int msn_soap_profile_set_dn_handle_response( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_set_dn_handle_response(struct msn_soap_req_data *soap_req) { return MSN_SOAP_OK; } -static int msn_soap_profile_set_dn_free_data( struct msn_soap_req_data *soap_req ) +static int msn_soap_profile_set_dn_free_data(struct msn_soap_req_data *soap_req) { - g_free( soap_req->data ); + g_free(soap_req->data); return 0; } -int msn_soap_profile_set_dn( struct im_connection *ic, const char *dn ) +int msn_soap_profile_set_dn(struct im_connection *ic, const char *dn) { - return msn_soap_start( ic, g_strdup( dn ), - msn_soap_profile_set_dn_build_request, - msn_soap_profile_set_dn_parser, - msn_soap_profile_set_dn_handle_response, - msn_soap_profile_set_dn_free_data ); + return msn_soap_start(ic, g_strdup(dn), + msn_soap_profile_set_dn_build_request, + msn_soap_profile_set_dn_parser, + msn_soap_profile_set_dn_handle_response, + msn_soap_profile_set_dn_free_data); } diff --git a/protocols/msn/soap.h b/protocols/msn/soap.h index 73ef5f8a..44e27b2e 100644 --- a/protocols/msn/soap.h +++ b/protocols/msn/soap.h @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2012 Wilmer van der Gaast and others * @@ -42,20 +42,20 @@ #include "nogaim.h" -int msn_soapq_flush( struct im_connection *ic, gboolean resend ); +int msn_soapq_flush(struct im_connection *ic, gboolean resend); #define SOAP_HTTP_REQUEST \ -"POST %s HTTP/1.0\r\n" \ -"Host: %s\r\n" \ -"Accept: */*\r\n" \ -"User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ -"Content-Type: text/xml; charset=utf-8\r\n" \ -"%s" \ -"Content-Length: %zd\r\n" \ -"Cache-Control: no-cache\r\n" \ -"\r\n" \ -"%s" + "POST %s HTTP/1.0\r\n" \ + "Host: %s\r\n" \ + "Accept: */*\r\n" \ + "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ + "Content-Type: text/xml; charset=utf-8\r\n" \ + "%s" \ + "Content-Length: %zd\r\n" \ + "Cache-Control: no-cache\r\n" \ + "\r\n" \ + "%s" #define SOAP_PASSPORT_SSO_URL "https://login.live.com/RST.srf" @@ -63,205 +63,205 @@ int msn_soapq_flush( struct im_connection *ic, gboolean resend ); #define MAX_PASSPORT_PWLEN 16 #define SOAP_PASSPORT_SSO_PAYLOAD \ -"<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" " \ - "xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" " \ - "xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" " \ - "xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" " \ - "xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" " \ - "xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" " \ - "xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" " \ - "xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \ - "<Header>" \ - "<ps:AuthInfo " \ - "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \ - "Id=\"PPAuthInfo\">" \ - "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \ - "<ps:BinaryVersion>4</ps:BinaryVersion>" \ - "<ps:UIVersion>1</ps:UIVersion>" \ - "<ps:Cookies></ps:Cookies>" \ - "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>" \ - "</ps:AuthInfo>" \ - "<wsse:Security>" \ - "<wsse:UsernameToken Id=\"user\">" \ - "<wsse:Username>%s</wsse:Username>" \ - "<wsse:Password>%s</wsse:Password>" \ - "</wsse:UsernameToken>" \ - "</wsse:Security>" \ - "</Header>" \ - "<Body>" \ - "<ps:RequestMultipleSecurityTokens " \ - "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \ - "Id=\"RSTS\">" \ - "<wst:RequestSecurityToken Id=\"RST0\">" \ - "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ - "<wsp:AppliesTo>" \ - "<wsa:EndpointReference>" \ - "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \ - "</wsa:EndpointReference>" \ - "</wsp:AppliesTo>" \ - "</wst:RequestSecurityToken>" \ - "<wst:RequestSecurityToken Id=\"RST1\">" \ - "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ - "<wsp:AppliesTo>" \ - "<wsa:EndpointReference>" \ - "<wsa:Address>messengerclear.live.com</wsa:Address>" \ - "</wsa:EndpointReference>" \ - "</wsp:AppliesTo>" \ - "<wsse:PolicyReference URI=\"%s\"></wsse:PolicyReference>" \ - "</wst:RequestSecurityToken>" \ - "<wst:RequestSecurityToken Id=\"RST2\">" \ - "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ - "<wsp:AppliesTo>" \ - "<wsa:EndpointReference>" \ - "<wsa:Address>contacts.msn.com</wsa:Address>" \ - "</wsa:EndpointReference>" \ - "</wsp:AppliesTo>" \ - "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI\"></wsse:PolicyReference>" \ - "</wst:RequestSecurityToken>" \ - "<wst:RequestSecurityToken Id=\"RST3\">" \ - "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ - "<wsp:AppliesTo>" \ - "<wsa:EndpointReference>" \ - "<wsa:Address>messengersecure.live.com</wsa:Address>" \ - "</wsa:EndpointReference>" \ - "</wsp:AppliesTo>" \ - "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ - "</wst:RequestSecurityToken>" \ - "<wst:RequestSecurityToken Id=\"RST4\">" \ - "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ - "<wsp:AppliesTo>" \ - "<wsa:EndpointReference>" \ - "<wsa:Address>storage.msn.com</wsa:Address>" \ - "</wsa:EndpointReference>" \ - "</wsp:AppliesTo>" \ - "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ - "</wst:RequestSecurityToken>" \ - "</ps:RequestMultipleSecurityTokens>" \ - "</Body>" \ -"</Envelope>" - -int msn_soap_passport_sso_request( struct im_connection *ic, const char *nonce ); + "<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" " \ + "xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" " \ + "xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" " \ + "xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" " \ + "xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" " \ + "xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" " \ + "xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" " \ + "xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \ + "<Header>" \ + "<ps:AuthInfo " \ + "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \ + "Id=\"PPAuthInfo\">" \ + "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \ + "<ps:BinaryVersion>4</ps:BinaryVersion>" \ + "<ps:UIVersion>1</ps:UIVersion>" \ + "<ps:Cookies></ps:Cookies>" \ + "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>" \ + "</ps:AuthInfo>" \ + "<wsse:Security>" \ + "<wsse:UsernameToken Id=\"user\">" \ + "<wsse:Username>%s</wsse:Username>" \ + "<wsse:Password>%s</wsse:Password>" \ + "</wsse:UsernameToken>" \ + "</wsse:Security>" \ + "</Header>" \ + "<Body>" \ + "<ps:RequestMultipleSecurityTokens " \ + "xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" " \ + "Id=\"RSTS\">" \ + "<wst:RequestSecurityToken Id=\"RST0\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "</wst:RequestSecurityToken>" \ + "<wst:RequestSecurityToken Id=\"RST1\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>messengerclear.live.com</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "<wsse:PolicyReference URI=\"%s\"></wsse:PolicyReference>" \ + "</wst:RequestSecurityToken>" \ + "<wst:RequestSecurityToken Id=\"RST2\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>contacts.msn.com</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI\"></wsse:PolicyReference>" \ + "</wst:RequestSecurityToken>" \ + "<wst:RequestSecurityToken Id=\"RST3\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>messengersecure.live.com</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ + "</wst:RequestSecurityToken>" \ + "<wst:RequestSecurityToken Id=\"RST4\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>storage.msn.com</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ + "</wst:RequestSecurityToken>" \ + "</ps:RequestMultipleSecurityTokens>" \ + "</Body>" \ + "</Envelope>" + +int msn_soap_passport_sso_request(struct im_connection *ic, const char *nonce); #define SOAP_ABSERVICE_PAYLOAD \ -"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ -"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<ApplicationId xmlns=\"http://www.msn.com/webservices/AddressBook\">F6D2794D-501F-443A-ADBE-8F1490FF30FD</ApplicationId>" \ - "<IsMigration xmlns=\"http://www.msn.com/webservices/AddressBook\">false</IsMigration>" \ - "<PartnerScenario xmlns=\"http://www.msn.com/webservices/AddressBook\">%s</PartnerScenario>" \ - "</ABApplicationHeader>" \ - "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>" \ - "<TicketToken>%s</TicketToken>" \ - "</ABAuthHeader>" \ - "</soap:Header>" \ - "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "%%s" \ - "</soap:Body>" \ -"</soap:Envelope>" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<ApplicationId xmlns=\"http://www.msn.com/webservices/AddressBook\">F6D2794D-501F-443A-ADBE-8F1490FF30FD</ApplicationId>" \ + "<IsMigration xmlns=\"http://www.msn.com/webservices/AddressBook\">false</IsMigration>" \ + "<PartnerScenario xmlns=\"http://www.msn.com/webservices/AddressBook\">%s</PartnerScenario>" \ + "</ABApplicationHeader>" \ + "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>" \ + "<TicketToken>%s</TicketToken>" \ + "</ABAuthHeader>" \ + "</soap:Header>" \ + "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "%%s" \ + "</soap:Body>" \ + "</soap:Envelope>" #define SOAP_MEMLIST_URL "http://contacts.msn.com/abservice/SharingService.asmx" #define SOAP_MEMLIST_ACTION "http://www.msn.com/webservices/AddressBook/FindMembership" #define SOAP_MEMLIST_PAYLOAD \ - "<FindMembership xmlns=\"http://www.msn.com/webservices/AddressBook\"><serviceFilter xmlns=\"http://www.msn.com/webservices/AddressBook\"><Types xmlns=\"http://www.msn.com/webservices/AddressBook\"><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Messenger</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Invitation</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">SocialNetwork</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Space</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Profile</ServiceType></Types></serviceFilter>" \ - "</FindMembership>" + "<FindMembership xmlns=\"http://www.msn.com/webservices/AddressBook\"><serviceFilter xmlns=\"http://www.msn.com/webservices/AddressBook\"><Types xmlns=\"http://www.msn.com/webservices/AddressBook\"><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Messenger</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Invitation</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">SocialNetwork</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Space</ServiceType><ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Profile</ServiceType></Types></serviceFilter>" \ + "</FindMembership>" #define SOAP_MEMLIST_ADD_ACTION "http://www.msn.com/webservices/AddressBook/AddMember" #define SOAP_MEMLIST_DEL_ACTION "http://www.msn.com/webservices/AddressBook/DeleteMember" #define SOAP_MEMLIST_EDIT_PAYLOAD \ - "<%sMember xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<serviceHandle>" \ - "<Id>0</Id>" \ - "<Type>Messenger</Type>" \ - "<ForeignId></ForeignId>" \ - "</serviceHandle>" \ - "<memberships>" \ - "<Membership>" \ - "<MemberRole>%s</MemberRole>" \ - "<Members>" \ - "<Member xsi:type=\"PassportMember\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" \ - "<Type>Passport</Type>" \ - "<State>Accepted</State>" \ - "<PassportName>%s</PassportName>" \ - "</Member>" \ - "</Members>" \ - "</Membership>" \ - "</memberships>" \ - "</%sMember>" - -int msn_soap_memlist_request( struct im_connection *ic ); -int msn_soap_memlist_edit( struct im_connection *ic, const char *handle, gboolean add, int list ); + "<%sMember xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<serviceHandle>" \ + "<Id>0</Id>" \ + "<Type>Messenger</Type>" \ + "<ForeignId></ForeignId>" \ + "</serviceHandle>" \ + "<memberships>" \ + "<Membership>" \ + "<MemberRole>%s</MemberRole>" \ + "<Members>" \ + "<Member xsi:type=\"PassportMember\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" \ + "<Type>Passport</Type>" \ + "<State>Accepted</State>" \ + "<PassportName>%s</PassportName>" \ + "</Member>" \ + "</Members>" \ + "</Membership>" \ + "</memberships>" \ + "</%sMember>" + +int msn_soap_memlist_request(struct im_connection *ic); +int msn_soap_memlist_edit(struct im_connection *ic, const char *handle, gboolean add, int list); #define SOAP_ADDRESSBOOK_URL "http://contacts.msn.com/abservice/abservice.asmx" #define SOAP_ADDRESSBOOK_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll" #define SOAP_ADDRESSBOOK_PAYLOAD \ - "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<abId>00000000-0000-0000-0000-000000000000</abId>" \ - "<abView>Full</abView>" \ - "<deltasOnly>false</deltasOnly>" \ - "<lastChange>0001-01-01T00:00:00.0000000-08:00</lastChange>" \ - "</ABFindAll>" + "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<abId>00000000-0000-0000-0000-000000000000</abId>" \ + "<abView>Full</abView>" \ + "<deltasOnly>false</deltasOnly>" \ + "<lastChange>0001-01-01T00:00:00.0000000-08:00</lastChange>" \ + "</ABFindAll>" #define SOAP_AB_NAMECHANGE_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate" #define SOAP_AB_NAMECHANGE_PAYLOAD \ - "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<abId>00000000-0000-0000-0000-000000000000</abId>" \ - "<contacts>" \ - "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<contactInfo>" \ - "<contactType>Me</contactType>" \ - "<displayName>%s</displayName>" \ - "</contactInfo>" \ - "<propertiesChanged>DisplayName</propertiesChanged>" \ - "</Contact>" \ - "</contacts>" \ - "</ABContactUpdate>" + "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<abId>00000000-0000-0000-0000-000000000000</abId>" \ + "<contacts>" \ + "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<contactInfo>" \ + "<contactType>Me</contactType>" \ + "<displayName>%s</displayName>" \ + "</contactInfo>" \ + "<propertiesChanged>DisplayName</propertiesChanged>" \ + "</Contact>" \ + "</contacts>" \ + "</ABContactUpdate>" #define SOAP_AB_CONTACT_ADD_ACTION "http://www.msn.com/webservices/AddressBook/ABContactAdd" #define SOAP_AB_CONTACT_ADD_PAYLOAD \ - "<ABContactAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<abId>00000000-0000-0000-0000-000000000000</abId>" \ - "<contacts>" \ - "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<contactInfo>" \ - "<contactType>LivePending</contactType>" \ - "<passportName>%s</passportName>" \ - "<isMessengerUser>true</isMessengerUser>" \ - "<MessengerMemberInfo>" \ - "<DisplayName>%s</DisplayName>" \ - "</MessengerMemberInfo>" \ - "</contactInfo>" \ - "</Contact>" \ - "</contacts>" \ - "<options>" \ - "<EnableAllowListManagement>true</EnableAllowListManagement>" \ - "</options>" \ - "</ABContactAdd>" + "<ABContactAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<abId>00000000-0000-0000-0000-000000000000</abId>" \ + "<contacts>" \ + "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<contactInfo>" \ + "<contactType>LivePending</contactType>" \ + "<passportName>%s</passportName>" \ + "<isMessengerUser>true</isMessengerUser>" \ + "<MessengerMemberInfo>" \ + "<DisplayName>%s</DisplayName>" \ + "</MessengerMemberInfo>" \ + "</contactInfo>" \ + "</Contact>" \ + "</contacts>" \ + "<options>" \ + "<EnableAllowListManagement>true</EnableAllowListManagement>" \ + "</options>" \ + "</ABContactAdd>" #define SOAP_AB_CONTACT_DEL_ACTION "http://www.msn.com/webservices/AddressBook/ABContactDelete" #define SOAP_AB_CONTACT_DEL_PAYLOAD \ - "<ABContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<abId>00000000-0000-0000-0000-000000000000</abId>" \ - "<contacts>" \ - "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ - "<contactId>%s</contactId>" \ - "</Contact>" \ - "</contacts>" \ - "</ABContactDelete>" + "<ABContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<abId>00000000-0000-0000-0000-000000000000</abId>" \ + "<contacts>" \ + "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">" \ + "<contactId>%s</contactId>" \ + "</Contact>" \ + "</contacts>" \ + "</ABContactDelete>" -int msn_soap_addressbook_request( struct im_connection *ic ); -int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new ); -int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu ); -int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ); +int msn_soap_addressbook_request(struct im_connection *ic); +int msn_soap_addressbook_set_display_name(struct im_connection *ic, const char *new); +int msn_soap_ab_contact_add(struct im_connection *ic, bee_user_t *bu); +int msn_soap_ab_contact_del(struct im_connection *ic, bee_user_t *bu); #define SOAP_STORAGE_URL "https://storage.msn.com/storageservice/SchematizedStore.asmx" @@ -269,74 +269,74 @@ int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ); #define SOAP_PROFILE_SET_DN_ACTION "http://www.msn.com/webservices/storage/w10/UpdateProfile" #define SOAP_PROFILE_GET_PAYLOAD \ -"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ -"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<ApplicationID>Messenger Client 9.0</ApplicationID>" \ - "<Scenario>Initial</Scenario>" \ - "</StorageApplicationHeader>" \ - "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<Puid>0</Puid>" \ - "<TicketToken>%s</TicketToken>" \ - "</StorageUserHeader>" \ - "</soap:Header>" \ - "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<GetProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<profileHandle>" \ - "<Alias>" \ - "<Name>%s</Name>" \ - "<NameSpace>MyCidStuff</NameSpace>" \ - "</Alias>" \ - "<RelationshipName>MyProfile</RelationshipName>" \ - "</profileHandle>" \ - "<profileAttributes>" \ - "<ResourceID>true</ResourceID>" \ - "<DateModified>true</DateModified>" \ - "<ExpressionProfileAttributes>" \ - "<ResourceID>true</ResourceID>" \ - "<DateModified>true</DateModified>" \ - "<DisplayName>true</DisplayName>" \ - "<DisplayNameLastModified>true</DisplayNameLastModified>" \ - "<PersonalStatus>true</PersonalStatus>" \ - "<PersonalStatusLastModified>true</PersonalStatusLastModified>" \ - "<StaticUserTilePublicURL>true</StaticUserTilePublicURL>" \ - "<Photo>true</Photo>" \ - "<Flags>true</Flags>" \ - "</ExpressionProfileAttributes>" \ - "</profileAttributes>" \ - "</GetProfile>" \ - "</soap:Body>" \ -"</soap:Envelope>" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<ApplicationID>Messenger Client 9.0</ApplicationID>" \ + "<Scenario>Initial</Scenario>" \ + "</StorageApplicationHeader>" \ + "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<Puid>0</Puid>" \ + "<TicketToken>%s</TicketToken>" \ + "</StorageUserHeader>" \ + "</soap:Header>" \ + "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<GetProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<profileHandle>" \ + "<Alias>" \ + "<Name>%s</Name>" \ + "<NameSpace>MyCidStuff</NameSpace>" \ + "</Alias>" \ + "<RelationshipName>MyProfile</RelationshipName>" \ + "</profileHandle>" \ + "<profileAttributes>" \ + "<ResourceID>true</ResourceID>" \ + "<DateModified>true</DateModified>" \ + "<ExpressionProfileAttributes>" \ + "<ResourceID>true</ResourceID>" \ + "<DateModified>true</DateModified>" \ + "<DisplayName>true</DisplayName>" \ + "<DisplayNameLastModified>true</DisplayNameLastModified>" \ + "<PersonalStatus>true</PersonalStatus>" \ + "<PersonalStatusLastModified>true</PersonalStatusLastModified>" \ + "<StaticUserTilePublicURL>true</StaticUserTilePublicURL>" \ + "<Photo>true</Photo>" \ + "<Flags>true</Flags>" \ + "</ExpressionProfileAttributes>" \ + "</profileAttributes>" \ + "</GetProfile>" \ + "</soap:Body>" \ + "</soap:Envelope>" #define SOAP_PROFILE_SET_DN_PAYLOAD \ -"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ -"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<ApplicationID>Messenger Client 9.0</ApplicationID>" \ - "<Scenario>Initial</Scenario>" \ - "</StorageApplicationHeader>" \ - "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<Puid>0</Puid>" \ - "<TicketToken>%s</TicketToken>" \ - "</StorageUserHeader>" \ - "</soap:Header>" \ - "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ - "<UpdateProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ - "<profile>" \ - "<ResourceID>%s</ResourceID>" \ - "<ExpressionProfile>" \ - "<FreeText>Update</FreeText>" \ - "<DisplayName>%s</DisplayName>" \ - "<Flags>0</Flags>" \ - "</ExpressionProfile>" \ - "</profile>" \ - "</UpdateProfile>" \ - "</soap:Body>" \ -"</soap:Envelope>" - -int msn_soap_profile_get( struct im_connection *ic, const char *cid ); -int msn_soap_profile_set_dn( struct im_connection *ic, const char *dn ); + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<ApplicationID>Messenger Client 9.0</ApplicationID>" \ + "<Scenario>Initial</Scenario>" \ + "</StorageApplicationHeader>" \ + "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<Puid>0</Puid>" \ + "<TicketToken>%s</TicketToken>" \ + "</StorageUserHeader>" \ + "</soap:Header>" \ + "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<UpdateProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<profile>" \ + "<ResourceID>%s</ResourceID>" \ + "<ExpressionProfile>" \ + "<FreeText>Update</FreeText>" \ + "<DisplayName>%s</DisplayName>" \ + "<Flags>0</Flags>" \ + "</ExpressionProfile>" \ + "</profile>" \ + "</UpdateProfile>" \ + "</soap:Body>" \ + "</soap:Envelope>" + +int msn_soap_profile_get(struct im_connection *ic, const char *cid); +int msn_soap_profile_set_dn(struct im_connection *ic, const char *dn); #endif /* __SOAP_H__ */ diff --git a/protocols/msn/tables.c b/protocols/msn/tables.c index c3e36eb5..c4dc895e 100644 --- a/protocols/msn/tables.c +++ b/protocols/msn/tables.c @@ -1,4 +1,4 @@ - /********************************************************************\ +/********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * * Copyright 2002-2010 Wilmer van der Gaast and others * @@ -39,25 +39,29 @@ const struct msn_away_state msn_away_state_list[] = { "", "" } }; -const struct msn_away_state *msn_away_state_by_code( char *code ) +const struct msn_away_state *msn_away_state_by_code(char *code) { int i; - - for( i = 0; *msn_away_state_list[i].code; i ++ ) - if( g_strcasecmp( msn_away_state_list[i].code, code ) == 0 ) - return( msn_away_state_list + i ); - + + for (i = 0; *msn_away_state_list[i].code; i++) { + if (g_strcasecmp(msn_away_state_list[i].code, code) == 0) { + return(msn_away_state_list + i); + } + } + return NULL; } -const struct msn_away_state *msn_away_state_by_name( char *name ) +const struct msn_away_state *msn_away_state_by_name(char *name) { int i; - - for( i = 0; *msn_away_state_list[i].code; i ++ ) - if( g_strcasecmp( msn_away_state_list[i].name, name ) == 0 ) - return( msn_away_state_list + i ); - + + for (i = 0; *msn_away_state_list[i].code; i++) { + if (g_strcasecmp(msn_away_state_list[i].name, name) == 0) { + return(msn_away_state_list + i); + } + } + return NULL; } @@ -86,24 +90,24 @@ const struct msn_status_code msn_status_code_list[] = { 241, "ADL/RML command with invalid modification", 0 }, { 280, "Switchboard failed", STATUS_SB_FATAL }, { 281, "Transfer to switchboard failed", 0 }, - + { 300, "Required field missing", 0 }, { 302, "Not logged in", 0 }, - + { 500, "Internal server error/Account banned", STATUS_FATAL }, { 501, "Database server error", STATUS_FATAL }, { 502, "Command disabled", 0 }, { 510, "File operation failed", STATUS_FATAL }, { 520, "Memory allocation failed", STATUS_FATAL }, { 540, "Challenge response invalid", STATUS_FATAL }, - + { 600, "Server is busy", STATUS_FATAL }, { 601, "Server is unavailable", STATUS_FATAL }, { 602, "Peer nameserver is down", STATUS_FATAL }, { 603, "Database connection failed", STATUS_FATAL }, { 604, "Server is going down", STATUS_FATAL }, { 605, "Server is unavailable", STATUS_FATAL }, - + { 700, "Could not create connection", STATUS_FATAL }, { 710, "Invalid CVR parameters", STATUS_FATAL }, { 711, "Write is blocking", STATUS_FATAL }, @@ -113,9 +117,9 @@ const struct msn_status_code msn_status_code_list[] = { 715, "Not expected/Invalid argument/action", 0 }, { 717, "Bad friend file", STATUS_FATAL }, { 731, "Not expected/Invalid argument", 0 }, - + { 800, "Changing too rapidly", 0 }, - + { 910, "Server is busy", STATUS_FATAL }, { 911, "Authentication failed", STATUS_SB_FATAL | STATUS_FATAL }, { 912, "Server is busy", STATUS_FATAL }, @@ -134,24 +138,25 @@ const struct msn_status_code msn_status_code_list[] = { -1, NULL, 0 } }; -const struct msn_status_code *msn_status_by_number( int number ) +const struct msn_status_code *msn_status_by_number(int number) { static struct msn_status_code *unknown = NULL; int i; - - for( i = 0; msn_status_code_list[i].number >= 0; i ++ ) - if( msn_status_code_list[i].number == number ) - return( msn_status_code_list + i ); - - if( unknown == NULL ) - { - unknown = g_new0( struct msn_status_code, 1 ); - unknown->text = g_new0( char, 128 ); + + for (i = 0; msn_status_code_list[i].number >= 0; i++) { + if (msn_status_code_list[i].number == number) { + return(msn_status_code_list + i); + } } - + + if (unknown == NULL) { + unknown = g_new0(struct msn_status_code, 1); + unknown->text = g_new0(char, 128); + } + unknown->number = number; unknown->flags = 0; - g_snprintf( unknown->text, 128, "Unknown error (%d)", number ); - - return( unknown ); + g_snprintf(unknown->text, 128, "Unknown error (%d)", number); + + return(unknown); } |