diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-07-24 15:29:48 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-07-24 15:29:48 +0200 |
commit | c8791f25459aeb32f770c46bd3a3613c9fd2d0e2 (patch) | |
tree | 6fb660cf39c58f3d880d4db7466391fdff169811 /protocols/yahoo/libyahoo2.c | |
parent | 938c30512f4dac4f084fd6bb8b7f41655de9bce4 (diff) | |
parent | c495217e7c02c908d831645b033cf115ccdc3d6d (diff) |
Merging libyahoo2 fixes. Now completely up-to-date with libyahoo2 svn
again, should try to keep it up a little bit better and submit my fixes
upstream.
This also adds code for Yahoo! file transfers but BitlBee isn't using it
yet. (It doesn't seem to support flow control which makes this complicated.)
Diffstat (limited to 'protocols/yahoo/libyahoo2.c')
-rw-r--r-- | protocols/yahoo/libyahoo2.c | 4183 |
1 files changed, 2139 insertions, 2044 deletions
diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 1bfc2e59..bd111654 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -2,6 +2,8 @@ * libyahoo2: libyahoo2.c * * Some code copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net> + * YMSG16 code copyright (C) 2009, + * Siddhesh Poyarekar <siddhesh dot poyarekar at gmail dot com> * * Yahoo Search copyright (C) 2003, Konstantin Klyagin <konst AT konst.org.ua> * @@ -26,6 +28,8 @@ * Portions of Sylpheed copyright 2000-2002 Hiroyuki Yamamoto * <hiro-y@kcn.ne.jp> * + * YMSG16 authentication code based mostly on write-up at: + * http://www.carbonize.co.uk/ymsg16.html * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,9 +95,9 @@ char *strchr (), *strrchr (); #include "http_client.h" #ifdef USE_STRUCT_CALLBACKS -struct yahoo_callbacks *yc=NULL; +struct yahoo_callbacks *yc = NULL; -void yahoo_register_callbacks(struct yahoo_callbacks * tyc) +void yahoo_register_callbacks(struct yahoo_callbacks *tyc) { yc = tyc; } @@ -103,21 +107,23 @@ void yahoo_register_callbacks(struct yahoo_callbacks * tyc) #define YAHOO_CALLBACK(x) x #endif -static int yahoo_send_data(int fd, void *data, int len); +static int yahoo_send_data(void *fd, void *data, int len); +static void _yahoo_http_connected(int id, void *fd, int error, void *data); +static void yahoo_connected(void *fd, int error, void *data); -int yahoo_log_message(char * fmt, ...) +int yahoo_log_message(char *fmt, ...) { char out[1024]; va_list ap; va_start(ap, fmt); vsnprintf(out, sizeof(out), fmt, ap); va_end(ap); - return YAHOO_CALLBACK(ext_yahoo_log)("%s", out); + return YAHOO_CALLBACK(ext_yahoo_log) ("%s", out); } -int yahoo_connect(char * host, int port) +int yahoo_connect(char *host, int port) { - return YAHOO_CALLBACK(ext_yahoo_connect)(host, port); + return YAHOO_CALLBACK(ext_yahoo_connect) (host, port); } static enum yahoo_log_level log_level = YAHOO_LOG_NONE; @@ -135,97 +141,30 @@ int yahoo_set_log_level(enum yahoo_log_level level) } /* default values for servers */ -static char pager_host[] = "scs.msg.yahoo.com"; +static char *default_pager_hosts[] = { "scs.msg.yahoo.com", + "scsa.msg.yahoo.com", + "scsb.msg.yahoo.com", + "scsc.msg.yahoo.com", + NULL}; + static int pager_port = 5050; -static int fallback_ports[]={23, 25, 80, 20, 119, 8001, 8002, 5050, 0}; -static char filetransfer_host[]="filetransfer.msg.yahoo.com"; -static int filetransfer_port=80; -static char webcam_host[]="webcam.yahoo.com"; -static int webcam_port=5100; -static char webcam_description[]=""; -static char local_host[]=""; -static int conn_type=Y_WCM_DSL; +static int fallback_ports[] = { 23, 25, 80, 20, 119, 8001, 8002, 5050, 0 }; + +static char filetransfer_host[] = "filetransfer.msg.yahoo.com"; +static int filetransfer_port = 80; +static char webcam_host[] = "webcam.yahoo.com"; +static int webcam_port = 5100; +static char webcam_description[] = ""; +static char local_host[] = ""; +static int conn_type = Y_WCM_DSL; static char profile_url[] = "http://profiles.yahoo.com/"; -enum yahoo_service { /* these are easier to see in hex */ - YAHOO_SERVICE_LOGON = 1, - YAHOO_SERVICE_LOGOFF, - YAHOO_SERVICE_ISAWAY, - YAHOO_SERVICE_ISBACK, - YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ - YAHOO_SERVICE_MESSAGE, - YAHOO_SERVICE_IDACT, - YAHOO_SERVICE_IDDEACT, - YAHOO_SERVICE_MAILSTAT, - YAHOO_SERVICE_USERSTAT, /* 0xa */ - YAHOO_SERVICE_NEWMAIL, - YAHOO_SERVICE_CHATINVITE, - YAHOO_SERVICE_CALENDAR, - YAHOO_SERVICE_NEWPERSONALMAIL, - YAHOO_SERVICE_NEWCONTACT, - YAHOO_SERVICE_ADDIDENT, /* 0x10 */ - YAHOO_SERVICE_ADDIGNORE, - YAHOO_SERVICE_PING, - YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ - YAHOO_SERVICE_SYSMESSAGE = 0x14, - YAHOO_SERVICE_SKINNAME = 0x15, - YAHOO_SERVICE_PASSTHROUGH2 = 0x16, - YAHOO_SERVICE_CONFINVITE = 0x18, - YAHOO_SERVICE_CONFLOGON, - YAHOO_SERVICE_CONFDECLINE, - YAHOO_SERVICE_CONFLOGOFF, - YAHOO_SERVICE_CONFADDINVITE, - YAHOO_SERVICE_CONFMSG, - YAHOO_SERVICE_CHATLOGON, - YAHOO_SERVICE_CHATLOGOFF, - YAHOO_SERVICE_CHATMSG = 0x20, - YAHOO_SERVICE_GAMELOGON = 0x28, - YAHOO_SERVICE_GAMELOGOFF, - YAHOO_SERVICE_GAMEMSG = 0x2a, - YAHOO_SERVICE_FILETRANSFER = 0x46, - YAHOO_SERVICE_VOICECHAT = 0x4A, - YAHOO_SERVICE_NOTIFY, - YAHOO_SERVICE_VERIFY, - YAHOO_SERVICE_P2PFILEXFER, - YAHOO_SERVICE_PEERTOPEER = 0x4F, /* Checks if P2P possible */ - YAHOO_SERVICE_WEBCAM, - YAHOO_SERVICE_AUTHRESP = 0x54, - YAHOO_SERVICE_LIST, - YAHOO_SERVICE_AUTH = 0x57, - YAHOO_SERVICE_AUTHBUDDY = 0x6d, - YAHOO_SERVICE_ADDBUDDY = 0x83, - YAHOO_SERVICE_REMBUDDY, - YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/ - YAHOO_SERVICE_REJECTCONTACT, - YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ - YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ - YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ - YAHOO_SERVICE_CHATGOTO, - YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */ - YAHOO_SERVICE_CHATLEAVE, - YAHOO_SERVICE_CHATEXIT = 0x9b, - YAHOO_SERVICE_CHATADDINVITE = 0x9d, - YAHOO_SERVICE_CHATLOGOUT = 0xa0, - YAHOO_SERVICE_CHATPING, - YAHOO_SERVICE_COMMENT = 0xa8, - YAHOO_SERVICE_STEALTH = 0xb9, - YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, - YAHOO_SERVICE_PICTURE = 0xbe, - YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, - YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, - YAHOO_SERVICE_Y6_VISIBILITY=0xc5, - YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6, - YAHOO_PHOTOSHARE_INIT=0xd2, - YAHOO_SERVICE_CONTACT_YMSG13=0xd6, - YAHOO_PHOTOSHARE_PREV=0xd7, - YAHOO_PHOTOSHARE_KEY=0xd8, - YAHOO_PHOTOSHARE_TRANS=0xda, - YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc, - YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd, - YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde, - YAHOO_SERVICE_YMSG15_STATUS=0xf0, - YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1, +struct connect_callback_data { + struct yahoo_data *yd; + int tag; + int i; + int server_i; }; struct yahoo_pair { @@ -241,15 +180,15 @@ struct yahoo_packet { }; struct yahoo_search_state { - int lsearch_type; - char *lsearch_text; - int lsearch_gender; - int lsearch_agerange; - int lsearch_photo; - int lsearch_yahoo_only; - int lsearch_nstart; - int lsearch_nfound; - int lsearch_ntotal; + int lsearch_type; + char *lsearch_text; + int lsearch_gender; + int lsearch_agerange; + int lsearch_photo; + int lsearch_yahoo_only; + int lsearch_nstart; + int lsearch_nfound; + int lsearch_ntotal; }; struct data_queue { @@ -263,34 +202,52 @@ struct yahoo_input_data { struct yahoo_webcam_data *wcd; struct yahoo_search_state *ys; - int fd; + void *fd; enum yahoo_connection_type type; - - unsigned char *rxqueue; - int rxlen; - int read_tag; + + unsigned char *rxqueue; + int rxlen; + int read_tag; YList *txqueues; - int write_tag; + int write_tag; }; struct yahoo_server_settings { char *pager_host; - int pager_port; + int pager_port; char *filetransfer_host; - int filetransfer_port; + int filetransfer_port; char *webcam_host; - int webcam_port; + int webcam_port; char *webcam_description; char *local_host; - int conn_type; + int conn_type; + char **pager_host_list; }; -static void * _yahoo_default_server_settings() +static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over); + +static void yahoo_process_filetransfer(struct yahoo_input_data *yid, + struct yahoo_packet *pkt); +static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, + struct yahoo_packet *pkt); +static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, + struct yahoo_packet *pkt); + +static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn); + +static void *_yahoo_default_server_settings() { - struct yahoo_server_settings *yss = y_new0(struct yahoo_server_settings, 1); + struct yahoo_server_settings *yss = + y_new0(struct yahoo_server_settings, 1); + + /* Give preference to the default host list + * Make sure that only one of the two is set at any time + */ + yss->pager_host = NULL; + yss->pager_host_list = default_pager_hosts; - yss->pager_host = strdup(pager_host); yss->pager_port = pager_port; yss->filetransfer_host = strdup(filetransfer_host); yss->filetransfer_port = filetransfer_port; @@ -303,54 +260,61 @@ static void * _yahoo_default_server_settings() return yss; } -static void * _yahoo_assign_server_settings(va_list ap) +static void *_yahoo_assign_server_settings(va_list ap) { struct yahoo_server_settings *yss = _yahoo_default_server_settings(); char *key; char *svalue; - int nvalue; + int nvalue; + char **pvalue; - while(1) { + while (1) { key = va_arg(ap, char *); - if(key == NULL) + if (key == NULL) break; - if(!strcmp(key, "pager_host")) { + if (!strcmp(key, "pager_host")) { svalue = va_arg(ap, char *); free(yss->pager_host); yss->pager_host = strdup(svalue); - } else if(!strcmp(key, "pager_port")) { + yss->pager_host_list = NULL; + } else if (!strcmp(key, "pager_host_list")) { + pvalue = va_arg(ap, char **); + yss->pager_host_list = pvalue; + free(yss->pager_host); + yss->pager_host = NULL; + } else if (!strcmp(key, "pager_port")) { nvalue = va_arg(ap, int); yss->pager_port = nvalue; - } else if(!strcmp(key, "filetransfer_host")) { + } else if (!strcmp(key, "filetransfer_host")) { svalue = va_arg(ap, char *); free(yss->filetransfer_host); yss->filetransfer_host = strdup(svalue); - } else if(!strcmp(key, "filetransfer_port")) { + } else if (!strcmp(key, "filetransfer_port")) { nvalue = va_arg(ap, int); yss->filetransfer_port = nvalue; - } else if(!strcmp(key, "webcam_host")) { + } else if (!strcmp(key, "webcam_host")) { svalue = va_arg(ap, char *); free(yss->webcam_host); yss->webcam_host = strdup(svalue); - } else if(!strcmp(key, "webcam_port")) { + } else if (!strcmp(key, "webcam_port")) { nvalue = va_arg(ap, int); yss->webcam_port = nvalue; - } else if(!strcmp(key, "webcam_description")) { + } else if (!strcmp(key, "webcam_description")) { svalue = va_arg(ap, char *); free(yss->webcam_description); yss->webcam_description = strdup(svalue); - } else if(!strcmp(key, "local_host")) { + } else if (!strcmp(key, "local_host")) { svalue = va_arg(ap, char *); free(yss->local_host); yss->local_host = strdup(svalue); - } else if(!strcmp(key, "conn_type")) { + } else if (!strcmp(key, "conn_type")) { nvalue = va_arg(ap, int); yss->conn_type = nvalue; } else { WARNING(("Unknown key passed to yahoo_init, " - "perhaps you didn't terminate the list " - "with NULL")); + "perhaps you didn't terminate the list " + "with NULL")); } } @@ -359,7 +323,7 @@ static void * _yahoo_assign_server_settings(va_list ap) static void yahoo_free_server_settings(struct yahoo_server_settings *yss) { - if(!yss) + if (!yss) return; free(yss->pager_host); @@ -371,30 +335,33 @@ static void yahoo_free_server_settings(struct yahoo_server_settings *yss) free(yss); } -static YList *conns=NULL; -static YList *inputs=NULL; -static int last_id=0; +static YList *conns = NULL; +static YList *inputs = NULL; +static int last_id = 0; static void add_to_list(struct yahoo_data *yd) { conns = y_list_prepend(conns, yd); } -static struct yahoo_data * find_conn_by_id(int id) + +static struct yahoo_data *find_conn_by_id(int id) { YList *l; - for(l = conns; l; l = y_list_next(l)) { + for (l = conns; l; l = y_list_next(l)) { struct yahoo_data *yd = l->data; - if(yd->client_id == id) + if (yd->client_id == id) return yd; } return NULL; } + static void del_from_list(struct yahoo_data *yd) { conns = y_list_remove(conns, yd); } /* call repeatedly to get the next one */ +/* static struct yahoo_input_data * find_input_by_id(int id) { YList *l; @@ -405,41 +372,45 @@ static struct yahoo_input_data * find_input_by_id(int id) } return NULL; } +*/ -static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who) +static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id, + const char *who) { YList *l; LOG(("find_input_by_id_and_webcam_user")); - for(l = inputs; l; l = y_list_next(l)) { + for (l = inputs; l; l = y_list_next(l)) { struct yahoo_input_data *yid = l->data; - if(yid->type == YAHOO_CONNECTION_WEBCAM && yid->yd->client_id == id - && yid->wcm && - ((who && yid->wcm->user && !strcmp(who, yid->wcm->user)) || - !(yid->wcm->user && !who))) + if (yid->type == YAHOO_CONNECTION_WEBCAM + && yid->yd->client_id == id && yid->wcm && ((who + && yid->wcm->user + && !strcmp(who, yid->wcm->user)) + || !(yid->wcm->user && !who))) return yid; } return NULL; } -static struct yahoo_input_data * find_input_by_id_and_type(int id, enum yahoo_connection_type type) +static struct yahoo_input_data *find_input_by_id_and_type(int id, + enum yahoo_connection_type type) { YList *l; LOG(("find_input_by_id_and_type")); - for(l = inputs; l; l = y_list_next(l)) { + for (l = inputs; l; l = y_list_next(l)) { struct yahoo_input_data *yid = l->data; - if(yid->type == type && yid->yd->client_id == id) + if (yid->type == type && yid->yd->client_id == id) return yid; } return NULL; } -static struct yahoo_input_data * find_input_by_id_and_fd(int id, int fd) +static struct yahoo_input_data *find_input_by_id_and_fd(int id, void *fd) { YList *l; LOG(("find_input_by_id_and_fd")); - for(l = inputs; l; l = y_list_next(l)) { + for (l = inputs; l; l = y_list_next(l)) { struct yahoo_input_data *yid = l->data; - if(yid->fd == fd && yid->yd->client_id == id) + if (yid->fd == fd && yid->yd->client_id == id) return yid; } return NULL; @@ -447,36 +418,34 @@ static struct yahoo_input_data * find_input_by_id_and_fd(int id, int fd) static int count_inputs_with_id(int id) { - int c=0; + int c = 0; YList *l; LOG(("counting %d", id)); - for(l = inputs; l; l = y_list_next(l)) { + for (l = inputs; l; l = y_list_next(l)) { struct yahoo_input_data *yid = l->data; - if(yid->yd->client_id == id) + if (yid->yd->client_id == id) c++; } LOG(("%d", c)); return c; } - extern char *yahoo_crypt(char *, char *); /* Free a buddy list */ -static void yahoo_free_buddies(YList * list) +static void yahoo_free_buddies(YList *list) { YList *l; - for(l = list; l; l = l->next) - { + for (l = list; l; l = l->next) { struct yahoo_buddy *bud = l->data; - if(!bud) + if (!bud) continue; FREE(bud->group); FREE(bud->id); FREE(bud->real_name); - if(bud->yab_entry) { + if (bud->yab_entry) { FREE(bud->yab_entry->fname); FREE(bud->yab_entry->lname); FREE(bud->yab_entry->nname); @@ -495,7 +464,7 @@ static void yahoo_free_buddies(YList * list) } /* Free an identities list */ -static void yahoo_free_identities(YList * list) +static void yahoo_free_identities(YList *list) { while (list) { YList *n = list; @@ -524,6 +493,7 @@ static void yahoo_free_data(struct yahoo_data *yd) FREE(yd->password); FREE(yd->cookie_y); FREE(yd->cookie_t); + FREE(yd->cookie_b); FREE(yd->cookie_c); FREE(yd->login_cookie); FREE(yd->login_id); @@ -539,8 +509,8 @@ static void yahoo_free_data(struct yahoo_data *yd) #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) -static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, - enum yahoo_status status, int id) +static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, + enum ypacket_status status, int id) { struct yahoo_packet *pkt = y_new0(struct yahoo_packet, 1); @@ -551,7 +521,8 @@ static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, return pkt; } -static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) +static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, + const char *value) { struct yahoo_pair *pair = y_new0(struct yahoo_pair, 1); pair->key = key; @@ -596,7 +567,8 @@ static int yahoo_packet_length(struct yahoo_packet *pkt) (((*((buf)+2))&0xff)<< 8) + \ (((*((buf)+3))&0xff))) -static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int len) +static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, + int len) { int pos = 0; @@ -649,7 +621,8 @@ static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int pair->value = strdup(value); FREE(value); pkt->hash = y_list_append(pkt->hash, pair); - DEBUG_MSG(("Key: %d \tValue: %s", pair->key, pair->value)); + DEBUG_MSG(("Key: %d \tValue: %s", pair->key, + pair->value)); } else { FREE(pair); } @@ -689,30 +662,29 @@ static void yahoo_dump_unhandled(struct yahoo_packet *pkt) } } - static void yahoo_packet_dump(unsigned char *data, int len) { - if(yahoo_get_log_level() >= YAHOO_LOG_DEBUG) { + if (yahoo_get_log_level() >= YAHOO_LOG_DEBUG) { int i; for (i = 0; i < len; i++) { if ((i % 8 == 0) && i) - YAHOO_CALLBACK(ext_yahoo_log)(" "); + YAHOO_CALLBACK(ext_yahoo_log) (" "); if ((i % 16 == 0) && i) - YAHOO_CALLBACK(ext_yahoo_log)("\n"); - YAHOO_CALLBACK(ext_yahoo_log)("%02x ", data[i]); + YAHOO_CALLBACK(ext_yahoo_log) ("\n"); + YAHOO_CALLBACK(ext_yahoo_log) ("%02x ", data[i]); } - YAHOO_CALLBACK(ext_yahoo_log)("\n"); + YAHOO_CALLBACK(ext_yahoo_log) ("\n"); for (i = 0; i < len; i++) { if ((i % 8 == 0) && i) - YAHOO_CALLBACK(ext_yahoo_log)(" "); + YAHOO_CALLBACK(ext_yahoo_log) (" "); if ((i % 16 == 0) && i) - YAHOO_CALLBACK(ext_yahoo_log)("\n"); + YAHOO_CALLBACK(ext_yahoo_log) ("\n"); if (isprint(data[i])) - YAHOO_CALLBACK(ext_yahoo_log)(" %c ", data[i]); + YAHOO_CALLBACK(ext_yahoo_log) (" %c ", data[i]); else - YAHOO_CALLBACK(ext_yahoo_log)(" . "); + YAHOO_CALLBACK(ext_yahoo_log) (" . "); } - YAHOO_CALLBACK(ext_yahoo_log)("\n"); + YAHOO_CALLBACK(ext_yahoo_log) ("\n"); } } @@ -722,7 +694,8 @@ static void to_y64(unsigned char *out, const unsigned char *in, int inlen) base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); } -static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length) +static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, + int length) { struct data_queue *tx = y_new0(struct data_queue, 1); tx->queue = y_new0(unsigned char, length); @@ -731,15 +704,17 @@ static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, in yid->txqueues = y_list_append(yid->txqueues, tx); - if(!yid->write_tag) - yid->write_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_WRITE, yid); + if (!yid->write_tag) + yid->write_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd-> + client_id, yid->fd, YAHOO_INPUT_WRITE, yid); } -static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet *pkt, int extra_pad) +static void yahoo_send_packet(struct yahoo_input_data *yid, + struct yahoo_packet *pkt, int extra_pad) { int pktlen = yahoo_packet_length(pkt); int len = YAHOO_PACKET_HDRLEN + pktlen; - unsigned char *data; int pos = 0; @@ -748,19 +723,20 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet data = y_new0(unsigned char, len + 1); - memcpy(data + pos, "YMSG", 4); pos += 4; - pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); - pos += yahoo_put16(data + pos, 0x0000); - pos += yahoo_put16(data + pos, pktlen + extra_pad); - pos += yahoo_put16(data + pos, pkt->service); - pos += yahoo_put32(data + pos, pkt->status); - pos += yahoo_put32(data + pos, pkt->id); + memcpy(data + pos, "YMSG", 4); + pos += 4; + pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); /* version [latest 12 0x000c] */ + pos += yahoo_put16(data + pos, 0x0000); /* HIWORD pkt length??? */ + pos += yahoo_put16(data + pos, pktlen + extra_pad); /* LOWORD pkt length? */ + pos += yahoo_put16(data + pos, pkt->service); /* service */ + pos += yahoo_put32(data + pos, pkt->status); /* status [4bytes] */ + pos += yahoo_put32(data + pos, pkt->id); /* session [4bytes] */ yahoo_packet_write(pkt, data + pos); yahoo_packet_dump(data, len); - - if( yid->type == YAHOO_CONNECTION_FT ) + + if (yid->type == YAHOO_CONNECTION_FT) yahoo_send_data(yid->fd, data, len); else yahoo_add_to_send_queue(yid, data, len); @@ -781,92 +757,94 @@ static void yahoo_packet_free(struct yahoo_packet *pkt) FREE(pkt); } -static int yahoo_send_data(int fd, void *data, int len) +static int yahoo_send_data(void *fd, void *data, int len) { int ret; int e; - if (fd < 0) + if (fd == NULL) return -1; yahoo_packet_dump(data, len); do { - ret = write(fd, data, len); - } while(ret == -1 && errno==EINTR); - e=errno; + ret = YAHOO_CALLBACK(ext_yahoo_write) (fd, data, len); + } while (ret == -1 && errno == EINTR); + e = errno; - if (ret == -1) { + if (ret == -1) { LOG(("wrote data: ERR %s", strerror(errno))); } else { LOG(("wrote data: OK")); } - errno=e; + errno = e; return ret; } -void yahoo_close(int id) +void yahoo_close(int id) { struct yahoo_data *yd = find_conn_by_id(id); - - if(!yd) + if (!yd) return; del_from_list(yd); yahoo_free_data(yd); - if(id == last_id) + if (id == last_id) last_id--; } -static void yahoo_input_close(struct yahoo_input_data *yid) +static void yahoo_input_close(struct yahoo_input_data *yid) { inputs = y_list_remove(inputs, yid); - LOG(("yahoo_input_close(read)")); - YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->read_tag); - LOG(("yahoo_input_close(write)")); - YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->write_tag); + LOG(("yahoo_input_close(read)")); + YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id, + yid->read_tag); + LOG(("yahoo_input_close(write)")); + YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id, + yid->write_tag); yid->read_tag = yid->write_tag = 0; - if(yid->fd) - close(yid->fd); + if (yid->fd) + YAHOO_CALLBACK(ext_yahoo_close) (yid->fd); yid->fd = 0; FREE(yid->rxqueue); - if(count_inputs_with_id(yid->yd->client_id) == 0) { + if (count_inputs_with_id(yid->yd->client_id) == 0) { LOG(("closing %d", yid->yd->client_id)); yahoo_close(yid->yd->client_id); } yahoo_free_webcam(yid->wcm); - if(yid->wcd) + if (yid->wcd) FREE(yid->wcd); - if(yid->ys) { + if (yid->ys) { FREE(yid->ys->lsearch_text); FREE(yid->ys); } FREE(yid); } -static int is_same_bud(const void * a, const void * b) { +static int is_same_bud(const void *a, const void *b) +{ const struct yahoo_buddy *subject = a; const struct yahoo_buddy *object = b; return strcmp(subject->id, object->id); } -static char * getcookie(char *rawcookie) +static char *getcookie(char *rawcookie) { - char * cookie=NULL; - char * tmpcookie; - char * cookieend; + char *cookie = NULL; + char *tmpcookie; + char *cookieend; - if (strlen(rawcookie) < 2) + if (strlen(rawcookie) < 2) return NULL; - tmpcookie = strdup(rawcookie+2); + tmpcookie = strdup(rawcookie + 2); cookieend = strchr(tmpcookie, ';'); - if(cookieend) + if (cookieend) *cookieend = '\0'; cookie = strdup(tmpcookie); @@ -876,18 +854,18 @@ static char * getcookie(char *rawcookie) return cookie; } -static char * getlcookie(char *cookie) +static char *getlcookie(char *cookie) { char *tmp; char *tmpend; char *login_cookie = NULL; tmpend = strstr(cookie, "n="); - if(tmpend) { - tmp = strdup(tmpend+2); + if (tmpend) { + tmp = strdup(tmpend + 2); tmpend = strchr(tmp, '&'); - if(tmpend) - *tmpend='\0'; + if (tmpend) + *tmpend = '\0'; login_cookie = strdup(tmp); FREE(tmp); } @@ -895,7 +873,8 @@ static char * getlcookie(char *cookie) return login_cookie; } -static void yahoo_process_notify(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_notify(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *msg = NULL; @@ -926,84 +905,31 @@ static void yahoo_process_notify(struct yahoo_input_data *yid, struct yahoo_pack if (!msg) return; - - if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) - YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, to, from, stat); - else if (!strncasecmp(msg, "GAME", strlen("GAME"))) - YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, to, from, stat); - else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) - { + + if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) + YAHOO_CALLBACK(ext_yahoo_typing_notify) (yd->client_id, to, + from, stat); + else if (!strncasecmp(msg, "GAME", strlen("GAME"))) + YAHOO_CALLBACK(ext_yahoo_game_notify) (yd->client_id, to, from, + stat, ind); + else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) { if (!strcmp(ind, " ")) { - YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from); + YAHOO_CALLBACK(ext_yahoo_webcam_invite) (yd->client_id, + to, from); } else { accept = atoi(ind); /* accept the invitation (-1 = deny 1 = accept) */ if (accept < 0) accept = 0; - YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept); + YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply) (yd-> + client_id, to, from, accept); } - } - else + } else LOG(("Got unknown notification: %s", msg)); } -static void yahoo_process_filetransfer(struct yahoo_input_data *yid, struct yahoo_packet *pkt) -{ - struct yahoo_data *yd = yid->yd; - char *from=NULL; - char *to=NULL; - char *msg=NULL; - char *url=NULL; - long expires=0; - - char *service=NULL; - - char *filename=NULL; - unsigned long filesize=0L; - - YList *l; - for (l = pkt->hash; l; l = l->next) { - struct yahoo_pair *pair = l->data; - if (pair->key == 4) - from = pair->value; - if (pair->key == 5) - to = pair->value; - if (pair->key == 14) - msg = pair->value; - if (pair->key == 20) - url = pair->value; - if (pair->key == 38) - expires = atol(pair->value); - - if (pair->key == 27) - filename = pair->value; - if (pair->key == 28) - filesize = atol(pair->value); - - if (pair->key == 49) - service = pair->value; - } - - if(pkt->service == YAHOO_SERVICE_P2PFILEXFER) { - if(strcmp("FILEXFER", service) != 0) { - WARNING(("unhandled service 0x%02x", pkt->service)); - yahoo_dump_unhandled(pkt); - return; - } - } - - if(msg) { - char *tmp; - tmp = strchr(msg, '\006'); - if(tmp) - *tmp = '\0'; - } - if(url && from) - YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, to, from, url, expires, msg, filename, filesize); - -} - -static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_conference(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *msg = NULL; @@ -1011,98 +937,102 @@ static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_ char *who = NULL; char *room = NULL; char *id = NULL; - int utf8 = 0; + int utf8 = 0; YList *members = NULL; YList *l; - + for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; if (pair->key == 50) host = pair->value; - - if (pair->key == 52) { /* invite */ + + if (pair->key == 52) { /* invite */ members = y_list_append(members, strdup(pair->value)); } - if (pair->key == 53) /* logon */ + if (pair->key == 53) /* logon */ who = pair->value; - if (pair->key == 54) /* decline */ + if (pair->key == 54) /* decline */ who = pair->value; - if (pair->key == 55) /* unavailable (status == 2) */ + if (pair->key == 55) /* unavailable (status == 2) */ who = pair->value; - if (pair->key == 56) /* logoff */ + if (pair->key == 56) /* logoff */ who = pair->value; if (pair->key == 57) room = pair->value; - if (pair->key == 58) /* join message */ + if (pair->key == 58) /* join message */ msg = pair->value; - if (pair->key == 14) /* decline/conf message */ + if (pair->key == 14) /* decline/conf message */ msg = pair->value; - if (pair->key == 13) - ; - if (pair->key == 16) /* error */ + if (pair->key == 13) ; + if (pair->key == 16) /* error */ msg = pair->value; - if (pair->key == 1) /* my id */ + if (pair->key == 1) /* my id */ id = pair->value; - if (pair->key == 3) /* message sender */ + if (pair->key == 3) /* message sender */ who = pair->value; if (pair->key == 97) utf8 = atoi(pair->value); } - if(!room) + if (!room) return; - if(host) { - for(l = members; l; l = l->next) { - char * w = l->data; - if(!strcmp(w, host)) + if (host) { + for (l = members; l; l = l->next) { + char *w = l->data; + if (!strcmp(w, host)) break; } - if(!l) + if (!l) members = y_list_append(members, strdup(host)); } /* invite, decline, join, left, message -> status == 1 */ - switch(pkt->service) { + switch (pkt->service) { case YAHOO_SERVICE_CONFINVITE: - if(pkt->status == 2) - ; - else if(members) - YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); - else if(msg) - YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0, E_CONFNOTAVAIL); + if (pkt->status == 2) ; + else if (members) + YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd-> + client_id, id, host, room, msg, members); + else if (msg) + YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, msg, 0, + E_CONFNOTAVAIL); break; case YAHOO_SERVICE_CONFADDINVITE: - if(pkt->status == 2) - ; - else - YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); + if (pkt->status == 1) + YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd-> + client_id, id, host, room, msg, members); break; case YAHOO_SERVICE_CONFDECLINE: - if(who) - YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg); + if (who) + YAHOO_CALLBACK(ext_yahoo_conf_userdecline) (yd-> + client_id, id, who, room, msg); break; case YAHOO_SERVICE_CONFLOGON: - if(who) - YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room); + if (who) + YAHOO_CALLBACK(ext_yahoo_conf_userjoin) (yd->client_id, + id, who, room); break; case YAHOO_SERVICE_CONFLOGOFF: - if(who) - YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room); + if (who) + YAHOO_CALLBACK(ext_yahoo_conf_userleave) (yd->client_id, + id, who, room); break; case YAHOO_SERVICE_CONFMSG: - if(who) - YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8); + if (who) + YAHOO_CALLBACK(ext_yahoo_conf_message) (yd->client_id, + id, who, room, msg, utf8); break; } } -static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_chat(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *msg = NULL; char *id = NULL; @@ -1111,13 +1041,13 @@ static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet char *topic = NULL; YList *members = NULL; struct yahoo_chat_member *currentmember = NULL; - int msgtype = 1; - int utf8 = 0; - int firstjoin = 0; - int membercount = 0; - int chaterr=0; + int msgtype = 1; + int utf8 = 0; + int firstjoin = 0; + int membercount = 0; + int chaterr = 0; YList *l; - + yahoo_dump_unhandled(pkt); for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; @@ -1147,7 +1077,8 @@ static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet who = pair->value; if (pkt->service == YAHOO_SERVICE_CHATJOIN) { - currentmember = y_new0(struct yahoo_chat_member, 1); + currentmember = + y_new0(struct yahoo_chat_member, 1); currentmember->id = strdup(pair->value); members = y_list_append(members, currentmember); } @@ -1177,7 +1108,6 @@ static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet currentmember->location = strdup(pair->value); } - if (pair->key == 130) { /* first join */ firstjoin = 1; @@ -1195,17 +1125,19 @@ static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet if (pair->key == 114) { /* message error not sure what all the pair values mean */ /* but -1 means no session in room */ - chaterr= atoi(pair->value); + chaterr = atoi(pair->value); } } - if(!room) { - if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */ - YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id, id); - return ; + if (!room) { + if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */ + YAHOO_CALLBACK(ext_yahoo_chat_yahoologout) (yid->yd-> + client_id, id); + return; } - if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) { - YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id, id); + if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) { + YAHOO_CALLBACK(ext_yahoo_chat_yahooerror) (yid->yd-> + client_id, id); return; } @@ -1213,103 +1145,156 @@ static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet return; } - switch(pkt->service) { + switch (pkt->service) { case YAHOO_SERVICE_CHATJOIN: - if(y_list_length(members) != membercount) { + if (y_list_length(members) != membercount) { WARNING(("Count of members doesn't match No. of members we got")); } - if(firstjoin && members) { - YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, id, room, topic, members, yid->fd); - } else if(who) { - if(y_list_length(members) != 1) { + if (firstjoin && members) { + YAHOO_CALLBACK(ext_yahoo_chat_join) (yid->yd->client_id, + id, room, topic, members, yid->fd); + } else if (who) { + if (y_list_length(members) != 1) { WARNING(("Got more than 1 member on a normal join")); } /* this should only ever have one, but just in case */ - while(members) { + while (members) { YList *n = members->next; currentmember = members->data; - YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember); + YAHOO_CALLBACK(ext_yahoo_chat_userjoin) (yid-> + yd->client_id, id, room, currentmember); y_list_free_1(members); - members=n; + members = n; } } break; case YAHOO_SERVICE_CHATEXIT: - if(who) { - YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who); + if (who) { + YAHOO_CALLBACK(ext_yahoo_chat_userleave) (yid->yd-> + client_id, id, room, who); } break; case YAHOO_SERVICE_COMMENT: - if(who) { - YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8); + if (who) { + YAHOO_CALLBACK(ext_yahoo_chat_message) (yid->yd-> + client_id, id, who, room, msg, msgtype, utf8); } break; } } -static void yahoo_process_message(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_message(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; YList *l; - YList * messages = NULL; + YList *messages = NULL; struct m { - int i_31; - int i_32; + int i_31; + int i_32; char *to; char *from; long tm; char *msg; - int utf8; + int utf8; + char *gunk; } *message = y_new0(struct m, 1); for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; - if (pair->key == 1 || pair->key == 4) - { - if(!message->from) + if (pair->key == 1 || pair->key == 4) { + if (!message->from) message->from = pair->value; - } - else if (pair->key == 5) + } else if (pair->key == 5) message->to = pair->value; else if (pair->key == 15) message->tm = strtol(pair->value, NULL, 10); else if (pair->key == 97) message->utf8 = atoi(pair->value); - /* user message */ /* sys message */ + /* This comes when the official client sends us a message */ + else if (pair->key == 429) + message->gunk = pair->value; + /* user message *//* sys message */ else if (pair->key == 14 || pair->key == 16) message->msg = pair->value; else if (pair->key == 31) { - if(message->i_31) { + if (message->i_31) { messages = y_list_append(messages, message); message = y_new0(struct m, 1); } message->i_31 = atoi(pair->value); - } - else if (pair->key == 32) + } else if (pair->key == 32) message->i_32 = atoi(pair->value); else - LOG(("yahoo_process_message: status: %d, key: %d, value: %s", - pkt->status, pair->key, pair->value)); + LOG(("yahoo_process_message: status: %d, key: %d, value: %s", pkt->status, pair->key, pair->value)); } messages = y_list_append(messages, message); - for (l = messages; l; l=l->next) { + for (l = messages; l; l = l->next) { message = l->data; if (pkt->service == YAHOO_SERVICE_SYSMESSAGE) { - YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg); + YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id, + message->to, message->from, message->msg); } else if (pkt->status <= 2 || pkt->status == 5) { - YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8); + /* Confirm message receipt if we got the gunk */ + if(message->gunk) { + struct yahoo_packet *outpkt; + + outpkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_CONFIRM, + YPACKET_STATUS_DEFAULT, 0); + yahoo_packet_hash(outpkt, 1, yd->user); + yahoo_packet_hash(outpkt, 5, message->from); + yahoo_packet_hash(outpkt, 302, "430"); + yahoo_packet_hash(outpkt, 430, message->gunk); + yahoo_packet_hash(outpkt, 303, "430"); + yahoo_packet_hash(outpkt, 450, "0"); + yahoo_send_packet(yid, outpkt, 0); + + yahoo_packet_free(outpkt); + } + + if (!strcmp(message->msg, "<ding>")) + YAHOO_CALLBACK(ext_yahoo_got_buzz) (yd->client_id, + message->to, message->from, message->tm); + else + YAHOO_CALLBACK(ext_yahoo_got_im) (yd->client_id, + message->to, message->from, message->msg, + message->tm, pkt->status, message->utf8); } else if (pkt->status == 0xffffffff) { - YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM); + YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, + message->msg, 0, E_SYSTEM); } - free(message); + FREE(message); } y_list_free(messages); } +/* + * Here's what multi-level packets look like. Data in brackets is the value. + * + * 3 level: + * ======= + * + * 302 (318) - Beginning level 1 + * 300 (318) - Begin level 2 + * 302 (319) - End level 2 header + * 300 (319) - Begin level 3 + * 301 (319) - End level 3 + * 303 (319) - End level 2 + * 303 (318) - End level 1 + * + * 2 level: + * ======= + * + * 302 (315) - Beginning level 1 + * 300 (315) - Begin level 2 + * 301 (315) - End level 2 + * 303 (315) - End level 1 + * + */ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { @@ -1326,10 +1311,12 @@ static void yahoo_process_status(struct yahoo_input_data *yid, return; } - /* Status updates may be spread accross multiple packets and not - even on buddy boundaries, so keeping some state is important. - So, continue where we left off, and only add a user entry to - the list once it's complete (301-315 End buddy). */ + /* + * Status updates may be spread accross multiple packets and not + * even on buddy boundaries, so keeping some state is important. + * So, continue where we left off, and only add a user entry to + * the list once it's complete (301-315 End buddy). + */ u = yd->half_user; for (l = pkt->hash; l; l = l->next) { @@ -1593,17 +1580,20 @@ static void yahoo_process_list(struct yahoo_input_data *yid, YAHOO_CALLBACK(ext_yahoo_got_cookies) (yd->client_id); } -static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_verify(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; - if(pkt->status != 0x01) { + if (pkt->status != 0x01) { DEBUG_MSG(("expected status: 0x01, got: %d", pkt->status)); - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_LOCK, ""); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_LOCK, ""); return; } - pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT, + yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_send_packet(yid, pkt, 0); @@ -1612,7 +1602,8 @@ static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_pack } -static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_picture_checksum(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *from = NULL; @@ -1620,30 +1611,30 @@ static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct int checksum = 0; YList *l; - for(l = pkt->hash; l; l = l->next) - { + for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; - switch(pair->key) - { - case 1: - case 4: - from = pair->value; - case 5: - to = pair->value; - break; - case 212: - break; - case 192: - checksum = atoi( pair->value ); - break; + switch (pair->key) { + case 1: + case 4: + from = pair->value; + case 5: + to = pair->value; + break; + case 212: + break; + case 192: + checksum = atoi(pair->value); + break; } } - YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum)(yd->client_id,to,from,checksum); + YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum) (yd->client_id, to, + from, checksum); } -static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_picture(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *url = NULL; @@ -1652,607 +1643,108 @@ static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_pac int status = 0; int checksum = 0; YList *l; - - for(l = pkt->hash; l; l = l->next) - { + + for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; - switch(pair->key) - { + switch (pair->key) { case 1: - case 4: /* sender */ + case 4: /* sender */ from = pair->value; break; - case 5: /* we */ + case 5: /* we */ to = pair->value; break; - case 13: /* request / sending */ - status = atoi( pair->value ); + case 13: /* request / sending */ + status = atoi(pair->value); break; - case 20: /* url */ + case 20: /* url */ url = pair->value; break; case 192: /*checksum */ - checksum = atoi( pair->value ); + checksum = atoi(pair->value); break; } } - switch( status ) - { - case 1: /* this is a request, ignore for now */ - YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request)(yd->client_id, to, from); - break; - case 2: /* this is cool - we get a picture :) */ - YAHOO_CALLBACK(ext_yahoo_got_buddyicon)(yd->client_id,to, from, url, checksum); - break; + switch (status) { + case 1: /* this is a request, ignore for now */ + YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request) (yd->client_id, + to, from); + break; + case 2: /* this is cool - we get a picture :) */ + YAHOO_CALLBACK(ext_yahoo_got_buddyicon) (yd->client_id, to, + from, url, checksum); + break; } } -static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_picture_upload(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; YList *l; char *url = NULL; - if ( pkt->status != 1 ) + if (pkt->status != 1) return; /* something went wrong */ - - for(l = pkt->hash; l; l = l->next) - { - struct yahoo_pair *pair = l->data; - switch(pair->key) - { - case 5: /* we */ - break; - case 20: /* url */ - url = pair->value; - break; - case 27: /* local filename */ - break; - case 38: /* time */ - break; - } - } - - YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded)(yd->client_id, url); -} - -static void yahoo_process_auth_pre_0x0b(struct yahoo_input_data *yid, - const char *seed, const char *sn) -{ - struct yahoo_data *yd = yid->yd; - - /* So, Yahoo has stopped supporting its older clients in India, and - * undoubtedly will soon do so in the rest of the world. - * - * The new clients use this authentication method. I warn you in - * advance, it's bizzare, convoluted, inordinately complicated. - * It's also no more secure than crypt() was. The only purpose this - * scheme could serve is to prevent third part clients from connecting - * to their servers. - * - * Sorry, Yahoo. - */ - - struct yahoo_packet *pack; - - md5_byte_t result[16]; - md5_state_t ctx; - char *crypt_result; - unsigned char *password_hash = malloc(25); - unsigned char *crypt_hash = malloc(25); - unsigned char *hash_string_p = malloc(50 + strlen(sn)); - unsigned char *hash_string_c = malloc(50 + strlen(sn)); - - char checksum; - - int sv; - - unsigned char *result6 = malloc(25); - unsigned char *result96 = malloc(25); - - sv = seed[15]; - sv = (sv % 8) % 5; - - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password)); - md5_finish(&ctx, result); - to_y64(password_hash, result, 16); - - md5_init(&ctx); - crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); - md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); - md5_finish(&ctx, result); - to_y64(crypt_hash, result, 16); - free(crypt_result); - - switch (sv) { - case 0: - checksum = seed[seed[7] % 16]; - snprintf((char *)hash_string_p, strlen(sn) + 50, - "%c%s%s%s", checksum, password_hash, yd->user, seed); - snprintf((char *)hash_string_c, strlen(sn) + 50, - "%c%s%s%s", checksum, crypt_hash, yd->user, seed); - break; - case 1: - checksum = seed[seed[9] % 16]; - snprintf((char *)hash_string_p, strlen(sn) + 50, - "%c%s%s%s", checksum, yd->user, seed, password_hash); - snprintf((char *)hash_string_c, strlen(sn) + 50, - "%c%s%s%s", checksum, yd->user, seed, crypt_hash); - break; - case 2: - checksum = seed[seed[15] % 16]; - snprintf((char *)hash_string_p, strlen(sn) + 50, - "%c%s%s%s", checksum, seed, password_hash, yd->user); - snprintf((char *)hash_string_c, strlen(sn) + 50, - "%c%s%s%s", checksum, seed, crypt_hash, yd->user); - break; - case 3: - checksum = seed[seed[1] % 16]; - snprintf((char *)hash_string_p, strlen(sn) + 50, - "%c%s%s%s", checksum, yd->user, password_hash, seed); - snprintf((char *)hash_string_c, strlen(sn) + 50, - "%c%s%s%s", checksum, yd->user, crypt_hash, seed); - break; - case 4: - checksum = seed[seed[3] % 16]; - snprintf((char *)hash_string_p, strlen(sn) + 50, - "%c%s%s%s", checksum, password_hash, seed, yd->user); - snprintf((char *)hash_string_c, strlen(sn) + 50, - "%c%s%s%s", checksum, crypt_hash, seed, yd->user); - break; - } - - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)hash_string_p, strlen((char *)hash_string_p)); - md5_finish(&ctx, result); - to_y64(result6, result, 16); - - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)hash_string_c, strlen((char *)hash_string_c)); - md5_finish(&ctx, result); - to_y64(result96, result, 16); - - pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); - yahoo_packet_hash(pack, 0, yd->user); - yahoo_packet_hash(pack, 6, (char *)result6); - yahoo_packet_hash(pack, 96, (char *)result96); - yahoo_packet_hash(pack, 1, yd->user); - - yahoo_send_packet(yid, pack, 0); - - FREE(result6); - FREE(result96); - FREE(password_hash); - FREE(crypt_hash); - FREE(hash_string_p); - FREE(hash_string_c); - - yahoo_packet_free(pack); - -} - -/* - * New auth protocol cracked by Cerulean Studios and sent in to Gaim - */ -static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *seed, const char *sn) -{ - struct yahoo_packet *pack = NULL; - struct yahoo_data *yd = yid->yd; - - md5_byte_t result[16]; - md5_state_t ctx; - - sha1_state_t ctx1; - sha1_state_t ctx2; - - char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; - char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; - - char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; - char *operand_lookup = "+|&%/*^-"; - char *delimit_lookup = ",;"; - - unsigned char *password_hash = malloc(25); - unsigned char *crypt_hash = malloc(25); - char *crypt_result = NULL; - unsigned char pass_hash_xor1[64]; - unsigned char pass_hash_xor2[64]; - unsigned char crypt_hash_xor1[64]; - unsigned char crypt_hash_xor2[64]; - unsigned char chal[7]; - char resp_6[100]; - char resp_96[100]; - - unsigned char digest1[20]; - unsigned char digest2[20]; - unsigned char magic_key_char[4]; - const unsigned char *magic_ptr; - - unsigned int magic[64]; - unsigned int magic_work=0; - - char comparison_src[20]; - - int x, j, i; - int cnt = 0; - int magic_cnt = 0; - int magic_len; - int depth =0, table =0; - - memset(&pass_hash_xor1, 0, 64); - memset(&pass_hash_xor2, 0, 64); - memset(&crypt_hash_xor1, 0, 64); - memset(&crypt_hash_xor2, 0, 64); - memset(&digest1, 0, 20); - memset(&digest2, 0, 20); - memset(&magic, 0, 64); - memset(&resp_6, 0, 100); - memset(&resp_96, 0, 100); - memset(&magic_key_char, 0, 4); - - /* - * Magic: Phase 1. Generate what seems to be a 30 - * byte value (could change if base64 - * ends up differently? I don't remember and I'm - * tired, so use a 64 byte buffer. - */ - - magic_ptr = (unsigned char *)seed; - - while (*magic_ptr != 0) { - char *loc; - - /* Ignore parentheses. */ - - if (*magic_ptr == '(' || *magic_ptr == ')') { - magic_ptr++; - continue; - } - - /* Characters and digits verify against - the challenge lookup. - */ - - if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) { - loc = strchr(challenge_lookup, *magic_ptr); - if (!loc) { - /* This isn't good */ - continue; - } - - /* Get offset into lookup table and lsh 3. */ - - magic_work = loc - challenge_lookup; - magic_work <<= 3; - - magic_ptr++; - continue; - } else { - unsigned int local_store; - - loc = strchr(operand_lookup, *magic_ptr); - if (!loc) { - /* Also not good. */ - continue; - } - - local_store = loc - operand_lookup; - - /* Oops; how did this happen? */ - if (magic_cnt >= 64) - break; - - magic[magic_cnt++] = magic_work | local_store; - magic_ptr++; - continue; - } - } - - magic_len = magic_cnt; - magic_cnt = 0; - - /* Magic: Phase 2. Take generated magic value and - * sprinkle fairy dust on the values. */ - - for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) { - unsigned char byte1; - unsigned char byte2; - - /* Bad. Abort. - */ - if (magic_cnt >= magic_len) { - WARNING(("magic_cnt(%d) magic_len(%d)", magic_cnt, magic_len)) - break; - } - - byte1 = magic[magic_cnt]; - byte2 = magic[magic_cnt+1]; - - byte1 *= 0xcd; - byte1 ^= byte2; - - magic[magic_cnt+1] = byte1; - } - - /* Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic - * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key - * plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets - * into particular functions we'll later call to potentially alter the magic key. - * - * %-) - */ - - magic_cnt = 1; - x = 0; - - do { - unsigned int bl = 0; - unsigned int cl = magic[magic_cnt++]; - - if (magic_cnt >= magic_len) - break; - - if (cl > 0x7F) { - if (cl < 0xe0) - bl = cl = (cl & 0x1f) << 6; - else { - bl = magic[magic_cnt++]; - cl = (cl & 0x0f) << 6; - bl = ((bl & 0x3f) + cl) << 6; - } - - cl = magic[magic_cnt++]; - bl = (cl & 0x3f) + bl; - } else - bl = cl; - - comparison_src[x++] = (bl & 0xff00) >> 8; - comparison_src[x++] = bl & 0xff; - } while (x < 20); - - /* Dump magic key into a char for SHA1 action. */ - - - for(x = 0; x < 4; x++) - magic_key_char[x] = comparison_src[x]; - - /* Compute values for recursive function table! */ - memcpy( chal, magic_key_char, 4 ); - x = 1; - for( i = 0; i < 0xFFFF && x; i++ ) - { - for( j = 0; j < 5 && x; j++ ) - { - chal[4] = i; - chal[5] = i >> 8; - chal[6] = j; - md5_init( &ctx ); - md5_append( &ctx, chal, 7 ); - md5_finish( &ctx, result ); - if( memcmp( comparison_src + 4, result, 16 ) == 0 ) - { - depth = i; - table = j; - x = 0; - } - } - } - - /* Transform magic_key_char using transform table */ - x = magic_key_char[3] << 24 | magic_key_char[2] << 16 - | magic_key_char[1] << 8 | magic_key_char[0]; - x = yahoo_xfrm( table, depth, x ); - x = yahoo_xfrm( table, depth, x ); - magic_key_char[0] = x & 0xFF; - magic_key_char[1] = x >> 8 & 0xFF; - magic_key_char[2] = x >> 16 & 0xFF; - magic_key_char[3] = x >> 24 & 0xFF; - - /* Get password and crypt hashes as per usual. */ - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password)); - md5_finish(&ctx, result); - to_y64(password_hash, result, 16); - - md5_init(&ctx); - crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); - md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); - md5_finish(&ctx, result); - to_y64(crypt_hash, result, 16); - free(crypt_result); - - /* Our first authentication response is based off - * of the password hash. */ - - for (x = 0; x < (int)strlen((char *)password_hash); x++) - pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; - - if (cnt < 64) - memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); - - cnt = 0; - - for (x = 0; x < (int)strlen((char *)password_hash); x++) - pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; - - if (cnt < 64) - memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); - - sha1_init(&ctx1); - sha1_init(&ctx2); - - /* The first context gets the password hash XORed - * with 0x36 plus a magic value - * which we previously extrapolated from our - * challenge. */ - - sha1_append(&ctx1, pass_hash_xor1, 64); - if (j >= 3 ) - ctx1.Length_Low = 0x1ff; - sha1_append(&ctx1, magic_key_char, 4); - sha1_finish(&ctx1, digest1); - - /* The second context gets the password hash XORed - * with 0x5c plus the SHA-1 digest - * of the first context. */ - - sha1_append(&ctx2, pass_hash_xor2, 64); - sha1_append(&ctx2, digest1, 20); - sha1_finish(&ctx2, digest2); - - /* Now that we have digest2, use it to fetch - * characters from an alphabet to construct - * our first authentication response. */ - - for (x = 0; x < 20; x += 2) { - unsigned int val = 0; - unsigned int lookup = 0; - char byte[6]; - - memset(&byte, 0, 6); - - /* First two bytes of digest stuffed - * together. - */ - - val = digest2[x]; - val <<= 8; - val += digest2[x+1]; + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; - lookup = (val >> 0x0b); - lookup &= 0x1f; - if (lookup >= strlen(alphabet1)) + switch (pair->key) { + case 5: /* we */ break; - sprintf(byte, "%c", alphabet1[lookup]); - strcat(resp_6, byte); - strcat(resp_6, "="); - - lookup = (val >> 0x06); - lookup &= 0x1f; - if (lookup >= strlen(alphabet2)) + case 20: /* url */ + url = pair->value; break; - sprintf(byte, "%c", alphabet2[lookup]); - strcat(resp_6, byte); - - lookup = (val >> 0x01); - lookup &= 0x1f; - if (lookup >= strlen(alphabet2)) + case 27: /* local filename */ break; - sprintf(byte, "%c", alphabet2[lookup]); - strcat(resp_6, byte); - - lookup = (val & 0x01); - if (lookup >= strlen(delimit_lookup)) + case 38: /* time */ break; - sprintf(byte, "%c", delimit_lookup[lookup]); - strcat(resp_6, byte); + } } - /* Our second authentication response is based off - * of the crypto hash. */ - - cnt = 0; - memset(&digest1, 0, 20); - memset(&digest2, 0, 20); - - for (x = 0; x < (int)strlen((char *)crypt_hash); x++) - crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36; - - if (cnt < 64) - memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt); - - cnt = 0; - - for (x = 0; x < (int)strlen((char *)crypt_hash); x++) - crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; - - if (cnt < 64) - memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); - - sha1_init(&ctx1); - sha1_init(&ctx2); - - /* The first context gets the password hash XORed - * with 0x36 plus a magic value - * which we previously extrapolated from our - * challenge. */ - - sha1_append(&ctx1, crypt_hash_xor1, 64); - if (j >= 3 ) - ctx1.Length_Low = 0x1ff; - sha1_append(&ctx1, magic_key_char, 4); - sha1_finish(&ctx1, digest1); - - /* The second context gets the password hash XORed - * with 0x5c plus the SHA-1 digest - * of the first context. */ - - sha1_append(&ctx2, crypt_hash_xor2, 64); - sha1_append(&ctx2, digest1, 20); - sha1_finish(&ctx2, digest2); - - /* Now that we have digest2, use it to fetch - * characters from an alphabet to construct - * our first authentication response. */ - - for (x = 0; x < 20; x += 2) { - unsigned int val = 0; - unsigned int lookup = 0; + YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded) (yd->client_id, url); +} - char byte[6]; +void yahoo_login(int id, int initial) +{ + struct yahoo_data *yd = find_conn_by_id(id); + struct connect_callback_data *ccd; + struct yahoo_server_settings *yss; + int tag; - memset(&byte, 0, 6); + char *host; - /* First two bytes of digest stuffed - * together. */ + struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); + yid->yd = yd; + yid->type = YAHOO_CONNECTION_PAGER; + inputs = y_list_prepend(inputs, yid); - val = digest2[x]; - val <<= 8; - val += digest2[x+1]; + yd->initial_status = initial; + yss = yd->server_settings; - lookup = (val >> 0x0b); - lookup &= 0x1f; - if (lookup >= strlen(alphabet1)) - break; - sprintf(byte, "%c", alphabet1[lookup]); - strcat(resp_96, byte); - strcat(resp_96, "="); + ccd = y_new0(struct connect_callback_data, 1); + ccd->yd = yd; - lookup = (val >> 0x06); - lookup &= 0x1f; - if (lookup >= strlen(alphabet2)) - break; - sprintf(byte, "%c", alphabet2[lookup]); - strcat(resp_96, byte); + host = yss->pager_host; - lookup = (val >> 0x01); - lookup &= 0x1f; - if (lookup >= strlen(alphabet2)) - break; - sprintf(byte, "%c", alphabet2[lookup]); - strcat(resp_96, byte); + if (!host) + host = yss->pager_host_list[0]; - lookup = (val & 0x01); - if (lookup >= strlen(delimit_lookup)) - break; - sprintf(byte, "%c", delimit_lookup[lookup]); - strcat(resp_96, byte); - } + tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, + host, yss->pager_port, yahoo_connected, ccd, 0); - pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); - yahoo_packet_hash(pack, 0, sn); - yahoo_packet_hash(pack, 6, resp_6); - yahoo_packet_hash(pack, 96, resp_96); - yahoo_packet_hash(pack, 1, sn); - yahoo_send_packet(yid, pack, 0); - yahoo_packet_free(pack); - - free(password_hash); - free(crypt_hash); + /* + * if tag <= 0, then callback has already been called + * so ccd will have been freed + */ + if (tag > 0) + ccd->tag = tag; + else if (tag < 0) + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_SOCK, NULL); } struct yahoo_https_auth_data @@ -2302,7 +1794,7 @@ static enum yahoo_status yahoo_https_status_parse(int code) } } -static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) +static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn) { struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); @@ -2352,17 +1844,17 @@ static void yahoo_https_auth_token_finish(struct http_request *req) yd = yid->yd; if (req->status_code != 200) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL); goto fail; } if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL); goto fail; } if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3001, NULL); goto fail; } @@ -2408,19 +1900,19 @@ static void yahoo_https_auth_finish(struct http_request *req) unsigned char yhash[32]; if (req->status_code != 200) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2000 + req->status_code, NULL); goto fail; } if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, yahoo_https_status_parse(st), NULL); goto fail; } if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL || (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL || (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3002, NULL); goto fail; } @@ -2453,52 +1945,53 @@ fail: g_free(had); } -static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_auth(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *seed = NULL; - char *sn = NULL; + char *sn = NULL; YList *l = pkt->hash; int m = 0; + struct yahoo_data *yd = yid->yd; while (l) { struct yahoo_pair *pair = l->data; - if (pair->key == 94) + + switch (pair->key) { + case 94: seed = pair->value; - if (pair->key == 1) + break; + case 1: sn = pair->value; - if (pair->key == 13) + break; + case 13: m = atoi(pair->value); + break; + } l = l->next; } - if (!seed) + if (!seed) return; - switch (m) { - case 0: - yahoo_process_auth_pre_0x0b(yid, seed, sn); - break; - case 1: - yahoo_process_auth_0x0b(yid, seed, sn); - break; - case 2: - yahoo_process_auth_0x10(yid, seed, sn); - break; - default: - /* call error */ - WARNING(("unknown auth type %d", m)); - yahoo_process_auth_0x0b(yid, seed, sn); - break; + if (m==2) + yahoo_https_auth(yid, seed, sn); + else { + /* call error */ + WARNING(("unknown auth type %d", m)); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_UNKNOWN, NULL); } } -static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_auth_resp(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *login_id; char *handle; - char *url=NULL; - int login_status=0; + char *url = NULL; + int login_status = -1; YList *l; @@ -2514,13 +2007,15 @@ static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_p login_status = atoi(pair->value); } - if(pkt->status == 0xffffffff) { - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, login_status, url); - /* yahoo_logoff(yd->client_id);*/ + if (pkt->status == YPACKET_STATUS_DISCONNECTED) { + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + login_status, url); + /* yahoo_logoff(yd->client_id); */ } } -static void yahoo_process_mail(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_mail(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *who = NULL; @@ -2546,12 +2041,46 @@ static void yahoo_process_mail(struct yahoo_input_data *yid, struct yahoo_packet if (who && email && subj) { char from[1024]; snprintf(from, sizeof(from), "%s (%s)", who, email); - YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, from, subj, count); - } else if(count > 0) - YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, NULL, NULL, count); + YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, from, + subj, count); + } else if (count > 0) + YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, NULL, + NULL, count); } -static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_new_contact(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = yid->yd; + char *me = NULL; + char *who = NULL; + char *msg = NULL; + int online = -1; + + YList *l; + + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + if (pair->key == 4) + who = pair->value; + else if (pair->key == 5) + me = pair->value; + else if (pair->key == 14) + msg = pair->value; + else if (pair->key == 13) + online = strtol(pair->value, NULL, 10); + } + + if (who && online < 0) + YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, me, who, + msg); + else if (online == 2) + YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg); +} + +/* UNUSED? */ +static void yahoo_process_contact(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *id = NULL; @@ -2560,7 +2089,7 @@ static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_pac char *name = NULL; long tm = 0L; int state = YAHOO_STATUS_AVAILABLE; - int online = FALSE; + int online = 0; int away = 0; int idle = 0; int mobile = 0; @@ -2589,18 +2118,21 @@ static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_pac idle = strtol(pair->value, NULL, 10); else if (pair->key == 60) mobile = strtol(pair->value, NULL, 10); - + } if (id) - YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg); + YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, id, who, + msg); else if (name) - YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away, idle, mobile); - else if(pkt->status == 0x07) - YAHOO_CALLBACK(ext_yahoo_rejected)(yd->client_id, who, msg); + YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, name, + state, msg, away, idle, mobile); + else if (pkt->status == 0x07) + YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg); } -static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_buddyadd(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *who = NULL; @@ -2608,7 +2140,7 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa int status = 0; char *me = NULL; - struct yahoo_buddy *bud=NULL; + struct yahoo_buddy *bud = NULL; YList *l; for (l = pkt->hash; l; l = l->next) { @@ -2623,51 +2155,30 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa status = strtol(pair->value, NULL, 10); } - yahoo_dump_unhandled(pkt); - - if(!who) + if (!who) return; - if(!where) + if (!where) where = "Unknown"; - /* status: 0 == Successful, 1 == Error (does not exist), 2 == Already in list */ - if( status == 0 ) { - bud = y_new0(struct yahoo_buddy, 1); - bud->id = strdup(who); - bud->group = strdup(where); - bud->real_name = NULL; - - yd->buddies = y_list_append(yd->buddies, bud); - - /* Possibly called already, but at least the call above doesn't - seem to happen every time (not anytime I tried). */ - YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL); - } + bud = y_new0(struct yahoo_buddy, 1); + bud->id = strdup(who); + bud->group = strdup(where); + bud->real_name = NULL; -/* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ -} + yd->buddies = y_list_append(yd->buddies, bud); -static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) -{ - char* who=NULL; - char* me=NULL; - char* msg=NULL; - YList *l; - for (l = pkt->hash; l; l = l->next) { - struct yahoo_pair *pair = l->data; - if (pair->key == 4) - who = pair->value; - else if (pair->key == 5) - me = pair->value; - else - DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); + /* A non-zero status (i've seen 2) seems to mean the buddy is already + * added and is online */ + if (status) { + LOG(("Setting online see packet for info")); + yahoo_dump_unhandled(pkt); + YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who, + YAHOO_STATUS_AVAILABLE, NULL, 0, 0, 0); } - - if(pkt->status==3) - YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg); } -static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_buddydel(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; char *who = NULL; @@ -2690,12 +2201,13 @@ static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_pa else if (pair->key == 66) unk_66 = strtol(pair->value, NULL, 10); else - DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); + DEBUG_MSG(("unknown key: %d = %s", pair->key, + pair->value)); } - if(!who || !where) + if (!who || !where) return; - + bud = y_new0(struct yahoo_buddy, 1); bud->id = strdup(who); bud->group = strdup(where); @@ -2706,7 +2218,7 @@ static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_pa FREE(bud->group); FREE(bud); - if(buddy) { + if (buddy) { bud = buddy->data; yd->buddies = y_list_remove_link(yd->buddies, buddy); y_list_free_1(buddy); @@ -2716,16 +2228,17 @@ static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_pa FREE(bud->real_name); FREE(bud); - bud=NULL; + bud = NULL; } } -static void yahoo_process_ignore(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_ignore(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *who = NULL; - int status = 0; + int status = 0; char *me = NULL; - int un_ignore = 0; + int un_ignore = 0; YList *l; for (l = pkt->hash; l; l = l->next) { @@ -2734,27 +2247,27 @@ static void yahoo_process_ignore(struct yahoo_input_data *yid, struct yahoo_pack who = pair->value; if (pair->key == 1) me = pair->value; - if (pair->key == 13) /* 1 == ignore, 2 == unignore */ + if (pair->key == 13) /* 1 == ignore, 2 == unignore */ un_ignore = strtol(pair->value, NULL, 10); - if (pair->key == 66) + if (pair->key == 66) status = strtol(pair->value, NULL, 10); } - /* * status - * 0 - ok - * 2 - already in ignore list, could not add - * 3 - not in ignore list, could not delete - * 12 - is a buddy, could not add + * 0 - ok + * 2 - already in ignore list, could not add + * 3 - not in ignore list, could not delete + * 12 - is a buddy, could not add */ /* if(status) YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status); -*/ +*/ } -static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_voicechat(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *who = NULL; char *me = NULL; @@ -2769,12 +2282,13 @@ static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_p if (pair->key == 5) me = pair->value; if (pair->key == 13) - voice_room=pair->value; - if (pair->key == 57) - room=pair->value; + voice_room = pair->value; + if (pair->key == 57) + room = pair->value; } - NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, me)); + NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, + me)); /* * send: s:0 1:me 5:who 57:room 13:1 * ???? s:4 5:who 10:99 19:-1615114531 @@ -2786,33 +2300,59 @@ static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_p */ } -static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_ping(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *errormsg = NULL; - + YList *l; for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; if (pair->key == 16) errormsg = pair->value; } - + NOTICE(("got ping packet")); - YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg); + YAHOO_CALLBACK(ext_yahoo_got_ping) (yid->yd->client_id, errormsg); } -static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) +static void yahoo_process_buddy_change_group(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) +{ + YList *l; + char *me = NULL; + char *who = NULL; + char *old_group = NULL; + char *new_group = NULL; + + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + if (pair->key == 1) + me = pair->value; + if (pair->key == 7) + who = pair->value; + if (pair->key == 224) + old_group = pair->value; + if (pair->key == 264) + new_group = pair->value; + } + + YAHOO_CALLBACK(ext_yahoo_got_buddy_change_group) (yid->yd->client_id, + me, who, old_group, new_group); +} + +static void _yahoo_webcam_get_server_connected(void *fd, int error, void *d) { struct yahoo_input_data *yid = d; char *who = yid->wcm->user; char *data = NULL; char *packet = NULL; - unsigned char magic_nr[] = {0, 1, 0}; + unsigned char magic_nr[] = { 0, 1, 0 }; unsigned char header_len = 8; unsigned int len = 0; unsigned int pos = 0; - if(error || fd <= 0) { + if (error || !fd) { FREE(who); FREE(yid); return; @@ -2820,7 +2360,7 @@ static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) yid->fd = fd; inputs = y_list_prepend(inputs, yid); - + /* send initial packet */ if (who) data = strdup("<RVWCFG>"); @@ -2830,8 +2370,7 @@ static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) FREE(data); /* send data */ - if (who) - { + if (who) { data = strdup("g="); data = y_string_append(data, who); data = y_string_append(data, "\r\n"); @@ -2850,10 +2389,13 @@ static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) FREE(packet); FREE(data); - yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid); + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, + YAHOO_INPUT_READ, yid); } -static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, char *key) +static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, + char *key) { struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); struct yahoo_server_settings *yss = y->yd->server_settings; @@ -2861,34 +2403,36 @@ static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, char yid->type = YAHOO_CONNECTION_WEBCAM_MASTER; yid->yd = y->yd; yid->wcm = y_new0(struct yahoo_webcam, 1); - yid->wcm->user = who?strdup(who):NULL; - yid->wcm->direction = who?YAHOO_WEBCAM_DOWNLOAD:YAHOO_WEBCAM_UPLOAD; + yid->wcm->user = who ? strdup(who) : NULL; + yid->wcm->direction = who ? YAHOO_WEBCAM_DOWNLOAD : YAHOO_WEBCAM_UPLOAD; yid->wcm->key = strdup(key); - YAHOO_CALLBACK(ext_yahoo_connect_async)(yid->yd->client_id, yss->webcam_host, yss->webcam_port, - _yahoo_webcam_get_server_connected, yid); + YAHOO_CALLBACK(ext_yahoo_connect_async) (yid->yd->client_id, + yss->webcam_host, yss->webcam_port, + _yahoo_webcam_get_server_connected, yid, 0); } -static YList *webcam_queue=NULL; -static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static YList *webcam_queue = NULL; +static void yahoo_process_webcam_key(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { char *me = NULL; char *key = NULL; char *who = NULL; YList *l; - // yahoo_dump_unhandled(pkt); + yahoo_dump_unhandled(pkt); for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; if (pair->key == 5) me = pair->value; - if (pair->key == 61) - key=pair->value; + if (pair->key == 61) + key = pair->value; } l = webcam_queue; - if(!l) + if (!l) return; who = l->data; webcam_queue = y_list_remove_link(webcam_queue, webcam_queue); @@ -2897,12 +2441,11 @@ static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_ FREE(who); } -static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_packet_process(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) { DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service)); - yahoo_dump_unhandled(pkt); - switch (pkt->service) - { + switch (pkt->service) { case YAHOO_SERVICE_USERSTAT: case YAHOO_SERVICE_LOGON: case YAHOO_SERVICE_LOGOFF: @@ -2913,7 +2456,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_IDACT: case YAHOO_SERVICE_IDDEACT: case YAHOO_SERVICE_Y6_STATUS_UPDATE: - case YAHOO_SERVICE_YMSG15_STATUS: + case YAHOO_SERVICE_Y8_STATUS: yahoo_process_status(yid, pkt); break; case YAHOO_SERVICE_NOTIFY: @@ -2927,7 +2470,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_NEWMAIL: yahoo_process_mail(yid, pkt); break; - case YAHOO_SERVICE_REJECTCONTACT: + case YAHOO_SERVICE_Y7_AUTHORIZATION: + yahoo_process_new_contact(yid, pkt); + break; case YAHOO_SERVICE_NEWCONTACT: yahoo_process_contact(yid, pkt); break; @@ -2962,15 +2507,18 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack yahoo_process_chat(yid, pkt); break; case YAHOO_SERVICE_P2PFILEXFER: - case YAHOO_SERVICE_FILETRANSFER: + case YAHOO_SERVICE_Y7_FILETRANSFER: yahoo_process_filetransfer(yid, pkt); break; + case YAHOO_SERVICE_Y7_FILETRANSFERINFO: + yahoo_process_filetransferinfo(yid, pkt); + break; + case YAHOO_SERVICE_Y7_FILETRANSFERACCEPT: + yahoo_process_filetransferaccept(yid, pkt); + break; case YAHOO_SERVICE_ADDBUDDY: yahoo_process_buddyadd(yid, pkt); break; - case YAHOO_SERVICE_CONTACT_YMSG13: - yahoo_process_contact_ymsg13(yid,pkt); - break; case YAHOO_SERVICE_REMBUDDY: yahoo_process_buddydel(yid, pkt); break; @@ -2986,6 +2534,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_PING: yahoo_process_ping(yid, pkt); break; + case YAHOO_SERVICE_Y7_CHANGE_GROUP: + yahoo_process_buddy_change_group(yid, pkt); + break; case YAHOO_SERVICE_IDLE: case YAHOO_SERVICE_MAILSTAT: case YAHOO_SERVICE_CHATINVITE: @@ -2999,6 +2550,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_CHATLOGON: case YAHOO_SERVICE_CHATLOGOFF: case YAHOO_SERVICE_CHATMSG: + case YAHOO_SERVICE_REJECTCONTACT: case YAHOO_SERVICE_PEERTOPEER: WARNING(("unhandled service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -3011,9 +2563,10 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack break; case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(yid, pkt); - break; - case YAHOO_SERVICE_YMSG15_BUDDY_LIST: /* Buddy List */ + break; + case YAHOO_SERVICE_Y8_LIST: /* Buddy List */ yahoo_process_buddy_list(yid, pkt); + break; default: WARNING(("unknown service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -3021,14 +2574,14 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack } } -static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) +static struct yahoo_packet *yahoo_getdata(struct yahoo_input_data *yid) { struct yahoo_packet *pkt; struct yahoo_data *yd = yid->yd; int pos = 0; int pktlen; - if(!yd) + if (!yd) return NULL; DEBUG_MSG(("rxlen is %d", yid->rxlen)); @@ -3037,13 +2590,13 @@ static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) return NULL; } - pos += 4; /* YMSG */ + pos += 4; /* YMSG */ pos += 2; pos += 2; - pktlen = yahoo_get16(yid->rxqueue + pos); pos += 2; - DEBUG_MSG(("%d bytes to read, rxlen is %d", - pktlen, yid->rxlen)); + pktlen = yahoo_get16(yid->rxqueue + pos); + pos += 2; + DEBUG_MSG(("%d bytes to read, rxlen is %d", pktlen, yid->rxlen)); if (yid->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) { DEBUG_MSG(("len < YAHOO_PACKET_HDRLEN + pktlen")); @@ -3055,11 +2608,14 @@ static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) pkt = yahoo_packet_new(0, 0, 0); - pkt->service = yahoo_get16(yid->rxqueue + pos); pos += 2; - pkt->status = yahoo_get32(yid->rxqueue + pos); pos += 4; + pkt->service = yahoo_get16(yid->rxqueue + pos); + pos += 2; + pkt->status = yahoo_get32(yid->rxqueue + pos); + pos += 4; DEBUG_MSG(("Yahoo Service: 0x%02x Status: %d", pkt->service, - pkt->status)); - pkt->id = yahoo_get32(yid->rxqueue + pos); pos += 4; + pkt->status)); + pkt->id = yahoo_get32(yid->rxqueue + pos); + pos += 4; yd->session_id = pkt->id; @@ -3067,12 +2623,13 @@ static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) yid->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); - if (yid->rxlen>0) { - unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN - + pktlen, yid->rxlen); + if (yid->rxlen > 0) { + unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN + + pktlen, yid->rxlen); FREE(yid->rxqueue); yid->rxqueue = tmp; - DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); + DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, + yid->rxqueue)); } else { DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); FREE(yid->rxqueue); @@ -3081,136 +2638,166 @@ static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) return pkt; } -static void yahoo_yab_read(struct yab *yab, unsigned char *d, int len) +static struct yab *yahoo_yab_read(unsigned char *d, int len) { char *st, *en; char *data = (char *)d; - data[len]='\0'; + struct yab *yab = NULL; + + data[len] = '\0'; DEBUG_MSG(("Got yab: %s", data)); - st = en = strstr(data, "userid=\""); - if(st) { - st += strlen("userid=\""); - en = strchr(st, '"'); *en++ = '\0'; - yab->id = yahoo_xmldecode(st); + st = en = strstr(data, "e0=\""); + if (st) { + yab = y_new0(struct yab, 1); + + st += strlen("e0=\""); + en = strchr(st, '"'); + *en++ = '\0'; + yab->email = yahoo_xmldecode(st); } - st = strstr(en, "fname=\""); - if(st) { - st += strlen("fname=\""); - en = strchr(st, '"'); *en++ = '\0'; + if (!en) + return NULL; + + st = strstr(en, "id=\""); + if (st) { + st += strlen("id=\""); + en = strchr(st, '"'); + *en++ = '\0'; + yab->yid = atoi(yahoo_xmldecode(st)); + } + + st = strstr(en, "fn=\""); + if (st) { + st += strlen("fn=\""); + en = strchr(st, '"'); + *en++ = '\0'; yab->fname = yahoo_xmldecode(st); } - st = strstr(en, "lname=\""); - if(st) { - st += strlen("lname=\""); - en = strchr(st, '"'); *en++ = '\0'; + st = strstr(en, "ln=\""); + if (st) { + st += strlen("ln=\""); + en = strchr(st, '"'); + *en++ = '\0'; yab->lname = yahoo_xmldecode(st); } - st = strstr(en, "nname=\""); - if(st) { - st += strlen("nname=\""); - en = strchr(st, '"'); *en++ = '\0'; + st = strstr(en, "nn=\""); + if (st) { + st += strlen("nn=\""); + en = strchr(st, '"'); + *en++ = '\0'; yab->nname = yahoo_xmldecode(st); } - st = strstr(en, "email=\""); - if(st) { - st += strlen("email=\""); - en = strchr(st, '"'); *en++ = '\0'; - yab->email = yahoo_xmldecode(st); + st = strstr(en, "yi=\""); + if (st) { + st += strlen("yi=\""); + en = strchr(st, '"'); + *en++ = '\0'; + yab->id = yahoo_xmldecode(st); } st = strstr(en, "hphone=\""); - if(st) { + if (st) { st += strlen("hphone=\""); - en = strchr(st, '"'); *en++ = '\0'; + en = strchr(st, '"'); + *en++ = '\0'; yab->hphone = yahoo_xmldecode(st); } st = strstr(en, "wphone=\""); - if(st) { + if (st) { st += strlen("wphone=\""); - en = strchr(st, '"'); *en++ = '\0'; + en = strchr(st, '"'); + *en++ = '\0'; yab->wphone = yahoo_xmldecode(st); } st = strstr(en, "mphone=\""); - if(st) { + if (st) { st += strlen("mphone=\""); - en = strchr(st, '"'); *en++ = '\0'; + en = strchr(st, '"'); + *en++ = '\0'; yab->mphone = yahoo_xmldecode(st); } st = strstr(en, "dbid=\""); - if(st) { + if (st) { st += strlen("dbid=\""); - en = strchr(st, '"'); *en++ = '\0'; + en = strchr(st, '"'); + *en++ = '\0'; yab->dbid = atoi(st); } + + return yab; } -static struct yab * yahoo_getyab(struct yahoo_input_data *yid) +static struct yab *yahoo_getyab(struct yahoo_input_data *yid) { struct yab *yab = NULL; - int pos = 0, end=0; + int pos = 0, end = 0; struct yahoo_data *yd = yid->yd; - if(!yd) - return NULL; - - DEBUG_MSG(("rxlen is %d", yid->rxlen)); - - if(yid->rxlen <= strlen("<record")) + if (!yd) return NULL; - /* start with <record */ - while(pos < yid->rxlen-strlen("<record")+1 - && memcmp(yid->rxqueue + pos, "<record", strlen("<record"))) - pos++; - - if(pos >= yid->rxlen-1) - return NULL; - - end = pos+2; - /* end with /> */ - while(end < yid->rxlen-strlen("/>")+1 && memcmp(yid->rxqueue + end, "/>", strlen("/>"))) - end++; - - if(end >= yid->rxlen-1) - return NULL; - - yab = y_new0(struct yab, 1); - yahoo_yab_read(yab, yid->rxqueue + pos, end+2-pos); - - - yid->rxlen -= end+1; - DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); - if (yid->rxlen>0) { - unsigned char *tmp = y_memdup(yid->rxqueue + end + 1, yid->rxlen); - FREE(yid->rxqueue); - yid->rxqueue = tmp; - DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); - } else { - DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); - FREE(yid->rxqueue); - } + do { + DEBUG_MSG(("rxlen is %d", yid->rxlen)); + + if (yid->rxlen <= strlen("<ct")) + return NULL; + + /* start with <ct */ + while (pos < yid->rxlen - strlen("<ct") + 1 + && memcmp(yid->rxqueue + pos, "<ct", strlen("<ct"))) + pos++; + + if (pos >= yid->rxlen - 1) + return NULL; + + end = pos + 2; + /* end with > */ + while (end < yid->rxlen - strlen(">") + && memcmp(yid->rxqueue + end, ">", strlen(">"))) + end++; + + if (end >= yid->rxlen - 1) + return NULL; + + yab = yahoo_yab_read(yid->rxqueue + pos, end + 2 - pos); + + yid->rxlen -= end + 1; + DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, + yid->rxqueue)); + if (yid->rxlen > 0) { + unsigned char *tmp = + y_memdup(yid->rxqueue + end + 1, yid->rxlen); + FREE(yid->rxqueue); + yid->rxqueue = tmp; + DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, + yid->rxqueue)); + } else { + DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); + FREE(yid->rxqueue); + } + } while (!yab && end < yid->rxlen - 1); return yab; } -static char * yahoo_getwebcam_master(struct yahoo_input_data *yid) +static char *yahoo_getwebcam_master(struct yahoo_input_data *yid) { - unsigned int pos=0; - unsigned int len=0; - unsigned int status=0; - char *server=NULL; + unsigned int pos = 0; + unsigned int len = 0; + unsigned int status = 0; + char *server = NULL; struct yahoo_data *yd = yid->yd; - if(!yid || !yd) + if (!yid || !yd) return NULL; DEBUG_MSG(("rxlen is %d", yid->rxlen)); @@ -3222,14 +2809,11 @@ static char * yahoo_getwebcam_master(struct yahoo_input_data *yid) /* extract status (0 = ok, 6 = webcam not online) */ status = yid->rxqueue[pos++]; - if (status == 0) - { - pos += 2; /* skip next 2 bytes */ - server = y_memdup(yid->rxqueue+pos, 16); + if (status == 0) { + pos += 2; /* skip next 2 bytes */ + server = y_memdup(yid->rxqueue + pos, 16); pos += 16; - } - else if (status == 6) - { + } else if (status == 6) { YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, yid->wcm->user, 4); } @@ -3238,11 +2822,12 @@ static char * yahoo_getwebcam_master(struct yahoo_input_data *yid) yid->rxlen -= len; DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); - if (yid->rxlen>0) { + if (yid->rxlen > 0) { unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen); FREE(yid->rxqueue); yid->rxqueue = tmp; - DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); + DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, + yid->rxqueue)); } else { DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); FREE(yid->rxqueue); @@ -3253,35 +2838,33 @@ static char * yahoo_getwebcam_master(struct yahoo_input_data *yid) static int yahoo_get_webcam_data(struct yahoo_input_data *yid) { - unsigned char reason=0; - unsigned int pos=0; - unsigned int begin=0; - unsigned int end=0; - unsigned int closed=0; - unsigned char header_len=0; + unsigned char reason = 0; + unsigned int pos = 0; + unsigned int begin = 0; + unsigned int end = 0; + unsigned int closed = 0; + unsigned char header_len = 0; char *who; - int connect=0; + int connect = 0; struct yahoo_data *yd = yid->yd; - if(!yd) + if (!yd) return -1; - if(!yid->wcm || !yid->wcd || !yid->rxlen) + if (!yid->wcm || !yid->wcd || !yid->rxlen) return -1; DEBUG_MSG(("rxlen is %d", yid->rxlen)); /* if we are not reading part of image then read header */ - if (!yid->wcd->to_read) - { - header_len=yid->rxqueue[pos++]; - yid->wcd->packet_type=0; + if (!yid->wcd->to_read) { + header_len = yid->rxqueue[pos++]; + yid->wcd->packet_type = 0; if (yid->rxlen < header_len) return 0; - if (header_len >= 8) - { + if (header_len >= 8) { reason = yid->rxqueue[pos++]; /* next 2 bytes should always be 05 00 */ pos += 2; @@ -3289,8 +2872,7 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid) pos += 4; yid->wcd->to_read = yid->wcd->data_size; } - if (header_len >= 13) - { + if (header_len >= 13) { yid->wcd->packet_type = yid->rxqueue[pos++]; yid->wcd->timestamp = yahoo_get32(yid->rxqueue + pos); pos += 4; @@ -3302,7 +2884,8 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid) begin = pos; pos += yid->wcd->to_read; - if (pos > yid->rxlen) pos = yid->rxlen; + if (pos > yid->rxlen) + pos = yid->rxlen; /* if it is not an image then make sure we have the whole packet */ if (yid->wcd->packet_type != 0x02) { @@ -3315,93 +2898,95 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid) } DEBUG_MSG(("packet type %.2X, data length %d", yid->wcd->packet_type, - yid->wcd->data_size)); + yid->wcd->data_size)); /* find out what kind of packet we got */ - switch (yid->wcd->packet_type) - { - case 0x00: - /* user requests to view webcam (uploading) */ - if (yid->wcd->data_size && - yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { - end = begin; - while (end <= yid->rxlen && - yid->rxqueue[end++] != 13); - if (end > begin) - { - who = y_memdup(yid->rxqueue + begin, end - begin); - who[end - begin - 1] = 0; - YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who + 2, 2); - FREE(who); - } + switch (yid->wcd->packet_type) { + case 0x00: + /* user requests to view webcam (uploading) */ + if (yid->wcd->data_size && + yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { + end = begin; + while (end <= yid->rxlen && yid->rxqueue[end++] != 13) ; + if (end > begin) { + who = y_memdup(yid->rxqueue + begin, + end - begin); + who[end - begin - 1] = 0; + YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd-> + client_id, who + 2, 2); + FREE(who); } + } - if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { - /* timestamp/status field */ - /* 0 = declined viewing permission */ - /* 1 = accepted viewing permission */ - if (yid->wcd->timestamp == 0) { - YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, 3); - } - } - break; - case 0x01: /* status packets?? */ - /* timestamp contains status info */ - /* 00 00 00 01 = we have data?? */ - break; - case 0x02: /* image data */ - YAHOO_CALLBACK(ext_yahoo_got_webcam_image)(yd->client_id, - yid->wcm->user, yid->rxqueue + begin, - yid->wcd->data_size, pos - begin, - yid->wcd->timestamp); - break; - case 0x05: /* response packets when uploading */ - if (!yid->wcd->data_size) { - YAHOO_CALLBACK(ext_yahoo_webcam_data_request)(yd->client_id, yid->wcd->timestamp); + if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { + /* timestamp/status field */ + /* 0 = declined viewing permission */ + /* 1 = accepted viewing permission */ + if (yid->wcd->timestamp == 0) { + YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd-> + client_id, yid->wcm->user, 3); } + } + break; + case 0x01: /* status packets?? */ + /* timestamp contains status info */ + /* 00 00 00 01 = we have data?? */ + break; + case 0x02: /* image data */ + YAHOO_CALLBACK(ext_yahoo_got_webcam_image) (yd->client_id, + yid->wcm->user, yid->rxqueue + begin, + yid->wcd->data_size, pos - begin, yid->wcd->timestamp); + break; + case 0x05: /* response packets when uploading */ + if (!yid->wcd->data_size) { + YAHOO_CALLBACK(ext_yahoo_webcam_data_request) (yd-> + client_id, yid->wcd->timestamp); + } + break; + case 0x07: /* connection is closing */ + switch (reason) { + case 0x01: /* user closed connection */ + closed = 1; break; - case 0x07: /* connection is closing */ - switch(reason) - { - case 0x01: /* user closed connection */ - closed = 1; - break; - case 0x0F: /* user cancelled permission */ - closed = 2; - break; - } - YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, closed); - break; - case 0x0C: /* user connected */ - case 0x0D: /* user disconnected */ - if (yid->wcd->data_size) { - who = y_memdup(yid->rxqueue + begin, pos - begin + 1); - who[pos - begin] = 0; - if (yid->wcd->packet_type == 0x0C) - connect=1; - else - connect=0; - YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who, connect); - FREE(who); - } - break; - case 0x13: /* user data */ - /* i=user_ip (ip of the user we are viewing) */ - /* j=user_ext_ip (external ip of the user we */ - /* are viewing) */ - break; - case 0x17: /* ?? */ + case 0x0F: /* user cancelled permission */ + closed = 2; break; + } + YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, + yid->wcm->user, closed); + break; + case 0x0C: /* user connected */ + case 0x0D: /* user disconnected */ + if (yid->wcd->data_size) { + who = y_memdup(yid->rxqueue + begin, pos - begin + 1); + who[pos - begin] = 0; + if (yid->wcd->packet_type == 0x0C) + connect = 1; + else + connect = 0; + YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id, + who, connect); + FREE(who); + } + break; + case 0x13: /* user data */ + /* i=user_ip (ip of the user we are viewing) */ + /* j=user_ext_ip (external ip of the user we */ + /* are viewing) */ + break; + case 0x17: /* ?? */ + break; } yid->wcd->to_read -= pos - begin; yid->rxlen -= pos; DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); - if (yid->rxlen>0) { + if (yid->rxlen > 0) { unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen); FREE(yid->rxqueue); yid->rxqueue = tmp; - DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); + DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, + yid->rxqueue)); } else { DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); FREE(yid->rxqueue); @@ -3414,60 +2999,64 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid) return 0; } -int yahoo_write_ready(int id, int fd, void *data) +int yahoo_write_ready(int id, void *fd, void *data) { struct yahoo_input_data *yid = data; int len; struct data_queue *tx; - LOG(("write callback: id=%d fd=%d data=%p", id, fd, data)); - if(!yid || !yid->txqueues || !find_conn_by_id(id)) + LOG(("write callback: id=%d fd=%p data=%p", id, fd, data)); + if (!yid || !yid->txqueues) return -2; - + tx = yid->txqueues->data; LOG(("writing %d bytes", tx->len)); len = yahoo_send_data(fd, tx->queue, MIN(1024, tx->len)); - if(len == -1 && errno == EAGAIN) + if (len == -1 && errno == EAGAIN) return 1; - if(len <= 0) { + if (len <= 0) { int e = errno; DEBUG_MSG(("len == %d (<= 0)", len)); - while(yid->txqueues) { - YList *l=yid->txqueues; + while (yid->txqueues) { + YList *l = yid->txqueues; tx = l->data; free(tx->queue); free(tx); - yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); + yid->txqueues = + y_list_remove_link(yid->txqueues, + yid->txqueues); y_list_free_1(l); } - LOG(("yahoo_write_ready(%d, %d) len < 0", id, fd)); - YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag); + LOG(("yahoo_write_ready(%d, %p) len < 0", id, fd)); + YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, yid->write_tag); yid->write_tag = 0; - errno=e; + errno = e; return 0; } tx->len -= len; - if(tx->len > 0) { + if (tx->len > 0) { unsigned char *tmp = y_memdup(tx->queue + len, tx->len); FREE(tx->queue); tx->queue = tmp; } else { - YList *l=yid->txqueues; + YList *l = yid->txqueues; free(tx->queue); free(tx); - yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); + yid->txqueues = + y_list_remove_link(yid->txqueues, yid->txqueues); y_list_free_1(l); /* - if(!yid->txqueues) - LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); - */ - if(!yid->txqueues) { - LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); - YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag); + if(!yid->txqueues) + LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); + */ + if (!yid->txqueues) { + LOG(("yahoo_write_ready(%d, %p) !txqueues", id, fd)); + YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, + yid->write_tag); yid->write_tag = 0; } } @@ -3475,17 +3064,18 @@ int yahoo_write_ready(int id, int fd, void *data) return 1; } -static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_pager_connection(struct yahoo_input_data *yid, + int over) { struct yahoo_packet *pkt; struct yahoo_data *yd = yid->yd; int id = yd->client_id; - if(over) + if (over) return; - while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) - && (pkt = yahoo_getdata(yid)) != NULL) { + while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) + && (pkt = yahoo_getdata(yid)) != NULL) { yahoo_packet_process(yid, pkt); @@ -3493,17 +3083,15 @@ static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int ove } } -static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) -{ -} - -static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, + int over) { - if(over) + if (over) return; - if (strstr((char*)yid->rxqueue+(yid->rxlen-20), "</content>")) { - YAHOO_CALLBACK(ext_yahoo_chat_cat_xml)(yid->yd->client_id, (char*)yid->rxqueue); + if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) { + YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id, + (char *)yid->rxqueue); } } @@ -3512,111 +3100,143 @@ static void yahoo_process_yab_connection(struct yahoo_input_data *yid, int over) struct yahoo_data *yd = yid->yd; struct yab *yab; YList *buds; - int changed=0; + int changed = 0; int id = yd->client_id; + int yab_used = 0; + + LOG(("Got data for YAB")); - if(over) + if (over) return; - while(find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB) - && (yab = yahoo_getyab(yid)) != NULL) { - if(!yab->id) + while (find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB) + && (yab = yahoo_getyab(yid)) != NULL) { + if (!yab->id) continue; - changed=1; - for(buds = yd->buddies; buds; buds=buds->next) { - struct yahoo_buddy * bud = buds->data; - if(!strcmp(bud->id, yab->id)) { + + changed = 1; + yab_used = 0; + for (buds = yd->buddies; buds; buds = buds->next) { + struct yahoo_buddy *bud = buds->data; + if (!strcmp(bud->id, yab->id)) { + yab_used = 1; bud->yab_entry = yab; - if(yab->nname) { + if (yab->nname) { bud->real_name = strdup(yab->nname); - } else if(yab->fname && yab->lname) { - bud->real_name = y_new0(char, - strlen(yab->fname)+ - strlen(yab->lname)+2 - ); + } else if (yab->fname && yab->lname) { + bud->real_name = y_new0(char, + strlen(yab->fname) + + strlen(yab->lname) + 2); sprintf(bud->real_name, "%s %s", - yab->fname, yab->lname); - } else if(yab->fname) { + yab->fname, yab->lname); + } else if (yab->fname) { bud->real_name = strdup(yab->fname); } - break; /* for */ + break; /* for */ } } + + if (!yab_used) { + FREE(yab->fname); + FREE(yab->lname); + FREE(yab->nname); + FREE(yab->id); + FREE(yab->email); + FREE(yab->hphone); + FREE(yab->wphone); + FREE(yab->mphone); + FREE(yab); + } + } - if(changed) - YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); + if (changed) + YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, + yd->buddies); } -static void yahoo_process_search_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_search_connection(struct yahoo_input_data *yid, + int over) { - struct yahoo_found_contact *yct=NULL; + struct yahoo_found_contact *yct = NULL; char *p = (char *)yid->rxqueue, *np, *cp; int k, n; - int start=0, found=0, total=0; - YList *contacts=NULL; - struct yahoo_input_data *pyid = find_input_by_id_and_type(yid->yd->client_id, YAHOO_CONNECTION_PAGER); + int start = 0, found = 0, total = 0; + YList *contacts = NULL; + struct yahoo_input_data *pyid = + find_input_by_id_and_type(yid->yd->client_id, + YAHOO_CONNECTION_PAGER); - if(!over || !pyid) + if (!over || !pyid) return; - if(p && (p=strstr(p, "\r\n\r\n"))) { + if (p && (p = strstr(p, "\r\n\r\n"))) { p += 4; - for(k = 0; (p = strchr(p, 4)) && (k < 4); k++) { + for (k = 0; (p = strchr(p, 4)) && (k < 4); k++) { p++; n = atoi(p); - switch(k) { - case 0: found = pyid->ys->lsearch_nfound = n; break; - case 2: start = pyid->ys->lsearch_nstart = n; break; - case 3: total = pyid->ys->lsearch_ntotal = n; break; + switch (k) { + case 0: + found = pyid->ys->lsearch_nfound = n; + break; + case 2: + start = pyid->ys->lsearch_nstart = n; + break; + case 3: + total = pyid->ys->lsearch_ntotal = n; + break; } } - if(p) + if (p) p++; - k=0; - while(p && *p) { + k = 0; + while (p && *p) { cp = p; np = strchr(p, 4); - if(!np) + if (!np) break; *np = 0; - p = np+1; - - switch(k++) { - case 1: - if(strlen(cp) > 2 && y_list_length(contacts) < total) { - yct = y_new0(struct yahoo_found_contact, 1); - contacts = y_list_append(contacts, yct); - yct->id = cp+2; - } else { - *p = 0; - } - break; - case 2: - yct->online = !strcmp(cp, "2") ? 1 : 0; - break; - case 3: - yct->gender = cp; - break; - case 4: - yct->age = atoi(cp); - break; - case 5: - if(strcmp(cp, "5") != 0) - yct->location = cp; - k = 0; - break; + p = np + 1; + + switch (k++) { + case 1: + if (strlen(cp) > 2 + && y_list_length(contacts) < total) { + yct = y_new0(struct yahoo_found_contact, + 1); + contacts = y_list_append(contacts, yct); + yct->id = cp + 2; + } else { + *p = 0; + } + break; + case 2: + yct->online = !strcmp(cp, "2") ? 1 : 0; + break; + case 3: + yct->gender = cp; + break; + case 4: + yct->age = atoi(cp); + break; + case 5: + /* not worth the context switch for strcmp */ + if (cp[0] != '\005' || cp[1] != '\000') + yct->location = cp; + k = 0; + break; } } } - YAHOO_CALLBACK(ext_yahoo_got_search_result)(yid->yd->client_id, found, start, total, contacts); + YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found, + start, total, contacts); - while(contacts) { + while (contacts) { YList *node = contacts; contacts = y_list_remove_link(contacts, node); free(node->data); @@ -3624,20 +3244,20 @@ static void yahoo_process_search_connection(struct yahoo_input_data *yid, int ov } } -static void _yahoo_webcam_connected(int fd, int error, void *d) +static void _yahoo_webcam_connected(void *fd, int error, void *d) { struct yahoo_input_data *yid = d; struct yahoo_webcam *wcm = yid->wcm; struct yahoo_data *yd = yid->yd; char conn_type[100]; - char *data=NULL; - char *packet=NULL; - unsigned char magic_nr[] = {1, 0, 0, 0, 1}; - unsigned header_len=0; - unsigned int len=0; - unsigned int pos=0; - - if(error || fd <= 0) { + char *data = NULL; + char *packet = NULL; + unsigned char magic_nr[] = { 1, 0, 0, 0, 1 }; + unsigned header_len = 0; + unsigned int len = 0; + unsigned int pos = 0; + + if (error || !fd) { FREE(yid); return; } @@ -3647,74 +3267,70 @@ static void _yahoo_webcam_connected(int fd, int error, void *d) LOG(("Connected")); /* send initial packet */ - switch (wcm->direction) - { - case YAHOO_WEBCAM_DOWNLOAD: - data = strdup("<REQIMG>"); - break; - case YAHOO_WEBCAM_UPLOAD: - data = strdup("<SNDIMG>"); - break; - default: - return; + switch (wcm->direction) { + case YAHOO_WEBCAM_DOWNLOAD: + data = strdup("<REQIMG>"); + break; + case YAHOO_WEBCAM_UPLOAD: + data = strdup("<SNDIMG>"); + break; + default: + return; } yahoo_add_to_send_queue(yid, data, strlen(data)); FREE(data); /* send data */ - switch (wcm->direction) - { - case YAHOO_WEBCAM_DOWNLOAD: - header_len = 8; - data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); - data = y_string_append(data, yd->user); - data = y_string_append(data, "\r\nt="); - data = y_string_append(data, wcm->key); - data = y_string_append(data, "\r\ni="); - data = y_string_append(data, wcm->my_ip); - data = y_string_append(data, "\r\ng="); - data = y_string_append(data, wcm->user); - data = y_string_append(data, "\r\no=w-2-5-1\r\np="); - snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); - data = y_string_append(data, conn_type); - data = y_string_append(data, "\r\n"); - break; - case YAHOO_WEBCAM_UPLOAD: - header_len = 13; - data = strdup("a=2\r\nc=us\r\nu="); - data = y_string_append(data, yd->user); - data = y_string_append(data, "\r\nt="); - data = y_string_append(data, wcm->key); - data = y_string_append(data, "\r\ni="); - data = y_string_append(data, wcm->my_ip); - data = y_string_append(data, "\r\no=w-2-5-1\r\np="); - snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); - data = y_string_append(data, conn_type); - data = y_string_append(data, "\r\nb="); - data = y_string_append(data, wcm->description); - data = y_string_append(data, "\r\n"); - break; + switch (wcm->direction) { + case YAHOO_WEBCAM_DOWNLOAD: + header_len = 8; + data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); + data = y_string_append(data, yd->user); + data = y_string_append(data, "\r\nt="); + data = y_string_append(data, wcm->key); + data = y_string_append(data, "\r\ni="); + data = y_string_append(data, wcm->my_ip); + data = y_string_append(data, "\r\ng="); + data = y_string_append(data, wcm->user); + data = y_string_append(data, "\r\no=w-2-5-1\r\np="); + snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); + data = y_string_append(data, conn_type); + data = y_string_append(data, "\r\n"); + break; + case YAHOO_WEBCAM_UPLOAD: + header_len = 13; + data = strdup("a=2\r\nc=us\r\nu="); + data = y_string_append(data, yd->user); + data = y_string_append(data, "\r\nt="); + data = y_string_append(data, wcm->key); + data = y_string_append(data, "\r\ni="); + data = y_string_append(data, wcm->my_ip); + data = y_string_append(data, "\r\no=w-2-5-1\r\np="); + snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); + data = y_string_append(data, conn_type); + data = y_string_append(data, "\r\nb="); + data = y_string_append(data, wcm->description); + data = y_string_append(data, "\r\n"); + break; } len = strlen(data); packet = y_new0(char, header_len + len); packet[pos++] = header_len; packet[pos++] = 0; - switch (wcm->direction) - { - case YAHOO_WEBCAM_DOWNLOAD: - packet[pos++] = 1; - packet[pos++] = 0; - break; - case YAHOO_WEBCAM_UPLOAD: - packet[pos++] = 5; - packet[pos++] = 0; - break; + switch (wcm->direction) { + case YAHOO_WEBCAM_DOWNLOAD: + packet[pos++] = 1; + packet[pos++] = 0; + break; + case YAHOO_WEBCAM_UPLOAD: + packet[pos++] = 5; + packet[pos++] = 0; + break; } pos += yahoo_put32(packet + pos, len); - if (wcm->direction == YAHOO_WEBCAM_UPLOAD) - { + if (wcm->direction == YAHOO_WEBCAM_UPLOAD) { memcpy(packet + pos, magic_nr, sizeof(magic_nr)); pos += sizeof(magic_nr); } @@ -3723,7 +3339,9 @@ static void _yahoo_webcam_connected(int fd, int error, void *d) FREE(packet); FREE(data); - yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, + yid->fd, YAHOO_INPUT_READ, yid); } static void yahoo_webcam_connect(struct yahoo_input_data *y) @@ -3748,23 +3366,23 @@ static void yahoo_webcam_connect(struct yahoo_input_data *y) yid->wcd = y_new0(struct yahoo_webcam_data, 1); LOG(("Connecting to: %s:%d", wcm->server, wcm->port)); - YAHOO_CALLBACK(ext_yahoo_connect_async)(y->yd->client_id, wcm->server, wcm->port, - _yahoo_webcam_connected, yid); + YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server, + wcm->port, _yahoo_webcam_connected, yid, 0); } -static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, + int over) { - char* server; + char *server; struct yahoo_server_settings *yss; - if(over) + if (over) return; server = yahoo_getwebcam_master(yid); - if (server) - { + if (server) { yss = yid->yd->server_settings; yid->wcm->server = strdup(server); yid->wcm->port = yss->webcam_port; @@ -3777,72 +3395,74 @@ static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, } } -static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, + int over) { int id = yid->yd->client_id; - int fd = yid->fd; + void *fd = yid->fd; - if(over) + if (over) return; /* as long as we still have packets available keep processing them */ - while (find_input_by_id_and_fd(id, fd) - && yahoo_get_webcam_data(yid) == 1); -} - -static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { - yahoo_process_pager_connection, - yahoo_process_ft_connection, - yahoo_process_yab_connection, - yahoo_process_webcam_master_connection, - yahoo_process_webcam_connection, - yahoo_process_chatcat_connection, - yahoo_process_search_connection, -}; + while (find_input_by_id_and_fd(id, fd) + && yahoo_get_webcam_data(yid) == 1) ; +} + +static void (*yahoo_process_connection[]) (struct yahoo_input_data *, + int over) = { +yahoo_process_pager_connection, yahoo_process_ft_connection, + yahoo_process_yab_connection, + yahoo_process_webcam_master_connection, + yahoo_process_webcam_connection, + yahoo_process_chatcat_connection, + yahoo_process_search_connection}; -int yahoo_read_ready(int id, int fd, void *data) +int yahoo_read_ready(int id, void *fd, void *data) { struct yahoo_input_data *yid = data; char buf[1024]; int len; - LOG(("read callback: id=%d fd=%d data=%p", id, fd, data)); - if(!yid) + LOG(("read callback: id=%d fd=%p data=%p", id, fd, data)); + if (!yid) return -2; - do { - len = read(fd, buf, sizeof(buf)); - } while(len == -1 && errno == EINTR); + len = YAHOO_CALLBACK(ext_yahoo_read) (fd, buf, sizeof(buf)); + } while (len == -1 && errno == EINTR); - if(len == -1 && (errno == EAGAIN||errno == EINTR)) /* we'll try again later */ + if (len == -1 && (errno == EAGAIN || errno == EINTR)) /* we'll try again later */ return 1; if (len <= 0) { int e = errno; DEBUG_MSG(("len == %d (<= 0)", len)); - if(yid->type == YAHOO_CONNECTION_PAGER) { - YAHOO_CALLBACK(ext_yahoo_error)(yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION); + if (yid->type == YAHOO_CONNECTION_PAGER) { + YAHOO_CALLBACK(ext_yahoo_login_response) (yid->yd-> + client_id, YAHOO_LOGIN_SOCK, NULL); } - yahoo_process_connection[yid->type](yid, 1); + yahoo_process_connection[yid->type] (yid, 1); yahoo_input_close(yid); /* no need to return an error, because we've already fixed it */ - if(len == 0) + if (len == 0) return 1; - errno=e; + errno = e; LOG(("read error: %s", strerror(errno))); return -1; } - yid->rxqueue = y_renew(unsigned char, yid->rxqueue, len + yid->rxlen); + yid->rxqueue = + y_renew(unsigned char, yid->rxqueue, len + yid->rxlen + 1); memcpy(yid->rxqueue + yid->rxlen, buf, len); yid->rxlen += len; + yid->rxqueue[yid->rxlen] = 0; - yahoo_process_connection[yid->type](yid, 0); + yahoo_process_connection[yid->type] (yid, 0); return len; } @@ -3854,7 +3474,7 @@ int yahoo_init_with_attributes(const char *username, const char *password, ...) yd = y_new0(struct yahoo_data, 1); - if(!yd) + if (!yd) return 0; yd->user = strdup(username); @@ -3879,13 +3499,7 @@ int yahoo_init(const char *username, const char *password) return yahoo_init_with_attributes(username, password, NULL); } -struct connect_callback_data { - struct yahoo_data *yd; - int tag; - int i; -}; - -static void yahoo_connected(int fd, int error, void *data) +static void yahoo_connected(void *fd, int error, void *data) { struct connect_callback_data *ccd = data; struct yahoo_data *yd = ccd->yd; @@ -3893,114 +3507,112 @@ static void yahoo_connected(int fd, int error, void *data) struct yahoo_input_data *yid; struct yahoo_server_settings *yss = yd->server_settings; - if(error) { - if(fallback_ports[ccd->i]) { - int tag; - yss->pager_port = fallback_ports[ccd->i++]; - tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host, - yss->pager_port, yahoo_connected, ccd); + if (error) { + int tag; + if (fallback_ports[ccd->i]) { + char *host = yss->pager_host; + + if (!host) + host = yss->pager_host_list[ccd->server_i]; - if(tag > 0) - ccd->tag=tag; + yss->pager_port = fallback_ports[ccd->i++]; + tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd-> + client_id, host, yss->pager_port, + yahoo_connected, ccd, 0); + + if (tag > 0) + ccd->tag = tag; + } else if (yss->pager_host_list + && yss->pager_host_list[ccd->server_i]) { + + /* Get back to the default port */ + yss->pager_port = pager_port; + ccd->server_i++; + LOG(("Fallback: Connecting to %s:%d", yss->pager_host_list[ccd->server_i], yss->pager_port)); + + ccd->i = 0; + tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, + yss->pager_host_list[ccd->server_i], yss->pager_port, + yahoo_connected, ccd, 0); } else { FREE(ccd); - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL); + YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, + YAHOO_LOGIN_SOCK, NULL); } return; } FREE(ccd); - /* fd < 0 && error == 0 means connect was cancelled */ - if(fd < 0) + /* fd == NULL && error == 0 means connect was cancelled */ + if (!fd) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT, + yd->session_id); NOTICE(("Sending initial packet")); yahoo_packet_hash(pkt, 1, yd->user); - yid = y_new0(struct yahoo_input_data, 1); - yid->yd = yd; + yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); yid->fd = fd; - inputs = y_list_prepend(inputs, yid); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); - yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, + yid->fd, YAHOO_INPUT_READ, yid); } -void yahoo_login(int id, int initial) +void *yahoo_get_fd(int id) { - struct yahoo_data *yd = find_conn_by_id(id); - struct connect_callback_data *ccd; - struct yahoo_server_settings *yss; - int tag; - - if(!yd) - return; - - yss = yd->server_settings; - - yd->initial_status = initial; - - ccd = y_new0(struct connect_callback_data, 1); - ccd->yd = yd; - tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host, yss->pager_port, - yahoo_connected, ccd); - - /* - * if tag <= 0, then callback has already been called - * so ccd will have been freed - */ - if(tag > 0) - ccd->tag = tag; - else if(tag < 0) - YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL); -} - - -int yahoo_get_fd(int id) -{ - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); - if(!yid) + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + if (!yid) return 0; else return yid->fd; } -void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture) +void yahoo_send_buzz(int id, const char *from, const char *who) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + yahoo_send_im(id, from, who, "<ding>", 1, 0); +} + +void yahoo_send_im(int id, const char *from, const char *who, const char *what, + int utf8, int picture) +{ + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_packet *pkt = NULL; struct yahoo_data *yd; char pic_str[10]; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, + yd->session_id); snprintf(pic_str, sizeof(pic_str), "%d", picture); - - if(from && strcmp(from, yd->user)) + + if (from && strcmp(from, yd->user)) yahoo_packet_hash(pkt, 0, yd->user); - yahoo_packet_hash(pkt, 1, from?from:yd->user); + yahoo_packet_hash(pkt, 1, from ? from : yd->user); yahoo_packet_hash(pkt, 5, who); yahoo_packet_hash(pkt, 14, what); - if(utf8) + if (utf8) yahoo_packet_hash(pkt, 97, "1"); yahoo_packet_hash(pkt, 63, ";0"); /* imvironment name; or ;0 */ yahoo_packet_hash(pkt, 64, "0"); yahoo_packet_hash(pkt, 206, pic_str); - yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); @@ -4008,17 +3620,19 @@ void yahoo_send_im(int id, const char *from, const char *who, const char *what, void yahoo_send_typing(int id, const char *from, const char *who, int typ) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, + yd->session_id); yahoo_packet_hash(pkt, 5, who); - yahoo_packet_hash(pkt, 1, from?from:yd->user); + yahoo_packet_hash(pkt, 1, from ? from : yd->user); yahoo_packet_hash(pkt, 14, " "); yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); yahoo_packet_hash(pkt, 49, "TYPING"); @@ -4030,22 +3644,25 @@ void yahoo_send_typing(int id, const char *from, const char *who, int typ) void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; int old_status; char s[4]; - if(!yid) + if (!yid) return; yd = yid->yd; + old_status = yd->current_status; yd->current_status = state; /* Thank you libpurple :) */ if (yd->current_status == YAHOO_STATUS_INVISIBLE) { - pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, + YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 13, "2"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); @@ -4053,7 +3670,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) return; } - pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, + yd->current_status, yd->session_id); snprintf(s, sizeof(s), "%d", yd->current_status); yahoo_packet_hash(pkt, 10, s); yahoo_packet_hash(pkt, 19, msg && state == YAHOO_STATUS_CUSTOM ? msg : ""); @@ -4061,8 +3679,9 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); - if(old_status == YAHOO_STATUS_INVISIBLE) { - pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + if (old_status == YAHOO_STATUS_INVISIBLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, + YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, 13, "1"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); @@ -4071,21 +3690,23 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) void yahoo_logoff(int id) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; LOG(("yahoo_logoff: current status: %d", yd->current_status)); - if(yd->current_status != -1 && 0) { + if (yd->current_status != -1 && 0) { /* Meh. Don't send this. The event handlers are not going to get to do this so it'll just leak memory. And the TCP connection reset will hopefully be clear enough. */ - pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, + YPACKET_STATUS_DEFAULT, yd->session_id); yd->current_status = -1; if (pkt) { @@ -4094,22 +3715,25 @@ void yahoo_logoff(int id) } } - do { +/* do { yahoo_input_close(yid); - } while((yid = find_input_by_id(id))); + } while((yid = find_input_by_id(id)));*/ + } void yahoo_get_list(int id) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YPACKET_STATUS_DEFAULT, + yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); if (pkt) { yahoo_send_packet(yid, pkt, 0); @@ -4117,139 +3741,136 @@ void yahoo_get_list(int id) } } -static void _yahoo_http_connected(int id, int fd, int error, void *data) +static void _yahoo_http_connected(int id, void *fd, int error, void *data) { struct yahoo_input_data *yid = data; - if(fd <= 0) { + if (fd == NULL || error) { inputs = y_list_remove(inputs, yid); FREE(yid); return; } yid->fd = fd; - yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid); + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, + YAHOO_INPUT_READ, yid); } +/* FIXME Get address book from address.yahoo.com instead */ void yahoo_get_yab(int id) { struct yahoo_data *yd = find_conn_by_id(id); struct yahoo_input_data *yid; char url[1024]; - char buff[1024]; + char buff[2048]; - if(!yd) + if (!yd) return; yid = y_new0(struct yahoo_input_data, 1); yid->yd = yd; yid->type = YAHOO_CONNECTION_YAB; - snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?ab2=0"); + LOG(("Sending request for Address Book")); + + snprintf(url, 1024, + "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us" + "&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252"); - snprintf(buff, sizeof(buff), "Y=%s; T=%s", - yd->cookie_y, yd->cookie_t); + snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); inputs = y_list_prepend(inputs, yid); - yahoo_http_get(yid->yd->client_id, url, buff, - _yahoo_http_connected, yid); + yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, + _yahoo_http_connected, yid); +} + +struct yahoo_post_data { + struct yahoo_input_data *yid; + char *data; +}; + +static void _yahoo_http_post_connected(int id, void *fd, int error, void *data) +{ + struct yahoo_post_data *yad = data; + struct yahoo_input_data *yid = yad->yid; + char *buff = yad->data; + + if (!fd) { + inputs = y_list_remove(inputs, yid); + FREE(yid); + return; + } + + YAHOO_CALLBACK(ext_yahoo_write) (fd, buff, strlen(buff)); + + yid->fd = fd; + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, + YAHOO_INPUT_READ, yid); + + FREE(buff); + FREE(yad); } -void yahoo_set_yab(int id, struct yab * yab) +/* FIXME This is also likely affected */ +void yahoo_set_yab(int id, struct yab *yab) { + struct yahoo_post_data *yad = y_new0(struct yahoo_post_data, 1); struct yahoo_data *yd = find_conn_by_id(id); struct yahoo_input_data *yid; char url[1024]; char buff[1024]; - char *temp; - int size = sizeof(url)-1; + char post[1024]; + int size = 0; - if(!yd) + if (!yd) return; yid = y_new0(struct yahoo_input_data, 1); yid->type = YAHOO_CONNECTION_YAB; yid->yd = yd; - strncpy(url, "http://insider.msg.yahoo.com/ycontent/?addab2=0", size); - - if(yab->dbid) { - /* change existing yab */ - char tmp[32]; - strncat(url, "&ee=1&ow=1&id=", size - strlen(url)); - snprintf(tmp, sizeof(tmp), "%d", yab->dbid); - strncat(url, tmp, size - strlen(url)); - } - - if(yab->fname) { - strncat(url, "&fn=", size - strlen(url)); - temp = yahoo_urlencode(yab->fname); - strncat(url, temp, size - strlen(url)); - free(temp); - } - if(yab->lname) { - strncat(url, "&ln=", size - strlen(url)); - temp = yahoo_urlencode(yab->lname); - strncat(url, temp, size - strlen(url)); - free(temp); - } - strncat(url, "&yid=", size - strlen(url)); - temp = yahoo_urlencode(yab->id); - strncat(url, temp, size - strlen(url)); - free(temp); - if(yab->nname) { - strncat(url, "&nn=", size - strlen(url)); - temp = yahoo_urlencode(yab->nname); - strncat(url, temp, size - strlen(url)); - free(temp); - } - if(yab->email) { - strncat(url, "&e=", size - strlen(url)); - temp = yahoo_urlencode(yab->email); - strncat(url, temp, size - strlen(url)); - free(temp); - } - if(yab->hphone) { - strncat(url, "&hp=", size - strlen(url)); - temp = yahoo_urlencode(yab->hphone); - strncat(url, temp, size - strlen(url)); - free(temp); - } - if(yab->wphone) { - strncat(url, "&wp=", size - strlen(url)); - temp = yahoo_urlencode(yab->wphone); - strncat(url, temp, size - strlen(url)); - free(temp); - } - if(yab->mphone) { - strncat(url, "&mp=", size - strlen(url)); - temp = yahoo_urlencode(yab->mphone); - strncat(url, temp, size - strlen(url)); - free(temp); - } - strncat(url, "&pp=0", size - strlen(url)); - - snprintf(buff, sizeof(buff), "Y=%s; T=%s", - yd->cookie_y, yd->cookie_t); + if(yab->yid) + size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<ab k=\"%s\" cc=\"%d\">" + "<ct id=\"%d\" e=\"1\" yi=\"%s\" nn=\"%s\" />" + "</ab>", yd->user, 9, yab->yid, /* Don't know why */ + yab->id, yab->nname?yab->nname:""); + else + size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<ab k=\"%s\" cc=\"%d\">" + "<ct a=\"1\" yi=\"%s\" nn=\"%s\" />" + "</ab>", yd->user, 1, /* Don't know why */ + yab->id, yab->nname?yab->nname:""); + + yad->yid = yid; + yad->data = strdup(post); + + strcpy(url, "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us" + "&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252"); + + snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); inputs = y_list_prepend(inputs, yid); - yahoo_http_get(yid->yd->client_id, url, buff, - _yahoo_http_connected, yid); + yahoo_http_post(yid->yd->client_id, url, buff, size, + _yahoo_http_post_connected, yad); } -void yahoo_set_identity_status(int id, const char * identity, int active) +void yahoo_set_identity_status(int id, const char *identity, int active) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(active?YAHOO_SERVICE_IDACT:YAHOO_SERVICE_IDDEACT, - YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(active ? YAHOO_SERVICE_IDACT : + YAHOO_SERVICE_IDDEACT, YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 3, identity); if (pkt) { yahoo_send_packet(yid, pkt, 0); @@ -4259,15 +3880,17 @@ void yahoo_set_identity_status(int id, const char * identity, int active) void yahoo_refresh(int id) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YPACKET_STATUS_DEFAULT, + yd->session_id); if (pkt) { yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); @@ -4276,54 +3899,59 @@ void yahoo_refresh(int id) void yahoo_keepalive(int id) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; - struct yahoo_packet *pkt=NULL; - if(!yid) + struct yahoo_packet *pkt = NULL; + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YPACKET_STATUS_DEFAULT, + yd->session_id); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } -void yahoo_chat_keepalive (int id) +void yahoo_chat_keepalive(int id) { - struct yahoo_input_data *yid = find_input_by_id_and_type (id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; if (!yid) - return; + return; yd = yid->yd; - pkt = yahoo_packet_new (YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_send_packet (yid, pkt, 0); - yahoo_packet_free (pkt); + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YPACKET_STATUS_DEFAULT, + yd->session_id); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); } -void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg) +void yahoo_add_buddy(int id, const char *who, const char *group, + const char *msg) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - if(!yid) + if (!yid) return; yd = yid->yd; if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); - - if (msg != NULL) /* add message/request "it's me add me" */ + pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, + yd->session_id); + if (msg != NULL) /* add message/request "it's me add me" */ yahoo_packet_hash(pkt, 14, msg); else - yahoo_packet_hash(pkt,14,""); - + yahoo_packet_hash(pkt, 14, ""); yahoo_packet_hash(pkt, 65, group); yahoo_packet_hash(pkt, 97, "1"); yahoo_packet_hash(pkt, 1, yd->user); @@ -4333,23 +3961,23 @@ void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg yahoo_packet_hash(pkt, 334, "0"); yahoo_packet_hash(pkt, 301, "319"); yahoo_packet_hash(pkt, 303, "319"); - - yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } void yahoo_remove_buddy(int id, const char *who, const char *group) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YPACKET_STATUS_DEFAULT, + yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); @@ -4358,151 +3986,129 @@ void yahoo_remove_buddy(int id, const char *who, const char *group) yahoo_packet_free(pkt); } -void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); - struct yahoo_data *yd; - - if(!yid) - return; - yd = yid->yd; - - struct yahoo_packet* pkt=NULL; - pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); - - yahoo_packet_hash(pkt,1,me ?: yd->user); - yahoo_packet_hash(pkt,5,who); - yahoo_packet_hash(pkt,13,"1"); - yahoo_packet_hash(pkt,334,"0"); - yahoo_send_packet(yid, pkt, 0); - yahoo_packet_free(pkt); -} - -void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); - struct yahoo_data *yd; - - if(!yid) - return; - yd = yid->yd; - - struct yahoo_packet* pkt=NULL; - pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); - - yahoo_packet_hash(pkt,1,me ?: yd->user); - yahoo_packet_hash(pkt,5,who); -// yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); - yahoo_packet_hash(pkt,13,"2"); - yahoo_packet_hash(pkt,334,"0"); - yahoo_packet_hash(pkt,97,"1"); - yahoo_packet_hash(pkt,14,msg?:""); - - yahoo_send_packet(yid, pkt, 0); - yahoo_packet_free(pkt); - -} - -void yahoo_reject_buddy(int id, const char *who, const char *msg) +void yahoo_confirm_buddy(int id, const char *who, int reject, const char *msg) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - if(!yid) + if (!yid) return; yd = yid->yd; if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_AUTHORIZATION, + YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); - yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 14, msg); + yahoo_packet_hash(pkt, 5, who); + if (reject) + yahoo_packet_hash(pkt, 13, "2"); + else { + yahoo_packet_hash(pkt, 241, "0"); + yahoo_packet_hash(pkt, 13, "1"); + } + + yahoo_packet_hash(pkt, 334, "0"); + + if (reject) { + yahoo_packet_hash(pkt, 14, msg ? msg : ""); + yahoo_packet_hash(pkt, 97, "1"); + } + yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } void yahoo_ignore_buddy(int id, const char *who, int unignore) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - if(!yid) + if (!yid) return; yd = yid->yd; if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, + YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 13, unignore?"2":"1"); + yahoo_packet_hash(pkt, 13, unignore ? "2" : "1"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } void yahoo_stealth_buddy(int id, const char *who, int unstealth) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - if(!yid) + if (!yid) return; yd = yid->yd; if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, + YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); + yahoo_packet_hash(pkt, 31, unstealth ? "2" : "1"); yahoo_packet_hash(pkt, 13, "2"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } -void yahoo_change_buddy_group(int id, const char *who, const char *old_group, const char *new_group) +void yahoo_change_buddy_group(int id, const char *who, const char *old_group, + const char *new_group) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_CHANGE_GROUP, + YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); + yahoo_packet_hash(pkt, 302, "240"); + yahoo_packet_hash(pkt, 300, "240"); yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 65, new_group); - yahoo_packet_hash(pkt, 14, " "); - - yahoo_send_packet(yid, pkt, 0); - yahoo_packet_free(pkt); + yahoo_packet_hash(pkt, 224, old_group); + yahoo_packet_hash(pkt, 264, new_group); + yahoo_packet_hash(pkt, 301, "240"); + yahoo_packet_hash(pkt, 303, "240"); - pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt, 1, yd->user); - yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 65, old_group); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } void yahoo_group_rename(int id, const char *old_group, const char *new_group) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - if(!yid) + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, + YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 65, old_group); yahoo_packet_hash(pkt, 67, new_group); @@ -4511,24 +4117,27 @@ void yahoo_group_rename(int id, const char *old_group, const char *new_group) yahoo_packet_free(pkt); } -void yahoo_conference_addinvite(int id, const char * from, const char *who, const char *room, const YList * members, const char *msg) +void yahoo_conference_addinvite(int id, const char *from, const char *who, + const char *room, const YList *members, const char *msg) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, + YPACKET_STATUS_DEFAULT, yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 51, who); yahoo_packet_hash(pkt, 57, room); yahoo_packet_hash(pkt, 58, msg); yahoo_packet_hash(pkt, 13, "0"); - for(; members; members = members->next) { + for (; members; members = members->next) { yahoo_packet_hash(pkt, 52, (char *)members->data); yahoo_packet_hash(pkt, 53, (char *)members->data); } @@ -4539,21 +4148,24 @@ void yahoo_conference_addinvite(int id, const char * from, const char *who, cons yahoo_packet_free(pkt); } -void yahoo_conference_invite(int id, const char * from, YList *who, const char *room, const char *msg) +void yahoo_conference_invite(int id, const char *from, YList *who, + const char *room, const char *msg) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 50, yd->user); - for(; who; who = who->next) { + for (; who; who = who->next) { yahoo_packet_hash(pkt, 52, (char *)who->data); } yahoo_packet_hash(pkt, 57, room); @@ -4565,45 +4177,51 @@ void yahoo_conference_invite(int id, const char * from, YList *who, const char * yahoo_packet_free(pkt); } -void yahoo_conference_logon(int id, const char *from, YList *who, const char *room) +void yahoo_conference_logon(int id, const char *from, YList *who, + const char *room) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); - for(; who; who = who->next) { - yahoo_packet_hash(pkt, 3, (char *)who->data); - } + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); yahoo_packet_hash(pkt, 57, room); + for (; who; who = who->next) + yahoo_packet_hash(pkt, 3, (char *)who->data); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } -void yahoo_conference_decline(int id, const char * from, YList *who, const char *room, const char *msg) +void yahoo_conference_decline(int id, const char *from, YList *who, + const char *room, const char *msg) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, + YPACKET_STATUS_DEFAULT, yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); - for(; who; who = who->next) { + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); + for (; who; who = who->next) yahoo_packet_hash(pkt, 3, (char *)who->data); - } yahoo_packet_hash(pkt, 57, room); yahoo_packet_hash(pkt, 14, msg); @@ -4612,22 +4230,26 @@ void yahoo_conference_decline(int id, const char * from, YList *who, const char yahoo_packet_free(pkt); } -void yahoo_conference_logoff(int id, const char * from, YList *who, const char *room) +void yahoo_conference_logoff(int id, const char *from, YList *who, + const char *room) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); - for(; who; who = who->next) { + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); + for (; who; who = who->next) yahoo_packet_hash(pkt, 3, (char *)who->data); - } + yahoo_packet_hash(pkt, 57, room); yahoo_send_packet(yid, pkt, 0); @@ -4635,26 +4257,30 @@ void yahoo_conference_logoff(int id, const char * from, YList *who, const char * yahoo_packet_free(pkt); } -void yahoo_conference_message(int id, const char * from, YList *who, const char *room, const char *msg, int utf8) +void yahoo_conference_message(int id, const char *from, YList *who, + const char *room, const char *msg, int utf8) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); - for(; who; who = who->next) { + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + yahoo_packet_hash(pkt, 53, (from ? from : yd->user)); + for (; who; who = who->next) yahoo_packet_hash(pkt, 53, (char *)who->data); - } + yahoo_packet_hash(pkt, 57, room); yahoo_packet_hash(pkt, 14, msg); - if(utf8) + if (utf8) yahoo_packet_hash(pkt, 97, "1"); yahoo_send_packet(yid, pkt, 0); @@ -4669,7 +4295,7 @@ void yahoo_get_chatrooms(int id, int chatroomid) char url[1024]; char buff[1024]; - if(!yd) + if (!yd) return; yid = y_new0(struct yahoo_input_data, 1); @@ -4677,32 +4303,39 @@ void yahoo_get_chatrooms(int id, int chatroomid) yid->type = YAHOO_CONNECTION_CHATCAT; if (chatroomid == 0) { - snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); + snprintf(url, 1024, + "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); } else { - snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",chatroomid); + snprintf(url, 1024, + "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0", + chatroomid); } snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); inputs = y_list_prepend(inputs, yid); - yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); + yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, + _yahoo_http_connected, yid); } -void yahoo_chat_logon(int id, const char *from, const char *room, const char *roomid) +void yahoo_chat_logon(int id, const char *from, const char *room, + const char *roomid) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 109, yd->user); yahoo_packet_hash(pkt, 6, "abcde"); @@ -4710,41 +4343,44 @@ void yahoo_chat_logon(int id, const char *from, const char *room, const char *ro yahoo_packet_free(pkt); - pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 104, room); yahoo_packet_hash(pkt, 129, roomid); - yahoo_packet_hash(pkt, 62, "2"); /* ??? */ + yahoo_packet_hash(pkt, 62, "2"); /* ??? */ yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } - -void yahoo_chat_message(int id, const char *from, const char *room, const char *msg, const int msgtype, const int utf8) +void yahoo_chat_message(int id, const char *from, const char *room, + const char *msg, const int msgtype, const int utf8) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; char buf[2]; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 104, room); yahoo_packet_hash(pkt, 117, msg); - + snprintf(buf, sizeof(buf), "%d", msgtype); yahoo_packet_hash(pkt, 124, buf); - if(utf8) + if (utf8) yahoo_packet_hash(pkt, 97, "1"); yahoo_send_packet(yid, pkt, 0); @@ -4752,21 +4388,22 @@ void yahoo_chat_message(int id, const char *from, const char *room, const char yahoo_packet_free(pkt); } - void yahoo_chat_logoff(int id, const char *from) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YPACKET_STATUS_DEFAULT, + yd->session_id); - yahoo_packet_hash(pkt, 1, (from?from:yd->user)); + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_send_packet(yid, pkt, 0); @@ -4775,16 +4412,18 @@ void yahoo_chat_logoff(int id, const char *from) void yahoo_buddyicon_request(int id, const char *who) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - if( !yid ) + if (!yid) return; yd = yid->yd; - - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); + + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, + 0); yahoo_packet_hash(pkt, 4, yd->user); yahoo_packet_hash(pkt, 5, who); yahoo_packet_hash(pkt, 13, "1"); @@ -4793,21 +4432,24 @@ void yahoo_buddyicon_request(int id, const char *who) yahoo_packet_free(pkt); } -void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum) +void yahoo_send_picture_info(int id, const char *who, const char *url, + int checksum) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; char checksum_str[10]; - if( !yid ) + if (!yid) return; yd = yid->yd; snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, + 0); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 4, yd->user); yahoo_packet_hash(pkt, 5, who); @@ -4821,19 +4463,21 @@ void yahoo_send_picture_info(int id, const char *who, const char *url, int check void yahoo_send_picture_update(int id, const char *who, int type) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; char type_str[10]; - if( !yid ) + if (!yid) return; yd = yid->yd; snprintf(type_str, sizeof(type_str), "%d", type); - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0); + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, + YPACKET_STATUS_DEFAULT, 0); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 5, who); yahoo_packet_hash(pkt, 206, type_str); @@ -4844,21 +4488,23 @@ void yahoo_send_picture_update(int id, const char *who, int type) void yahoo_send_picture_checksum(int id, const char *who, int checksum) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; char checksum_str[10]; - if( !yid ) + if (!yid) return; yd = yid->yd; - + snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0); + pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, + YPACKET_STATUS_DEFAULT, 0); yahoo_packet_hash(pkt, 1, yd->user); - if( who != 0 ) + if (who != 0) yahoo_packet_hash(pkt, 5, who); yahoo_packet_hash(pkt, 192, checksum_str); yahoo_packet_hash(pkt, 212, "1"); @@ -4869,19 +4515,21 @@ void yahoo_send_picture_checksum(int id, const char *who, int checksum) void yahoo_webcam_close_feed(int id, const char *who) { - struct yahoo_input_data *yid = find_input_by_id_and_webcam_user(id, who); + struct yahoo_input_data *yid = + find_input_by_id_and_webcam_user(id, who); - if(yid) + if (yid) yahoo_input_close(yid); } void yahoo_webcam_get_feed(int id, const char *who) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; /* @@ -4891,11 +4539,12 @@ void yahoo_webcam_get_feed(int id, const char *who) * order that we request them. * The queue is popped in yahoo_process_webcam_key */ - webcam_queue = y_list_append(webcam_queue, who?strdup(who):NULL); + webcam_queue = y_list_append(webcam_queue, who ? strdup(who) : NULL); yd = yid->yd; - pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YPACKET_STATUS_DEFAULT, + yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); if (who != NULL) @@ -4905,9 +4554,11 @@ void yahoo_webcam_get_feed(int id, const char *who) yahoo_packet_free(pkt); } -void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, unsigned int timestamp) +void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, + unsigned int timestamp) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); unsigned char *packet; unsigned char header_len = 13; unsigned int pos = 0; @@ -4919,10 +4570,10 @@ void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, packet[pos++] = header_len; packet[pos++] = 0; - packet[pos++] = 5; /* version byte?? */ + packet[pos++] = 5; /* version byte?? */ packet[pos++] = 0; pos += yahoo_put32(packet + pos, length); - packet[pos++] = 2; /* packet type, image */ + packet[pos++] = 2; /* packet type, image */ pos += yahoo_put32(packet + pos, timestamp); yahoo_add_to_send_queue(yid, packet, header_len); FREE(packet); @@ -4931,9 +4582,10 @@ void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, yahoo_add_to_send_queue(yid, image, length); } -void yahoo_webcam_accept_viewer(int id, const char* who, int accept) +void yahoo_webcam_accept_viewer(int id, const char *who, int accept) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); char *packet = NULL; char *data = NULL; unsigned char header_len = 13; @@ -4944,17 +4596,17 @@ void yahoo_webcam_accept_viewer(int id, const char* who, int accept) return; data = strdup("u="); - data = y_string_append(data, (char*)who); + data = y_string_append(data, (char *)who); data = y_string_append(data, "\r\n"); len = strlen(data); packet = y_new0(char, header_len + len); packet[pos++] = header_len; packet[pos++] = 0; - packet[pos++] = 5; /* version byte?? */ + packet[pos++] = 5; /* version byte?? */ packet[pos++] = 0; pos += yahoo_put32(packet + pos, len); - packet[pos++] = 0; /* packet type */ + packet[pos++] = 0; /* packet type */ pos += yahoo_put32(packet + pos, accept); memcpy(packet + pos, data, len); FREE(data); @@ -4964,13 +4616,15 @@ void yahoo_webcam_accept_viewer(int id, const char* who, int accept) void yahoo_webcam_invite(int id, const char *who) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_packet *pkt; - - if(!yid) + + if (!yid) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yid->yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, + yid->yd->session_id); yahoo_packet_hash(pkt, 49, "WEBCAMINVITE"); yahoo_packet_hash(pkt, 14, " "); @@ -4982,7 +4636,8 @@ void yahoo_webcam_invite(int id, const char *who) yahoo_packet_free(pkt); } -static void yahoo_search_internal(int id, int t, const char *text, int g, int ar, int photo, int yahoo_only, int startpos, int total) +static void yahoo_search_internal(int id, int t, const char *text, int g, + int ar, int photo, int yahoo_only, int startpos, int total) { struct yahoo_data *yd = find_conn_by_id(id); struct yahoo_input_data *yid; @@ -4990,7 +4645,7 @@ static void yahoo_search_internal(int id, int t, const char *text, int g, int ar char buff[1024]; char *ctext, *p; - if(!yd) + if (!yd) return; yid = y_new0(struct yahoo_input_data, 1); @@ -4998,38 +4653,43 @@ static void yahoo_search_internal(int id, int t, const char *text, int g, int ar yid->type = YAHOO_CONNECTION_SEARCH; /* - age range - .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ - */ + age range + .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ + */ - snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, startpos); + snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, + startpos); ctext = strdup(text); - while((p = strchr(ctext, ' '))) + while ((p = strchr(ctext, ' '))) *p = '+'; - snprintf(url, 1024, "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", - ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", - startpos ? buff : ""); + snprintf(url, 1024, + "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", + ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", + startpos ? buff : ""); FREE(ctext); snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); inputs = y_list_prepend(inputs, yid); - yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); + yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, + _yahoo_http_connected, yid); } -void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo_search_gender g, enum yahoo_search_agerange ar, - int photo, int yahoo_only) +void yahoo_search(int id, enum yahoo_search_type t, const char *text, + enum yahoo_search_gender g, enum yahoo_search_agerange ar, int photo, + int yahoo_only) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_search_state *yss; - if(!yid) + if (!yid) return; - if(!yid->ys) + if (!yid->ys) yid->ys = y_new0(struct yahoo_search_state, 1); yss = yid->ys; @@ -5047,273 +4707,708 @@ void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo void yahoo_search_again(int id, int start) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_search_state *yss; - if(!yid || !yid->ys) + if (!yid || !yid->ys) return; yss = yid->ys; - if(start == -1) + if (start == -1) start = yss->lsearch_nstart + yss->lsearch_nfound; - yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text, - yss->lsearch_gender, yss->lsearch_agerange, - yss->lsearch_photo, yss->lsearch_yahoo_only, - start, yss->lsearch_ntotal); + yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text, + yss->lsearch_gender, yss->lsearch_agerange, + yss->lsearch_photo, yss->lsearch_yahoo_only, + start, yss->lsearch_ntotal); +} + +void yahoo_send_picture(int id, const char *name, unsigned long size, + yahoo_get_fd_callback callback, void *data) +{ + /* Not Implemented */ } +/* File Transfer */ +static YList *active_file_transfers = NULL; + +enum { + FT_STATE_HEAD = 1, + FT_STATE_RECV, + FT_STATE_RECV_START, + FT_STATE_SEND +}; + struct send_file_data { - struct yahoo_packet *pkt; + int client_id; + char *id; + char *who; + char *filename; + char *ip_addr; + char *token; + int size; + + struct yahoo_input_data *yid; + int state; + yahoo_get_fd_callback callback; - void *user_data; + void *data; }; -static void _yahoo_send_picture_connected(int id, int fd, int error, void *data) +static char *yahoo_get_random(void) +{ + int i = 0; + int r = 0; + int c = 0; + char out[25]; + + out[24] = '\0'; + out[23] = '$'; + out[22] = '$'; + + for (i = 0; i < 22; i++) { + if(r == 0) + r = rand(); + + c = r%61; + + if(c<26) + out[i] = c + 'a'; + else if (c<52) + out[i] = c - 26 + 'A'; + else + out[i] = c - 52 + '0'; + + r /= 61; + } + + return strdup(out); +} + +static int _are_same_id(const void *sfd1, const void *id) +{ + return strcmp(((struct send_file_data *)sfd1)->id, (char *)id); +} + +static int _are_same_yid(const void *sfd1, const void *yid) +{ + if(((struct send_file_data *)sfd1)->yid == yid) + return 0; + else + return 1; +} + +static struct send_file_data *yahoo_get_active_transfer(char *id) +{ + YList *l = y_list_find_custom(active_file_transfers, id, + _are_same_id); + + if(l) + return (struct send_file_data *)l->data; + + return NULL; +} + +static struct send_file_data *yahoo_get_active_transfer_with_yid(void *yid) +{ + YList *l = y_list_find_custom(active_file_transfers, yid, + _are_same_yid); + + if(l) + return (struct send_file_data *)l->data; + + return NULL; +} + +static void yahoo_add_active_transfer(struct send_file_data *sfd) +{ + active_file_transfers = y_list_prepend(active_file_transfers, sfd); +} + +static void yahoo_remove_active_transfer(struct send_file_data *sfd) +{ + active_file_transfers = y_list_remove(active_file_transfers, sfd); + free(sfd->id); + free(sfd->who); + free(sfd->filename); + free(sfd->ip_addr); + FREE(sfd); +} + +static void _yahoo_ft_upload_connected(int id, void *fd, int error, void *data) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); struct send_file_data *sfd = data; - struct yahoo_packet *pkt = sfd->pkt; - unsigned char buff[1024]; + struct yahoo_input_data *yid = sfd->yid; - if(fd <= 0) { - sfd->callback(id, fd, error, sfd->user_data); - FREE(sfd); - yahoo_packet_free(pkt); + if (!fd) { inputs = y_list_remove(inputs, yid); FREE(yid); return; } + sfd->callback(id, fd, error, sfd->data); + yid->fd = fd; - yahoo_send_packet(yid, pkt, 8); - yahoo_packet_free(pkt); + yid->read_tag = + YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, + YAHOO_INPUT_READ, yid); +} - snprintf((char *)buff, sizeof(buff), "29"); - buff[2] = 0xc0; - buff[3] = 0x80; - - write(yid->fd, buff, 4); +static void yahoo_file_transfer_upload(struct yahoo_data *yd, + struct send_file_data *sfd) +{ + char url[256]; + char buff[4096]; + char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; - /* YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */ + struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); - sfd->callback(id, fd, error, sfd->user_data); - FREE(sfd); - inputs = y_list_remove(inputs, yid); - /* - while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { - if(!strcmp(buff, "")) - break; + yid->yd = yd; + yid->type = YAHOO_CONNECTION_FT; + + inputs = y_list_prepend(inputs, yid); + sfd->yid = yid; + sfd->state = FT_STATE_SEND; + + token_enc = yahoo_urlencode(sfd->token); + sender_enc = yahoo_urlencode(yd->user); + recv_enc = yahoo_urlencode(sfd->who); + + snprintf(url, sizeof(url), + "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, + token_enc, sender_enc, recv_enc); + + snprintf(buff, sizeof(buff), "T=%s; Y=%s", yd->cookie_t, yd->cookie_y); + + yahoo_http_post(yd->client_id, url, buff, sfd->size, + _yahoo_ft_upload_connected, sfd); + + FREE(token_enc); + FREE(sender_enc); + FREE(recv_enc); } - */ - yahoo_input_close(yid); +static void yahoo_init_ft_recv(struct yahoo_data *yd, + struct send_file_data *sfd) +{ + char url[256]; + char buff[1024]; + char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; + + struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); + + yid->yd = yd; + yid->type = YAHOO_CONNECTION_FT; + + inputs = y_list_prepend(inputs, yid); + sfd->yid = yid; + sfd->state = FT_STATE_HEAD; + + token_enc = yahoo_urlencode(sfd->token); + sender_enc = yahoo_urlencode(sfd->who); + recv_enc = yahoo_urlencode(yd->user); + + snprintf(url, sizeof(url), + "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, + token_enc, sender_enc, recv_enc); + + snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); + + yahoo_http_head(yid->yd->client_id, url, buff, 0, NULL, + _yahoo_http_connected, yid); + + FREE(token_enc); + FREE(sender_enc); + FREE(recv_enc); } -void yahoo_send_picture(int id, const char *name, unsigned long size, - yahoo_get_fd_callback callback, void *data) +static void yahoo_file_transfer_accept(struct yahoo_input_data *yid, + struct send_file_data *sfd) { - struct yahoo_data *yd = find_conn_by_id(id); - struct yahoo_input_data *yid; - struct yahoo_server_settings *yss; - struct yahoo_packet *pkt = NULL; - char size_str[10]; - char expire_str[10]; - long content_length=0; - unsigned char buff[1024]; - char url[255]; + struct yahoo_packet *pkt; + + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, + YPACKET_STATUS_DEFAULT, yid->yd->session_id); + + yahoo_packet_hash(pkt, 1, yid->yd->user); + yahoo_packet_hash(pkt, 5, sfd->who); + yahoo_packet_hash(pkt, 265, sfd->id); + yahoo_packet_hash(pkt, 27, sfd->filename); + yahoo_packet_hash(pkt, 249, "3"); + yahoo_packet_hash(pkt, 251, sfd->token); + + yahoo_send_packet(yid, pkt, 0); + + yahoo_packet_free(pkt); + + yahoo_init_ft_recv(yid->yd, sfd); +} + +static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) +{ + YList *l; struct send_file_data *sfd; + char *who = NULL; + char *filename = NULL; + char *id = NULL; + char *token = NULL; - if(!yd) - return; + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + switch (pair->key) { + case 4: + who = pair->value; + break; + case 5: + /* Me... don't care */ + break; + case 249: + break; + case 265: + id = pair->value; + break; + case 251: + token = pair->value; + break; + case 27: + filename = pair->value; + break; + } + } - yss = yd->server_settings; + sfd = yahoo_get_active_transfer(id); - yid = y_new0(struct yahoo_input_data, 1); - yid->yd = yd; - yid->type = YAHOO_CONNECTION_FT; + if (sfd) { + sfd->token = strdup(token); - pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id); + yahoo_file_transfer_upload(yid->yd, sfd); + } + else { + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, + sfd->data); - snprintf(size_str, sizeof(size_str), "%ld", size); - snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800); + yahoo_remove_active_transfer(sfd); + } +} - yahoo_packet_hash(pkt, 0, yd->user); - yahoo_packet_hash(pkt, 1, yd->user); - yahoo_packet_hash(pkt, 14, ""); - yahoo_packet_hash(pkt, 27, name); - yahoo_packet_hash(pkt, 28, size_str); - yahoo_packet_hash(pkt, 38, expire_str); - +static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) +{ + YList *l; + char *who = NULL; + char *filename = NULL; + char *id = NULL; + char *token = NULL; + char *ip_addr = NULL; - content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); + struct send_file_data *sfd; - snprintf(url, sizeof(url), "http://%s:%d/notifyft", - yss->filetransfer_host, yss->filetransfer_port); - snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", - yd->cookie_y, yd->cookie_t); - inputs = y_list_prepend(inputs, yid); + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + switch (pair->key) { + case 1: + case 4: + who = pair->value; + break; + case 5: + /* Me... don't care */ + break; + case 249: + break; + case 265: + id = pair->value; + break; + case 250: + ip_addr = pair->value; + break; + case 251: + token = pair->value; + break; + case 27: + filename = pair->value; + break; + } + } - sfd = y_new0(struct send_file_data, 1); - sfd->pkt = pkt; - sfd->callback = callback; - sfd->user_data = data; - yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, - _yahoo_send_picture_connected, sfd); + sfd = yahoo_get_active_transfer(id); + + if (sfd) { + sfd->token = strdup(token); + sfd->ip_addr = strdup(ip_addr); + + yahoo_file_transfer_accept(yid, sfd); + } + else { + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, + sfd->data); + + yahoo_remove_active_transfer(sfd); + } } -static void _yahoo_send_file_connected(int id, int fd, int error, void *data) +static void yahoo_send_filetransferinfo(struct yahoo_data *yd, + struct send_file_data *sfd) { - struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); - struct send_file_data *sfd = data; - struct yahoo_packet *pkt = sfd->pkt; - unsigned char buff[1024]; + struct yahoo_input_data *yid; + struct yahoo_packet *pkt; + + yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); + sfd->ip_addr = YAHOO_CALLBACK(ext_yahoo_get_ip_addr)("relay.yahoo.com"); + + if (!sfd->ip_addr) { + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yd->client_id, YAHOO_FILE_TRANSFER_RELAY, sfd->data); + + yahoo_remove_active_transfer(sfd); - if(fd <= 0) { - sfd->callback(id, fd, error, sfd->user_data); - FREE(sfd); - yahoo_packet_free(pkt); - inputs = y_list_remove(inputs, yid); - FREE(yid); return; } - yid->fd = fd; - yahoo_send_packet(yid, pkt, 8); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERINFO, + YPACKET_STATUS_DEFAULT, yd->session_id); + + yahoo_packet_hash(pkt, 1, yd->user); + yahoo_packet_hash(pkt, 5, sfd->who); + yahoo_packet_hash(pkt, 265, sfd->id); + yahoo_packet_hash(pkt, 27, sfd->filename); + yahoo_packet_hash(pkt, 249, "3"); + yahoo_packet_hash(pkt, 250, sfd->ip_addr); + + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); +} - snprintf((char *)buff, sizeof(buff), "29"); - buff[2] = 0xc0; - buff[3] = 0x80; - - write(yid->fd, buff, 4); +static void yahoo_process_filetransfer(struct yahoo_input_data *yid, + struct yahoo_packet *pkt) +{ + YList *l; + char *who = NULL; + char *filename = NULL; + char *msg = NULL; + char *id = NULL; + int action = 0; + int size = 0; + struct yahoo_data *yd = yid->yd; -/* YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */ + struct send_file_data *sfd; - sfd->callback(id, fd, error, sfd->user_data); - FREE(sfd); - inputs = y_list_remove(inputs, yid); - /* - while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { - if(!strcmp(buff, "")) + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + switch (pair->key) { + case 4: + who = pair->value; + break; + case 5: + /* Me... don't care */ + break; + case 222: + action = atoi(pair->value); + break; + case 265: + id = pair->value; + break; + case 266: /* Don't know */ + break; + case 302: /* Start Data? */ + break; + case 300: + break; + case 27: + filename = pair->value; break; + case 28: + size = atoi(pair->value); + break; + case 14: + msg = pair->value; + case 301: /* End Data? */ + break; + case 303: + break; + + } + } + + if (action == YAHOO_FILE_TRANSFER_INIT) { + /* Received a FT request from buddy */ + sfd = y_new0(struct send_file_data, 1); + + sfd->client_id = yd->client_id; + sfd->id = strdup(id); + sfd->who = strdup(who); + sfd->filename = strdup(filename); + sfd->size = size; + + yahoo_add_active_transfer(sfd); + + YAHOO_CALLBACK(ext_yahoo_got_file) (yd->client_id, yd->user, + who, msg, filename, size, sfd->id); } + else { + /* Response to our request */ + sfd = yahoo_get_active_transfer(id); - */ - yahoo_input_close(yid); + if (sfd && action == YAHOO_FILE_TRANSFER_ACCEPT) { + yahoo_send_filetransferinfo(yd, sfd); + } + else if (!sfd || action == YAHOO_FILE_TRANSFER_REJECT) { + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yd->client_id, YAHOO_FILE_TRANSFER_REJECT, + sfd->data); + + yahoo_remove_active_transfer(sfd); + } + } } -void yahoo_send_file(int id, const char *who, const char *msg, - const char *name, unsigned long size, - yahoo_get_fd_callback callback, void *data) +void yahoo_send_file(int id, const char *who, const char *msg, + const char *name, unsigned long size, + yahoo_get_fd_callback callback, void *data) { - struct yahoo_data *yd = find_conn_by_id(id); - struct yahoo_input_data *yid; - struct yahoo_server_settings *yss; struct yahoo_packet *pkt = NULL; char size_str[10]; - long content_length=0; - unsigned char buff[1024]; - char url[255]; + struct yahoo_input_data *yid; + struct yahoo_data *yd; struct send_file_data *sfd; + + yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + yd = find_conn_by_id(id); + sfd = y_new0(struct send_file_data, 1); - if(!yd) - return; + sfd->client_id = id; + sfd->id = yahoo_get_random(); + sfd->who = strdup(who); + sfd->filename = strdup(name); + sfd->size = size; + sfd->callback = callback; + sfd->data = data; - yss = yd->server_settings; + yahoo_add_active_transfer(sfd); - yid = y_new0(struct yahoo_input_data, 1); - yid->yd = yd; - yid->type = YAHOO_CONNECTION_FT; + if (!yd) + return; - pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, + YPACKET_STATUS_DEFAULT, yd->session_id); snprintf(size_str, sizeof(size_str), "%ld", size); - yahoo_packet_hash(pkt, 0, yd->user); + yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 5, who); - yahoo_packet_hash(pkt, 14, msg); + yahoo_packet_hash(pkt, 265, sfd->id); + yahoo_packet_hash(pkt, 222, "1"); + yahoo_packet_hash(pkt, 266, "1"); + yahoo_packet_hash(pkt, 302, "268"); + yahoo_packet_hash(pkt, 300, "268"); yahoo_packet_hash(pkt, 27, name); yahoo_packet_hash(pkt, 28, size_str); + yahoo_packet_hash(pkt, 301, "268"); + yahoo_packet_hash(pkt, 303, "268"); - content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); + yahoo_send_packet(yid, pkt, 0); - snprintf(url, sizeof(url), "http://%s:%d/notifyft", - yss->filetransfer_host, yss->filetransfer_port); - snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", - yd->cookie_y, yd->cookie_t); - inputs = y_list_prepend(inputs, yid); + yahoo_packet_free(pkt); +} - sfd = y_new0(struct send_file_data, 1); - sfd->pkt = pkt; - sfd->callback = callback; - sfd->user_data = data; - yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, - _yahoo_send_file_connected, sfd); +void yahoo_send_file_transfer_response(int client_id, int response, char *id, void *data) +{ + struct yahoo_packet *pkt = NULL; + char resp[2]; + struct yahoo_input_data *yid; + + struct send_file_data *sfd = yahoo_get_active_transfer(id); + + sfd->data = data; + + yid = find_input_by_id_and_type(client_id, YAHOO_CONNECTION_PAGER); + + pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, + YPACKET_STATUS_DEFAULT, yid->yd->session_id); + + snprintf(resp, sizeof(resp), "%d", response); + + yahoo_packet_hash(pkt, 1, yid->yd->user); + yahoo_packet_hash(pkt, 5, sfd->who); + yahoo_packet_hash(pkt, 265, sfd->id); + yahoo_packet_hash(pkt, 222, resp); + + yahoo_send_packet(yid, pkt, 0); + + yahoo_packet_free(pkt); + + if(response == YAHOO_FILE_TRANSFER_REJECT) + yahoo_remove_active_transfer(sfd); +} + +static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) +{ + struct send_file_data *sfd; + struct yahoo_data *yd = yid->yd; + + sfd = yahoo_get_active_transfer_with_yid(yid); + + if (!sfd) { + LOG(("Something funny happened. yid %p has no sfd.\n", yid)); + return; + } + + /* + * We want to handle only the complete data with HEAD since we don't + * want a situation where both the GET and HEAD are active. + * With SEND, we really can't do much with partial response + */ + if ((sfd->state == FT_STATE_HEAD || sfd->state == FT_STATE_SEND) + && !over) + return; + + if (sfd->state == FT_STATE_HEAD) { + /* Do a GET */ + char url[256]; + char buff[1024]; + char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; + + struct yahoo_input_data *yid_ft = + y_new0(struct yahoo_input_data, 1); + + yid_ft->yd = yid->yd; + yid_ft->type = YAHOO_CONNECTION_FT; + + inputs = y_list_prepend(inputs, yid_ft); + sfd->yid = yid_ft; + sfd->state = FT_STATE_RECV; + + token_enc = yahoo_urlencode(sfd->token); + sender_enc = yahoo_urlencode(sfd->who); + recv_enc = yahoo_urlencode(yd->user); + + snprintf(url, sizeof(url), + "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, + token_enc, sender_enc, recv_enc); + + snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, + yd->cookie_t); + + + yahoo_http_get(yd->client_id, url, buff, 1, 1, + _yahoo_http_connected, yid_ft); + + FREE(token_enc); + FREE(sender_enc); + FREE(recv_enc); + } + else if (sfd->state == FT_STATE_RECV || + sfd->state == FT_STATE_RECV_START) { + + unsigned char *data_begin = NULL; + + if (yid->rxlen == 0) + yahoo_remove_active_transfer(sfd); + + if (sfd->state != FT_STATE_RECV_START && + (data_begin = + (unsigned char *)strstr((char *)yid->rxqueue, + "\r\n\r\n"))) { + + sfd->state = FT_STATE_RECV_START; + + yid->rxlen -= 4+(data_begin-yid->rxqueue)/sizeof(char); + data_begin += 4; + + if (yid->rxlen > 0) + YAHOO_CALLBACK(ext_yahoo_got_ft_data) + (yd->client_id, data_begin, + yid->rxlen, sfd->data); + } + else if (sfd->state == FT_STATE_RECV_START) + YAHOO_CALLBACK(ext_yahoo_got_ft_data) (yd->client_id, + yid->rxqueue, yid->rxlen, sfd->data); + + FREE(yid->rxqueue); + yid->rxqueue = NULL; + yid->rxlen = 0; + } + else if (sfd->state == FT_STATE_SEND) { + /* Sent file completed */ + int len = 0; + char *off = strstr((char *)yid->rxqueue, "Content-Length: "); + + if (off) { + off += 16; + len = atoi(off); + } + + if (len < sfd->size) + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yd->client_id, + YAHOO_FILE_TRANSFER_FAILED, sfd->data); + else + YAHOO_CALLBACK(ext_yahoo_file_transfer_done) + (yd->client_id, + YAHOO_FILE_TRANSFER_DONE, sfd->data); + + yahoo_remove_active_transfer(sfd); + } } +/* End File Transfer */ enum yahoo_status yahoo_current_status(int id) { struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) + if (!yd) return YAHOO_STATUS_OFFLINE; return yd->current_status; } -const YList * yahoo_get_buddylist(int id) +const YList *yahoo_get_buddylist(int id) { struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) + if (!yd) return NULL; return yd->buddies; } -const YList * yahoo_get_ignorelist(int id) +const YList *yahoo_get_ignorelist(int id) { struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) + if (!yd) return NULL; return yd->ignore; } -const YList * yahoo_get_identities(int id) +const YList *yahoo_get_identities(int id) { struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) + if (!yd) return NULL; return yd->identities; } -const char * yahoo_get_cookie(int id, const char *which) +const char *yahoo_get_cookie(int id, const char *which) { struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) + if (!yd) return NULL; - if(!strncasecmp(which, "y", 1)) + if (!strncasecmp(which, "y", 1)) return yd->cookie_y; - if(!strncasecmp(which, "t", 1)) + if (!strncasecmp(which, "b", 1)) + return yd->cookie_b; + if (!strncasecmp(which, "t", 1)) return yd->cookie_t; - if(!strncasecmp(which, "c", 1)) + if (!strncasecmp(which, "c", 1)) return yd->cookie_c; - if(!strncasecmp(which, "login", 5)) + if (!strncasecmp(which, "login", 5)) return yd->login_cookie; return NULL; } -void yahoo_get_url_handle(int id, const char *url, - yahoo_get_url_handle_callback callback, void *data) -{ - struct yahoo_data *yd = find_conn_by_id(id); - if(!yd) - return; - - yahoo_get_url_fd(id, url, yd, callback, data); -} - -const char * yahoo_get_profile_url( void ) +const char *yahoo_get_profile_url(void) { return profile_url; } - |