diff options
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; } - |