aboutsummaryrefslogtreecommitdiff
path: root/src/msnprotocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/msnprotocol.c')
-rw-r--r--src/msnprotocol.c492
1 files changed, 246 insertions, 246 deletions
diff --git a/src/msnprotocol.c b/src/msnprotocol.c
index fe7635e..680783e 100644
--- a/src/msnprotocol.c
+++ b/src/msnprotocol.c
@@ -8,17 +8,17 @@
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 dated June, 1991.
+ * the Free Software Foundation; version 2 dated June, 1991.
*
* This package 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.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this package; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*
*/
@@ -96,7 +96,7 @@ static struct {
NSConMode conmode; /* What's being read at the moment? */
size_t expect_length; /* Amount of MSG/UBX etc expected. */
char *msg_source; /* Source of MSG/UBX etc */
-
+
/* Read/write buffers */
char *wbuffer; /* Buffer for outgoing data */
unsigned int wbufsize; /* Current size of the write buffer */
@@ -123,7 +123,7 @@ static struct {
NSCONMODE_LINE,
0,
NULL,
-
+
NULL,
0,
0,
@@ -150,7 +150,7 @@ static void msnprotocol_cleanup_internal() {
cstate.wbufsize = 0;
cstate.wbuffer = NULL;
cstate.woffset = 0;
-
+
if ( cstate.rcallback != 0 ) {
gdk_input_remove(cstate.rcallback);
}
@@ -159,7 +159,7 @@ static void msnprotocol_cleanup_internal() {
gdk_input_remove(cstate.wcallback);
}
cstate.wcallback = 0;
-
+
if ( cstate.disconnect_callback != 0 ) {
gtk_timeout_remove(cstate.disconnect_callback);
cstate.disconnect_callback = 0;
@@ -169,24 +169,24 @@ static void msnprotocol_cleanup_internal() {
gtk_timeout_remove(cstate.ping_callback);
cstate.ping_callback = 0;
}
-
+
cstate.connect_lock = 0;
cstate.trid = 1;
cstate.disconnect_expected = 0;
cstate.connected = CSTATE_DISCONNECTED;
-
+
sbsessions_destroy_all();
messagewindow_disable_all();
contactlist_clear();
-
+
}
/* Free buffers, remove callbacks, return main window to dispatch mode, etc. */
static void msnprotocol_cleanup() {
- msnprotocol_cleanup_internal();
+ msnprotocol_cleanup_internal();
mainwindow_setdispatch();
-
+
}
/* If a disconnection hasn't happened ten seconds after requesting it, pull the plug. */
@@ -197,15 +197,15 @@ static gint msnprotocol_forcedisconnect() {
debug_print("NS: Waited too long for disconnection... pulling the plug.\n");
cstate.disconnect_callback = 0;
-
+
closeval = close(cstate.socket);
if ( closeval != 0 ) {
/* Grrr.. now it won't close - not much we can do. */
debug_print("NS: Couldn't close socket after write error.\n");
}
-
+
msnprotocol_cleanup();
-
+
return FALSE;
}
@@ -230,12 +230,12 @@ static void msnprotocol_writeable() {
if ( debug_string[i] == '\n' ) {
debug_string[i] = 'n';
}
- }
+ }
debug_print("NS: send: '%s'\n", debug_string);
free(debug_string);
if ( wlen > 0 ) {
-
+
/* wlen holds the number of bytes written. Sort the buffer out accordingly... */
memmove(cstate.wbuffer, cstate.wbuffer + wlen, cstate.wbufsize - wlen);
new_wbufsize = cstate.wbufsize - wlen;
@@ -243,19 +243,19 @@ static void msnprotocol_writeable() {
cstate.wbuffer = realloc(cstate.wbuffer, new_wbufsize);
if ( new_wbufsize == 0 ) {
-
+
gdk_input_remove(cstate.wcallback);
cstate.wcallback = 0;
cstate.wbuffer = NULL;
-
+
}
cstate.wbufsize = new_wbufsize;
- cstate.woffset -= wlen;
+ cstate.woffset -= wlen;
} else {
-
+
if ( wlen == -1 ) {
-
+
/* Write error! :( */
if ( errno != EAGAIN ) { /* EAGAIN should never happen here */
@@ -269,11 +269,11 @@ static void msnprotocol_writeable() {
error_report("Write error! Signed out.");
msnprotocol_cleanup();
return;
-
+
}
-
+
}
-
+
}
}
@@ -286,13 +286,13 @@ static int msnprotocol_sendtr_internal(char *instr, char *args, int newline, int
len = strlen(instr);
if ( send_trid ) {
-
+
trid_string = malloc(8);
assert(cstate.trid < 999999); /* Sanity check */
sprintf(trid_string, "%i", cstate.trid);
len += 1; /* Space before the TrId */
len += strlen(trid_string);
-
+
}
if ( strlen(args) > 0 ) {
len += strlen(args);
@@ -309,7 +309,7 @@ static int msnprotocol_sendtr_internal(char *instr, char *args, int newline, int
assert(cstate.wbuffer != NULL);
cstate.wbufsize = len;
cstate.woffset = 0;
-
+
}
if ( (cstate.wbufsize - cstate.woffset) < len ) {
@@ -318,37 +318,37 @@ static int msnprotocol_sendtr_internal(char *instr, char *args, int newline, int
assert(cstate.wbuffer != NULL);
cstate.wbufsize = len + cstate.woffset;
assert(cstate.wbufsize < 1024*1024); /* Stop the buffer from getting insane */
-
+
}
-
+
/* Do the write (to memory). Deliberately verbose... */
memcpy(cstate.wbuffer + cstate.woffset, instr, strlen(instr));
cstate.woffset += strlen(instr);
if ( send_trid ) {
-
+
*(cstate.wbuffer + cstate.woffset) = ' ';
cstate.woffset += 1;
-
+
memcpy(cstate.wbuffer + cstate.woffset, trid_string, strlen(trid_string));
cstate.woffset += strlen(trid_string);
free(trid_string);
-
+
}
if ( strlen(args) > 0 ) {
-
+
*(cstate.wbuffer + cstate.woffset) = ' ';
cstate.woffset += 1;
memcpy(cstate.wbuffer + cstate.woffset, args, strlen(args));
cstate.woffset += strlen(args);
-
+
}
if ( newline ) {
-
+
*(cstate.wbuffer + cstate.woffset) = '\r';
cstate.woffset += 1;
*(cstate.wbuffer + cstate.woffset) = '\n';
cstate.woffset += 1;
-
+
}
/* Note the lack of a \0 terminator. It's done using records of the buffer data lengths. */
@@ -372,7 +372,7 @@ static gint msnprotocol_sendping() {
msnprotocol_sendtr_internal("PNG", "", 1, 0);
cstate.ping_callback = 0;
-
+
return FALSE;
}
@@ -394,11 +394,11 @@ static void msnprotocol_handle_lst(char *line) {
int finished = 0;
int field_num = 1;
int list_coming = 0;
-
+
/* Step through the LST data and look for friendlyname, username and list number */
-
+
while ( !finished ) {
-
+
char *field;
int field_used = 0;
field = routines_lindex(line, field_num);
@@ -406,9 +406,9 @@ static void msnprotocol_handle_lst(char *line) {
if ( strlen(field) == 0 ) {
finished = 1;
} else {
-
+
if ( strlen(field) > 2 ) {
-
+
if ( (field[0] == 'F') && (field[1] == '=') ) {
friendlyname = strdup(field+2);
list_coming = 1;
@@ -422,22 +422,22 @@ static void msnprotocol_handle_lst(char *line) {
list_coming = 1;
field_used = 1;
}
-
+
}
/* "list" is the first field without "X=" */
if ( list_coming && !field_used ) {
list = strdup(field);
finished = 1; /* Otherwise the next field will get used instead. */
}
-
+
}
free(field);
-
+
}
/* Need at least a username and list to continue */
if ( (username == NULL) || (list == NULL) ) {
-
+
debug_print("NS: Didn't get enough information from LST: missing");
if ( username == NULL ) {
debug_print(" username");
@@ -453,15 +453,15 @@ static void msnprotocol_handle_lst(char *line) {
free(friendlyname); /* Don't leak memory */
}
debug_print("\n");
-
+
} else {
-
+
list_num = atoi(list);
free(list);
if ( list_num > 31 ) {
debug_print("NS: Warning: contact is on unrecognised list(s).\n");
}
-
+
if ( list_num & 1 ) {
contactlist_fldetails(CONTACT_SOURCE_LST, username, friendlyname, 0, NULL, ONLINE_FLN, guid);
}
@@ -481,17 +481,17 @@ static void msnprotocol_handle_lst(char *line) {
/* If contact is ONLY on the RL, add them to the PL as well. This should never
happen with MSNP11+, but ensures that caching takes place properly. */
contactlist_pldetails(CONTACT_SOURCE_LST, username, friendlyname, ONLINE_FLN);
- }
+ }
if ( (list_num == 8) || (list_num & 16) ) {
-
+
/* On RL but not FL, AL or BL indicates new user.
On PL also indicates new user. */
addcontact_added(username, friendlyname);
-
+
}
-
+
}
-
+
}
/* Despite the name, handles ILN and NLN */
@@ -505,27 +505,27 @@ static void msnprotocol_handle_nln(nln_t nln, char *line) {
char *dpobject;
char *status_string;
int lindex_sub;
-
+
/* Subtract one from all the list indices if this isn't ILN, since there's no TrID */
if ( nln == NLN_ILN ) {
lindex_sub = 0;
} else {
lindex_sub = 1;
}
-
+
status_string = routines_lindex(line, 2-lindex_sub);
new_status = msngenerics_decodestatus(status_string);
assert(new_status != ONLINE_FLN); /* This would be handled elsewhere. */
assert(new_status != ONLINE_HDN); /* Nonsense */
free(status_string);
-
+
username = routines_lindex(line, 3-lindex_sub);
friendlyname = routines_lindex(line, 4-lindex_sub);
features_string = routines_lindex(line, 5-lindex_sub);
features = atoi(features_string);
free(features_string);
dpobject = routines_lindex(line, 6-lindex_sub);
-
+
/* Pass NULL if there's no "dpobject" */
if ( strlen(dpobject) == 0 ) {
free(dpobject);
@@ -541,7 +541,7 @@ static void msnprotocol_handle_nln(nln_t nln, char *line) {
/* contactlist_fldetails won't overwrite the GUID with NULL. */
contactlist_fldetails(CONTACT_SOURCE_NLN, username, friendlyname, features, dpobject, new_status, NULL);
-
+
/* contactlist_fldetails copies anything it's interested in */
free(username);
free(friendlyname);
@@ -556,12 +556,12 @@ static void msnprotocol_doneconnect() {
cstate.connected = CSTATE_CONNECTED;
mainwindow_forcestatus(ONLINE_HDN);
-
+
/* Start pinging. */
if ( cstate.ping_callback == 0 ) {
cstate.ping_callback = gtk_timeout_add(50000, (GtkFunction)msnprotocol_sendping, NULL);
}
-
+
if ( cstate.protocol_version >= 11 ) {
msnprotocol_sendtr("GCF", "Shields.xml");
}
@@ -578,22 +578,22 @@ static int msnprotocol_parseline(char *line) {
int trid;
debug_print("NS: recv: '%s'\n", line);
-
+
/* Prevent blank or short lines from being a problem */
if ( strlen(line) < 4 ) {
return 0;
}
-
+
instr = malloc(4);
strncpy(instr, line, 3);
instr[3] = '\0';
-
+
if ( line[3] != ' ' ) {
line[0] = ' ';
line[1] = ' ';
line[2] = ' '; /* Prevent bogus interpretations of things that aren't three letters */
}
-
+
err_num = atoi(instr);
err_str = malloc(4);
assert(err_num < 1000);
@@ -608,7 +608,7 @@ static int msnprotocol_parseline(char *line) {
}
}
free(err_str);
-
+
trid_string = routines_lindex(line, 1);
trid = atoi(trid_string);
free(trid_string);
@@ -620,16 +620,16 @@ static int msnprotocol_parseline(char *line) {
error_report("Signed in somewhere else.");
}
free(sit);
- }
+ }
if ( strcmp("VER", instr) == 0 ) {
-
+
char *string;
char *protocol;
int got_cvr = FALSE;
int highest_msnp = 0;
int pos = 1;
-
+
protocol = routines_lindex(line, pos++);
while ( strlen(protocol) ) {
if ( strncmp(protocol, "MSNP", 4) == 0 ) {
@@ -653,18 +653,18 @@ static int msnprotocol_parseline(char *line) {
return -1;
}
cstate.protocol_version = highest_msnp;
-
+
string = malloc(128);
strcpy(string, "0x0409 winnt 5.1 i386 MSNMSGR 7.5.0311 msmsgs ");
strncat(string, options_username(), 64);
string[127] = '\0';
msnprotocol_sendtr("CVR", string);
free(string);
-
+
}
-
+
if ( strcmp("CVR", instr) == 0 ) {
-
+
char *string;
string = malloc(128);
strcpy(string, "TWN I ");
@@ -672,16 +672,16 @@ static int msnprotocol_parseline(char *line) {
string[127] = '\0';
msnprotocol_sendtr("USR", string);
free(string);
-
+
}
-
+
if ( strcmp("XFR", instr) == 0 ) {
-
+
char *mbuffer_type;
mbuffer_type = routines_lindex(line, 2);
-
+
if ( strcmp("NS", mbuffer_type) == 0 ) {
-
+
/* got transferred to a different NS */
unsigned int new_port;
char *new_hostname;
@@ -698,16 +698,16 @@ static int msnprotocol_parseline(char *line) {
msnprotocol_cleanup_internal();
msnprotocol_connect(new_hostname, new_port);
-
+
/* ...and now for some "tedious mucking-about in hyperspace"... */
free(target);
free(new_hostname);
free(mbuffer_type);
free(instr);
return -1;
-
+
} else if ( strcmp("SB", mbuffer_type) == 0 ) {
-
+
/* SB transfer - part of an SbSession negotiation. */
unsigned int port;
char *hostname;
@@ -724,7 +724,7 @@ static int msnprotocol_parseline(char *line) {
port = DEFAULT_SB_PORT;
debug_print("NS: Corrected to %i\n", port);
}
-
+
authtype = routines_lindex(line, 4);
if ( strcmp(authtype, "CKI") != 0 ) {
@@ -741,26 +741,26 @@ static int msnprotocol_parseline(char *line) {
cki_key = routines_lindex(line, 5);
trid_char = routines_lindex(line, 1);
sbprotocol_initiate_local(atoi(trid_char), hostname, port, cki_key);
-
+
free(trid_char);
free(cki_key);
free(hostname);
free(target);
}
-
+
free(mbuffer_type);
-
+
}
-
+
if ( strcmp("USR", instr) == 0 ) {
-
+
if ( line[10] == 'S' ) {
-
+
char *auth_string;
char *auth_data;
char *auth_ticket;
-
+
auth_string = malloc(1024);
strcpy(auth_string, "TWN S ");
auth_data = routines_lindex(line, 4);
@@ -780,41 +780,41 @@ static int msnprotocol_parseline(char *line) {
}
free(auth_data);
free(auth_string);
-
+
} else {
-
+
if ( ( line[6] == 'O' ) && ( line[7] == 'K' ) ) {
/* Success! */
char *syn_max;
-
+
cstate.connected = CSTATE_LIST;
syn_max = listcache_loadtag();
msnprotocol_sendtr("SYN", syn_max);
-
+
}
}
-
+
}
-
+
if ( strcmp("LST", instr) == 0 ) {
-
+
msnprotocol_handle_lst(line);
cstate.lst_num++;
if ( cstate.lst_num == cstate.lst_num_max ) {
msnprotocol_doneconnect();
}
-
+
}
-
+
if ( strcmp("REM", instr) == 0 ) {
-
+
char *list = routines_lindex(line, 2);
char *usernameguid = routines_lindex(line, 3); /* Could be either! */
-
+
if ( strcmp(list, "FL") == 0 ) {
contactlist_removecontactguid(list, usernameguid);
} else {
@@ -822,31 +822,31 @@ static int msnprotocol_parseline(char *line) {
}
free(list);
free(usernameguid);
-
+
}
if ( strcmp("ADC", instr) == 0 ) {
-
+
char *list;
unsigned int field_num = 2;
int finished = 0;
char *friendlyname = NULL;
char *username = NULL;
char *guid = NULL;
-
+
while ( !finished ) {
-
+
char *field;
-
+
field = routines_lindex(line, field_num);
field_num++;
-
+
if ( strlen(field) == 0 ) {
finished = 1;
} else {
-
+
if ( strlen(field) > 2 ) {
-
+
if ( (field[0] == 'F') && (field[1] == '=') ) {
friendlyname = strdup(field+2);
} else if ( (field[0] == 'N') && (field[1] == '=') ) {
@@ -854,14 +854,14 @@ static int msnprotocol_parseline(char *line) {
} else if ( (field[0] == 'C') && (field[1] == '=') ) {
guid = strdup(field+2);
}
-
+
}
-
+
}
free(field);
-
+
}
-
+
list = routines_lindex(line, 2);
if ( guid != NULL ) {
if ( strlen(guid) == 0 ) {
@@ -903,29 +903,29 @@ static int msnprotocol_parseline(char *line) {
if ( guid != NULL ) {
free(guid);
}
-
+
}
-
+
if ( strcmp("NLN", instr) == 0 ) {
msnprotocol_handle_nln(NLN_NLN, line);
}
-
+
if ( strcmp("ILN", instr) == 0 ) {
msnprotocol_handle_nln(NLN_ILN, line);
}
if ( strcmp("FLN", instr) == 0 ) {
-
+
char *username = routines_lindex(line, 1);
/* NULL values won't overwrite anything since CONTACT_SOURCE_FLN has extremely low priority */
contactlist_fldetails(CONTACT_SOURCE_FLN, username, NULL, 0, NULL, ONLINE_FLN, NULL);
messagewindow_notifyoffline(username);
free(username);
-
+
}
if ( strcmp("CHL", instr) == 0 ) {
-
+
char *response;
char *challenge;
challenge = routines_lindex(line, 2);
@@ -933,8 +933,8 @@ static int msnprotocol_parseline(char *line) {
if ( cstate.protocol_version < 11 ) {
unsigned char *md5;
- unsigned int i;
-
+ unsigned int i;
+
response = malloc(1024);
strncpy(response, challenge, 64);
response[1023] = '\0';
@@ -954,79 +954,79 @@ static int msnprotocol_parseline(char *line) {
}
} else {
-
+
char *hex;
hex = msnp11chl_response(challenge);
response = malloc(strlen(hex)+strlen(CLIENT_ID)+7);
sprintf(response, CLIENT_ID" 32\n%s", hex);
free(hex);
-
+
}
free(challenge);
msnprotocol_sendtr_nonewline("QRY", response);
free(response);
-
+
}
-
+
if ( strcmp("PRP", instr) == 0 ) {
-
+
char *prp_field;
int check;
-
+
/* Format #1: from SYN */
prp_field = routines_lindex(line, 1);
if ( strcmp(prp_field, "MFN") == 0 ) {
-
+
char *new_friendlyname;
new_friendlyname = routines_lindex(line, 2);
mainwindow_setmfn(new_friendlyname);
listcache_setmfn(new_friendlyname);
free(new_friendlyname);
-
+
}
-
+
check = atoi(prp_field);
if ( check > 0 ) {
-
+
char *prp_field2;
-
+
/* Format #2: from PRP - only attempt if TrID is present. */
prp_field2 = routines_lindex(line, 2);
if ( strcmp(prp_field2, "MFN") == 0 ) {
-
+
char *new_friendlyname;
new_friendlyname = routines_lindex(line, 3);
mainwindow_setmfn(new_friendlyname);
listcache_setmfn(new_friendlyname);
free(new_friendlyname);
-
+
}
free(prp_field2);
-
+
}
free(prp_field);
-
-
-
+
+
+
}
-
+
if ( strcmp("SYN", instr) == 0 ) {
-
+
char *newest_tag_1;
char *newest_tag_2;
char *full_tag;
char *num_contacts;
-
+
newest_tag_1 = routines_lindex(line, 2);
newest_tag_2 = routines_lindex(line, 3);
num_contacts = routines_lindex(line, 4);
/* num_groups = routines_lindex(line, 5); */
-
+
assert(num_contacts != NULL);
cstate.lst_num_max = atoi(num_contacts);
free(num_contacts);
- if ( cstate.lst_num_max == 0 ) {
+ if ( cstate.lst_num_max == 0 ) {
/* This indicates an empty list OR an up-to-date list */
listcache_load();
msnprotocol_doneconnect();
@@ -1034,63 +1034,63 @@ static int msnprotocol_parseline(char *line) {
cstate.connected = CSTATE_LIST;
}
cstate.lst_num = 0;
-
+
assert(newest_tag_1 != NULL);
assert(newest_tag_2 != NULL);
-
+
full_tag = malloc(strlen(newest_tag_1) + strlen(newest_tag_2) + 2);
assert(full_tag != NULL);
-
+
strcpy(full_tag, newest_tag_1);
strcat(full_tag, " ");
strcat(full_tag, newest_tag_2);
-
+
listcache_settag(full_tag);
-
+
free(full_tag);
free(newest_tag_1);
free(newest_tag_2);
-
+
}
-
+
if ( strcmp("QNG", instr) == 0 ) {
-
+
/* The time interval given by the QNG is ignored to keep things under program control.
Let me know if this causes any problems for you... */
if ( cstate.ping_callback == 0 ) {
cstate.ping_callback = gtk_timeout_add(50000, (GtkFunction)msnprotocol_sendping, NULL);
}
-
+
}
-
+
if ( strcmp("RNG", instr) == 0 ) {
-
+
/* Yay! */
char *sessionid;
char *callinguser;
char *switchboardaddress;
char *authchallenge;
char *authtype;
-
+
sessionid = routines_lindex(line, 1);
callinguser = routines_lindex(line, 5);
switchboardaddress = routines_lindex(line, 2);
authchallenge = routines_lindex(line, 4);
-
+
debug_print("NS: Received SB invitation from %s (ID=%s, Key=%s, Addr=%s)\n", callinguser, sessionid, authchallenge, switchboardaddress);
-
+
/* Check if the friendly name is available for this user. If not, TL them.
This could actually happen if the user is on another list but has no friendlyname.
This situation doesn't matter. */
if ( contactlist_friendlyname(callinguser) == NULL ) {
-
+
char *friendlyname = routines_lindex(line, 6);
debug_print("NS: Creating TL record: '%s'/'%s'\n", callinguser, friendlyname);
contactlist_tldetails(CONTACT_SOURCE_RNG, callinguser, friendlyname, ONLINE_NLN);
free(friendlyname);
-
+
}
-
+
authtype = routines_lindex(line, 3);
if ( strcmp(authtype, "CKI") != 0 ) {
@@ -1101,19 +1101,19 @@ static int msnprotocol_parseline(char *line) {
return 0;
}
- free(authtype);
+ free(authtype);
sbsessions_create_remote(callinguser, switchboardaddress, sessionid, authchallenge);
free(callinguser);
free(switchboardaddress);
free(authchallenge);
free(sessionid);
-
+
}
-
+
if ( strcmp("MSG", instr) == 0 ) {
-
+
char *length;
-
+
length = routines_lindex(line, 3);
cstate.expect_length = atoi(length);
free(length);
@@ -1123,13 +1123,13 @@ static int msnprotocol_parseline(char *line) {
} else {
debug_print("NS: Zero-sized MSG??\n");
}
-
+
}
if ( strcmp("UBX", instr) == 0 ) {
-
+
char *length;
-
+
length = routines_lindex(line, 2);
cstate.expect_length = atoi(length);
free(length);
@@ -1139,13 +1139,13 @@ static int msnprotocol_parseline(char *line) {
} else {
debug_print("NS: Zero-sized UBX??\n"); /* This seems to happen sometimes. */
}
-
+
}
-
+
if ( strcmp("NOT", instr) == 0 ) {
-
+
char *length;
-
+
length = routines_lindex(line, 1);
cstate.expect_length = atoi(length);
free(length);
@@ -1154,14 +1154,14 @@ static int msnprotocol_parseline(char *line) {
} else {
debug_print("NS: Zero-sized NOT??\n");
}
-
+
}
if ( strcmp("GCF", instr) == 0 ) {
-
+
char *length;
char *file;
-
+
length = routines_lindex(line, 3);
file = routines_lindex(line, 2);
cstate.expect_length = atoi(length);
@@ -1176,25 +1176,25 @@ static int msnprotocol_parseline(char *line) {
debug_print("NS: Zero-sized GCF??\n");
}
free(file);
-
+
}
if ( strcmp("CHG", instr) == 0 ) {
-
+
OnlineState old_state = cstate.status;
-
+
char *state = routines_lindex(line, 2);
cstate.status = msngenerics_decodestatus(state);
free(state);
-
+
if ( (old_state == ONLINE_HDN) && (cstate.status != ONLINE_HDN) ) {
messagewindow_enable_all();
}
-
+
}
free(instr);
-
+
return 0;
}
@@ -1209,7 +1209,7 @@ static void msnprotocol_parsemsg(const char *msg, size_t msglen) {
static void msnprotocol_parseubx(const char *msg, size_t msglen) {
debug_print("NS: Got UBX data for '%s' (%i bytes) '%s'\n", cstate.msg_source, msglen, msg);
- contactlist_setubx(cstate.msg_source, msg, msglen);
+ contactlist_setubx(cstate.msg_source, msg, msglen);
free(cstate.msg_source);
}
@@ -1243,13 +1243,13 @@ static void msnprotocol_readable() {
if ( (rlen == 0) || (rlen == -1) ) {
int closeval;
-
+
closeval = close(cstate.socket);
-
+
if ( closeval != 0 ) {
debug_print("NS: Couldn't close socket after read error.\n");
}
-
+
/* A variety of ways to express this to the user... */
if ( cstate.connected == CSTATE_CONNECTED ) {
if ( !cstate.disconnect_expected ) {
@@ -1264,75 +1264,75 @@ static void msnprotocol_readable() {
error_report("Read error in unrecognised connection state. This never happens :P");
debug_print("NS: Connection state %i\n", cstate.connected);
}
-
+
msnprotocol_cleanup();
return;
-
+
}
-
+
while ( (!no_string) && (cstate.roffset > 0) ) {
-
+
int block_ready = 0;
size_t i = 0;
/* See if there's a full "block" in the buffer yet */
if ( cstate.conmode == NSCONMODE_LINE ) {
-
+
for ( i=0; i<cstate.roffset-1; i++ ) { /* Means the last value looked at is roffset-2 */
- if ( (cstate.rbuffer[i] == '\r') && (cstate.rbuffer[i+1] == '\n') ) {
+ if ( (cstate.rbuffer[i] == '\r') && (cstate.rbuffer[i+1] == '\n') ) {
block_ready = 1;
break;
}
}
-
+
} else if ( cstate.conmode == NSCONMODE_MSG ) {
-
+
if ( cstate.roffset >= cstate.expect_length ) {
i = cstate.expect_length - 2;
block_ready = 1;
}
-
+
} else if ( cstate.conmode == NSCONMODE_UBX ) {
-
+
if ( cstate.roffset >= cstate.expect_length ) {
i = cstate.expect_length - 2;
block_ready = 1;
}
-
+
} else if ( cstate.conmode == NSCONMODE_NOT ) {
-
+
if ( cstate.roffset >= cstate.expect_length ) {
i = cstate.expect_length - 2;
block_ready = 1;
}
-
+
} else if ( cstate.conmode == NSCONMODE_GCF_SHIELDS ) {
-
+
if ( cstate.roffset >= cstate.expect_length ) {
i = cstate.expect_length - 2;
block_ready = 1;
}
-
+
} else {
/* "Never happens". */
debug_print("NS: Can't determine end of block for NsConMode %i!\n", cstate.conmode);
}
-
+
if ( block_ready == 1 ) {
-
+
char *block_buffer = NULL;
unsigned int new_rbufsize;
unsigned int endbit_length;
NSConMode next_mode = cstate.conmode;
-
+
if ( cstate.conmode == NSCONMODE_LINE ) {
assert(cstate.rbuffer[i] == '\r');
assert(cstate.rbuffer[i+1] == '\n');
}
-
-
+
+
if ( cstate.conmode == NSCONMODE_LINE ) {
-
+
block_buffer = malloc(i+1);
memcpy(block_buffer, cstate.rbuffer, i);
block_buffer[i] = '\0';
@@ -1342,55 +1342,55 @@ static void msnprotocol_readable() {
free(block_buffer);
return;
}
-
+
/* Check to see if sbprotocol_parseline changed the mode. If so, make sure
it stays changed. */
if ( cstate.conmode != NSCONMODE_LINE ) {
next_mode = cstate.conmode;
}
-
+
} else if ( cstate.conmode == NSCONMODE_MSG ) {
-
+
block_buffer = malloc(i+3); /* Exactly the number of bytes we were told to expect, plus one for terminator. */
memcpy(block_buffer, cstate.rbuffer, i+2); /* Copy it in */
block_buffer[i+2] = '\0'; /* Terminate */
-
+
msnprotocol_parsemsg(block_buffer, i+2);
next_mode = NSCONMODE_LINE;
-
+
} else if ( cstate.conmode == NSCONMODE_UBX ) {
-
+
block_buffer = malloc(i+3); /* Exactly the number of bytes we were told to expect, plus one for terminator. */
memcpy(block_buffer, cstate.rbuffer, i+2); /* Copy it in */
block_buffer[i+2] = '\0'; /* Terminate */
-
+
msnprotocol_parseubx(block_buffer, i+2);
next_mode = NSCONMODE_LINE;
-
+
} else if ( cstate.conmode == NSCONMODE_NOT ) {
-
+
block_buffer = malloc(i+3); /* Exactly the number of bytes we were told to expect, plus one for terminator. */
memcpy(block_buffer, cstate.rbuffer, i+2); /* Copy it in */
block_buffer[i+2] = '\0'; /* Terminate */
-
+
msnprotocol_parsenotification(block_buffer, i+2);
next_mode = NSCONMODE_LINE;
-
+
} else if ( cstate.conmode == NSCONMODE_GCF_SHIELDS ) {
-
+
block_buffer = malloc(i+3); /* Exactly the number of bytes we were told to expect, plus one for terminator. */
memcpy(block_buffer, cstate.rbuffer, i+2); /* Copy it in */
block_buffer[i+2] = '\0'; /* Terminate */
-
+
msnprotocol_parseshields(block_buffer, i+2);
next_mode = NSCONMODE_LINE;
-
+
} else {
debug_print("NS: No handler for NsConMode %i !\n", cstate.conmode);
}
-
+
free(block_buffer);
-
+
/* Now the block's been parsed, it should be forgotten about */
if ( cstate.conmode == NSCONMODE_LINE ) {
assert(cstate.rbuffer[i+1] == '\n'); /* Should still be the case. Paranoid. */
@@ -1405,19 +1405,19 @@ static void msnprotocol_readable() {
cstate.rbuffer = realloc(cstate.rbuffer, new_rbufsize);
cstate.rbufsize = new_rbufsize;
cstate.conmode = next_mode;
-
+
} else {
if ( cstate.roffset == cstate.rbufsize ) {
-
+
/* More buffer space is needed */
cstate.rbuffer = realloc(cstate.rbuffer, cstate.rbufsize + 32);
cstate.rbufsize = cstate.rbufsize + 32;
/* The new space gets used at the next read, shortly... */
-
+
}
no_string = 1;
-
+
}
}
@@ -1430,7 +1430,7 @@ int msnprotocol_signedin() {
if ( cstate.connected == CSTATE_CONNECTED ) {
return 1;
}
-
+
return 0;
}
@@ -1441,7 +1441,7 @@ int msnprotocol_disconnected() {
if ( cstate.connected == CSTATE_DISCONNECTED ) {
return 1;
}
-
+
return 0;
}
@@ -1494,7 +1494,7 @@ void msnprotocol_connect(const char *hostname, unsigned short int port) {
}
sockopts = fcntl(cstate.socket, F_GETFL);
fcntl(cstate.socket, F_SETFL, sockopts | O_NONBLOCK);
-
+
/* Resolve the server name */
server = gethostbyname(hostname);
if ( server == NULL ) {
@@ -1502,7 +1502,7 @@ void msnprotocol_connect(const char *hostname, unsigned short int port) {
msnprotocol_cleanup();
return;
}
-
+
memset(&sa_desc, 0, sizeof(sa_desc));
sa_desc.sin_family = AF_INET;
memcpy(&sa_desc.sin_addr.s_addr, server->h_addr, server->h_length);
@@ -1512,15 +1512,15 @@ void msnprotocol_connect(const char *hostname, unsigned short int port) {
assert(cstate.rbuffer != NULL);
cstate.rbufsize = 256;
/* wbuffer starts at NULL and gets created when data is written */
-
+
conn_error = connect(cstate.socket, (struct sockaddr *)&sa_desc, sizeof(sa_desc));
if ( (conn_error < 0) && (errno != EINPROGRESS) ) {
-
+
debug_print("NS: Couldn't connect to server - %i\n", errno);
error_report("Couldn't connect to server");
msnprotocol_cleanup();
return;
-
+
} else {
cstate.wcallback = gdk_input_add(cstate.socket, GDK_INPUT_WRITE, (GdkInputFunction) msnprotocol_ready, NULL);
}
@@ -1538,7 +1538,7 @@ void msnprotocol_setstatus(OnlineState newstatus) {
char *dpobj;
char *string;
unsigned int clientid;
-
+
/* Don't change status too early (MSN server bug) unless signing out */
if ( (cstate.connected != CSTATE_CONNECTED) && (newstatus != ONLINE_FLN) ) {
debug_print("NS: Not ready for status change - aborting.\n");
@@ -1549,7 +1549,7 @@ void msnprotocol_setstatus(OnlineState newstatus) {
mode = "NLN"; /* Fallback */
switch ( newstatus ) {
-
+
case ONLINE_NLN : mode = "NLN"; break;
case ONLINE_AWY : mode = "AWY"; break;
case ONLINE_BSY : mode = "BSY"; break;
@@ -1566,7 +1566,7 @@ void msnprotocol_setstatus(OnlineState newstatus) {
case ONLINE_ERR : mode = "NLN"; break;
case ONLINE_IDL : mode = "AWY"; break;
case ONLINE_FLN : {
-
+
msnprotocol_sendtr("OUT", "");
if ( cstate.connected == CSTATE_CONNECTED ) {
listcache_save();
@@ -1576,16 +1576,16 @@ void msnprotocol_setstatus(OnlineState newstatus) {
cstate.disconnect_callback = gtk_timeout_add(10000, (GtkFunction)msnprotocol_forcedisconnect, NULL);
}
return;
-
+
}
-
+
}
-
+
clientid = 0x50000000 + (1<<5) + (1<<3) + (1<<2); /* MSNC5, Multipacketing (bit 5), Ink (bits 2 and 3) */
capabilities = malloc(12);
sprintf(capabilities, "%i", clientid);
dpobj = avatars_localobject();
-
+
string = malloc(strlen(mode) + strlen(capabilities) + strlen(dpobj) + 3);
strcpy(string, mode);
strcat(string, " ");
@@ -1593,11 +1593,11 @@ void msnprotocol_setstatus(OnlineState newstatus) {
strcat(string, " ");
strcat(string, dpobj);
free(dpobj);
-
+
msnprotocol_sendtr("CHG", string);
free(string);
free(capabilities);
-
+
messagewindow_picturekick(NULL);
}
@@ -1617,14 +1617,14 @@ void msnprotocol_setmfn(const char *new_mfn) {
char *mfn_string;
char *mfn_code;
-
+
mfn_code = routines_urlencode(new_mfn);
mfn_string = malloc(strlen(mfn_code)+5);
strcpy(mfn_string, "MFN ");
strcat(mfn_string, mfn_code);
msnprotocol_sendtr("PRP", mfn_string);
-
+
free(mfn_string);
}
@@ -1633,11 +1633,11 @@ void msnprotocol_setcsm(const char *new_csm) {
const char *template;
char *uuxblock;
char *sendage;
-
+
if ( cstate.protocol_version >= 11 ) {
template = "<Data><PSM></PSM><CurrentMedia></CurrentMedia></Data>";
uuxblock = xml_setblock(template, strlen(template), "Data", "PSM", new_csm);
-
+
sendage = malloc(strlen(uuxblock)+8);
assert(strlen(uuxblock)<=99999); /* 5 chars max. */
sprintf(sendage, "%i\r\n%s", strlen(uuxblock), uuxblock);