Changes in protocols/yahoo/libyahoo2.c [9034ba0:9fca0657]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/yahoo/libyahoo2.c
r9034ba0 r9fca0657 3 3 * 4 4 * Some code copyright (C) 2002-2004, Philip S Tellis <philip.tellis AT gmx.net> 5 * YMSG16 code copyright (C) 2009,6 * Siddhesh Poyarekar <siddhesh dot poyarekar at gmail dot com>7 5 * 8 6 * Yahoo Search copyright (C) 2003, Konstantin Klyagin <konst AT konst.org.ua> … … 29 27 * <hiro-y@kcn.ne.jp> 30 28 * 31 * YMSG16 authentication code based mostly on write-up at:32 * http://www.carbonize.co.uk/ymsg16.html33 29 * 34 30 * This program is free software; you can redistribute it and/or modify … … 96 92 97 93 #ifdef USE_STRUCT_CALLBACKS 98 struct yahoo_callbacks *yc =NULL;99 100 void yahoo_register_callbacks(struct yahoo_callbacks * tyc)94 struct yahoo_callbacks *yc=NULL; 95 96 void yahoo_register_callbacks(struct yahoo_callbacks * tyc) 101 97 { 102 98 yc = tyc; … … 108 104 #endif 109 105 110 static int yahoo_send_data(void *fd, void *data, int len); 111 static void _yahoo_http_connected(int id, void *fd, int error, void *data); 112 static void yahoo_connected(void *fd, int error, void *data); 113 114 int yahoo_log_message(char *fmt, ...) 106 static int yahoo_send_data(int fd, void *data, int len); 107 108 int yahoo_log_message(char * fmt, ...) 115 109 { 116 110 char out[1024]; … … 119 113 vsnprintf(out, sizeof(out), fmt, ap); 120 114 va_end(ap); 121 return YAHOO_CALLBACK(ext_yahoo_log) 122 } 123 124 int yahoo_connect(char * host, int port)125 { 126 return YAHOO_CALLBACK(ext_yahoo_connect) 115 return YAHOO_CALLBACK(ext_yahoo_log)("%s", out); 116 } 117 118 int yahoo_connect(char * host, int port) 119 { 120 return YAHOO_CALLBACK(ext_yahoo_connect)(host, port); 127 121 } 128 122 … … 142 136 143 137 /* default values for servers */ 144 static char *default_pager_hosts[] = { "scs.msg.yahoo.com", 145 "scsa.msg.yahoo.com", 146 "scsb.msg.yahoo.com", 147 "scsc.msg.yahoo.com", 148 NULL}; 149 138 static char pager_host[] = "scs.msg.yahoo.com"; 150 139 static int pager_port = 5050; 151 static int fallback_ports[] = { 23, 25, 80, 20, 119, 8001, 8002, 5050, 0 }; 152 153 static char filetransfer_host[] = "filetransfer.msg.yahoo.com"; 154 static int filetransfer_port = 80; 155 static char webcam_host[] = "webcam.yahoo.com"; 156 static int webcam_port = 5100; 157 static char webcam_description[] = ""; 158 static char local_host[] = ""; 159 static int conn_type = Y_WCM_DSL; 140 static int fallback_ports[]={23, 25, 80, 20, 119, 8001, 8002, 5050, 0}; 141 static char filetransfer_host[]="filetransfer.msg.yahoo.com"; 142 static int filetransfer_port=80; 143 static char webcam_host[]="webcam.yahoo.com"; 144 static int webcam_port=5100; 145 static char webcam_description[]=""; 146 static char local_host[]=""; 147 static int conn_type=Y_WCM_DSL; 160 148 161 149 static char profile_url[] = "http://profiles.yahoo.com/"; 162 150 163 struct connect_callback_data { 164 struct yahoo_data *yd; 165 int tag; 166 int i; 167 int server_i; 151 enum yahoo_service { /* these are easier to see in hex */ 152 YAHOO_SERVICE_LOGON = 1, 153 YAHOO_SERVICE_LOGOFF, 154 YAHOO_SERVICE_ISAWAY, 155 YAHOO_SERVICE_ISBACK, 156 YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ 157 YAHOO_SERVICE_MESSAGE, 158 YAHOO_SERVICE_IDACT, 159 YAHOO_SERVICE_IDDEACT, 160 YAHOO_SERVICE_MAILSTAT, 161 YAHOO_SERVICE_USERSTAT, /* 0xa */ 162 YAHOO_SERVICE_NEWMAIL, 163 YAHOO_SERVICE_CHATINVITE, 164 YAHOO_SERVICE_CALENDAR, 165 YAHOO_SERVICE_NEWPERSONALMAIL, 166 YAHOO_SERVICE_NEWCONTACT, 167 YAHOO_SERVICE_ADDIDENT, /* 0x10 */ 168 YAHOO_SERVICE_ADDIGNORE, 169 YAHOO_SERVICE_PING, 170 YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ 171 YAHOO_SERVICE_SYSMESSAGE = 0x14, 172 YAHOO_SERVICE_SKINNAME = 0x15, 173 YAHOO_SERVICE_PASSTHROUGH2 = 0x16, 174 YAHOO_SERVICE_CONFINVITE = 0x18, 175 YAHOO_SERVICE_CONFLOGON, 176 YAHOO_SERVICE_CONFDECLINE, 177 YAHOO_SERVICE_CONFLOGOFF, 178 YAHOO_SERVICE_CONFADDINVITE, 179 YAHOO_SERVICE_CONFMSG, 180 YAHOO_SERVICE_CHATLOGON, 181 YAHOO_SERVICE_CHATLOGOFF, 182 YAHOO_SERVICE_CHATMSG = 0x20, 183 YAHOO_SERVICE_GAMELOGON = 0x28, 184 YAHOO_SERVICE_GAMELOGOFF, 185 YAHOO_SERVICE_GAMEMSG = 0x2a, 186 YAHOO_SERVICE_FILETRANSFER = 0x46, 187 YAHOO_SERVICE_VOICECHAT = 0x4A, 188 YAHOO_SERVICE_NOTIFY, 189 YAHOO_SERVICE_VERIFY, 190 YAHOO_SERVICE_P2PFILEXFER, 191 YAHOO_SERVICE_PEERTOPEER = 0x4F, /* Checks if P2P possible */ 192 YAHOO_SERVICE_WEBCAM, 193 YAHOO_SERVICE_AUTHRESP = 0x54, 194 YAHOO_SERVICE_LIST, 195 YAHOO_SERVICE_AUTH = 0x57, 196 YAHOO_SERVICE_AUTHBUDDY = 0x6d, 197 YAHOO_SERVICE_ADDBUDDY = 0x83, 198 YAHOO_SERVICE_REMBUDDY, 199 YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/ 200 YAHOO_SERVICE_REJECTCONTACT, 201 YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ 202 YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ 203 YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ 204 YAHOO_SERVICE_CHATGOTO, 205 YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */ 206 YAHOO_SERVICE_CHATLEAVE, 207 YAHOO_SERVICE_CHATEXIT = 0x9b, 208 YAHOO_SERVICE_CHATADDINVITE = 0x9d, 209 YAHOO_SERVICE_CHATLOGOUT = 0xa0, 210 YAHOO_SERVICE_CHATPING, 211 YAHOO_SERVICE_COMMENT = 0xa8, 212 YAHOO_SERVICE_STEALTH = 0xb9, 213 YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, 214 YAHOO_SERVICE_PICTURE = 0xbe, 215 YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, 216 YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, 217 YAHOO_SERVICE_Y6_VISIBILITY=0xc5, 218 YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6, 219 YAHOO_PHOTOSHARE_INIT=0xd2, 220 YAHOO_SERVICE_CONTACT_YMSG13=0xd6, 221 YAHOO_PHOTOSHARE_PREV=0xd7, 222 YAHOO_PHOTOSHARE_KEY=0xd8, 223 YAHOO_PHOTOSHARE_TRANS=0xda, 224 YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc, 225 YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd, 226 YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde, 227 YAHOO_SERVICE_YMSG15_STATUS=0xf0, 228 YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1, 168 229 }; 169 230 … … 181 242 182 243 struct yahoo_search_state { 183 int lsearch_type;184 char *lsearch_text;185 int lsearch_gender;186 int lsearch_agerange;187 int lsearch_photo;188 int lsearch_yahoo_only;189 int lsearch_nstart;190 int lsearch_nfound;191 int lsearch_ntotal;244 int lsearch_type; 245 char *lsearch_text; 246 int lsearch_gender; 247 int lsearch_agerange; 248 int lsearch_photo; 249 int lsearch_yahoo_only; 250 int lsearch_nstart; 251 int lsearch_nfound; 252 int lsearch_ntotal; 192 253 }; 193 254 … … 203 264 struct yahoo_search_state *ys; 204 265 205 void *fd;266 int fd; 206 267 enum yahoo_connection_type type; 207 208 unsigned char 209 int rxlen;210 int read_tag;268 269 unsigned char *rxqueue; 270 int rxlen; 271 int read_tag; 211 272 212 273 YList *txqueues; 213 int write_tag;274 int write_tag; 214 275 }; 215 276 216 277 struct yahoo_server_settings { 217 278 char *pager_host; 218 int pager_port;279 int pager_port; 219 280 char *filetransfer_host; 220 int filetransfer_port;281 int filetransfer_port; 221 282 char *webcam_host; 222 int webcam_port;283 int webcam_port; 223 284 char *webcam_description; 224 285 char *local_host; 225 int conn_type; 226 char **pager_host_list; 286 int conn_type; 227 287 }; 228 288 229 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over); 230 231 static void yahoo_process_filetransfer(struct yahoo_input_data *yid, 232 struct yahoo_packet *pkt); 233 static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, 234 struct yahoo_packet *pkt); 235 static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, 236 struct yahoo_packet *pkt); 237 238 static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn); 239 240 static void *_yahoo_default_server_settings() 241 { 242 struct yahoo_server_settings *yss = 243 y_new0(struct yahoo_server_settings, 1); 244 245 /* Give preference to the default host list 246 * Make sure that only one of the two is set at any time 247 */ 248 yss->pager_host = NULL; 249 yss->pager_host_list = default_pager_hosts; 250 289 static void * _yahoo_default_server_settings() 290 { 291 struct yahoo_server_settings *yss = y_new0(struct yahoo_server_settings, 1); 292 293 yss->pager_host = strdup(pager_host); 251 294 yss->pager_port = pager_port; 252 295 yss->filetransfer_host = strdup(filetransfer_host); … … 261 304 } 262 305 263 static void * _yahoo_assign_server_settings(va_list ap)306 static void * _yahoo_assign_server_settings(va_list ap) 264 307 { 265 308 struct yahoo_server_settings *yss = _yahoo_default_server_settings(); 266 309 char *key; 267 310 char *svalue; 268 int nvalue; 269 char **pvalue; 270 271 while (1) { 311 int nvalue; 312 313 while(1) { 272 314 key = va_arg(ap, char *); 273 if 274 break; 275 276 if 315 if(key == NULL) 316 break; 317 318 if(!strcmp(key, "pager_host")) { 277 319 svalue = va_arg(ap, char *); 278 320 free(yss->pager_host); 279 321 yss->pager_host = strdup(svalue); 280 yss->pager_host_list = NULL; 281 } else if (!strcmp(key, "pager_host_list")) { 282 pvalue = va_arg(ap, char **); 283 yss->pager_host_list = pvalue; 284 free(yss->pager_host); 285 yss->pager_host = NULL; 286 } else if (!strcmp(key, "pager_port")) { 322 } else if(!strcmp(key, "pager_port")) { 287 323 nvalue = va_arg(ap, int); 288 324 yss->pager_port = nvalue; 289 } else if 325 } else if(!strcmp(key, "filetransfer_host")) { 290 326 svalue = va_arg(ap, char *); 291 327 free(yss->filetransfer_host); 292 328 yss->filetransfer_host = strdup(svalue); 293 } else if 329 } else if(!strcmp(key, "filetransfer_port")) { 294 330 nvalue = va_arg(ap, int); 295 331 yss->filetransfer_port = nvalue; 296 } else if 332 } else if(!strcmp(key, "webcam_host")) { 297 333 svalue = va_arg(ap, char *); 298 334 free(yss->webcam_host); 299 335 yss->webcam_host = strdup(svalue); 300 } else if 336 } else if(!strcmp(key, "webcam_port")) { 301 337 nvalue = va_arg(ap, int); 302 338 yss->webcam_port = nvalue; 303 } else if 339 } else if(!strcmp(key, "webcam_description")) { 304 340 svalue = va_arg(ap, char *); 305 341 free(yss->webcam_description); 306 342 yss->webcam_description = strdup(svalue); 307 } else if 343 } else if(!strcmp(key, "local_host")) { 308 344 svalue = va_arg(ap, char *); 309 345 free(yss->local_host); 310 346 yss->local_host = strdup(svalue); 311 } else if 347 } else if(!strcmp(key, "conn_type")) { 312 348 nvalue = va_arg(ap, int); 313 349 yss->conn_type = nvalue; 314 350 } else { 315 351 WARNING(("Unknown key passed to yahoo_init, " 316 317 352 "perhaps you didn't terminate the list " 353 "with NULL")); 318 354 } 319 355 } … … 324 360 static void yahoo_free_server_settings(struct yahoo_server_settings *yss) 325 361 { 326 if 362 if(!yss) 327 363 return; 328 364 … … 336 372 } 337 373 338 static YList *conns =NULL;339 static YList *inputs =NULL;340 static int last_id =0;374 static YList *conns=NULL; 375 static YList *inputs=NULL; 376 static int last_id=0; 341 377 342 378 static void add_to_list(struct yahoo_data *yd) … … 344 380 conns = y_list_prepend(conns, yd); 345 381 } 346 347 static struct yahoo_data *find_conn_by_id(int id) 382 static struct yahoo_data * find_conn_by_id(int id) 348 383 { 349 384 YList *l; 350 for 385 for(l = conns; l; l = y_list_next(l)) { 351 386 struct yahoo_data *yd = l->data; 352 if 387 if(yd->client_id == id) 353 388 return yd; 354 389 } 355 390 return NULL; 356 391 } 357 358 392 static void del_from_list(struct yahoo_data *yd) 359 393 { … … 362 396 363 397 /* call repeatedly to get the next one */ 364 /*365 398 static struct yahoo_input_data * find_input_by_id(int id) 366 399 { … … 373 406 return NULL; 374 407 } 375 */ 376 377 static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id, 378 const char *who) 408 409 static struct yahoo_input_data * find_input_by_id_and_webcam_user(int id, const char * who) 379 410 { 380 411 YList *l; 381 412 LOG(("find_input_by_id_and_webcam_user")); 382 for 413 for(l = inputs; l; l = y_list_next(l)) { 383 414 struct yahoo_input_data *yid = l->data; 384 if (yid->type == YAHOO_CONNECTION_WEBCAM 385 && yid->yd->client_id == id && yid->wcm && ((who 386 && yid->wcm->user 387 && !strcmp(who, yid->wcm->user)) 388 || !(yid->wcm->user && !who))) 415 if(yid->type == YAHOO_CONNECTION_WEBCAM && yid->yd->client_id == id 416 && yid->wcm && 417 ((who && yid->wcm->user && !strcmp(who, yid->wcm->user)) || 418 !(yid->wcm->user && !who))) 389 419 return yid; 390 420 } … … 392 422 } 393 423 394 static struct yahoo_input_data *find_input_by_id_and_type(int id, 395 enum yahoo_connection_type type) 424 static struct yahoo_input_data * find_input_by_id_and_type(int id, enum yahoo_connection_type type) 396 425 { 397 426 YList *l; 398 427 LOG(("find_input_by_id_and_type")); 399 for 428 for(l = inputs; l; l = y_list_next(l)) { 400 429 struct yahoo_input_data *yid = l->data; 401 if 430 if(yid->type == type && yid->yd->client_id == id) 402 431 return yid; 403 432 } … … 405 434 } 406 435 407 static struct yahoo_input_data * find_input_by_id_and_fd(int id, void *fd)436 static struct yahoo_input_data * find_input_by_id_and_fd(int id, int fd) 408 437 { 409 438 YList *l; 410 439 LOG(("find_input_by_id_and_fd")); 411 for 440 for(l = inputs; l; l = y_list_next(l)) { 412 441 struct yahoo_input_data *yid = l->data; 413 if 442 if(yid->fd == fd && yid->yd->client_id == id) 414 443 return yid; 415 444 } … … 419 448 static int count_inputs_with_id(int id) 420 449 { 421 int c =0;450 int c=0; 422 451 YList *l; 423 452 LOG(("counting %d", id)); 424 for 453 for(l = inputs; l; l = y_list_next(l)) { 425 454 struct yahoo_input_data *yid = l->data; 426 if 455 if(yid->yd->client_id == id) 427 456 c++; 428 457 } … … 431 460 } 432 461 462 433 463 extern char *yahoo_crypt(char *, char *); 434 464 435 465 /* Free a buddy list */ 436 static void yahoo_free_buddies(YList * list)466 static void yahoo_free_buddies(YList * list) 437 467 { 438 468 YList *l; 439 469 440 for (l = list; l; l = l->next) { 470 for(l = list; l; l = l->next) 471 { 441 472 struct yahoo_buddy *bud = l->data; 442 if 473 if(!bud) 443 474 continue; 444 475 … … 446 477 FREE(bud->id); 447 478 FREE(bud->real_name); 448 if 479 if(bud->yab_entry) { 449 480 FREE(bud->yab_entry->fname); 450 481 FREE(bud->yab_entry->lname); … … 465 496 466 497 /* Free an identities list */ 467 static void yahoo_free_identities(YList * list)498 static void yahoo_free_identities(YList * list) 468 499 { 469 500 while (list) { … … 494 525 FREE(yd->cookie_y); 495 526 FREE(yd->cookie_t); 496 FREE(yd->cookie_b);497 527 FREE(yd->cookie_c); 498 528 FREE(yd->login_cookie); … … 510 540 #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) 511 541 512 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, 513 enum ypacket_status status, int id)542 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, 543 enum yahoo_status status, int id) 514 544 { 515 545 struct yahoo_packet *pkt = y_new0(struct yahoo_packet, 1); … … 522 552 } 523 553 524 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, 525 const char *value) 554 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) 526 555 { 527 556 struct yahoo_pair *pair = y_new0(struct yahoo_pair, 1); … … 568 597 (((*((buf)+3))&0xff))) 569 598 570 static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, 571 int len) 599 static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int len) 572 600 { 573 601 int pos = 0; … … 622 650 FREE(value); 623 651 pkt->hash = y_list_append(pkt->hash, pair); 624 DEBUG_MSG(("Key: %d \tValue: %s", pair->key, 625 pair->value)); 652 DEBUG_MSG(("Key: %d \tValue: %s", pair->key, pair->value)); 626 653 } else { 627 654 FREE(pair); … … 663 690 } 664 691 692 665 693 static void yahoo_packet_dump(unsigned char *data, int len) 666 694 { 667 if 695 if(yahoo_get_log_level() >= YAHOO_LOG_DEBUG) { 668 696 int i; 669 697 for (i = 0; i < len; i++) { 670 698 if ((i % 8 == 0) && i) 671 YAHOO_CALLBACK(ext_yahoo_log) 699 YAHOO_CALLBACK(ext_yahoo_log)(" "); 672 700 if ((i % 16 == 0) && i) 673 YAHOO_CALLBACK(ext_yahoo_log) 674 YAHOO_CALLBACK(ext_yahoo_log) 675 } 676 YAHOO_CALLBACK(ext_yahoo_log) 701 YAHOO_CALLBACK(ext_yahoo_log)("\n"); 702 YAHOO_CALLBACK(ext_yahoo_log)("%02x ", data[i]); 703 } 704 YAHOO_CALLBACK(ext_yahoo_log)("\n"); 677 705 for (i = 0; i < len; i++) { 678 706 if ((i % 8 == 0) && i) 679 YAHOO_CALLBACK(ext_yahoo_log) 707 YAHOO_CALLBACK(ext_yahoo_log)(" "); 680 708 if ((i % 16 == 0) && i) 681 YAHOO_CALLBACK(ext_yahoo_log) 709 YAHOO_CALLBACK(ext_yahoo_log)("\n"); 682 710 if (isprint(data[i])) 683 YAHOO_CALLBACK(ext_yahoo_log) 711 YAHOO_CALLBACK(ext_yahoo_log)(" %c ", data[i]); 684 712 else 685 YAHOO_CALLBACK(ext_yahoo_log) 686 } 687 YAHOO_CALLBACK(ext_yahoo_log) 713 YAHOO_CALLBACK(ext_yahoo_log)(" . "); 714 } 715 YAHOO_CALLBACK(ext_yahoo_log)("\n"); 688 716 } 689 717 } … … 695 723 } 696 724 697 static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, 698 int length) 725 static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length) 699 726 { 700 727 struct data_queue *tx = y_new0(struct data_queue, 1); … … 705 732 yid->txqueues = y_list_append(yid->txqueues, tx); 706 733 707 if (!yid->write_tag) 708 yid->write_tag = 709 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd-> 710 client_id, yid->fd, YAHOO_INPUT_WRITE, yid); 711 } 712 713 static void yahoo_send_packet(struct yahoo_input_data *yid, 714 struct yahoo_packet *pkt, int extra_pad) 734 if(!yid->write_tag) 735 yid->write_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_WRITE, yid); 736 } 737 738 static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet *pkt, int extra_pad) 715 739 { 716 740 int pktlen = yahoo_packet_length(pkt); 717 741 int len = YAHOO_PACKET_HDRLEN + pktlen; 742 718 743 unsigned char *data; 719 744 int pos = 0; … … 724 749 data = y_new0(unsigned char, len + 1); 725 750 726 memcpy(data + pos, "YMSG", 4); 727 pos += 4; 728 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); /* version [latest 12 0x000c] */ 729 pos += yahoo_put16(data + pos, 0x0000); /* HIWORD pkt length??? */ 730 pos += yahoo_put16(data + pos, pktlen + extra_pad); /* LOWORD pkt length? */ 731 pos += yahoo_put16(data + pos, pkt->service); /* service */ 732 pos += yahoo_put32(data + pos, pkt->status); /* status [4bytes] */ 733 pos += yahoo_put32(data + pos, pkt->id); /* session [4bytes] */ 751 memcpy(data + pos, "YMSG", 4); pos += 4; 752 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); 753 pos += yahoo_put16(data + pos, 0x0000); 754 pos += yahoo_put16(data + pos, pktlen + extra_pad); 755 pos += yahoo_put16(data + pos, pkt->service); 756 pos += yahoo_put32(data + pos, pkt->status); 757 pos += yahoo_put32(data + pos, pkt->id); 734 758 735 759 yahoo_packet_write(pkt, data + pos); 736 760 737 761 yahoo_packet_dump(data, len); 738 739 if (yid->type == YAHOO_CONNECTION_FT)762 763 if( yid->type == YAHOO_CONNECTION_FT ) 740 764 yahoo_send_data(yid->fd, data, len); 741 765 else … … 758 782 } 759 783 760 static int yahoo_send_data( void *fd, void *data, int len)784 static int yahoo_send_data(int fd, void *data, int len) 761 785 { 762 786 int ret; 763 787 int e; 764 788 765 if (fd == NULL)789 if (fd < 0) 766 790 return -1; 767 791 … … 769 793 770 794 do { 771 ret = YAHOO_CALLBACK(ext_yahoo_write)(fd, data, len);772 } while (ret == -1 && errno ==EINTR);773 e =errno;774 775 if (ret == -1) {795 ret = write(fd, data, len); 796 } while(ret == -1 && errno==EINTR); 797 e=errno; 798 799 if (ret == -1) { 776 800 LOG(("wrote data: ERR %s", strerror(errno))); 777 801 } else { … … 779 803 } 780 804 781 errno =e;805 errno=e; 782 806 return ret; 783 807 } 784 808 785 void yahoo_close(int id) 809 void yahoo_close(int id) 786 810 { 787 811 struct yahoo_data *yd = find_conn_by_id(id); 788 if (!yd) 812 813 if(!yd) 789 814 return; 790 815 … … 792 817 793 818 yahoo_free_data(yd); 794 if 819 if(id == last_id) 795 820 last_id--; 796 821 } 797 822 798 static void yahoo_input_close(struct yahoo_input_data *yid) 823 static void yahoo_input_close(struct yahoo_input_data *yid) 799 824 { 800 825 inputs = y_list_remove(inputs, yid); 801 826 802 LOG(("yahoo_input_close(read)")); 803 YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id, 804 yid->read_tag); 805 LOG(("yahoo_input_close(write)")); 806 YAHOO_CALLBACK(ext_yahoo_remove_handler) (yid->yd->client_id, 807 yid->write_tag); 827 LOG(("yahoo_input_close(read)")); 828 YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->read_tag); 829 LOG(("yahoo_input_close(write)")); 830 YAHOO_CALLBACK(ext_yahoo_remove_handler)(yid->yd->client_id, yid->write_tag); 808 831 yid->read_tag = yid->write_tag = 0; 809 if 810 YAHOO_CALLBACK(ext_yahoo_close)(yid->fd);832 if(yid->fd) 833 close(yid->fd); 811 834 yid->fd = 0; 812 835 FREE(yid->rxqueue); 813 if 836 if(count_inputs_with_id(yid->yd->client_id) == 0) { 814 837 LOG(("closing %d", yid->yd->client_id)); 815 838 yahoo_close(yid->yd->client_id); 816 839 } 817 840 yahoo_free_webcam(yid->wcm); 818 if 841 if(yid->wcd) 819 842 FREE(yid->wcd); 820 if 843 if(yid->ys) { 821 844 FREE(yid->ys->lsearch_text); 822 845 FREE(yid->ys); … … 825 848 } 826 849 827 static int is_same_bud(const void *a, const void *b) 828 { 850 static int is_same_bud(const void * a, const void * b) { 829 851 const struct yahoo_buddy *subject = a; 830 852 const struct yahoo_buddy *object = b; … … 833 855 } 834 856 835 static char * getcookie(char *rawcookie)836 { 837 char * cookie =NULL;838 char * tmpcookie;839 char * cookieend;840 841 if (strlen(rawcookie) < 2) 857 static char * getcookie(char *rawcookie) 858 { 859 char * cookie=NULL; 860 char * tmpcookie; 861 char * cookieend; 862 863 if (strlen(rawcookie) < 2) 842 864 return NULL; 843 865 844 tmpcookie = strdup(rawcookie +2);866 tmpcookie = strdup(rawcookie+2); 845 867 cookieend = strchr(tmpcookie, ';'); 846 868 847 if 869 if(cookieend) 848 870 *cookieend = '\0'; 849 871 … … 855 877 } 856 878 857 static char * getlcookie(char *cookie)879 static char * getlcookie(char *cookie) 858 880 { 859 881 char *tmp; … … 862 884 863 885 tmpend = strstr(cookie, "n="); 864 if 865 tmp = strdup(tmpend +2);886 if(tmpend) { 887 tmp = strdup(tmpend+2); 866 888 tmpend = strchr(tmp, '&'); 867 if 868 *tmpend ='\0';889 if(tmpend) 890 *tmpend='\0'; 869 891 login_cookie = strdup(tmp); 870 892 FREE(tmp); … … 874 896 } 875 897 876 static void yahoo_process_notify(struct yahoo_input_data *yid, 877 struct yahoo_packet *pkt) 898 static void yahoo_process_notify(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 878 899 { 879 900 struct yahoo_data *yd = yid->yd; … … 906 927 if (!msg) 907 928 return; 908 909 if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) 910 YAHOO_CALLBACK(ext_yahoo_typing_notify) (yd->client_id, to, 911 from, stat); 912 else if (!strncasecmp(msg, "GAME", strlen("GAME"))) 913 YAHOO_CALLBACK(ext_yahoo_game_notify) (yd->client_id, to, from, 914 stat, ind); 915 else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) { 929 930 if (!strncasecmp(msg, "TYPING", strlen("TYPING"))) 931 YAHOO_CALLBACK(ext_yahoo_typing_notify)(yd->client_id, to, from, stat); 932 else if (!strncasecmp(msg, "GAME", strlen("GAME"))) 933 YAHOO_CALLBACK(ext_yahoo_game_notify)(yd->client_id, to, from, stat); 934 else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) 935 { 916 936 if (!strcmp(ind, " ")) { 917 YAHOO_CALLBACK(ext_yahoo_webcam_invite) (yd->client_id, 918 to, from); 937 YAHOO_CALLBACK(ext_yahoo_webcam_invite)(yd->client_id, to, from); 919 938 } else { 920 939 accept = atoi(ind); … … 922 941 if (accept < 0) 923 942 accept = 0; 924 YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply) (yd->925 client_id, to, from, accept);926 927 }else943 YAHOO_CALLBACK(ext_yahoo_webcam_invite_reply)(yd->client_id, to, from, accept); 944 } 945 } 946 else 928 947 LOG(("Got unknown notification: %s", msg)); 929 948 } 930 949 931 static void yahoo_process_conference(struct yahoo_input_data *yid, 932 struct yahoo_packet *pkt) 950 static void yahoo_process_filetransfer(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 951 { 952 struct yahoo_data *yd = yid->yd; 953 char *from=NULL; 954 char *to=NULL; 955 char *msg=NULL; 956 char *url=NULL; 957 long expires=0; 958 959 char *service=NULL; 960 961 char *filename=NULL; 962 unsigned long filesize=0L; 963 964 YList *l; 965 for (l = pkt->hash; l; l = l->next) { 966 struct yahoo_pair *pair = l->data; 967 if (pair->key == 4) 968 from = pair->value; 969 if (pair->key == 5) 970 to = pair->value; 971 if (pair->key == 14) 972 msg = pair->value; 973 if (pair->key == 20) 974 url = pair->value; 975 if (pair->key == 38) 976 expires = atol(pair->value); 977 978 if (pair->key == 27) 979 filename = pair->value; 980 if (pair->key == 28) 981 filesize = atol(pair->value); 982 983 if (pair->key == 49) 984 service = pair->value; 985 } 986 987 if(pkt->service == YAHOO_SERVICE_P2PFILEXFER) { 988 if(strcmp("FILEXFER", service) != 0) { 989 WARNING(("unhandled service 0x%02x", pkt->service)); 990 yahoo_dump_unhandled(pkt); 991 return; 992 } 993 } 994 995 if(msg) { 996 char *tmp; 997 tmp = strchr(msg, '\006'); 998 if(tmp) 999 *tmp = '\0'; 1000 } 1001 if(url && from) 1002 YAHOO_CALLBACK(ext_yahoo_got_file)(yd->client_id, to, from, url, expires, msg, filename, filesize); 1003 1004 } 1005 1006 static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 933 1007 { 934 1008 struct yahoo_data *yd = yid->yd; … … 938 1012 char *room = NULL; 939 1013 char *id = NULL; 940 int utf8 = 0;1014 int utf8 = 0; 941 1015 YList *members = NULL; 942 1016 YList *l; 943 1017 944 1018 for (l = pkt->hash; l; l = l->next) { 945 1019 struct yahoo_pair *pair = l->data; 946 1020 if (pair->key == 50) 947 1021 host = pair->value; 948 949 if (pair->key == 52) { /* invite */1022 1023 if (pair->key == 52) { /* invite */ 950 1024 members = y_list_append(members, strdup(pair->value)); 951 1025 } 952 if (pair->key == 53) /* logon */1026 if (pair->key == 53) /* logon */ 953 1027 who = pair->value; 954 if (pair->key == 54) /* decline */1028 if (pair->key == 54) /* decline */ 955 1029 who = pair->value; 956 if (pair->key == 55) /* unavailable (status == 2) */1030 if (pair->key == 55) /* unavailable (status == 2) */ 957 1031 who = pair->value; 958 if (pair->key == 56) /* logoff */1032 if (pair->key == 56) /* logoff */ 959 1033 who = pair->value; 960 1034 … … 962 1036 room = pair->value; 963 1037 964 if (pair->key == 58) /* join message */1038 if (pair->key == 58) /* join message */ 965 1039 msg = pair->value; 966 if (pair->key == 14) /* decline/conf message */1040 if (pair->key == 14) /* decline/conf message */ 967 1041 msg = pair->value; 968 1042 969 if (pair->key == 13) ; 970 if (pair->key == 16) /* error */ 1043 if (pair->key == 13) 1044 ; 1045 if (pair->key == 16) /* error */ 971 1046 msg = pair->value; 972 1047 973 if (pair->key == 1) /* my id */1048 if (pair->key == 1) /* my id */ 974 1049 id = pair->value; 975 if (pair->key == 3) /* message sender */1050 if (pair->key == 3) /* message sender */ 976 1051 who = pair->value; 977 1052 … … 980 1055 } 981 1056 982 if 983 return; 984 985 if 986 for 987 char * w = l->data;988 if 1057 if(!room) 1058 return; 1059 1060 if(host) { 1061 for(l = members; l; l = l->next) { 1062 char * w = l->data; 1063 if(!strcmp(w, host)) 989 1064 break; 990 1065 } 991 if 1066 if(!l) 992 1067 members = y_list_append(members, strdup(host)); 993 1068 } 994 1069 /* invite, decline, join, left, message -> status == 1 */ 995 1070 996 switch 1071 switch(pkt->service) { 997 1072 case YAHOO_SERVICE_CONFINVITE: 998 if (pkt->status == 2) ; 999 else if (members) 1000 YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd-> 1001 client_id, id, host, room, msg, members); 1002 else if (msg) 1003 YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, msg, 0, 1004 E_CONFNOTAVAIL); 1073 if(pkt->status == 2) 1074 ; 1075 else if(members) 1076 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); 1077 else if(msg) 1078 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, msg, 0, E_CONFNOTAVAIL); 1005 1079 break; 1006 1080 case YAHOO_SERVICE_CONFADDINVITE: 1007 if (pkt->status == 1) 1008 YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd-> 1009 client_id, id, host, room, msg, members); 1081 if(pkt->status == 2) 1082 ; 1083 else 1084 YAHOO_CALLBACK(ext_yahoo_got_conf_invite)(yd->client_id, id, host, room, msg, members); 1010 1085 break; 1011 1086 case YAHOO_SERVICE_CONFDECLINE: 1012 if (who) 1013 YAHOO_CALLBACK(ext_yahoo_conf_userdecline) (yd-> 1014 client_id, id, who, room, msg); 1087 if(who) 1088 YAHOO_CALLBACK(ext_yahoo_conf_userdecline)(yd->client_id, id, who, room, msg); 1015 1089 break; 1016 1090 case YAHOO_SERVICE_CONFLOGON: 1017 if (who) 1018 YAHOO_CALLBACK(ext_yahoo_conf_userjoin) (yd->client_id, 1019 id, who, room); 1091 if(who) 1092 YAHOO_CALLBACK(ext_yahoo_conf_userjoin)(yd->client_id, id, who, room); 1020 1093 break; 1021 1094 case YAHOO_SERVICE_CONFLOGOFF: 1022 if (who) 1023 YAHOO_CALLBACK(ext_yahoo_conf_userleave) (yd->client_id, 1024 id, who, room); 1095 if(who) 1096 YAHOO_CALLBACK(ext_yahoo_conf_userleave)(yd->client_id, id, who, room); 1025 1097 break; 1026 1098 case YAHOO_SERVICE_CONFMSG: 1027 if (who) 1028 YAHOO_CALLBACK(ext_yahoo_conf_message) (yd->client_id, 1029 id, who, room, msg, utf8); 1099 if(who) 1100 YAHOO_CALLBACK(ext_yahoo_conf_message)(yd->client_id, id, who, room, msg, utf8); 1030 1101 break; 1031 1102 } 1032 1103 } 1033 1104 1034 static void yahoo_process_chat(struct yahoo_input_data *yid, 1035 struct yahoo_packet *pkt) 1105 static void yahoo_process_chat(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1036 1106 { 1037 1107 char *msg = NULL; … … 1042 1112 YList *members = NULL; 1043 1113 struct yahoo_chat_member *currentmember = NULL; 1044 int msgtype = 1;1045 int utf8 = 0;1046 int firstjoin = 0;1047 int membercount = 0;1048 int chaterr =0;1114 int msgtype = 1; 1115 int utf8 = 0; 1116 int firstjoin = 0; 1117 int membercount = 0; 1118 int chaterr=0; 1049 1119 YList *l; 1050 1120 1051 1121 yahoo_dump_unhandled(pkt); 1052 1122 for (l = pkt->hash; l; l = l->next) { … … 1078 1148 1079 1149 if (pkt->service == YAHOO_SERVICE_CHATJOIN) { 1080 currentmember = 1081 y_new0(struct yahoo_chat_member, 1); 1150 currentmember = y_new0(struct yahoo_chat_member, 1); 1082 1151 currentmember->id = strdup(pair->value); 1083 1152 members = y_list_append(members, currentmember); … … 1109 1178 } 1110 1179 1180 1111 1181 if (pair->key == 130) { 1112 1182 /* first join */ … … 1126 1196 /* message error not sure what all the pair values mean */ 1127 1197 /* but -1 means no session in room */ 1128 chaterr = atoi(pair->value); 1129 } 1130 } 1131 1132 if (!room) { 1133 if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */ 1134 YAHOO_CALLBACK(ext_yahoo_chat_yahoologout) (yid->yd-> 1135 client_id, id); 1198 chaterr= atoi(pair->value); 1199 } 1200 } 1201 1202 if(!room) { 1203 if (pkt->service == YAHOO_SERVICE_CHATLOGOUT) { /* yahoo originated chat logout */ 1204 YAHOO_CALLBACK(ext_yahoo_chat_yahoologout)(yid->yd->client_id, id); 1205 return ; 1206 } 1207 if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) { 1208 YAHOO_CALLBACK(ext_yahoo_chat_yahooerror)(yid->yd->client_id, id); 1136 1209 return; 1137 1210 } 1138 if (pkt->service == YAHOO_SERVICE_COMMENT && chaterr) {1139 YAHOO_CALLBACK(ext_yahoo_chat_yahooerror) (yid->yd->1140 client_id, id);1141 return;1142 }1143 1211 1144 1212 WARNING(("We didn't get a room name, ignoring packet")); … … 1146 1214 } 1147 1215 1148 switch 1216 switch(pkt->service) { 1149 1217 case YAHOO_SERVICE_CHATJOIN: 1150 if 1218 if(y_list_length(members) != membercount) { 1151 1219 WARNING(("Count of members doesn't match No. of members we got")); 1152 1220 } 1153 if (firstjoin && members) { 1154 YAHOO_CALLBACK(ext_yahoo_chat_join) (yid->yd->client_id, 1155 id, room, topic, members, yid->fd); 1156 } else if (who) { 1157 if (y_list_length(members) != 1) { 1221 if(firstjoin && members) { 1222 YAHOO_CALLBACK(ext_yahoo_chat_join)(yid->yd->client_id, id, room, topic, members, yid->fd); 1223 } else if(who) { 1224 if(y_list_length(members) != 1) { 1158 1225 WARNING(("Got more than 1 member on a normal join")); 1159 1226 } 1160 1227 /* this should only ever have one, but just in case */ 1161 while 1228 while(members) { 1162 1229 YList *n = members->next; 1163 1230 currentmember = members->data; 1164 YAHOO_CALLBACK(ext_yahoo_chat_userjoin) (yid-> 1165 yd->client_id, id, room, currentmember); 1231 YAHOO_CALLBACK(ext_yahoo_chat_userjoin)(yid->yd->client_id, id, room, currentmember); 1166 1232 y_list_free_1(members); 1167 members =n;1233 members=n; 1168 1234 } 1169 1235 } 1170 1236 break; 1171 1237 case YAHOO_SERVICE_CHATEXIT: 1172 if (who) { 1173 YAHOO_CALLBACK(ext_yahoo_chat_userleave) (yid->yd-> 1174 client_id, id, room, who); 1238 if(who) { 1239 YAHOO_CALLBACK(ext_yahoo_chat_userleave)(yid->yd->client_id, id, room, who); 1175 1240 } 1176 1241 break; 1177 1242 case YAHOO_SERVICE_COMMENT: 1178 if (who) { 1179 YAHOO_CALLBACK(ext_yahoo_chat_message) (yid->yd-> 1180 client_id, id, who, room, msg, msgtype, utf8); 1243 if(who) { 1244 YAHOO_CALLBACK(ext_yahoo_chat_message)(yid->yd->client_id, id, who, room, msg, msgtype, utf8); 1181 1245 } 1182 1246 break; … … 1184 1248 } 1185 1249 1186 static void yahoo_process_message(struct yahoo_input_data *yid, 1187 struct yahoo_packet *pkt) 1250 static void yahoo_process_message(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1188 1251 { 1189 1252 struct yahoo_data *yd = yid->yd; 1190 1253 YList *l; 1191 YList * messages = NULL;1254 YList * messages = NULL; 1192 1255 1193 1256 struct m { 1194 int i_31;1195 int i_32;1257 int i_31; 1258 int i_32; 1196 1259 char *to; 1197 1260 char *from; 1198 1261 long tm; 1199 1262 char *msg; 1200 int utf8; 1201 char *gunk; 1263 int utf8; 1202 1264 } *message = y_new0(struct m, 1); 1203 1265 1204 1266 for (l = pkt->hash; l; l = l->next) { 1205 1267 struct yahoo_pair *pair = l->data; 1206 if (pair->key == 1 || pair->key == 4) { 1207 if (!message->from) 1268 if (pair->key == 1 || pair->key == 4) 1269 { 1270 if(!message->from) 1208 1271 message->from = pair->value; 1209 } else if (pair->key == 5) 1272 } 1273 else if (pair->key == 5) 1210 1274 message->to = pair->value; 1211 1275 else if (pair->key == 15) … … 1213 1277 else if (pair->key == 97) 1214 1278 message->utf8 = atoi(pair->value); 1215 /* This comes when the official client sends us a message */ 1216 else if (pair->key == 429) 1217 message->gunk = pair->value; 1218 /* user message *//* sys message */ 1279 /* user message */ /* sys message */ 1219 1280 else if (pair->key == 14 || pair->key == 16) 1220 1281 message->msg = pair->value; 1221 1282 else if (pair->key == 31) { 1222 if 1283 if(message->i_31) { 1223 1284 messages = y_list_append(messages, message); 1224 1285 message = y_new0(struct m, 1); 1225 1286 } 1226 1287 message->i_31 = atoi(pair->value); 1227 } else if (pair->key == 32) 1288 } 1289 else if (pair->key == 32) 1228 1290 message->i_32 = atoi(pair->value); 1229 1291 else 1230 LOG(("yahoo_process_message: status: %d, key: %d, value: %s", pkt->status, pair->key, pair->value)); 1292 LOG(("yahoo_process_message: status: %d, key: %d, value: %s", 1293 pkt->status, pair->key, pair->value)); 1231 1294 } 1232 1295 1233 1296 messages = y_list_append(messages, message); 1234 1297 1235 for (l = messages; l; l =l->next) {1298 for (l = messages; l; l=l->next) { 1236 1299 message = l->data; 1237 1300 if (pkt->service == YAHOO_SERVICE_SYSMESSAGE) { 1238 YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id, 1239 message->to, message->from, message->msg); 1301 YAHOO_CALLBACK(ext_yahoo_system_message)(yd->client_id, message->msg); 1240 1302 } else if (pkt->status <= 2 || pkt->status == 5) { 1241 /* Confirm message receipt if we got the gunk */ 1242 if(message->gunk) { 1243 struct yahoo_packet *outpkt; 1244 1245 outpkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_CONFIRM, 1246 YPACKET_STATUS_DEFAULT, 0); 1247 yahoo_packet_hash(outpkt, 1, yd->user); 1248 yahoo_packet_hash(outpkt, 5, message->from); 1249 yahoo_packet_hash(outpkt, 302, "430"); 1250 yahoo_packet_hash(outpkt, 430, message->gunk); 1251 yahoo_packet_hash(outpkt, 303, "430"); 1252 yahoo_packet_hash(outpkt, 450, "0"); 1253 yahoo_send_packet(yid, outpkt, 0); 1254 1255 yahoo_packet_free(outpkt); 1256 } 1257 1258 if (!strcmp(message->msg, "<ding>")) 1259 YAHOO_CALLBACK(ext_yahoo_got_buzz) (yd->client_id, 1260 message->to, message->from, message->tm); 1261 else 1262 YAHOO_CALLBACK(ext_yahoo_got_im) (yd->client_id, 1263 message->to, message->from, message->msg, 1264 message->tm, pkt->status, message->utf8); 1303 YAHOO_CALLBACK(ext_yahoo_got_im)(yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8); 1265 1304 } else if (pkt->status == 0xffffffff) { 1266 YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, 1267 message->msg, 0, E_SYSTEM); 1268 } 1269 FREE(message); 1305 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, message->msg, 0, E_SYSTEM); 1306 } 1307 free(message); 1270 1308 } 1271 1309 … … 1273 1311 } 1274 1312 1275 /*1276 * Here's what multi-level packets look like. Data in brackets is the value.1277 *1278 * 3 level:1279 * =======1280 *1281 * 302 (318) - Beginning level 11282 * 300 (318) - Begin level 21283 * 302 (319) - End level 2 header1284 * 300 (319) - Begin level 31285 * 301 (319) - End level 31286 * 303 (319) - End level 21287 * 303 (318) - End level 11288 *1289 * 2 level:1290 * =======1291 *1292 * 302 (315) - Beginning level 11293 * 300 (315) - Begin level 21294 * 301 (315) - End level 21295 * 303 (315) - End level 11296 *1297 */1298 1313 static void yahoo_process_status(struct yahoo_input_data *yid, 1299 1314 struct yahoo_packet *pkt) … … 1312 1327 } 1313 1328 1314 /* 1315 * Status updates may be spread accross multiple packets and not 1316 * even on buddy boundaries, so keeping some state is important. 1317 * So, continue where we left off, and only add a user entry to 1318 * the list once it's complete (301-315 End buddy). 1319 */ 1329 /* Status updates may be spread accross multiple packets and not 1330 even on buddy boundaries, so keeping some state is important. 1331 So, continue where we left off, and only add a user entry to 1332 the list once it's complete (301-315 End buddy). */ 1320 1333 u = yd->half_user; 1321 1334 … … 1581 1594 } 1582 1595 1583 static void yahoo_process_verify(struct yahoo_input_data *yid, 1584 struct yahoo_packet *pkt) 1596 static void yahoo_process_verify(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1585 1597 { 1586 1598 struct yahoo_data *yd = yid->yd; 1587 1599 1588 if 1600 if(pkt->status != 0x01) { 1589 1601 DEBUG_MSG(("expected status: 0x01, got: %d", pkt->status)); 1590 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 1591 YAHOO_LOGIN_LOCK, ""); 1592 return; 1593 } 1594 1595 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT, 1596 yd->session_id); 1602 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_LOCK, ""); 1603 return; 1604 } 1605 1606 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id); 1597 1607 1598 1608 yahoo_packet_hash(pkt, 1, yd->user); … … 1603 1613 } 1604 1614 1605 static void yahoo_process_picture_checksum(struct yahoo_input_data *yid, 1606 struct yahoo_packet *pkt) 1615 static void yahoo_process_picture_checksum( struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1607 1616 { 1608 1617 struct yahoo_data *yd = yid->yd; … … 1612 1621 YList *l; 1613 1622 1614 for (l = pkt->hash; l; l = l->next) { 1623 for(l = pkt->hash; l; l = l->next) 1624 { 1615 1625 struct yahoo_pair *pair = l->data; 1616 1626 1617 switch (pair->key) { 1618 case 1: 1619 case 4: 1620 from = pair->value; 1621 case 5: 1622 to = pair->value; 1623 break; 1624 case 212: 1625 break; 1626 case 192: 1627 checksum = atoi(pair->value); 1628 break; 1629 } 1630 } 1631 1632 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum) (yd->client_id, to, 1633 from, checksum); 1634 } 1635 1636 static void yahoo_process_picture(struct yahoo_input_data *yid, 1637 struct yahoo_packet *pkt) 1627 switch(pair->key) 1628 { 1629 case 1: 1630 case 4: 1631 from = pair->value; 1632 case 5: 1633 to = pair->value; 1634 break; 1635 case 212: 1636 break; 1637 case 192: 1638 checksum = atoi( pair->value ); 1639 break; 1640 } 1641 } 1642 1643 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_checksum)(yd->client_id,to,from,checksum); 1644 } 1645 1646 static void yahoo_process_picture(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1638 1647 { 1639 1648 struct yahoo_data *yd = yid->yd; … … 1644 1653 int checksum = 0; 1645 1654 YList *l; 1646 1647 for (l = pkt->hash; l; l = l->next) { 1655 1656 for(l = pkt->hash; l; l = l->next) 1657 { 1648 1658 struct yahoo_pair *pair = l->data; 1649 1659 1650 switch (pair->key) { 1660 switch(pair->key) 1661 { 1651 1662 case 1: 1652 case 4: /* sender */1663 case 4: /* sender */ 1653 1664 from = pair->value; 1654 1665 break; 1655 case 5: /* we */1666 case 5: /* we */ 1656 1667 to = pair->value; 1657 1668 break; 1658 case 13: /* request / sending */1659 status = atoi( pair->value);1660 break; 1661 case 20: /* url */1669 case 13: /* request / sending */ 1670 status = atoi( pair->value ); 1671 break; 1672 case 20: /* url */ 1662 1673 url = pair->value; 1663 1674 break; 1664 1675 case 192: /*checksum */ 1665 checksum = atoi(pair->value); 1666 break; 1667 } 1668 } 1669 1670 switch (status) { 1671 case 1: /* this is a request, ignore for now */ 1672 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request) (yd->client_id, 1673 to, from); 1674 break; 1675 case 2: /* this is cool - we get a picture :) */ 1676 YAHOO_CALLBACK(ext_yahoo_got_buddyicon) (yd->client_id, to, 1677 from, url, checksum); 1678 break; 1679 } 1680 } 1681 1682 static void yahoo_process_picture_upload(struct yahoo_input_data *yid, 1683 struct yahoo_packet *pkt) 1676 checksum = atoi( pair->value ); 1677 break; 1678 } 1679 } 1680 1681 switch( status ) 1682 { 1683 case 1: /* this is a request, ignore for now */ 1684 YAHOO_CALLBACK(ext_yahoo_got_buddyicon_request)(yd->client_id, to, from); 1685 break; 1686 case 2: /* this is cool - we get a picture :) */ 1687 YAHOO_CALLBACK(ext_yahoo_got_buddyicon)(yd->client_id,to, from, url, checksum); 1688 break; 1689 } 1690 } 1691 1692 static void yahoo_process_picture_upload(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1684 1693 { 1685 1694 struct yahoo_data *yd = yid->yd; … … 1687 1696 char *url = NULL; 1688 1697 1689 if ( pkt->status != 1)1698 if ( pkt->status != 1 ) 1690 1699 return; /* something went wrong */ 1691 1692 for (l = pkt->hash; l; l = l->next) { 1700 1701 for(l = pkt->hash; l; l = l->next) 1702 { 1693 1703 struct yahoo_pair *pair = l->data; 1694 1704 1695 switch (pair->key) { 1696 case 5: /* we */ 1697 break; 1698 case 20: /* url */ 1699 url = pair->value; 1700 break; 1701 case 27: /* local filename */ 1702 break; 1703 case 38: /* time */ 1704 break; 1705 } 1706 } 1707 1708 YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded) (yd->client_id, url); 1709 } 1710 1711 void yahoo_login(int id, int initial) 1712 { 1713 struct yahoo_data *yd = find_conn_by_id(id); 1714 struct connect_callback_data *ccd; 1715 struct yahoo_server_settings *yss; 1716 int tag; 1717 1718 char *host; 1719 1720 struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); 1721 yid->yd = yd; 1722 yid->type = YAHOO_CONNECTION_PAGER; 1723 inputs = y_list_prepend(inputs, yid); 1724 1725 yd->initial_status = initial; 1726 yss = yd->server_settings; 1727 1728 ccd = y_new0(struct connect_callback_data, 1); 1729 ccd->yd = yd; 1730 1731 host = yss->pager_host; 1732 1733 if (!host) 1734 host = yss->pager_host_list[0]; 1735 1736 tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, 1737 host, yss->pager_port, yahoo_connected, ccd, 0); 1738 1739 /* 1740 * if tag <= 0, then callback has already been called 1741 * so ccd will have been freed 1705 switch(pair->key) 1706 { 1707 case 5: /* we */ 1708 break; 1709 case 20: /* url */ 1710 url = pair->value; 1711 break; 1712 case 27: /* local filename */ 1713 break; 1714 case 38: /* time */ 1715 break; 1716 } 1717 } 1718 1719 YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded)(yd->client_id, url); 1720 } 1721 1722 static void yahoo_process_auth_pre_0x0b(struct yahoo_input_data *yid, 1723 const char *seed, const char *sn) 1724 { 1725 struct yahoo_data *yd = yid->yd; 1726 1727 /* So, Yahoo has stopped supporting its older clients in India, and 1728 * undoubtedly will soon do so in the rest of the world. 1729 * 1730 * The new clients use this authentication method. I warn you in 1731 * advance, it's bizzare, convoluted, inordinately complicated. 1732 * It's also no more secure than crypt() was. The only purpose this 1733 * scheme could serve is to prevent third part clients from connecting 1734 * to their servers. 1735 * 1736 * Sorry, Yahoo. 1742 1737 */ 1743 if (tag > 0) 1744 ccd->tag = tag; 1745 else if (tag < 0) 1746 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 1747 YAHOO_LOGIN_SOCK, NULL); 1738 1739 struct yahoo_packet *pack; 1740 1741 md5_byte_t result[16]; 1742 md5_state_t ctx; 1743 char *crypt_result; 1744 unsigned char *password_hash = malloc(25); 1745 unsigned char *crypt_hash = malloc(25); 1746 unsigned char *hash_string_p = malloc(50 + strlen(sn)); 1747 unsigned char *hash_string_c = malloc(50 + strlen(sn)); 1748 1749 char checksum; 1750 1751 int sv; 1752 1753 unsigned char *result6 = malloc(25); 1754 unsigned char *result96 = malloc(25); 1755 1756 sv = seed[15]; 1757 sv = (sv % 8) % 5; 1758 1759 md5_init(&ctx); 1760 md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password)); 1761 md5_finish(&ctx, result); 1762 to_y64(password_hash, result, 16); 1763 1764 md5_init(&ctx); 1765 crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); 1766 md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); 1767 md5_finish(&ctx, result); 1768 to_y64(crypt_hash, result, 16); 1769 free(crypt_result); 1770 1771 switch (sv) { 1772 case 0: 1773 checksum = seed[seed[7] % 16]; 1774 snprintf((char *)hash_string_p, strlen(sn) + 50, 1775 "%c%s%s%s", checksum, password_hash, yd->user, seed); 1776 snprintf((char *)hash_string_c, strlen(sn) + 50, 1777 "%c%s%s%s", checksum, crypt_hash, yd->user, seed); 1778 break; 1779 case 1: 1780 checksum = seed[seed[9] % 16]; 1781 snprintf((char *)hash_string_p, strlen(sn) + 50, 1782 "%c%s%s%s", checksum, yd->user, seed, password_hash); 1783 snprintf((char *)hash_string_c, strlen(sn) + 50, 1784 "%c%s%s%s", checksum, yd->user, seed, crypt_hash); 1785 break; 1786 case 2: 1787 checksum = seed[seed[15] % 16]; 1788 snprintf((char *)hash_string_p, strlen(sn) + 50, 1789 "%c%s%s%s", checksum, seed, password_hash, yd->user); 1790 snprintf((char *)hash_string_c, strlen(sn) + 50, 1791 "%c%s%s%s", checksum, seed, crypt_hash, yd->user); 1792 break; 1793 case 3: 1794 checksum = seed[seed[1] % 16]; 1795 snprintf((char *)hash_string_p, strlen(sn) + 50, 1796 "%c%s%s%s", checksum, yd->user, password_hash, seed); 1797 snprintf((char *)hash_string_c, strlen(sn) + 50, 1798 "%c%s%s%s", checksum, yd->user, crypt_hash, seed); 1799 break; 1800 case 4: 1801 checksum = seed[seed[3] % 16]; 1802 snprintf((char *)hash_string_p, strlen(sn) + 50, 1803 "%c%s%s%s", checksum, password_hash, seed, yd->user); 1804 snprintf((char *)hash_string_c, strlen(sn) + 50, 1805 "%c%s%s%s", checksum, crypt_hash, seed, yd->user); 1806 break; 1807 } 1808 1809 md5_init(&ctx); 1810 md5_append(&ctx, (md5_byte_t *)hash_string_p, strlen((char *)hash_string_p)); 1811 md5_finish(&ctx, result); 1812 to_y64(result6, result, 16); 1813 1814 md5_init(&ctx); 1815 md5_append(&ctx, (md5_byte_t *)hash_string_c, strlen((char *)hash_string_c)); 1816 md5_finish(&ctx, result); 1817 to_y64(result96, result, 16); 1818 1819 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); 1820 yahoo_packet_hash(pack, 0, yd->user); 1821 yahoo_packet_hash(pack, 6, (char *)result6); 1822 yahoo_packet_hash(pack, 96, (char *)result96); 1823 yahoo_packet_hash(pack, 1, yd->user); 1824 1825 yahoo_send_packet(yid, pack, 0); 1826 1827 FREE(result6); 1828 FREE(result96); 1829 FREE(password_hash); 1830 FREE(crypt_hash); 1831 FREE(hash_string_p); 1832 FREE(hash_string_c); 1833 1834 yahoo_packet_free(pack); 1835 1836 } 1837 1838 /* 1839 * New auth protocol cracked by Cerulean Studios and sent in to Gaim 1840 */ 1841 static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *seed, const char *sn) 1842 { 1843 struct yahoo_packet *pack = NULL; 1844 struct yahoo_data *yd = yid->yd; 1845 1846 md5_byte_t result[16]; 1847 md5_state_t ctx; 1848 1849 sha1_state_t ctx1; 1850 sha1_state_t ctx2; 1851 1852 char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; 1853 char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; 1854 1855 char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; 1856 char *operand_lookup = "+|&%/*^-"; 1857 char *delimit_lookup = ",;"; 1858 1859 unsigned char *password_hash = malloc(25); 1860 unsigned char *crypt_hash = malloc(25); 1861 char *crypt_result = NULL; 1862 unsigned char pass_hash_xor1[64]; 1863 unsigned char pass_hash_xor2[64]; 1864 unsigned char crypt_hash_xor1[64]; 1865 unsigned char crypt_hash_xor2[64]; 1866 unsigned char chal[7]; 1867 char resp_6[100]; 1868 char resp_96[100]; 1869 1870 unsigned char digest1[20]; 1871 unsigned char digest2[20]; 1872 unsigned char magic_key_char[4]; 1873 const unsigned char *magic_ptr; 1874 1875 unsigned int magic[64]; 1876 unsigned int magic_work=0; 1877 1878 char comparison_src[20]; 1879 1880 int x, j, i; 1881 int cnt = 0; 1882 int magic_cnt = 0; 1883 int magic_len; 1884 int depth =0, table =0; 1885 1886 memset(&pass_hash_xor1, 0, 64); 1887 memset(&pass_hash_xor2, 0, 64); 1888 memset(&crypt_hash_xor1, 0, 64); 1889 memset(&crypt_hash_xor2, 0, 64); 1890 memset(&digest1, 0, 20); 1891 memset(&digest2, 0, 20); 1892 memset(&magic, 0, 64); 1893 memset(&resp_6, 0, 100); 1894 memset(&resp_96, 0, 100); 1895 memset(&magic_key_char, 0, 4); 1896 1897 /* 1898 * Magic: Phase 1. Generate what seems to be a 30 1899 * byte value (could change if base64 1900 * ends up differently? I don't remember and I'm 1901 * tired, so use a 64 byte buffer. 1902 */ 1903 1904 magic_ptr = (unsigned char *)seed; 1905 1906 while (*magic_ptr != 0) { 1907 char *loc; 1908 1909 /* Ignore parentheses. */ 1910 1911 if (*magic_ptr == '(' || *magic_ptr == ')') { 1912 magic_ptr++; 1913 continue; 1914 } 1915 1916 /* Characters and digits verify against 1917 the challenge lookup. 1918 */ 1919 1920 if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) { 1921 loc = strchr(challenge_lookup, *magic_ptr); 1922 if (!loc) { 1923 /* This isn't good */ 1924 continue; 1925 } 1926 1927 /* Get offset into lookup table and lsh 3. */ 1928 1929 magic_work = loc - challenge_lookup; 1930 magic_work <<= 3; 1931 1932 magic_ptr++; 1933 continue; 1934 } else { 1935 unsigned int local_store; 1936 1937 loc = strchr(operand_lookup, *magic_ptr); 1938 if (!loc) { 1939 /* Also not good. */ 1940 continue; 1941 } 1942 1943 local_store = loc - operand_lookup; 1944 1945 /* Oops; how did this happen? */ 1946 if (magic_cnt >= 64) 1947 break; 1948 1949 magic[magic_cnt++] = magic_work | local_store; 1950 magic_ptr++; 1951 continue; 1952 } 1953 } 1954 1955 magic_len = magic_cnt; 1956 magic_cnt = 0; 1957 1958 /* Magic: Phase 2. Take generated magic value and 1959 * sprinkle fairy dust on the values. */ 1960 1961 for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) { 1962 unsigned char byte1; 1963 unsigned char byte2; 1964 1965 /* Bad. Abort. 1966 */ 1967 if (magic_cnt >= magic_len) { 1968 WARNING(("magic_cnt(%d) magic_len(%d)", magic_cnt, magic_len)) 1969 break; 1970 } 1971 1972 byte1 = magic[magic_cnt]; 1973 byte2 = magic[magic_cnt+1]; 1974 1975 byte1 *= 0xcd; 1976 byte1 ^= byte2; 1977 1978 magic[magic_cnt+1] = byte1; 1979 } 1980 1981 /* Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic 1982 * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key 1983 * plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets 1984 * into particular functions we'll later call to potentially alter the magic key. 1985 * 1986 * %-) 1987 */ 1988 1989 magic_cnt = 1; 1990 x = 0; 1991 1992 do { 1993 unsigned int bl = 0; 1994 unsigned int cl = magic[magic_cnt++]; 1995 1996 if (magic_cnt >= magic_len) 1997 break; 1998 1999 if (cl > 0x7F) { 2000 if (cl < 0xe0) 2001 bl = cl = (cl & 0x1f) << 6; 2002 else { 2003 bl = magic[magic_cnt++]; 2004 cl = (cl & 0x0f) << 6; 2005 bl = ((bl & 0x3f) + cl) << 6; 2006 } 2007 2008 cl = magic[magic_cnt++]; 2009 bl = (cl & 0x3f) + bl; 2010 } else 2011 bl = cl; 2012 2013 comparison_src[x++] = (bl & 0xff00) >> 8; 2014 comparison_src[x++] = bl & 0xff; 2015 } while (x < 20); 2016 2017 /* Dump magic key into a char for SHA1 action. */ 2018 2019 2020 for(x = 0; x < 4; x++) 2021 magic_key_char[x] = comparison_src[x]; 2022 2023 /* Compute values for recursive function table! */ 2024 memcpy( chal, magic_key_char, 4 ); 2025 x = 1; 2026 for( i = 0; i < 0xFFFF && x; i++ ) 2027 { 2028 for( j = 0; j < 5 && x; j++ ) 2029 { 2030 chal[4] = i; 2031 chal[5] = i >> 8; 2032 chal[6] = j; 2033 md5_init( &ctx ); 2034 md5_append( &ctx, chal, 7 ); 2035 md5_finish( &ctx, result ); 2036 if( memcmp( comparison_src + 4, result, 16 ) == 0 ) 2037 { 2038 depth = i; 2039 table = j; 2040 x = 0; 2041 } 2042 } 2043 } 2044 2045 /* Transform magic_key_char using transform table */ 2046 x = magic_key_char[3] << 24 | magic_key_char[2] << 16 2047 | magic_key_char[1] << 8 | magic_key_char[0]; 2048 x = yahoo_xfrm( table, depth, x ); 2049 x = yahoo_xfrm( table, depth, x ); 2050 magic_key_char[0] = x & 0xFF; 2051 magic_key_char[1] = x >> 8 & 0xFF; 2052 magic_key_char[2] = x >> 16 & 0xFF; 2053 magic_key_char[3] = x >> 24 & 0xFF; 2054 2055 /* Get password and crypt hashes as per usual. */ 2056 md5_init(&ctx); 2057 md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password)); 2058 md5_finish(&ctx, result); 2059 to_y64(password_hash, result, 16); 2060 2061 md5_init(&ctx); 2062 crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$"); 2063 md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); 2064 md5_finish(&ctx, result); 2065 to_y64(crypt_hash, result, 16); 2066 free(crypt_result); 2067 2068 /* Our first authentication response is based off 2069 * of the password hash. */ 2070 2071 for (x = 0; x < (int)strlen((char *)password_hash); x++) 2072 pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; 2073 2074 if (cnt < 64) 2075 memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); 2076 2077 cnt = 0; 2078 2079 for (x = 0; x < (int)strlen((char *)password_hash); x++) 2080 pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; 2081 2082 if (cnt < 64) 2083 memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); 2084 2085 sha1_init(&ctx1); 2086 sha1_init(&ctx2); 2087 2088 /* The first context gets the password hash XORed 2089 * with 0x36 plus a magic value 2090 * which we previously extrapolated from our 2091 * challenge. */ 2092 2093 sha1_append(&ctx1, pass_hash_xor1, 64); 2094 if (j >= 3 ) 2095 ctx1.Length_Low = 0x1ff; 2096 sha1_append(&ctx1, magic_key_char, 4); 2097 sha1_finish(&ctx1, digest1); 2098 2099 /* The second context gets the password hash XORed 2100 * with 0x5c plus the SHA-1 digest 2101 * of the first context. */ 2102 2103 sha1_append(&ctx2, pass_hash_xor2, 64); 2104 sha1_append(&ctx2, digest1, 20); 2105 sha1_finish(&ctx2, digest2); 2106 2107 /* Now that we have digest2, use it to fetch 2108 * characters from an alphabet to construct 2109 * our first authentication response. */ 2110 2111 for (x = 0; x < 20; x += 2) { 2112 unsigned int val = 0; 2113 unsigned int lookup = 0; 2114 char byte[6]; 2115 2116 memset(&byte, 0, 6); 2117 2118 /* First two bytes of digest stuffed 2119 * together. 2120 */ 2121 2122 val = digest2[x]; 2123 val <<= 8; 2124 val += digest2[x+1]; 2125 2126 lookup = (val >> 0x0b); 2127 lookup &= 0x1f; 2128 if (lookup >= strlen(alphabet1)) 2129 break; 2130 sprintf(byte, "%c", alphabet1[lookup]); 2131 strcat(resp_6, byte); 2132 strcat(resp_6, "="); 2133 2134 lookup = (val >> 0x06); 2135 lookup &= 0x1f; 2136 if (lookup >= strlen(alphabet2)) 2137 break; 2138 sprintf(byte, "%c", alphabet2[lookup]); 2139 strcat(resp_6, byte); 2140 2141 lookup = (val >> 0x01); 2142 lookup &= 0x1f; 2143 if (lookup >= strlen(alphabet2)) 2144 break; 2145 sprintf(byte, "%c", alphabet2[lookup]); 2146 strcat(resp_6, byte); 2147 2148 lookup = (val & 0x01); 2149 if (lookup >= strlen(delimit_lookup)) 2150 break; 2151 sprintf(byte, "%c", delimit_lookup[lookup]); 2152 strcat(resp_6, byte); 2153 } 2154 2155 /* Our second authentication response is based off 2156 * of the crypto hash. */ 2157 2158 cnt = 0; 2159 memset(&digest1, 0, 20); 2160 memset(&digest2, 0, 20); 2161 2162 for (x = 0; x < (int)strlen((char *)crypt_hash); x++) 2163 crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36; 2164 2165 if (cnt < 64) 2166 memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt); 2167 2168 cnt = 0; 2169 2170 for (x = 0; x < (int)strlen((char *)crypt_hash); x++) 2171 crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; 2172 2173 if (cnt < 64) 2174 memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); 2175 2176 sha1_init(&ctx1); 2177 sha1_init(&ctx2); 2178 2179 /* The first context gets the password hash XORed 2180 * with 0x36 plus a magic value 2181 * which we previously extrapolated from our 2182 * challenge. */ 2183 2184 sha1_append(&ctx1, crypt_hash_xor1, 64); 2185 if (j >= 3 ) 2186 ctx1.Length_Low = 0x1ff; 2187 sha1_append(&ctx1, magic_key_char, 4); 2188 sha1_finish(&ctx1, digest1); 2189 2190 /* The second context gets the password hash XORed 2191 * with 0x5c plus the SHA-1 digest 2192 * of the first context. */ 2193 2194 sha1_append(&ctx2, crypt_hash_xor2, 64); 2195 sha1_append(&ctx2, digest1, 20); 2196 sha1_finish(&ctx2, digest2); 2197 2198 /* Now that we have digest2, use it to fetch 2199 * characters from an alphabet to construct 2200 * our first authentication response. */ 2201 2202 for (x = 0; x < 20; x += 2) { 2203 unsigned int val = 0; 2204 unsigned int lookup = 0; 2205 2206 char byte[6]; 2207 2208 memset(&byte, 0, 6); 2209 2210 /* First two bytes of digest stuffed 2211 * together. */ 2212 2213 val = digest2[x]; 2214 val <<= 8; 2215 val += digest2[x+1]; 2216 2217 lookup = (val >> 0x0b); 2218 lookup &= 0x1f; 2219 if (lookup >= strlen(alphabet1)) 2220 break; 2221 sprintf(byte, "%c", alphabet1[lookup]); 2222 strcat(resp_96, byte); 2223 strcat(resp_96, "="); 2224 2225 lookup = (val >> 0x06); 2226 lookup &= 0x1f; 2227 if (lookup >= strlen(alphabet2)) 2228 break; 2229 sprintf(byte, "%c", alphabet2[lookup]); 2230 strcat(resp_96, byte); 2231 2232 lookup = (val >> 0x01); 2233 lookup &= 0x1f; 2234 if (lookup >= strlen(alphabet2)) 2235 break; 2236 sprintf(byte, "%c", alphabet2[lookup]); 2237 strcat(resp_96, byte); 2238 2239 lookup = (val & 0x01); 2240 if (lookup >= strlen(delimit_lookup)) 2241 break; 2242 sprintf(byte, "%c", delimit_lookup[lookup]); 2243 strcat(resp_96, byte); 2244 } 2245 2246 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); 2247 yahoo_packet_hash(pack, 0, sn); 2248 yahoo_packet_hash(pack, 6, resp_6); 2249 yahoo_packet_hash(pack, 96, resp_96); 2250 yahoo_packet_hash(pack, 1, sn); 2251 yahoo_send_packet(yid, pack, 0); 2252 yahoo_packet_free(pack); 2253 2254 free(password_hash); 2255 free(crypt_hash); 1748 2256 } 1749 2257 … … 1795 2303 } 1796 2304 1797 static void yahoo_ https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn)2305 static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) 1798 2306 { 1799 2307 struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); … … 1845 2353 1846 2354 if (req->status_code != 200) { 1847 YAHOO_CALLBACK(ext_yahoo_login_response) 2355 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); 1848 2356 goto fail; 1849 2357 } 1850 2358 1851 2359 if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { 1852 YAHOO_CALLBACK(ext_yahoo_login_response) 2360 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); 1853 2361 goto fail; 1854 2362 } 1855 2363 1856 2364 if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) { 1857 YAHOO_CALLBACK(ext_yahoo_login_response) 2365 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL); 1858 2366 goto fail; 1859 2367 } … … 1901 2409 1902 2410 if (req->status_code != 200) { 1903 YAHOO_CALLBACK(ext_yahoo_login_response) 2411 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); 1904 2412 goto fail; 1905 2413 } 1906 2414 1907 2415 if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { 1908 YAHOO_CALLBACK(ext_yahoo_login_response) 2416 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); 1909 2417 goto fail; 1910 2418 } … … 1913 2421 (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL || 1914 2422 (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) { 1915 YAHOO_CALLBACK(ext_yahoo_login_response) 2423 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL); 1916 2424 goto fail; 1917 2425 } … … 1946 2454 } 1947 2455 1948 static void yahoo_process_auth(struct yahoo_input_data *yid, 1949 struct yahoo_packet *pkt) 2456 static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1950 2457 { 1951 2458 char *seed = NULL; 1952 char *sn = NULL;2459 char *sn = NULL; 1953 2460 YList *l = pkt->hash; 1954 2461 int m = 0; 1955 struct yahoo_data *yd = yid->yd;1956 2462 1957 2463 while (l) { 1958 2464 struct yahoo_pair *pair = l->data; 1959 1960 switch (pair->key) { 1961 case 94: 2465 if (pair->key == 94) 1962 2466 seed = pair->value; 2467 if (pair->key == 1) 2468 sn = pair->value; 2469 if (pair->key == 13) 2470 m = atoi(pair->value); 2471 l = l->next; 2472 } 2473 2474 if (!seed) 2475 return; 2476 2477 switch (m) { 2478 case 0: 2479 yahoo_process_auth_pre_0x0b(yid, seed, sn); 1963 2480 break; 1964 2481 case 1: 1965 sn = pair->value; 1966 break; 1967 case 13: 1968 m = atoi(pair->value); 1969 break; 1970 } 1971 l = l->next; 1972 } 1973 1974 if (!seed) 1975 return; 1976 1977 if (m==2) 1978 yahoo_https_auth(yid, seed, sn); 1979 else { 1980 /* call error */ 1981 WARNING(("unknown auth type %d", m)); 1982 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 1983 YAHOO_LOGIN_UNKNOWN, NULL); 1984 } 1985 } 1986 1987 static void yahoo_process_auth_resp(struct yahoo_input_data *yid, 1988 struct yahoo_packet *pkt) 2482 yahoo_process_auth_0x0b(yid, seed, sn); 2483 break; 2484 case 2: 2485 yahoo_process_auth_0x10(yid, seed, sn); 2486 break; 2487 default: 2488 /* call error */ 2489 WARNING(("unknown auth type %d", m)); 2490 yahoo_process_auth_0x0b(yid, seed, sn); 2491 break; 2492 } 2493 } 2494 2495 static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1989 2496 { 1990 2497 struct yahoo_data *yd = yid->yd; 1991 2498 char *login_id; 1992 2499 char *handle; 1993 char *url =NULL;1994 int login_status = -1;2500 char *url=NULL; 2501 int login_status=0; 1995 2502 1996 2503 YList *l; … … 2008 2515 } 2009 2516 2010 if (pkt->status == YPACKET_STATUS_DISCONNECTED) { 2011 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 2012 login_status, url); 2013 /* yahoo_logoff(yd->client_id); */ 2014 } 2015 } 2016 2017 static void yahoo_process_mail(struct yahoo_input_data *yid, 2018 struct yahoo_packet *pkt) 2517 if(pkt->status == 0xffffffff) { 2518 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, login_status, url); 2519 /* yahoo_logoff(yd->client_id);*/ 2520 } 2521 } 2522 2523 static void yahoo_process_mail(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2019 2524 { 2020 2525 struct yahoo_data *yd = yid->yd; … … 2042 2547 char from[1024]; 2043 2548 snprintf(from, sizeof(from), "%s (%s)", who, email); 2044 YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, from, 2045 subj, count); 2046 } else if (count > 0) 2047 YAHOO_CALLBACK(ext_yahoo_mail_notify) (yd->client_id, NULL, 2048 NULL, count); 2049 } 2050 2051 static void yahoo_process_new_contact(struct yahoo_input_data *yid, 2052 struct yahoo_packet *pkt) 2053 { 2054 struct yahoo_data *yd = yid->yd; 2055 char *me = NULL; 2056 char *who = NULL; 2057 char *msg = NULL; 2058 int online = -1; 2059 2060 YList *l; 2061 2062 for (l = pkt->hash; l; l = l->next) { 2063 struct yahoo_pair *pair = l->data; 2064 if (pair->key == 4) 2065 who = pair->value; 2066 else if (pair->key == 5) 2067 me = pair->value; 2068 else if (pair->key == 14) 2069 msg = pair->value; 2070 else if (pair->key == 13) 2071 online = strtol(pair->value, NULL, 10); 2072 } 2073 2074 if (who && online < 0) 2075 YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, me, who, 2076 msg); 2077 else if (online == 2) 2078 YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg); 2079 } 2080 2081 /* UNUSED? */ 2082 static void yahoo_process_contact(struct yahoo_input_data *yid, 2083 struct yahoo_packet *pkt) 2549 YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, from, subj, count); 2550 } else if(count > 0) 2551 YAHOO_CALLBACK(ext_yahoo_mail_notify)(yd->client_id, NULL, NULL, count); 2552 } 2553 2554 static void yahoo_process_contact(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2084 2555 { 2085 2556 struct yahoo_data *yd = yid->yd; … … 2090 2561 long tm = 0L; 2091 2562 int state = YAHOO_STATUS_AVAILABLE; 2092 int online = 0;2563 int online = FALSE; 2093 2564 int away = 0; 2094 2565 int idle = 0; … … 2119 2590 else if (pair->key == 60) 2120 2591 mobile = strtol(pair->value, NULL, 10); 2121 2592 2122 2593 } 2123 2594 2124 2595 if (id) 2125 YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, id, who, 2126 msg); 2596 YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, id, who, msg); 2127 2597 else if (name) 2128 YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, name, 2129 state, msg, away, idle, mobile); 2130 else if (pkt->status == 0x07) 2131 YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg); 2132 } 2133 2134 static void yahoo_process_buddyadd(struct yahoo_input_data *yid, 2135 struct yahoo_packet *pkt) 2598 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, name, state, msg, away, idle, mobile); 2599 else if(pkt->status == 0x07) 2600 YAHOO_CALLBACK(ext_yahoo_rejected)(yd->client_id, who, msg); 2601 } 2602 2603 static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2136 2604 { 2137 2605 struct yahoo_data *yd = yid->yd; … … 2141 2609 char *me = NULL; 2142 2610 2143 struct yahoo_buddy *bud =NULL;2611 struct yahoo_buddy *bud=NULL; 2144 2612 2145 2613 YList *l; … … 2156 2624 } 2157 2625 2158 if (!who) 2159 return; 2160 if (!where) 2626 yahoo_dump_unhandled(pkt); 2627 2628 if(!who) 2629 return; 2630 if(!where) 2161 2631 where = "Unknown"; 2162 2632 2163 bud = y_new0(struct yahoo_buddy, 1); 2164 bud->id = strdup(who); 2165 bud->group = strdup(where); 2166 bud->real_name = NULL; 2167 2168 yd->buddies = y_list_append(yd->buddies, bud); 2169 2170 /* A non-zero status (i've seen 2) seems to mean the buddy is already 2171 * added and is online */ 2172 if (status) { 2173 LOG(("Setting online see packet for info")); 2174 yahoo_dump_unhandled(pkt); 2175 YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who, 2176 YAHOO_STATUS_AVAILABLE, NULL, 0, 0, 0); 2177 } 2178 } 2179 2180 static void yahoo_process_buddydel(struct yahoo_input_data *yid, 2181 struct yahoo_packet *pkt) 2633 /* status: 0 == Successful, 1 == Error (does not exist), 2 == Already in list */ 2634 if( status == 0 ) { 2635 bud = y_new0(struct yahoo_buddy, 1); 2636 bud->id = strdup(who); 2637 bud->group = strdup(where); 2638 bud->real_name = NULL; 2639 2640 yd->buddies = y_list_append(yd->buddies, bud); 2641 2642 /* Possibly called already, but at least the call above doesn't 2643 seem to happen every time (not anytime I tried). */ 2644 YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL); 2645 } 2646 2647 /* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ 2648 } 2649 2650 static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2651 { 2652 char* who=NULL; 2653 char* me=NULL; 2654 char* msg=NULL; 2655 YList *l; 2656 for (l = pkt->hash; l; l = l->next) { 2657 struct yahoo_pair *pair = l->data; 2658 if (pair->key == 4) 2659 who = pair->value; 2660 else if (pair->key == 5) 2661 me = pair->value; 2662 else 2663 DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); 2664 } 2665 2666 if(pkt->status==3) 2667 YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg); 2668 } 2669 2670 static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2182 2671 { 2183 2672 struct yahoo_data *yd = yid->yd; … … 2202 2691 unk_66 = strtol(pair->value, NULL, 10); 2203 2692 else 2204 DEBUG_MSG(("unknown key: %d = %s", pair->key, 2205 pair->value)); 2206 } 2207 2208 if (!who || !where) 2209 return; 2210 2693 DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); 2694 } 2695 2696 if(!who || !where) 2697 return; 2698 2211 2699 bud = y_new0(struct yahoo_buddy, 1); 2212 2700 bud->id = strdup(who); … … 2219 2707 FREE(bud); 2220 2708 2221 if 2709 if(buddy) { 2222 2710 bud = buddy->data; 2223 2711 yd->buddies = y_list_remove_link(yd->buddies, buddy); … … 2229 2717 FREE(bud); 2230 2718 2231 bud = NULL; 2232 } 2233 } 2234 2235 static void yahoo_process_ignore(struct yahoo_input_data *yid, 2236 struct yahoo_packet *pkt) 2719 bud=NULL; 2720 } 2721 } 2722 2723 static void yahoo_process_ignore(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2237 2724 { 2238 2725 char *who = NULL; 2239 int status = 0;2726 int status = 0; 2240 2727 char *me = NULL; 2241 int un_ignore = 0;2728 int un_ignore = 0; 2242 2729 2243 2730 YList *l; … … 2248 2735 if (pair->key == 1) 2249 2736 me = pair->value; 2250 if (pair->key == 13) /* 1 == ignore, 2 == unignore */2737 if (pair->key == 13) /* 1 == ignore, 2 == unignore */ 2251 2738 un_ignore = strtol(pair->value, NULL, 10); 2252 if (pair->key == 66) 2739 if (pair->key == 66) 2253 2740 status = strtol(pair->value, NULL, 10); 2254 2741 } 2742 2255 2743 2256 2744 /* 2257 2745 * status 2258 * 2259 * 2260 * 2261 * 2746 * 0 - ok 2747 * 2 - already in ignore list, could not add 2748 * 3 - not in ignore list, could not delete 2749 * 12 - is a buddy, could not add 2262 2750 */ 2263 2751 2264 2752 /* if(status) 2265 2753 YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status); 2266 */ 2267 } 2268 2269 static void yahoo_process_voicechat(struct yahoo_input_data *yid, 2270 struct yahoo_packet *pkt) 2754 */ 2755 } 2756 2757 static void yahoo_process_voicechat(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2271 2758 { 2272 2759 char *who = NULL; … … 2283 2770 me = pair->value; 2284 2771 if (pair->key == 13) 2285 voice_room = pair->value; 2286 if (pair->key == 57) 2287 room = pair->value; 2288 } 2289 2290 NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, 2291 me)); 2772 voice_room=pair->value; 2773 if (pair->key == 57) 2774 room=pair->value; 2775 } 2776 2777 NOTICE(("got voice chat invite from %s in %s to identity %s", who, room, me)); 2292 2778 /* 2293 2779 * send: s:0 1:me 5:who 57:room 13:1 … … 2301 2787 } 2302 2788 2303 static void yahoo_process_ping(struct yahoo_input_data *yid, 2304 struct yahoo_packet *pkt) 2789 static void yahoo_process_ping(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2305 2790 { 2306 2791 char *errormsg = NULL; 2307 2792 2308 2793 YList *l; 2309 2794 for (l = pkt->hash; l; l = l->next) { … … 2312 2797 errormsg = pair->value; 2313 2798 } 2314 2799 2315 2800 NOTICE(("got ping packet")); 2316 YAHOO_CALLBACK(ext_yahoo_got_ping) (yid->yd->client_id, errormsg); 2317 } 2318 2319 static void yahoo_process_buddy_change_group(struct yahoo_input_data *yid, 2320 struct yahoo_packet *pkt) 2321 { 2322 YList *l; 2323 char *me = NULL; 2324 char *who = NULL; 2325 char *old_group = NULL; 2326 char *new_group = NULL; 2327 2328 for (l = pkt->hash; l; l = l->next) { 2329 struct yahoo_pair *pair = l->data; 2330 if (pair->key == 1) 2331 me = pair->value; 2332 if (pair->key == 7) 2333 who = pair->value; 2334 if (pair->key == 224) 2335 old_group = pair->value; 2336 if (pair->key == 264) 2337 new_group = pair->value; 2338 } 2339 2340 YAHOO_CALLBACK(ext_yahoo_got_buddy_change_group) (yid->yd->client_id, 2341 me, who, old_group, new_group); 2342 } 2343 2344 static void _yahoo_webcam_get_server_connected(void *fd, int error, void *d) 2801 YAHOO_CALLBACK(ext_yahoo_got_ping)(yid->yd->client_id, errormsg); 2802 } 2803 2804 static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) 2345 2805 { 2346 2806 struct yahoo_input_data *yid = d; … … 2348 2808 char *data = NULL; 2349 2809 char *packet = NULL; 2350 unsigned char magic_nr[] = { 0, 1, 0};2810 unsigned char magic_nr[] = {0, 1, 0}; 2351 2811 unsigned char header_len = 8; 2352 2812 unsigned int len = 0; 2353 2813 unsigned int pos = 0; 2354 2814 2355 if (error || !fd) {2815 if(error || fd <= 0) { 2356 2816 FREE(who); 2357 2817 FREE(yid); … … 2361 2821 yid->fd = fd; 2362 2822 inputs = y_list_prepend(inputs, yid); 2363 2823 2364 2824 /* send initial packet */ 2365 2825 if (who) … … 2371 2831 2372 2832 /* send data */ 2373 if (who) { 2833 if (who) 2834 { 2374 2835 data = strdup("g="); 2375 2836 data = y_string_append(data, who); … … 2390 2851 FREE(data); 2391 2852 2392 yid->read_tag = 2393 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, 2394 YAHOO_INPUT_READ, yid); 2395 } 2396 2397 static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, 2398 char *key) 2853 yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid); 2854 } 2855 2856 static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who, char *key) 2399 2857 { 2400 2858 struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); … … 2404 2862 yid->yd = y->yd; 2405 2863 yid->wcm = y_new0(struct yahoo_webcam, 1); 2406 yid->wcm->user = who ? strdup(who) :NULL;2407 yid->wcm->direction = who ? YAHOO_WEBCAM_DOWNLOAD :YAHOO_WEBCAM_UPLOAD;2864 yid->wcm->user = who?strdup(who):NULL; 2865 yid->wcm->direction = who?YAHOO_WEBCAM_DOWNLOAD:YAHOO_WEBCAM_UPLOAD; 2408 2866 yid->wcm->key = strdup(key); 2409 2867 2410 YAHOO_CALLBACK(ext_yahoo_connect_async) (yid->yd->client_id, 2411 yss->webcam_host, yss->webcam_port, 2412 _yahoo_webcam_get_server_connected, yid, 0); 2413 2414 } 2415 2416 static YList *webcam_queue = NULL; 2417 static void yahoo_process_webcam_key(struct yahoo_input_data *yid, 2418 struct yahoo_packet *pkt) 2868 YAHOO_CALLBACK(ext_yahoo_connect_async)(yid->yd->client_id, yss->webcam_host, yss->webcam_port, 2869 _yahoo_webcam_get_server_connected, yid); 2870 2871 } 2872 2873 static YList *webcam_queue=NULL; 2874 static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2419 2875 { 2420 2876 char *me = NULL; … … 2423 2879 2424 2880 YList *l; 2425 yahoo_dump_unhandled(pkt);2881 // yahoo_dump_unhandled(pkt); 2426 2882 for (l = pkt->hash; l; l = l->next) { 2427 2883 struct yahoo_pair *pair = l->data; 2428 2884 if (pair->key == 5) 2429 2885 me = pair->value; 2430 if (pair->key == 61) 2431 key =pair->value;2886 if (pair->key == 61) 2887 key=pair->value; 2432 2888 } 2433 2889 2434 2890 l = webcam_queue; 2435 if 2891 if(!l) 2436 2892 return; 2437 2893 who = l->data; … … 2442 2898 } 2443 2899 2444 static void yahoo_packet_process(struct yahoo_input_data *yid, 2445 struct yahoo_packet *pkt) 2900 static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2446 2901 { 2447 2902 DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service)); 2448 switch (pkt->service) { 2903 yahoo_dump_unhandled(pkt); 2904 switch (pkt->service) 2905 { 2449 2906 case YAHOO_SERVICE_USERSTAT: 2450 2907 case YAHOO_SERVICE_LOGON: … … 2457 2914 case YAHOO_SERVICE_IDDEACT: 2458 2915 case YAHOO_SERVICE_Y6_STATUS_UPDATE: 2459 case YAHOO_SERVICE_Y 8_STATUS:2916 case YAHOO_SERVICE_YMSG15_STATUS: 2460 2917 yahoo_process_status(yid, pkt); 2461 2918 break; … … 2471 2928 yahoo_process_mail(yid, pkt); 2472 2929 break; 2473 case YAHOO_SERVICE_Y7_AUTHORIZATION: 2474 yahoo_process_new_contact(yid, pkt); 2475 break; 2930 case YAHOO_SERVICE_REJECTCONTACT: 2476 2931 case YAHOO_SERVICE_NEWCONTACT: 2477 2932 yahoo_process_contact(yid, pkt); … … 2508 2963 break; 2509 2964 case YAHOO_SERVICE_P2PFILEXFER: 2510 case YAHOO_SERVICE_ Y7_FILETRANSFER:2965 case YAHOO_SERVICE_FILETRANSFER: 2511 2966 yahoo_process_filetransfer(yid, pkt); 2512 break;2513 case YAHOO_SERVICE_Y7_FILETRANSFERINFO:2514 yahoo_process_filetransferinfo(yid, pkt);2515 break;2516 case YAHOO_SERVICE_Y7_FILETRANSFERACCEPT:2517 yahoo_process_filetransferaccept(yid, pkt);2518 2967 break; 2519 2968 case YAHOO_SERVICE_ADDBUDDY: 2520 2969 yahoo_process_buddyadd(yid, pkt); 2970 break; 2971 case YAHOO_SERVICE_CONTACT_YMSG13: 2972 yahoo_process_contact_ymsg13(yid,pkt); 2521 2973 break; 2522 2974 case YAHOO_SERVICE_REMBUDDY: … … 2535 2987 yahoo_process_ping(yid, pkt); 2536 2988 break; 2537 case YAHOO_SERVICE_Y7_CHANGE_GROUP:2538 yahoo_process_buddy_change_group(yid, pkt);2539 break;2540 2989 case YAHOO_SERVICE_IDLE: 2541 2990 case YAHOO_SERVICE_MAILSTAT: … … 2551 3000 case YAHOO_SERVICE_CHATLOGOFF: 2552 3001 case YAHOO_SERVICE_CHATMSG: 2553 case YAHOO_SERVICE_REJECTCONTACT:2554 3002 case YAHOO_SERVICE_PEERTOPEER: 2555 3003 WARNING(("unhandled service 0x%02x", pkt->service)); … … 2564 3012 case YAHOO_SERVICE_PICTURE_UPLOAD: 2565 3013 yahoo_process_picture_upload(yid, pkt); 2566 break; 2567 case YAHOO_SERVICE_Y 8_LIST: /* Buddy List */3014 break; 3015 case YAHOO_SERVICE_YMSG15_BUDDY_LIST: /* Buddy List */ 2568 3016 yahoo_process_buddy_list(yid, pkt); 2569 break;2570 3017 default: 2571 3018 WARNING(("unknown service 0x%02x", pkt->service)); … … 2575 3022 } 2576 3023 2577 static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data *yid)3024 static struct yahoo_packet * yahoo_getdata(struct yahoo_input_data * yid) 2578 3025 { 2579 3026 struct yahoo_packet *pkt; … … 2582 3029 int pktlen; 2583 3030 2584 if 3031 if(!yd) 2585 3032 return NULL; 2586 3033 … … 2591 3038 } 2592 3039 2593 pos += 4; 3040 pos += 4; /* YMSG */ 2594 3041 pos += 2; 2595 3042 pos += 2; 2596 3043 2597 pktlen = yahoo_get16(yid->rxqueue + pos); 2598 pos += 2;2599 DEBUG_MSG(("%d bytes to read, rxlen is %d",pktlen, yid->rxlen));3044 pktlen = yahoo_get16(yid->rxqueue + pos); pos += 2; 3045 DEBUG_MSG(("%d bytes to read, rxlen is %d", 3046 pktlen, yid->rxlen)); 2600 3047 2601 3048 if (yid->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) { … … 2609 3056 pkt = yahoo_packet_new(0, 0, 0); 2610 3057 2611 pkt->service = yahoo_get16(yid->rxqueue + pos); 2612 pos += 2; 2613 pkt->status = yahoo_get32(yid->rxqueue + pos); 2614 pos += 4; 3058 pkt->service = yahoo_get16(yid->rxqueue + pos); pos += 2; 3059 pkt->status = yahoo_get32(yid->rxqueue + pos); pos += 4; 2615 3060 DEBUG_MSG(("Yahoo Service: 0x%02x Status: %d", pkt->service, 2616 pkt->status)); 2617 pkt->id = yahoo_get32(yid->rxqueue + pos); 2618 pos += 4; 3061 pkt->status)); 3062 pkt->id = yahoo_get32(yid->rxqueue + pos); pos += 4; 2619 3063 2620 3064 yd->session_id = pkt->id; … … 2624 3068 yid->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; 2625 3069 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2626 if (yid->rxlen >0) {2627 unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN 2628 + pktlen, yid->rxlen);3070 if (yid->rxlen>0) { 3071 unsigned char *tmp = y_memdup(yid->rxqueue + YAHOO_PACKET_HDRLEN 3072 + pktlen, yid->rxlen); 2629 3073 FREE(yid->rxqueue); 2630 3074 yid->rxqueue = tmp; 2631 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, 2632 yid->rxqueue)); 3075 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2633 3076 } else { 2634 3077 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); … … 2639 3082 } 2640 3083 2641 static struct yab *yahoo_yab_read(unsigned char *d, int len)3084 static void yahoo_yab_read(struct yab *yab, unsigned char *d, int len) 2642 3085 { 2643 3086 char *st, *en; 2644 3087 char *data = (char *)d; 3088 data[len]='\0'; 3089 3090 DEBUG_MSG(("Got yab: %s", data)); 3091 st = en = strstr(data, "userid=\""); 3092 if(st) { 3093 st += strlen("userid=\""); 3094 en = strchr(st, '"'); *en++ = '\0'; 3095 yab->id = yahoo_xmldecode(st); 3096 } 3097 3098 st = strstr(en, "fname=\""); 3099 if(st) { 3100 st += strlen("fname=\""); 3101 en = strchr(st, '"'); *en++ = '\0'; 3102 yab->fname = yahoo_xmldecode(st); 3103 } 3104 3105 st = strstr(en, "lname=\""); 3106 if(st) { 3107 st += strlen("lname=\""); 3108 en = strchr(st, '"'); *en++ = '\0'; 3109 yab->lname = yahoo_xmldecode(st); 3110 } 3111 3112 st = strstr(en, "nname=\""); 3113 if(st) { 3114 st += strlen("nname=\""); 3115 en = strchr(st, '"'); *en++ = '\0'; 3116 yab->nname = yahoo_xmldecode(st); 3117 } 3118 3119 st = strstr(en, "email=\""); 3120 if(st) { 3121 st += strlen("email=\""); 3122 en = strchr(st, '"'); *en++ = '\0'; 3123 yab->email = yahoo_xmldecode(st); 3124 } 3125 3126 st = strstr(en, "hphone=\""); 3127 if(st) { 3128 st += strlen("hphone=\""); 3129 en = strchr(st, '"'); *en++ = '\0'; 3130 yab->hphone = yahoo_xmldecode(st); 3131 } 3132 3133 st = strstr(en, "wphone=\""); 3134 if(st) { 3135 st += strlen("wphone=\""); 3136 en = strchr(st, '"'); *en++ = '\0'; 3137 yab->wphone = yahoo_xmldecode(st); 3138 } 3139 3140 st = strstr(en, "mphone=\""); 3141 if(st) { 3142 st += strlen("mphone=\""); 3143 en = strchr(st, '"'); *en++ = '\0'; 3144 yab->mphone = yahoo_xmldecode(st); 3145 } 3146 3147 st = strstr(en, "dbid=\""); 3148 if(st) { 3149 st += strlen("dbid=\""); 3150 en = strchr(st, '"'); *en++ = '\0'; 3151 yab->dbid = atoi(st); 3152 } 3153 } 3154 3155 static struct yab * yahoo_getyab(struct yahoo_input_data *yid) 3156 { 2645 3157 struct yab *yab = NULL; 2646 2647 data[len] = '\0'; 2648 2649 DEBUG_MSG(("Got yab: %s", data)); 2650 st = en = strstr(data, "e0=\""); 2651 if (st) { 2652 yab = y_new0(struct yab, 1); 2653 2654 st += strlen("e0=\""); 2655 en = strchr(st, '"'); 2656 *en++ = '\0'; 2657 yab->email = yahoo_xmldecode(st); 2658 } 2659 2660 if (!en) 3158 int pos = 0, end=0; 3159 struct yahoo_data *yd = yid->yd; 3160 3161 if(!yd) 2661 3162 return NULL; 2662 3163 2663 st = strstr(en, "id=\""); 2664 if (st) { 2665 st += strlen("id=\""); 2666 en = strchr(st, '"'); 2667 *en++ = '\0'; 2668 yab->yid = atoi(yahoo_xmldecode(st)); 2669 } 2670 2671 st = strstr(en, "fn=\""); 2672 if (st) { 2673 st += strlen("fn=\""); 2674 en = strchr(st, '"'); 2675 *en++ = '\0'; 2676 yab->fname = yahoo_xmldecode(st); 2677 } 2678 2679 st = strstr(en, "ln=\""); 2680 if (st) { 2681 st += strlen("ln=\""); 2682 en = strchr(st, '"'); 2683 *en++ = '\0'; 2684 yab->lname = yahoo_xmldecode(st); 2685 } 2686 2687 st = strstr(en, "nn=\""); 2688 if (st) { 2689 st += strlen("nn=\""); 2690 en = strchr(st, '"'); 2691 *en++ = '\0'; 2692 yab->nname = yahoo_xmldecode(st); 2693 } 2694 2695 st = strstr(en, "yi=\""); 2696 if (st) { 2697 st += strlen("yi=\""); 2698 en = strchr(st, '"'); 2699 *en++ = '\0'; 2700 yab->id = yahoo_xmldecode(st); 2701 } 2702 2703 st = strstr(en, "hphone=\""); 2704 if (st) { 2705 st += strlen("hphone=\""); 2706 en = strchr(st, '"'); 2707 *en++ = '\0'; 2708 yab->hphone = yahoo_xmldecode(st); 2709 } 2710 2711 st = strstr(en, "wphone=\""); 2712 if (st) { 2713 st += strlen("wphone=\""); 2714 en = strchr(st, '"'); 2715 *en++ = '\0'; 2716 yab->wphone = yahoo_xmldecode(st); 2717 } 2718 2719 st = strstr(en, "mphone=\""); 2720 if (st) { 2721 st += strlen("mphone=\""); 2722 en = strchr(st, '"'); 2723 *en++ = '\0'; 2724 yab->mphone = yahoo_xmldecode(st); 2725 } 2726 2727 st = strstr(en, "dbid=\""); 2728 if (st) { 2729 st += strlen("dbid=\""); 2730 en = strchr(st, '"'); 2731 *en++ = '\0'; 2732 yab->dbid = atoi(st); 2733 } 3164 DEBUG_MSG(("rxlen is %d", yid->rxlen)); 3165 3166 if(yid->rxlen <= strlen("<record")) 3167 return NULL; 3168 3169 /* start with <record */ 3170 while(pos < yid->rxlen-strlen("<record")+1 3171 && memcmp(yid->rxqueue + pos, "<record", strlen("<record"))) 3172 pos++; 3173 3174 if(pos >= yid->rxlen-1) 3175 return NULL; 3176 3177 end = pos+2; 3178 /* end with /> */ 3179 while(end < yid->rxlen-strlen("/>")+1 && memcmp(yid->rxqueue + end, "/>", strlen("/>"))) 3180 end++; 3181 3182 if(end >= yid->rxlen-1) 3183 return NULL; 3184 3185 yab = y_new0(struct yab, 1); 3186 yahoo_yab_read(yab, yid->rxqueue + pos, end+2-pos); 3187 3188 3189 yid->rxlen -= end+1; 3190 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 3191 if (yid->rxlen>0) { 3192 unsigned char *tmp = y_memdup(yid->rxqueue + end + 1, yid->rxlen); 3193 FREE(yid->rxqueue); 3194 yid->rxqueue = tmp; 3195 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 3196 } else { 3197 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); 3198 FREE(yid->rxqueue); 3199 } 3200 2734 3201 2735 3202 return yab; 2736 3203 } 2737 3204 2738 static struct yab *yahoo_getyab(struct yahoo_input_data *yid) 2739 { 2740 struct yab *yab = NULL; 2741 int pos = 0, end = 0; 3205 static char * yahoo_getwebcam_master(struct yahoo_input_data *yid) 3206 { 3207 unsigned int pos=0; 3208 unsigned int len=0; 3209 unsigned int status=0; 3210 char *server=NULL; 2742 3211 struct yahoo_data *yd = yid->yd; 2743 3212 2744 if (!yd) 2745 return NULL; 2746 2747 do { 2748 DEBUG_MSG(("rxlen is %d", yid->rxlen)); 2749 2750 if (yid->rxlen <= strlen("<ct")) 2751 return NULL; 2752 2753 /* start with <ct */ 2754 while (pos < yid->rxlen - strlen("<ct") + 1 2755 && memcmp(yid->rxqueue + pos, "<ct", strlen("<ct"))) 2756 pos++; 2757 2758 if (pos >= yid->rxlen - 1) 2759 return NULL; 2760 2761 end = pos + 2; 2762 /* end with > */ 2763 while (end < yid->rxlen - strlen(">") 2764 && memcmp(yid->rxqueue + end, ">", strlen(">"))) 2765 end++; 2766 2767 if (end >= yid->rxlen - 1) 2768 return NULL; 2769 2770 yab = yahoo_yab_read(yid->rxqueue + pos, end + 2 - pos); 2771 2772 yid->rxlen -= end + 1; 2773 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, 2774 yid->rxqueue)); 2775 if (yid->rxlen > 0) { 2776 unsigned char *tmp = 2777 y_memdup(yid->rxqueue + end + 1, yid->rxlen); 2778 FREE(yid->rxqueue); 2779 yid->rxqueue = tmp; 2780 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, 2781 yid->rxqueue)); 2782 } else { 2783 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); 2784 FREE(yid->rxqueue); 2785 } 2786 2787 } while (!yab && end < yid->rxlen - 1); 2788 2789 return yab; 2790 } 2791 2792 static char *yahoo_getwebcam_master(struct yahoo_input_data *yid) 2793 { 2794 unsigned int pos = 0; 2795 unsigned int len = 0; 2796 unsigned int status = 0; 2797 char *server = NULL; 2798 struct yahoo_data *yd = yid->yd; 2799 2800 if (!yid || !yd) 3213 if(!yid || !yd) 2801 3214 return NULL; 2802 3215 … … 2810 3223 status = yid->rxqueue[pos++]; 2811 3224 2812 if (status == 0) { 2813 pos += 2; /* skip next 2 bytes */ 2814 server = y_memdup(yid->rxqueue + pos, 16); 3225 if (status == 0) 3226 { 3227 pos += 2; /* skip next 2 bytes */ 3228 server = y_memdup(yid->rxqueue+pos, 16); 2815 3229 pos += 16; 2816 } else if (status == 6) { 3230 } 3231 else if (status == 6) 3232 { 2817 3233 YAHOO_CALLBACK(ext_yahoo_webcam_closed) 2818 3234 (yd->client_id, yid->wcm->user, 4); … … 2823 3239 yid->rxlen -= len; 2824 3240 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2825 if (yid->rxlen >0) {3241 if (yid->rxlen>0) { 2826 3242 unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen); 2827 3243 FREE(yid->rxqueue); 2828 3244 yid->rxqueue = tmp; 2829 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, 2830 yid->rxqueue)); 3245 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2831 3246 } else { 2832 3247 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); … … 2839 3254 static int yahoo_get_webcam_data(struct yahoo_input_data *yid) 2840 3255 { 2841 unsigned char reason =0;2842 unsigned int pos =0;2843 unsigned int begin =0;2844 unsigned int end =0;2845 unsigned int closed =0;2846 unsigned char header_len =0;3256 unsigned char reason=0; 3257 unsigned int pos=0; 3258 unsigned int begin=0; 3259 unsigned int end=0; 3260 unsigned int closed=0; 3261 unsigned char header_len=0; 2847 3262 char *who; 2848 int connect =0;3263 int connect=0; 2849 3264 struct yahoo_data *yd = yid->yd; 2850 3265 2851 if 3266 if(!yd) 2852 3267 return -1; 2853 3268 2854 if 3269 if(!yid->wcm || !yid->wcd || !yid->rxlen) 2855 3270 return -1; 2856 3271 … … 2858 3273 2859 3274 /* if we are not reading part of image then read header */ 2860 if (!yid->wcd->to_read) { 2861 header_len = yid->rxqueue[pos++]; 2862 yid->wcd->packet_type = 0; 3275 if (!yid->wcd->to_read) 3276 { 3277 header_len=yid->rxqueue[pos++]; 3278 yid->wcd->packet_type=0; 2863 3279 2864 3280 if (yid->rxlen < header_len) 2865 3281 return 0; 2866 3282 2867 if (header_len >= 8) { 3283 if (header_len >= 8) 3284 { 2868 3285 reason = yid->rxqueue[pos++]; 2869 3286 /* next 2 bytes should always be 05 00 */ … … 2873 3290 yid->wcd->to_read = yid->wcd->data_size; 2874 3291 } 2875 if (header_len >= 13) { 3292 if (header_len >= 13) 3293 { 2876 3294 yid->wcd->packet_type = yid->rxqueue[pos++]; 2877 3295 yid->wcd->timestamp = yahoo_get32(yid->rxqueue + pos); … … 2885 3303 begin = pos; 2886 3304 pos += yid->wcd->to_read; 2887 if (pos > yid->rxlen) 2888 pos = yid->rxlen; 3305 if (pos > yid->rxlen) pos = yid->rxlen; 2889 3306 2890 3307 /* if it is not an image then make sure we have the whole packet */ … … 2899 3316 2900 3317 DEBUG_MSG(("packet type %.2X, data length %d", yid->wcd->packet_type, 2901 3318 yid->wcd->data_size)); 2902 3319 2903 3320 /* find out what kind of packet we got */ 2904 switch (yid->wcd->packet_type) { 2905 case 0x00: 2906 /* user requests to view webcam (uploading) */ 2907 if (yid->wcd->data_size && 2908 yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { 2909 end = begin; 2910 while (end <= yid->rxlen && yid->rxqueue[end++] != 13) ; 2911 if (end > begin) { 2912 who = y_memdup(yid->rxqueue + begin, 2913 end - begin); 2914 who[end - begin - 1] = 0; 2915 YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd-> 2916 client_id, who + 2, 2); 3321 switch (yid->wcd->packet_type) 3322 { 3323 case 0x00: 3324 /* user requests to view webcam (uploading) */ 3325 if (yid->wcd->data_size && 3326 yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { 3327 end = begin; 3328 while (end <= yid->rxlen && 3329 yid->rxqueue[end++] != 13); 3330 if (end > begin) 3331 { 3332 who = y_memdup(yid->rxqueue + begin, end - begin); 3333 who[end - begin - 1] = 0; 3334 YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who + 2, 2); 3335 FREE(who); 3336 } 3337 } 3338 3339 if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { 3340 /* timestamp/status field */ 3341 /* 0 = declined viewing permission */ 3342 /* 1 = accepted viewing permission */ 3343 if (yid->wcd->timestamp == 0) { 3344 YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, 3); 3345 } 3346 } 3347 break; 3348 case 0x01: /* status packets?? */ 3349 /* timestamp contains status info */ 3350 /* 00 00 00 01 = we have data?? */ 3351 break; 3352 case 0x02: /* image data */ 3353 YAHOO_CALLBACK(ext_yahoo_got_webcam_image)(yd->client_id, 3354 yid->wcm->user, yid->rxqueue + begin, 3355 yid->wcd->data_size, pos - begin, 3356 yid->wcd->timestamp); 3357 break; 3358 case 0x05: /* response packets when uploading */ 3359 if (!yid->wcd->data_size) { 3360 YAHOO_CALLBACK(ext_yahoo_webcam_data_request)(yd->client_id, yid->wcd->timestamp); 3361 } 3362 break; 3363 case 0x07: /* connection is closing */ 3364 switch(reason) 3365 { 3366 case 0x01: /* user closed connection */ 3367 closed = 1; 3368 break; 3369 case 0x0F: /* user cancelled permission */ 3370 closed = 2; 3371 break; 3372 } 3373 YAHOO_CALLBACK(ext_yahoo_webcam_closed)(yd->client_id, yid->wcm->user, closed); 3374 break; 3375 case 0x0C: /* user connected */ 3376 case 0x0D: /* user disconnected */ 3377 if (yid->wcd->data_size) { 3378 who = y_memdup(yid->rxqueue + begin, pos - begin + 1); 3379 who[pos - begin] = 0; 3380 if (yid->wcd->packet_type == 0x0C) 3381 connect=1; 3382 else 3383 connect=0; 3384 YAHOO_CALLBACK(ext_yahoo_webcam_viewer)(yd->client_id, who, connect); 2917 3385 FREE(who); 2918 3386 } 2919 } 2920 2921 if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { 2922 /* timestamp/status field */ 2923 /* 0 = declined viewing permission */ 2924 /* 1 = accepted viewing permission */ 2925 if (yid->wcd->timestamp == 0) { 2926 YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd-> 2927 client_id, yid->wcm->user, 3); 2928 } 2929 } 2930 break; 2931 case 0x01: /* status packets?? */ 2932 /* timestamp contains status info */ 2933 /* 00 00 00 01 = we have data?? */ 2934 break; 2935 case 0x02: /* image data */ 2936 YAHOO_CALLBACK(ext_yahoo_got_webcam_image) (yd->client_id, 2937 yid->wcm->user, yid->rxqueue + begin, 2938 yid->wcd->data_size, pos - begin, yid->wcd->timestamp); 2939 break; 2940 case 0x05: /* response packets when uploading */ 2941 if (!yid->wcd->data_size) { 2942 YAHOO_CALLBACK(ext_yahoo_webcam_data_request) (yd-> 2943 client_id, yid->wcd->timestamp); 2944 } 2945 break; 2946 case 0x07: /* connection is closing */ 2947 switch (reason) { 2948 case 0x01: /* user closed connection */ 2949 closed = 1; 2950 break; 2951 case 0x0F: /* user cancelled permission */ 2952 closed = 2; 2953 break; 2954 } 2955 YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, 2956 yid->wcm->user, closed); 2957 break; 2958 case 0x0C: /* user connected */ 2959 case 0x0D: /* user disconnected */ 2960 if (yid->wcd->data_size) { 2961 who = y_memdup(yid->rxqueue + begin, pos - begin + 1); 2962 who[pos - begin] = 0; 2963 if (yid->wcd->packet_type == 0x0C) 2964 connect = 1; 2965 else 2966 connect = 0; 2967 YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id, 2968 who, connect); 2969 FREE(who); 2970 } 2971 break; 2972 case 0x13: /* user data */ 2973 /* i=user_ip (ip of the user we are viewing) */ 2974 /* j=user_ext_ip (external ip of the user we */ 2975 /* are viewing) */ 2976 break; 2977 case 0x17: /* ?? */ 2978 break; 3387 break; 3388 case 0x13: /* user data */ 3389 /* i=user_ip (ip of the user we are viewing) */ 3390 /* j=user_ext_ip (external ip of the user we */ 3391 /* are viewing) */ 3392 break; 3393 case 0x17: /* ?? */ 3394 break; 2979 3395 } 2980 3396 yid->wcd->to_read -= pos - begin; … … 2982 3398 yid->rxlen -= pos; 2983 3399 DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2984 if (yid->rxlen >0) {3400 if (yid->rxlen>0) { 2985 3401 unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen); 2986 3402 FREE(yid->rxqueue); 2987 3403 yid->rxqueue = tmp; 2988 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, 2989 yid->rxqueue)); 3404 DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); 2990 3405 } else { 2991 3406 DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue)); … … 3000 3415 } 3001 3416 3002 int yahoo_write_ready(int id, void *fd, void *data)3417 int yahoo_write_ready(int id, int fd, void *data) 3003 3418 { 3004 3419 struct yahoo_input_data *yid = data; … … 3006 3421 struct data_queue *tx; 3007 3422 3008 LOG(("write callback: id=%d fd=% pdata=%p", id, fd, data));3009 if (!yid || !yid->txqueues)3423 LOG(("write callback: id=%d fd=%d data=%p", id, fd, data)); 3424 if(!yid || !yid->txqueues || !find_conn_by_id(id)) 3010 3425 return -2; 3011 3426 3012 3427 tx = yid->txqueues->data; 3013 3428 LOG(("writing %d bytes", tx->len)); 3014 3429 len = yahoo_send_data(fd, tx->queue, MIN(1024, tx->len)); 3015 3430 3016 if 3431 if(len == -1 && errno == EAGAIN) 3017 3432 return 1; 3018 3433 3019 if 3434 if(len <= 0) { 3020 3435 int e = errno; 3021 3436 DEBUG_MSG(("len == %d (<= 0)", len)); 3022 while 3023 YList *l =yid->txqueues;3437 while(yid->txqueues) { 3438 YList *l=yid->txqueues; 3024 3439 tx = l->data; 3025 3440 free(tx->queue); 3026 3441 free(tx); 3027 yid->txqueues = 3028 y_list_remove_link(yid->txqueues, 3029 yid->txqueues); 3442 yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); 3030 3443 y_list_free_1(l); 3031 3444 } 3032 LOG(("yahoo_write_ready(%d, % p) len < 0", id, fd));3033 YAHOO_CALLBACK(ext_yahoo_remove_handler) 3445 LOG(("yahoo_write_ready(%d, %d) len < 0", id, fd)); 3446 YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag); 3034 3447 yid->write_tag = 0; 3035 errno =e;3448 errno=e; 3036 3449 return 0; 3037 3450 } … … 3039 3452 3040 3453 tx->len -= len; 3041 if 3454 if(tx->len > 0) { 3042 3455 unsigned char *tmp = y_memdup(tx->queue + len, tx->len); 3043 3456 FREE(tx->queue); 3044 3457 tx->queue = tmp; 3045 3458 } else { 3046 YList *l =yid->txqueues;3459 YList *l=yid->txqueues; 3047 3460 free(tx->queue); 3048 3461 free(tx); 3049 yid->txqueues = 3050 y_list_remove_link(yid->txqueues, yid->txqueues); 3462 yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); 3051 3463 y_list_free_1(l); 3052 3464 /* 3053 if(!yid->txqueues) 3054 LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); 3055 */ 3056 if (!yid->txqueues) { 3057 LOG(("yahoo_write_ready(%d, %p) !txqueues", id, fd)); 3058 YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, 3059 yid->write_tag); 3465 if(!yid->txqueues) 3466 LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); 3467 */ 3468 if(!yid->txqueues) { 3469 LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); 3470 YAHOO_CALLBACK(ext_yahoo_remove_handler)(id, yid->write_tag); 3060 3471 yid->write_tag = 0; 3061 3472 } … … 3065 3476 } 3066 3477 3067 static void yahoo_process_pager_connection(struct yahoo_input_data *yid, 3068 int over) 3478 static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int over) 3069 3479 { 3070 3480 struct yahoo_packet *pkt; … … 3072 3482 int id = yd->client_id; 3073 3483 3074 if 3075 return; 3076 3077 while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) 3078 && (pkt = yahoo_getdata(yid)) != NULL) {3484 if(over) 3485 return; 3486 3487 while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) 3488 && (pkt = yahoo_getdata(yid)) != NULL) { 3079 3489 3080 3490 yahoo_packet_process(yid, pkt); … … 3084 3494 } 3085 3495 3086 static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, 3087 int over) 3088 { 3089 if (over) 3090 return; 3091 3092 if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) { 3093 YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id, 3094 (char *)yid->rxqueue); 3496 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) 3497 { 3498 } 3499 3500 static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over) 3501 { 3502 if(over) 3503 return; 3504 3505 if (strstr((char*)yid->rxqueue+(yid->rxlen-20), "</content>")) { 3506 YAHOO_CALLBACK(ext_yahoo_chat_cat_xml)(yid->yd->client_id, (char*)yid->rxqueue); 3095 3507 } 3096 3508 } … … 3101 3513 struct yab *yab; 3102 3514 YList *buds; 3103 int changed =0;3515 int changed=0; 3104 3516 int id = yd->client_id; 3105 int yab_used = 0; 3106 3107 LOG(("Got data for YAB")); 3108 3109 if (over) 3110 return; 3111 3112 while (find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB) 3113 && (yab = yahoo_getyab(yid)) != NULL) { 3114 if (!yab->id) 3517 3518 if(over) 3519 return; 3520 3521 while(find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB) 3522 && (yab = yahoo_getyab(yid)) != NULL) { 3523 if(!yab->id) 3115 3524 continue; 3116 3117 changed = 1; 3118 yab_used = 0; 3119 for (buds = yd->buddies; buds; buds = buds->next) { 3120 struct yahoo_buddy *bud = buds->data; 3121 if (!strcmp(bud->id, yab->id)) { 3122 yab_used = 1; 3525 changed=1; 3526 for(buds = yd->buddies; buds; buds=buds->next) { 3527 struct yahoo_buddy * bud = buds->data; 3528 if(!strcmp(bud->id, yab->id)) { 3123 3529 bud->yab_entry = yab; 3124 if 3530 if(yab->nname) { 3125 3531 bud->real_name = strdup(yab->nname); 3126 } else if (yab->fname && yab->lname) { 3127 bud->real_name = y_new0(char, 3128 strlen(yab->fname) + 3129 strlen(yab->lname) + 2); 3532 } else if(yab->fname && yab->lname) { 3533 bud->real_name = y_new0(char, 3534 strlen(yab->fname)+ 3535 strlen(yab->lname)+2 3536 ); 3130 3537 sprintf(bud->real_name, "%s %s", 3131 yab->fname, yab->lname);3132 } else if 3538 yab->fname, yab->lname); 3539 } else if(yab->fname) { 3133 3540 bud->real_name = strdup(yab->fname); 3134 3541 } 3135 break; 3542 break; /* for */ 3136 3543 } 3137 3544 } 3138 3139 if (!yab_used) { 3140 FREE(yab->fname); 3141 FREE(yab->lname); 3142 FREE(yab->nname); 3143 FREE(yab->id); 3144 FREE(yab->email); 3145 FREE(yab->hphone); 3146 FREE(yab->wphone); 3147 FREE(yab->mphone); 3148 FREE(yab); 3149 } 3150 3151 } 3152 3153 if (changed) 3154 YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, 3155 yd->buddies); 3156 } 3157 3158 static void yahoo_process_search_connection(struct yahoo_input_data *yid, 3159 int over) 3160 { 3161 struct yahoo_found_contact *yct = NULL; 3545 } 3546 3547 if(changed) 3548 YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); 3549 } 3550 3551 static void yahoo_process_search_connection(struct yahoo_input_data *yid, int over) 3552 { 3553 struct yahoo_found_contact *yct=NULL; 3162 3554 char *p = (char *)yid->rxqueue, *np, *cp; 3163 3555 int k, n; 3164 int start = 0, found = 0, total = 0; 3165 YList *contacts = NULL; 3166 struct yahoo_input_data *pyid = 3167 find_input_by_id_and_type(yid->yd->client_id, 3168 YAHOO_CONNECTION_PAGER); 3169 3170 if (!over || !pyid) 3171 return; 3172 3173 if (p && (p = strstr(p, "\r\n\r\n"))) { 3556 int start=0, found=0, total=0; 3557 YList *contacts=NULL; 3558 struct yahoo_input_data *pyid = find_input_by_id_and_type(yid->yd->client_id, YAHOO_CONNECTION_PAGER); 3559 3560 if(!over || !pyid) 3561 return; 3562 3563 if(p && (p=strstr(p, "\r\n\r\n"))) { 3174 3564 p += 4; 3175 3565 3176 for 3566 for(k = 0; (p = strchr(p, 4)) && (k < 4); k++) { 3177 3567 p++; 3178 3568 n = atoi(p); 3179 switch (k) { 3180 case 0: 3181 found = pyid->ys->lsearch_nfound = n; 3182 break; 3183 case 2: 3184 start = pyid->ys->lsearch_nstart = n; 3185 break; 3186 case 3: 3187 total = pyid->ys->lsearch_ntotal = n; 3188 break; 3569 switch(k) { 3570 case 0: found = pyid->ys->lsearch_nfound = n; break; 3571 case 2: start = pyid->ys->lsearch_nstart = n; break; 3572 case 3: total = pyid->ys->lsearch_ntotal = n; break; 3189 3573 } 3190 3574 } 3191 3575 3192 if 3576 if(p) 3193 3577 p++; 3194 3578 3195 k =0;3196 while 3579 k=0; 3580 while(p && *p) { 3197 3581 cp = p; 3198 3582 np = strchr(p, 4); 3199 3583 3200 if 3584 if(!np) 3201 3585 break; 3202 3586 *np = 0; 3203 p = np + 1; 3204 3205 switch (k++) { 3206 case 1: 3207 if (strlen(cp) > 2 3208 && y_list_length(contacts) < total) { 3209 yct = y_new0(struct yahoo_found_contact, 3210 1); 3211 contacts = y_list_append(contacts, yct); 3212 yct->id = cp + 2; 3213 } else { 3214 *p = 0; 3215 } 3216 break; 3217 case 2: 3218 yct->online = !strcmp(cp, "2") ? 1 : 0; 3219 break; 3220 case 3: 3221 yct->gender = cp; 3222 break; 3223 case 4: 3224 yct->age = atoi(cp); 3225 break; 3226 case 5: 3227 /* not worth the context switch for strcmp */ 3228 if (cp[0] != '\005' || cp[1] != '\000') 3229 yct->location = cp; 3230 k = 0; 3231 break; 3587 p = np+1; 3588 3589 switch(k++) { 3590 case 1: 3591 if(strlen(cp) > 2 && y_list_length(contacts) < total) { 3592 yct = y_new0(struct yahoo_found_contact, 1); 3593 contacts = y_list_append(contacts, yct); 3594 yct->id = cp+2; 3595 } else { 3596 *p = 0; 3597 } 3598 break; 3599 case 2: 3600 yct->online = !strcmp(cp, "2") ? 1 : 0; 3601 break; 3602 case 3: 3603 yct->gender = cp; 3604 break; 3605 case 4: 3606 yct->age = atoi(cp); 3607 break; 3608 case 5: 3609 if(strcmp(cp, "5") != 0) 3610 yct->location = cp; 3611 k = 0; 3612 break; 3232 3613 } 3233 3614 } 3234 3615 } 3235 3616 3236 YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found, 3237 start, total, contacts); 3238 3239 while (contacts) { 3617 YAHOO_CALLBACK(ext_yahoo_got_search_result)(yid->yd->client_id, found, start, total, contacts); 3618 3619 while(contacts) { 3240 3620 YList *node = contacts; 3241 3621 contacts = y_list_remove_link(contacts, node); … … 3245 3625 } 3246 3626 3247 static void _yahoo_webcam_connected( void *fd, int error, void *d)3627 static void _yahoo_webcam_connected(int fd, int error, void *d) 3248 3628 { 3249 3629 struct yahoo_input_data *yid = d; … … 3251 3631 struct yahoo_data *yd = yid->yd; 3252 3632 char conn_type[100]; 3253 char *data =NULL;3254 char *packet =NULL;3255 unsigned char magic_nr[] = { 1, 0, 0, 0, 1};3256 unsigned header_len =0;3257 unsigned int len =0;3258 unsigned int pos =0;3259 3260 if (error || !fd) {3633 char *data=NULL; 3634 char *packet=NULL; 3635 unsigned char magic_nr[] = {1, 0, 0, 0, 1}; 3636 unsigned header_len=0; 3637 unsigned int len=0; 3638 unsigned int pos=0; 3639 3640 if(error || fd <= 0) { 3261 3641 FREE(yid); 3262 3642 return; … … 3268 3648 LOG(("Connected")); 3269 3649 /* send initial packet */ 3270 switch (wcm->direction) { 3271 case YAHOO_WEBCAM_DOWNLOAD: 3272 data = strdup("<REQIMG>"); 3273 break; 3274 case YAHOO_WEBCAM_UPLOAD: 3275 data = strdup("<SNDIMG>"); 3276 break; 3277 default: 3278 return; 3650 switch (wcm->direction) 3651 { 3652 case YAHOO_WEBCAM_DOWNLOAD: 3653 data = strdup("<REQIMG>"); 3654 break; 3655 case YAHOO_WEBCAM_UPLOAD: 3656 data = strdup("<SNDIMG>"); 3657 break; 3658 default: 3659 return; 3279 3660 } 3280 3661 yahoo_add_to_send_queue(yid, data, strlen(data)); … … 3282 3663 3283 3664 /* send data */ 3284 switch (wcm->direction) { 3285 case YAHOO_WEBCAM_DOWNLOAD: 3286 header_len = 8; 3287 data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); 3288 data = y_string_append(data, yd->user); 3289 data = y_string_append(data, "\r\nt="); 3290 data = y_string_append(data, wcm->key); 3291 data = y_string_append(data, "\r\ni="); 3292 data = y_string_append(data, wcm->my_ip); 3293 data = y_string_append(data, "\r\ng="); 3294 data = y_string_append(data, wcm->user); 3295 data = y_string_append(data, "\r\no=w-2-5-1\r\np="); 3296 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); 3297 data = y_string_append(data, conn_type); 3298 data = y_string_append(data, "\r\n"); 3299 break; 3300 case YAHOO_WEBCAM_UPLOAD: 3301 header_len = 13; 3302 data = strdup("a=2\r\nc=us\r\nu="); 3303 data = y_string_append(data, yd->user); 3304 data = y_string_append(data, "\r\nt="); 3305 data = y_string_append(data, wcm->key); 3306 data = y_string_append(data, "\r\ni="); 3307 data = y_string_append(data, wcm->my_ip); 3308 data = y_string_append(data, "\r\no=w-2-5-1\r\np="); 3309 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); 3310 data = y_string_append(data, conn_type); 3311 data = y_string_append(data, "\r\nb="); 3312 data = y_string_append(data, wcm->description); 3313 data = y_string_append(data, "\r\n"); 3314 break; 3665 switch (wcm->direction) 3666 { 3667 case YAHOO_WEBCAM_DOWNLOAD: 3668 header_len = 8; 3669 data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); 3670 data = y_string_append(data, yd->user); 3671 data = y_string_append(data, "\r\nt="); 3672 data = y_string_append(data, wcm->key); 3673 data = y_string_append(data, "\r\ni="); 3674 data = y_string_append(data, wcm->my_ip); 3675 data = y_string_append(data, "\r\ng="); 3676 data = y_string_append(data, wcm->user); 3677 data = y_string_append(data, "\r\no=w-2-5-1\r\np="); 3678 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); 3679 data = y_string_append(data, conn_type); 3680 data = y_string_append(data, "\r\n"); 3681 break; 3682 case YAHOO_WEBCAM_UPLOAD: 3683 header_len = 13; 3684 data = strdup("a=2\r\nc=us\r\nu="); 3685 data = y_string_append(data, yd->user); 3686 data = y_string_append(data, "\r\nt="); 3687 data = y_string_append(data, wcm->key); 3688 data = y_string_append(data, "\r\ni="); 3689 data = y_string_append(data, wcm->my_ip); 3690 data = y_string_append(data, "\r\no=w-2-5-1\r\np="); 3691 snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); 3692 data = y_string_append(data, conn_type); 3693 data = y_string_append(data, "\r\nb="); 3694 data = y_string_append(data, wcm->description); 3695 data = y_string_append(data, "\r\n"); 3696 break; 3315 3697 } 3316 3698 … … 3319 3701 packet[pos++] = header_len; 3320 3702 packet[pos++] = 0; 3321 switch (wcm->direction) { 3322 case YAHOO_WEBCAM_DOWNLOAD: 3323 packet[pos++] = 1; 3324 packet[pos++] = 0; 3325 break; 3326 case YAHOO_WEBCAM_UPLOAD: 3327 packet[pos++] = 5; 3328 packet[pos++] = 0; 3329 break; 3703 switch (wcm->direction) 3704 { 3705 case YAHOO_WEBCAM_DOWNLOAD: 3706 packet[pos++] = 1; 3707 packet[pos++] = 0; 3708 break; 3709 case YAHOO_WEBCAM_UPLOAD: 3710 packet[pos++] = 5; 3711 packet[pos++] = 0; 3712 break; 3330 3713 } 3331 3714 3332 3715 pos += yahoo_put32(packet + pos, len); 3333 if (wcm->direction == YAHOO_WEBCAM_UPLOAD) { 3716 if (wcm->direction == YAHOO_WEBCAM_UPLOAD) 3717 { 3334 3718 memcpy(packet + pos, magic_nr, sizeof(magic_nr)); 3335 3719 pos += sizeof(magic_nr); … … 3340 3724 FREE(data); 3341 3725 3342 yid->read_tag = 3343 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, 3344 yid->fd, YAHOO_INPUT_READ, yid); 3726 yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); 3345 3727 } 3346 3728 … … 3367 3749 3368 3750 LOG(("Connecting to: %s:%d", wcm->server, wcm->port)); 3369 YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server, 3370 wcm->port, _yahoo_webcam_connected, yid, 0); 3371 3372 } 3373 3374 static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, 3375 int over) 3376 { 3377 char *server; 3751 YAHOO_CALLBACK(ext_yahoo_connect_async)(y->yd->client_id, wcm->server, wcm->port, 3752 _yahoo_webcam_connected, yid); 3753 3754 } 3755 3756 static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, int over) 3757 { 3758 char* server; 3378 3759 struct yahoo_server_settings *yss; 3379 3760 3380 if 3761 if(over) 3381 3762 return; 3382 3763 3383 3764 server = yahoo_getwebcam_master(yid); 3384 3765 3385 if (server) { 3766 if (server) 3767 { 3386 3768 yss = yid->yd->server_settings; 3387 3769 yid->wcm->server = strdup(server); … … 3396 3778 } 3397 3779 3398 static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, 3399 int over) 3780 static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int over) 3400 3781 { 3401 3782 int id = yid->yd->client_id; 3402 void *fd = yid->fd;3403 3404 if 3783 int fd = yid->fd; 3784 3785 if(over) 3405 3786 return; 3406 3787 3407 3788 /* as long as we still have packets available keep processing them */ 3408 while (find_input_by_id_and_fd(id, fd) 3409 && yahoo_get_webcam_data(yid) == 1) ; 3410 } 3411 3412 static void (*yahoo_process_connection[]) (struct yahoo_input_data *, 3413 int over) = { 3414 yahoo_process_pager_connection, yahoo_process_ft_connection, 3415 yahoo_process_yab_connection, 3416 yahoo_process_webcam_master_connection, 3417 yahoo_process_webcam_connection, 3418 yahoo_process_chatcat_connection, 3419 yahoo_process_search_connection}; 3420 3421 int yahoo_read_ready(int id, void *fd, void *data) 3789 while (find_input_by_id_and_fd(id, fd) 3790 && yahoo_get_webcam_data(yid) == 1); 3791 } 3792 3793 static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { 3794 yahoo_process_pager_connection, 3795 yahoo_process_ft_connection, 3796 yahoo_process_yab_connection, 3797 yahoo_process_webcam_master_connection, 3798 yahoo_process_webcam_connection, 3799 yahoo_process_chatcat_connection, 3800 yahoo_process_search_connection, 3801 }; 3802 3803 int yahoo_read_ready(int id, int fd, void *data) 3422 3804 { 3423 3805 struct yahoo_input_data *yid = data; … … 3425 3807 int len; 3426 3808 3427 LOG(("read callback: id=%d fd=% pdata=%p", id, fd, data));3428 if 3809 LOG(("read callback: id=%d fd=%d data=%p", id, fd, data)); 3810 if(!yid) 3429 3811 return -2; 3430 3812 3813 3431 3814 do { 3432 len = YAHOO_CALLBACK(ext_yahoo_read)(fd, buf, sizeof(buf));3433 } while 3434 3435 if (len == -1 && (errno == EAGAIN ||errno == EINTR)) /* we'll try again later */3815 len = read(fd, buf, sizeof(buf)); 3816 } while(len == -1 && errno == EINTR); 3817 3818 if(len == -1 && (errno == EAGAIN||errno == EINTR)) /* we'll try again later */ 3436 3819 return 1; 3437 3820 … … 3440 3823 DEBUG_MSG(("len == %d (<= 0)", len)); 3441 3824 3442 if (yid->type == YAHOO_CONNECTION_PAGER) { 3443 YAHOO_CALLBACK(ext_yahoo_login_response) (yid->yd-> 3444 client_id, YAHOO_LOGIN_SOCK, NULL); 3445 } 3446 3447 yahoo_process_connection[yid->type] (yid, 1); 3825 if(yid->type == YAHOO_CONNECTION_PAGER) { 3826 YAHOO_CALLBACK(ext_yahoo_error)(yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION); 3827 } 3828 3829 yahoo_process_connection[yid->type](yid, 1); 3448 3830 yahoo_input_close(yid); 3449 3831 3450 3832 /* no need to return an error, because we've already fixed it */ 3451 if 3833 if(len == 0) 3452 3834 return 1; 3453 3835 3454 errno =e;3836 errno=e; 3455 3837 LOG(("read error: %s", strerror(errno))); 3456 3838 return -1; 3457 3839 } 3458 3840 3459 yid->rxqueue = 3460 y_renew(unsigned char, yid->rxqueue, len + yid->rxlen + 1); 3841 yid->rxqueue = y_renew(unsigned char, yid->rxqueue, len + yid->rxlen); 3461 3842 memcpy(yid->rxqueue + yid->rxlen, buf, len); 3462 3843 yid->rxlen += len; 3463 yid->rxqueue[yid->rxlen] = 0; 3464 3465 yahoo_process_connection[yid->type] (yid, 0); 3844 3845 yahoo_process_connection[yid->type](yid, 0); 3466 3846 3467 3847 return len; … … 3475 3855 yd = y_new0(struct yahoo_data, 1); 3476 3856 3477 if 3857 if(!yd) 3478 3858 return 0; 3479 3859 … … 3500 3880 } 3501 3881 3502 static void yahoo_connected(void *fd, int error, void *data) 3882 struct connect_callback_data { 3883 struct yahoo_data *yd; 3884 int tag; 3885 int i; 3886 }; 3887 3888 static void yahoo_connected(int fd, int error, void *data) 3503 3889 { 3504 3890 struct connect_callback_data *ccd = data; … … 3508 3894 struct yahoo_server_settings *yss = yd->server_settings; 3509 3895 3510 if (error) { 3511 int tag; 3512 if (fallback_ports[ccd->i]) { 3513 char *host = yss->pager_host; 3514 3515 if (!host) 3516 host = yss->pager_host_list[ccd->server_i]; 3517 3896 if(error) { 3897 if(fallback_ports[ccd->i]) { 3898 int tag; 3518 3899 yss->pager_port = fallback_ports[ccd->i++]; 3519 tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd-> 3520 client_id, host, yss->pager_port, 3521 yahoo_connected, ccd, 0); 3522 3523 if (tag > 0) 3524 ccd->tag = tag; 3525 } else if (yss->pager_host_list 3526 && yss->pager_host_list[ccd->server_i]) { 3527 3528 /* Get back to the default port */ 3529 yss->pager_port = pager_port; 3530 ccd->server_i++; 3531 LOG(("Fallback: Connecting to %s:%d", yss->pager_host_list[ccd->server_i], yss->pager_port)); 3532 3533 ccd->i = 0; 3534 tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, 3535 yss->pager_host_list[ccd->server_i], yss->pager_port, 3536 yahoo_connected, ccd, 0); 3900 tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host, 3901 yss->pager_port, yahoo_connected, ccd); 3902 3903 if(tag > 0) 3904 ccd->tag=tag; 3537 3905 } else { 3538 3906 FREE(ccd); 3539 YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, 3540 YAHOO_LOGIN_SOCK, NULL); 3907 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL); 3541 3908 } 3542 3909 return; … … 3545 3912 FREE(ccd); 3546 3913 3547 /* fd == NULL && error == 0 means connect was cancelled */ 3548 if (!fd) 3549 return; 3550 3551 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT, 3552 yd->session_id); 3914 /* fd < 0 && error == 0 means connect was cancelled */ 3915 if(fd < 0) 3916 return; 3917 3918 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id); 3553 3919 NOTICE(("Sending initial packet")); 3554 3920 3555 3921 yahoo_packet_hash(pkt, 1, yd->user); 3556 3922 3557 yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); 3923 yid = y_new0(struct yahoo_input_data, 1); 3924 yid->yd = yd; 3558 3925 yid->fd = fd; 3926 inputs = y_list_prepend(inputs, yid); 3559 3927 3560 3928 yahoo_send_packet(yid, pkt, 0); … … 3562 3930 yahoo_packet_free(pkt); 3563 3931 3564 yid->read_tag = 3565 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, 3566 yid->fd, YAHOO_INPUT_READ, yid); 3567 } 3568 3569 void *yahoo_get_fd(int id) 3570 { 3571 struct yahoo_input_data *yid = 3572 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3573 if (!yid) 3932 yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); 3933 } 3934 3935 void yahoo_login(int id, int initial) 3936 { 3937 struct yahoo_data *yd = find_conn_by_id(id); 3938 struct connect_callback_data *ccd; 3939 struct yahoo_server_settings *yss; 3940 int tag; 3941 3942 if(!yd) 3943 return; 3944 3945 yss = yd->server_settings; 3946 3947 yd->initial_status = initial; 3948 3949 ccd = y_new0(struct connect_callback_data, 1); 3950 ccd->yd = yd; 3951 tag = YAHOO_CALLBACK(ext_yahoo_connect_async)(yd->client_id, yss->pager_host, yss->pager_port, 3952 yahoo_connected, ccd); 3953 3954 /* 3955 * if tag <= 0, then callback has already been called 3956 * so ccd will have been freed 3957 */ 3958 if(tag > 0) 3959 ccd->tag = tag; 3960 else if(tag < 0) 3961 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_SOCK, NULL); 3962 } 3963 3964 3965 int yahoo_get_fd(int id) 3966 { 3967 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3968 if(!yid) 3574 3969 return 0; 3575 3970 else … … 3577 3972 } 3578 3973 3579 void yahoo_send_buzz(int id, const char *from, const char *who) 3580 { 3581 yahoo_send_im(id, from, who, "<ding>", 1, 0); 3582 } 3583 3584 void yahoo_send_im(int id, const char *from, const char *who, const char *what, 3585 int utf8, int picture) 3586 { 3587 struct yahoo_input_data *yid = 3588 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3974 void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture) 3975 { 3976 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3589 3977 struct yahoo_packet *pkt = NULL; 3590 3978 struct yahoo_data *yd; 3591 3979 char pic_str[10]; 3592 3980 3593 if 3981 if(!yid) 3594 3982 return; 3595 3983 3596 3984 yd = yid->yd; 3597 3985 3598 pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 3599 yd->session_id); 3986 pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id); 3600 3987 3601 3988 snprintf(pic_str, sizeof(pic_str), "%d", picture); 3602 3603 if 3989 3990 if(from && strcmp(from, yd->user)) 3604 3991 yahoo_packet_hash(pkt, 0, yd->user); 3605 yahoo_packet_hash(pkt, 1, from ? from :yd->user);3992 yahoo_packet_hash(pkt, 1, from?from:yd->user); 3606 3993 yahoo_packet_hash(pkt, 5, who); 3607 3994 yahoo_packet_hash(pkt, 14, what); 3608 3995 3609 if 3996 if(utf8) 3610 3997 yahoo_packet_hash(pkt, 97, "1"); 3611 3998 … … 3614 4001 yahoo_packet_hash(pkt, 206, pic_str); 3615 4002 4003 3616 4004 yahoo_send_packet(yid, pkt, 0); 3617 4005 … … 3621 4009 void yahoo_send_typing(int id, const char *from, const char *who, int typ) 3622 4010 { 3623 struct yahoo_input_data *yid = 3624 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4011 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3625 4012 struct yahoo_data *yd; 3626 4013 struct yahoo_packet *pkt = NULL; 3627 if 4014 if(!yid) 3628 4015 return; 3629 4016 3630 4017 yd = yid->yd; 3631 pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, 3632 yd->session_id); 4018 pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id); 3633 4019 3634 4020 yahoo_packet_hash(pkt, 5, who); 3635 yahoo_packet_hash(pkt, 1, from ? from :yd->user);4021 yahoo_packet_hash(pkt, 1, from?from:yd->user); 3636 4022 yahoo_packet_hash(pkt, 14, " "); 3637 4023 yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); … … 3645 4031 void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) 3646 4032 { 3647 struct yahoo_input_data *yid = 3648 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4033 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3649 4034 struct yahoo_data *yd; 3650 4035 struct yahoo_packet *pkt = NULL; … … 3652 4037 char s[4]; 3653 4038 3654 if 4039 if(!yid) 3655 4040 return; 3656 4041 3657 4042 yd = yid->yd; 3658 3659 4043 old_status = yd->current_status; 3660 4044 yd->current_status = state; … … 3662 4046 /* Thank you libpurple :) */ 3663 4047 if (yd->current_status == YAHOO_STATUS_INVISIBLE) { 3664 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, 3665 YAHOO_STATUS_AVAILABLE, 0); 4048 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); 3666 4049 yahoo_packet_hash(pkt, 13, "2"); 3667 4050 yahoo_send_packet(yid, pkt, 0); … … 3671 4054 } 3672 4055 3673 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, 3674 yd->current_status, yd->session_id); 4056 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); 3675 4057 snprintf(s, sizeof(s), "%d", yd->current_status); 3676 4058 yahoo_packet_hash(pkt, 10, s); … … 3680 4062 yahoo_packet_free(pkt); 3681 4063 3682 if (old_status == YAHOO_STATUS_INVISIBLE) { 3683 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, 3684 YAHOO_STATUS_AVAILABLE, 0); 4064 if(old_status == YAHOO_STATUS_INVISIBLE) { 4065 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); 3685 4066 yahoo_packet_hash(pkt, 13, "1"); 3686 4067 yahoo_send_packet(yid, pkt, 0); … … 3691 4072 void yahoo_logoff(int id) 3692 4073 { 3693 struct yahoo_input_data *yid = 3694 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4074 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3695 4075 struct yahoo_data *yd; 3696 4076 struct yahoo_packet *pkt = NULL; 3697 4077 3698 if 4078 if(!yid) 3699 4079 return; 3700 4080 yd = yid->yd; … … 3702 4082 LOG(("yahoo_logoff: current status: %d", yd->current_status)); 3703 4083 3704 if 4084 if(yd->current_status != -1 && 0) { 3705 4085 /* Meh. Don't send this. The event handlers are not going to 3706 4086 get to do this so it'll just leak memory. And the TCP 3707 4087 connection reset will hopefully be clear enough. */ 3708 pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, 3709 YPACKET_STATUS_DEFAULT, yd->session_id); 4088 pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); 3710 4089 yd->current_status = -1; 3711 4090 … … 3716 4095 } 3717 4096 3718 /*do {4097 do { 3719 4098 yahoo_input_close(yid); 3720 } while((yid = find_input_by_id(id)));*/ 3721 4099 } while((yid = find_input_by_id(id))); 3722 4100 } 3723 4101 3724 4102 void yahoo_get_list(int id) 3725 4103 { 3726 struct yahoo_input_data *yid = 3727 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4104 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3728 4105 struct yahoo_data *yd; 3729 4106 struct yahoo_packet *pkt = NULL; 3730 4107 3731 if 4108 if(!yid) 3732 4109 return; 3733 4110 yd = yid->yd; 3734 4111 3735 pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YPACKET_STATUS_DEFAULT, 3736 yd->session_id); 4112 pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_AVAILABLE, yd->session_id); 3737 4113 yahoo_packet_hash(pkt, 1, yd->user); 3738 4114 if (pkt) { … … 3742 4118 } 3743 4119 3744 static void _yahoo_http_connected(int id, void *fd, int error, void *data)4120 static void _yahoo_http_connected(int id, int fd, int error, void *data) 3745 4121 { 3746 4122 struct yahoo_input_data *yid = data; 3747 if (fd == NULL || error) {4123 if(fd <= 0) { 3748 4124 inputs = y_list_remove(inputs, yid); 3749 4125 FREE(yid); … … 3752 4128 3753 4129 yid->fd = fd; 3754 yid->read_tag = 3755 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, 3756 YAHOO_INPUT_READ, yid); 3757 } 3758 3759 /* FIXME Get address book from address.yahoo.com instead */ 4130 yid->read_tag=YAHOO_CALLBACK(ext_yahoo_add_handler)(yid->yd->client_id, fd, YAHOO_INPUT_READ, yid); 4131 } 4132 3760 4133 void yahoo_get_yab(int id) 3761 4134 { 3762 struct yahoo_data *yd = find_conn_by_id(id);3763 struct yahoo_input_data *yid;3764 char url[1024];3765 char buff[2048];3766 3767 if (!yd)3768 return;3769 3770 yid = y_new0(struct yahoo_input_data, 1);3771 yid->yd = yd;3772 yid->type = YAHOO_CONNECTION_YAB;3773 3774 LOG(("Sending request for Address Book"));3775 3776 snprintf(url, 1024,3777 "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us"3778 "&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252");3779 3780 snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);3781 3782 inputs = y_list_prepend(inputs, yid);3783 3784 yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,3785 _yahoo_http_connected, yid);3786 }3787 3788 struct yahoo_post_data {3789 struct yahoo_input_data *yid;3790 char *data;3791 };3792 3793 static void _yahoo_http_post_connected(int id, void *fd, int error, void *data)3794 {3795 struct yahoo_post_data *yad = data;3796 struct yahoo_input_data *yid = yad->yid;3797 char *buff = yad->data;3798 3799 if (!fd) {3800 inputs = y_list_remove(inputs, yid);3801 FREE(yid);3802 return;3803 }3804 3805 YAHOO_CALLBACK(ext_yahoo_write) (fd, buff, strlen(buff));3806 3807 yid->fd = fd;3808 yid->read_tag =3809 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd,3810 YAHOO_INPUT_READ, yid);3811 3812 FREE(buff);3813 FREE(yad);3814 }3815 3816 /* FIXME This is also likely affected */3817 void yahoo_set_yab(int id, struct yab *yab)3818 {3819 struct yahoo_post_data *yad = y_new0(struct yahoo_post_data, 1);3820 4135 struct yahoo_data *yd = find_conn_by_id(id); 3821 4136 struct yahoo_input_data *yid; 3822 4137 char url[1024]; 3823 4138 char buff[1024]; 3824 char post[1024]; 3825 int size = 0; 3826 3827 if (!yd) 4139 4140 if(!yd) 4141 return; 4142 4143 yid = y_new0(struct yahoo_input_data, 1); 4144 yid->yd = yd; 4145 yid->type = YAHOO_CONNECTION_YAB; 4146 4147 snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?ab2=0"); 4148 4149 snprintf(buff, sizeof(buff), "Y=%s; T=%s", 4150 yd->cookie_y, yd->cookie_t); 4151 4152 inputs = y_list_prepend(inputs, yid); 4153 4154 yahoo_http_get(yid->yd->client_id, url, buff, 4155 _yahoo_http_connected, yid); 4156 } 4157 4158 void yahoo_set_yab(int id, struct yab * yab) 4159 { 4160 struct yahoo_data *yd = find_conn_by_id(id); 4161 struct yahoo_input_data *yid; 4162 char url[1024]; 4163 char buff[1024]; 4164 char *temp; 4165 int size = sizeof(url)-1; 4166 4167 if(!yd) 3828 4168 return; 3829 4169 … … 3832 4172 yid->yd = yd; 3833 4173 3834 if(yab->yid) 3835 size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 3836 "<ab k=\"%s\" cc=\"%d\">" 3837 "<ct id=\"%d\" e=\"1\" yi=\"%s\" nn=\"%s\" />" 3838 "</ab>", yd->user, 9, yab->yid, /* Don't know why */ 3839 yab->id, yab->nname?yab->nname:""); 3840 else 3841 size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 3842 "<ab k=\"%s\" cc=\"%d\">" 3843 "<ct a=\"1\" yi=\"%s\" nn=\"%s\" />" 3844 "</ab>", yd->user, 1, /* Don't know why */ 3845 yab->id, yab->nname?yab->nname:""); 3846 3847 yad->yid = yid; 3848 yad->data = strdup(post); 3849 3850 strcpy(url, "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us" 3851 "&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252"); 3852 3853 snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); 4174 strncpy(url, "http://insider.msg.yahoo.com/ycontent/?addab2=0", size); 4175 4176 if(yab->dbid) { 4177 /* change existing yab */ 4178 char tmp[32]; 4179 strncat(url, "&ee=1&ow=1&id=", size - strlen(url)); 4180 snprintf(tmp, sizeof(tmp), "%d", yab->dbid); 4181 strncat(url, tmp, size - strlen(url)); 4182 } 4183 4184 if(yab->fname) { 4185 strncat(url, "&fn=", size - strlen(url)); 4186 temp = yahoo_urlencode(yab->fname); 4187 strncat(url, temp, size - strlen(url)); 4188 free(temp); 4189 } 4190 if(yab->lname) { 4191 strncat(url, "&ln=", size - strlen(url)); 4192 temp = yahoo_urlencode(yab->lname); 4193 strncat(url, temp, size - strlen(url)); 4194 free(temp); 4195 } 4196 strncat(url, "&yid=", size - strlen(url)); 4197 temp = yahoo_urlencode(yab->id); 4198 strncat(url, temp, size - strlen(url)); 4199 free(temp); 4200 if(yab->nname) { 4201 strncat(url, "&nn=", size - strlen(url)); 4202 temp = yahoo_urlencode(yab->nname); 4203 strncat(url, temp, size - strlen(url)); 4204 free(temp); 4205 } 4206 if(yab->email) { 4207 strncat(url, "&e=", size - strlen(url)); 4208 temp = yahoo_urlencode(yab->email); 4209 strncat(url, temp, size - strlen(url)); 4210 free(temp); 4211 } 4212 if(yab->hphone) { 4213 strncat(url, "&hp=", size - strlen(url)); 4214 temp = yahoo_urlencode(yab->hphone); 4215 strncat(url, temp, size - strlen(url)); 4216 free(temp); 4217 } 4218 if(yab->wphone) { 4219 strncat(url, "&wp=", size - strlen(url)); 4220 temp = yahoo_urlencode(yab->wphone); 4221 strncat(url, temp, size - strlen(url)); 4222 free(temp); 4223 } 4224 if(yab->mphone) { 4225 strncat(url, "&mp=", size - strlen(url)); 4226 temp = yahoo_urlencode(yab->mphone); 4227 strncat(url, temp, size - strlen(url)); 4228 free(temp); 4229 } 4230 strncat(url, "&pp=0", size - strlen(url)); 4231 4232 snprintf(buff, sizeof(buff), "Y=%s; T=%s", 4233 yd->cookie_y, yd->cookie_t); 3854 4234 3855 4235 inputs = y_list_prepend(inputs, yid); 3856 4236 3857 yahoo_http_post(yid->yd->client_id, url, buff, size, 3858 _yahoo_http_post_connected, yad); 3859 } 3860 3861 void yahoo_set_identity_status(int id, const char *identity, int active) 3862 { 3863 struct yahoo_input_data *yid = 3864 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4237 yahoo_http_get(yid->yd->client_id, url, buff, 4238 _yahoo_http_connected, yid); 4239 } 4240 4241 void yahoo_set_identity_status(int id, const char * identity, int active) 4242 { 4243 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3865 4244 struct yahoo_data *yd; 3866 4245 struct yahoo_packet *pkt = NULL; 3867 4246 3868 if 4247 if(!yid) 3869 4248 return; 3870 4249 yd = yid->yd; 3871 4250 3872 pkt = yahoo_packet_new(active ? YAHOO_SERVICE_IDACT :3873 YAHOO_SERVICE_IDDEACT, YPACKET_STATUS_DEFAULT, yd->session_id);4251 pkt = yahoo_packet_new(active?YAHOO_SERVICE_IDACT:YAHOO_SERVICE_IDDEACT, 4252 YAHOO_STATUS_AVAILABLE, yd->session_id); 3874 4253 yahoo_packet_hash(pkt, 3, identity); 3875 4254 if (pkt) { … … 3881 4260 void yahoo_refresh(int id) 3882 4261 { 3883 struct yahoo_input_data *yid = 3884 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4262 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3885 4263 struct yahoo_data *yd; 3886 4264 struct yahoo_packet *pkt = NULL; 3887 4265 3888 if 4266 if(!yid) 3889 4267 return; 3890 4268 yd = yid->yd; 3891 4269 3892 pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YPACKET_STATUS_DEFAULT, 3893 yd->session_id); 4270 pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YAHOO_STATUS_AVAILABLE, yd->session_id); 3894 4271 if (pkt) { 3895 4272 yahoo_send_packet(yid, pkt, 0); … … 3900 4277 void yahoo_keepalive(int id) 3901 4278 { 3902 struct yahoo_input_data *yid = 3903 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4279 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4280 struct yahoo_data *yd; 4281 struct yahoo_packet *pkt=NULL; 4282 if(!yid) 4283 return; 4284 yd = yid->yd; 4285 4286 pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id); 4287 yahoo_send_packet(yid, pkt, 0); 4288 yahoo_packet_free(pkt); 4289 } 4290 4291 void yahoo_chat_keepalive (int id) 4292 { 4293 struct yahoo_input_data *yid = find_input_by_id_and_type (id, YAHOO_CONNECTION_PAGER); 3904 4294 struct yahoo_data *yd; 3905 4295 struct yahoo_packet *pkt = NULL; 4296 3906 4297 if (!yid) 3907 return; 4298 return; 4299 3908 4300 yd = yid->yd; 3909 4301 3910 pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YPACKET_STATUS_DEFAULT, 3911 yd->session_id); 3912 yahoo_send_packet(yid, pkt, 0); 3913 yahoo_packet_free(pkt); 3914 } 3915 3916 void yahoo_chat_keepalive(int id) 3917 { 3918 struct yahoo_input_data *yid = 3919 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3920 struct yahoo_data *yd; 3921 struct yahoo_packet *pkt = NULL; 3922 3923 if (!yid) 3924 return; 3925 3926 yd = yid->yd; 3927 3928 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YPACKET_STATUS_DEFAULT, 3929 yd->session_id); 3930 yahoo_send_packet(yid, pkt, 0); 3931 yahoo_packet_free(pkt); 3932 } 3933 3934 void yahoo_add_buddy(int id, const char *who, const char *group, 3935 const char *msg) 3936 { 3937 struct yahoo_input_data *yid = 3938 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4302 pkt = yahoo_packet_new (YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, yd->session_id); 4303 yahoo_send_packet (yid, pkt, 0); 4304 yahoo_packet_free (pkt); 4305 } 4306 4307 void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg) 4308 { 4309 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3939 4310 struct yahoo_data *yd; 3940 4311 struct yahoo_packet *pkt; 3941 4312 3942 if 4313 if(!yid) 3943 4314 return; 3944 4315 yd = yid->yd; … … 3947 4318 return; 3948 4319 3949 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, 3950 yd->session_id); 3951 if (msg != NULL) 4320 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); 4321 4322 if (msg != NULL) /* add message/request "it's me add me" */ 3952 4323 yahoo_packet_hash(pkt, 14, msg); 3953 4324 else 3954 yahoo_packet_hash(pkt, 14, ""); 4325 yahoo_packet_hash(pkt,14,""); 4326 3955 4327 yahoo_packet_hash(pkt, 65, group); 3956 4328 yahoo_packet_hash(pkt, 97, "1"); … … 3962 4334 yahoo_packet_hash(pkt, 301, "319"); 3963 4335 yahoo_packet_hash(pkt, 303, "319"); 4336 4337 3964 4338 yahoo_send_packet(yid, pkt, 0); 3965 4339 yahoo_packet_free(pkt); … … 3968 4342 void yahoo_remove_buddy(int id, const char *who, const char *group) 3969 4343 { 3970 struct yahoo_input_data *yid = 3971 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4344 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3972 4345 struct yahoo_data *yd; 3973 4346 struct yahoo_packet *pkt = NULL; 3974 4347 3975 if 4348 if(!yid) 3976 4349 return; 3977 4350 yd = yid->yd; 3978 4351 3979 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YPACKET_STATUS_DEFAULT, 3980 yd->session_id); 4352 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); 3981 4353 3982 4354 yahoo_packet_hash(pkt, 1, yd->user); … … 3987 4359 } 3988 4360 3989 void yahoo_confirm_buddy(int id, const char *who, int reject, const char *msg) 3990 { 3991 struct yahoo_input_data *yid = 3992 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4361 void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ 4362 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4363 struct yahoo_data *yd; 4364 4365 if(!yid) 4366 return; 4367 yd = yid->yd; 4368 4369 struct yahoo_packet* pkt=NULL; 4370 pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); 4371 4372 yahoo_packet_hash(pkt,1,me ?: yd->user); 4373 yahoo_packet_hash(pkt,5,who); 4374 yahoo_packet_hash(pkt,13,"1"); 4375 yahoo_packet_hash(pkt,334,"0"); 4376 yahoo_send_packet(yid, pkt, 0); 4377 yahoo_packet_free(pkt); 4378 } 4379 4380 void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ 4381 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4382 struct yahoo_data *yd; 4383 4384 if(!yid) 4385 return; 4386 yd = yid->yd; 4387 4388 struct yahoo_packet* pkt=NULL; 4389 pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); 4390 4391 yahoo_packet_hash(pkt,1,me ?: yd->user); 4392 yahoo_packet_hash(pkt,5,who); 4393 // yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); 4394 yahoo_packet_hash(pkt,13,"2"); 4395 yahoo_packet_hash(pkt,334,"0"); 4396 yahoo_packet_hash(pkt,97,"1"); 4397 yahoo_packet_hash(pkt,14,msg?:""); 4398 4399 yahoo_send_packet(yid, pkt, 0); 4400 yahoo_packet_free(pkt); 4401 4402 } 4403 4404 void yahoo_reject_buddy(int id, const char *who, const char *msg) 4405 { 4406 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 3993 4407 struct yahoo_data *yd; 3994 4408 struct yahoo_packet *pkt; 3995 4409 3996 if 4410 if(!yid) 3997 4411 return; 3998 4412 yd = yid->yd; … … 4001 4415 return; 4002 4416 4003 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_AUTHORIZATION, 4004 YPACKET_STATUS_DEFAULT, yd->session_id); 4417 pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); 4005 4418 yahoo_packet_hash(pkt, 1, yd->user); 4006 yahoo_packet_hash(pkt, 5, who); 4007 if (reject) 4008 yahoo_packet_hash(pkt, 13, "2"); 4009 else { 4010 yahoo_packet_hash(pkt, 241, "0"); 4011 yahoo_packet_hash(pkt, 13, "1"); 4012 } 4013 4014 yahoo_packet_hash(pkt, 334, "0"); 4015 4016 if (reject) { 4017 yahoo_packet_hash(pkt, 14, msg ? msg : ""); 4018 yahoo_packet_hash(pkt, 97, "1"); 4019 } 4020 4419 yahoo_packet_hash(pkt, 7, who); 4420 yahoo_packet_hash(pkt, 14, msg); 4021 4421 yahoo_send_packet(yid, pkt, 0); 4022 4422 yahoo_packet_free(pkt); … … 4025 4425 void yahoo_ignore_buddy(int id, const char *who, int unignore) 4026 4426 { 4027 struct yahoo_input_data *yid = 4028 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4427 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4029 4428 struct yahoo_data *yd; 4030 4429 struct yahoo_packet *pkt; 4031 4430 4032 if 4431 if(!yid) 4033 4432 return; 4034 4433 yd = yid->yd; … … 4037 4436 return; 4038 4437 4039 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, 4040 YPACKET_STATUS_DEFAULT, yd->session_id); 4438 pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); 4041 4439 yahoo_packet_hash(pkt, 1, yd->user); 4042 4440 yahoo_packet_hash(pkt, 7, who); 4043 yahoo_packet_hash(pkt, 13, unignore ? "2" :"1");4441 yahoo_packet_hash(pkt, 13, unignore?"2":"1"); 4044 4442 yahoo_send_packet(yid, pkt, 0); 4045 4443 yahoo_packet_free(pkt); … … 4048 4446 void yahoo_stealth_buddy(int id, const char *who, int unstealth) 4049 4447 { 4050 struct yahoo_input_data *yid = 4051 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4448 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4052 4449 struct yahoo_data *yd; 4053 4450 struct yahoo_packet *pkt; 4054 4451 4055 if 4452 if(!yid) 4056 4453 return; 4057 4454 yd = yid->yd; … … 4060 4457 return; 4061 4458 4062 pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, 4063 YPACKET_STATUS_DEFAULT, yd->session_id); 4459 pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); 4064 4460 yahoo_packet_hash(pkt, 1, yd->user); 4065 4461 yahoo_packet_hash(pkt, 7, who); 4066 yahoo_packet_hash(pkt, 31, unstealth ? "2" :"1");4462 yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); 4067 4463 yahoo_packet_hash(pkt, 13, "2"); 4068 4464 yahoo_send_packet(yid, pkt, 0); … … 4070 4466 } 4071 4467 4072 void yahoo_change_buddy_group(int id, const char *who, const char *old_group, 4073 const char *new_group) 4074 { 4075 struct yahoo_input_data *yid = 4076 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4468 void yahoo_change_buddy_group(int id, const char *who, const char *old_group, const char *new_group) 4469 { 4470 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4077 4471 struct yahoo_data *yd; 4078 4472 struct yahoo_packet *pkt = NULL; 4079 4473 4080 if 4474 if(!yid) 4081 4475 return; 4082 4476 yd = yid->yd; 4083 4477 4084 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_CHANGE_GROUP, 4085 YPACKET_STATUS_DEFAULT, yd->session_id); 4478 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); 4086 4479 yahoo_packet_hash(pkt, 1, yd->user); 4087 yahoo_packet_hash(pkt, 302, "240");4088 yahoo_packet_hash(pkt, 300, "240");4089 4480 yahoo_packet_hash(pkt, 7, who); 4090 yahoo_packet_hash(pkt, 224, old_group); 4091 yahoo_packet_hash(pkt, 264, new_group); 4092 yahoo_packet_hash(pkt, 301, "240"); 4093 yahoo_packet_hash(pkt, 303, "240"); 4481 yahoo_packet_hash(pkt, 65, new_group); 4482 yahoo_packet_hash(pkt, 14, " "); 4094 4483 4095 4484 yahoo_send_packet(yid, pkt, 0); 4096 4485 yahoo_packet_free(pkt); 4486 4487 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); 4488 yahoo_packet_hash(pkt, 1, yd->user); 4489 yahoo_packet_hash(pkt, 7, who); 4490 yahoo_packet_hash(pkt, 65, old_group); 4491 yahoo_send_packet(yid, pkt, 0); 4492 yahoo_packet_free(pkt); 4097 4493 } 4098 4494 4099 4495 void yahoo_group_rename(int id, const char *old_group, const char *new_group) 4100 4496 { 4101 struct yahoo_input_data *yid = 4102 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4497 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4103 4498 struct yahoo_data *yd; 4104 4499 struct yahoo_packet *pkt = NULL; 4105 4500 4106 if 4501 if(!yid) 4107 4502 return; 4108 4503 yd = yid->yd; 4109 4504 4110 pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, 4111 YPACKET_STATUS_DEFAULT, yd->session_id); 4505 pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id); 4112 4506 yahoo_packet_hash(pkt, 1, yd->user); 4113 4507 yahoo_packet_hash(pkt, 65, old_group); … … 4118 4512 } 4119 4513 4120 void yahoo_conference_addinvite(int id, const char *from, const char *who, 4121 const char *room, const YList *members, const char *msg) 4122 { 4123 struct yahoo_input_data *yid = 4124 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4514 void yahoo_conference_addinvite(int id, const char * from, const char *who, const char *room, const YList * members, const char *msg) 4515 { 4516 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4125 4517 struct yahoo_data *yd; 4126 4518 struct yahoo_packet *pkt; 4127 4128 if 4519 4520 if(!yid) 4129 4521 return; 4130 4522 yd = yid->yd; 4131 4523 4132 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, 4133 YPACKET_STATUS_DEFAULT, yd->session_id); 4134 4135 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4524 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); 4525 4526 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4136 4527 yahoo_packet_hash(pkt, 51, who); 4137 4528 yahoo_packet_hash(pkt, 57, room); 4138 4529 yahoo_packet_hash(pkt, 58, msg); 4139 4530 yahoo_packet_hash(pkt, 13, "0"); 4140 for 4531 for(; members; members = members->next) { 4141 4532 yahoo_packet_hash(pkt, 52, (char *)members->data); 4142 4533 yahoo_packet_hash(pkt, 53, (char *)members->data); … … 4149 4540 } 4150 4541 4151 void yahoo_conference_invite(int id, const char *from, YList *who, 4152 const char *room, const char *msg) 4153 { 4154 struct yahoo_input_data *yid = 4155 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4542 void yahoo_conference_invite(int id, const char * from, YList *who, const char *room, const char *msg) 4543 { 4544 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4156 4545 struct yahoo_data *yd; 4157 4546 struct yahoo_packet *pkt; 4158 4159 if 4547 4548 if(!yid) 4160 4549 return; 4161 4550 yd = yid->yd; 4162 4551 4163 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YPACKET_STATUS_DEFAULT, 4164 yd->session_id); 4165 4166 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4552 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); 4553 4554 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4167 4555 yahoo_packet_hash(pkt, 50, yd->user); 4168 for 4556 for(; who; who = who->next) { 4169 4557 yahoo_packet_hash(pkt, 52, (char *)who->data); 4170 4558 } … … 4178 4566 } 4179 4567 4180 void yahoo_conference_logon(int id, const char *from, YList *who, 4181 const char *room) 4182 { 4183 struct yahoo_input_data *yid = 4184 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4568 void yahoo_conference_logon(int id, const char *from, YList *who, const char *room) 4569 { 4570 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4185 4571 struct yahoo_data *yd; 4186 4572 struct yahoo_packet *pkt; 4187 4188 if 4573 4574 if(!yid) 4189 4575 return; 4190 4576 yd = yid->yd; 4191 4577 4192 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YPACKET_STATUS_DEFAULT, 4193 yd->session_id); 4194 4195 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4196 yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); 4578 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, yd->session_id); 4579 4580 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4581 for(; who; who = who->next) { 4582 yahoo_packet_hash(pkt, 3, (char *)who->data); 4583 } 4197 4584 yahoo_packet_hash(pkt, 57, room); 4198 for (; who; who = who->next)4199 yahoo_packet_hash(pkt, 3, (char *)who->data);4200 4585 4201 4586 yahoo_send_packet(yid, pkt, 0); … … 4204 4589 } 4205 4590 4206 void yahoo_conference_decline(int id, const char *from, YList *who, 4207 const char *room, const char *msg) 4208 { 4209 struct yahoo_input_data *yid = 4210 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4591 void yahoo_conference_decline(int id, const char * from, YList *who, const char *room, const char *msg) 4592 { 4593 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4211 4594 struct yahoo_data *yd; 4212 4595 struct yahoo_packet *pkt; 4213 4214 if 4596 4597 if(!yid) 4215 4598 return; 4216 4599 yd = yid->yd; 4217 4600 4218 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, 4219 YPACKET_STATUS_DEFAULT, yd->session_id); 4220 4221 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4222 yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); 4223 for (; who; who = who->next) 4601 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); 4602 4603 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4604 for(; who; who = who->next) { 4224 4605 yahoo_packet_hash(pkt, 3, (char *)who->data); 4606 } 4225 4607 yahoo_packet_hash(pkt, 57, room); 4226 4608 yahoo_packet_hash(pkt, 14, msg); … … 4231 4613 } 4232 4614 4233 void yahoo_conference_logoff(int id, const char *from, YList *who, 4234 const char *room) 4235 { 4236 struct yahoo_input_data *yid = 4237 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4615 void yahoo_conference_logoff(int id, const char * from, YList *who, const char *room) 4616 { 4617 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4238 4618 struct yahoo_data *yd; 4239 4619 struct yahoo_packet *pkt; 4240 4241 if 4620 4621 if(!yid) 4242 4622 return; 4243 4623 yd = yid->yd; 4244 4624 4245 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YPACKET_STATUS_DEFAULT, 4246 yd->session_id); 4247 4248 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4249 yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); 4250 for (; who; who = who->next) 4625 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); 4626 4627 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4628 for(; who; who = who->next) { 4251 4629 yahoo_packet_hash(pkt, 3, (char *)who->data); 4252 4630 } 4253 4631 yahoo_packet_hash(pkt, 57, room); 4254 4632 … … 4258 4636 } 4259 4637 4260 void yahoo_conference_message(int id, const char *from, YList *who, 4261 const char *room, const char *msg, int utf8) 4262 { 4263 struct yahoo_input_data *yid = 4264 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4638 void yahoo_conference_message(int id, const char * from, YList *who, const char *room, const char *msg, int utf8) 4639 { 4640 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4265 4641 struct yahoo_data *yd; 4266 4642 struct yahoo_packet *pkt; 4267 4268 if 4643 4644 if(!yid) 4269 4645 return; 4270 4646 yd = yid->yd; 4271 4647 4272 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YPACKET_STATUS_DEFAULT, 4273 yd->session_id); 4274 4275 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4276 yahoo_packet_hash(pkt, 53, (from ? from : yd->user)); 4277 for (; who; who = who->next) 4648 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, yd->session_id); 4649 4650 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4651 for(; who; who = who->next) { 4278 4652 yahoo_packet_hash(pkt, 53, (char *)who->data); 4279 4653 } 4280 4654 yahoo_packet_hash(pkt, 57, room); 4281 4655 yahoo_packet_hash(pkt, 14, msg); 4282 4656 4283 if 4657 if(utf8) 4284 4658 yahoo_packet_hash(pkt, 97, "1"); 4285 4659 … … 4296 4670 char buff[1024]; 4297 4671 4298 if 4672 if(!yd) 4299 4673 return; 4300 4674 … … 4304 4678 4305 4679 if (chatroomid == 0) { 4306 snprintf(url, 1024, 4307 "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); 4680 snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); 4308 4681 } else { 4309 snprintf(url, 1024, 4310 "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0", 4311 chatroomid); 4682 snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",chatroomid); 4312 4683 } 4313 4684 … … 4316 4687 inputs = y_list_prepend(inputs, yid); 4317 4688 4318 yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, 4319 _yahoo_http_connected, yid); 4320 } 4321 4322 void yahoo_chat_logon(int id, const char *from, const char *room, 4323 const char *roomid) 4324 { 4325 struct yahoo_input_data *yid = 4326 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4689 yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); 4690 } 4691 4692 void yahoo_chat_logon(int id, const char *from, const char *room, const char *roomid) 4693 { 4694 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4327 4695 struct yahoo_data *yd; 4328 4696 struct yahoo_packet *pkt; 4329 4330 if 4697 4698 if(!yid) 4331 4699 return; 4332 4700 4333 4701 yd = yid->yd; 4334 4702 4335 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YPACKET_STATUS_DEFAULT, 4336 yd->session_id); 4337 4338 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4703 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); 4704 4705 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4339 4706 yahoo_packet_hash(pkt, 109, yd->user); 4340 4707 yahoo_packet_hash(pkt, 6, "abcde"); … … 4344 4711 yahoo_packet_free(pkt); 4345 4712 4346 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT, 4347 yd->session_id); 4348 4349 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4713 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, yd->session_id); 4714 4715 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4350 4716 yahoo_packet_hash(pkt, 104, room); 4351 4717 yahoo_packet_hash(pkt, 129, roomid); 4352 yahoo_packet_hash(pkt, 62, "2"); 4718 yahoo_packet_hash(pkt, 62, "2"); /* ??? */ 4353 4719 4354 4720 yahoo_send_packet(yid, pkt, 0); … … 4357 4723 } 4358 4724 4359 void yahoo_chat_message(int id, const char *from, const char *room, 4360 const char *msg, const int msgtype, const int utf8) 4361 { 4362 struct yahoo_input_data *yid = 4363 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4725 4726 void yahoo_chat_message(int id, const char *from, const char *room, const char *msg, const int msgtype, const int utf8) 4727 { 4728 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4364 4729 struct yahoo_data *yd; 4365 4730 struct yahoo_packet *pkt; 4366 4731 char buf[2]; 4367 4368 if 4732 4733 if(!yid) 4369 4734 return; 4370 4735 4371 4736 yd = yid->yd; 4372 4737 4373 pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YPACKET_STATUS_DEFAULT, 4374 yd->session_id); 4375 4376 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4738 pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, yd->session_id); 4739 4740 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4377 4741 yahoo_packet_hash(pkt, 104, room); 4378 4742 yahoo_packet_hash(pkt, 117, msg); 4379 4743 4380 4744 snprintf(buf, sizeof(buf), "%d", msgtype); 4381 4745 yahoo_packet_hash(pkt, 124, buf); 4382 4746 4383 if 4747 if(utf8) 4384 4748 yahoo_packet_hash(pkt, 97, "1"); 4385 4749 … … 4389 4753 } 4390 4754 4755 4391 4756 void yahoo_chat_logoff(int id, const char *from) 4392 4757 { 4393 struct yahoo_input_data *yid = 4394 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4758 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4395 4759 struct yahoo_data *yd; 4396 4760 struct yahoo_packet *pkt; 4397 4398 if 4761 4762 if(!yid) 4399 4763 return; 4400 4764 4401 4765 yd = yid->yd; 4402 4766 4403 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YPACKET_STATUS_DEFAULT, 4404 yd->session_id); 4405 4406 yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); 4767 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YAHOO_STATUS_AVAILABLE, yd->session_id); 4768 4769 yahoo_packet_hash(pkt, 1, (from?from:yd->user)); 4407 4770 4408 4771 yahoo_send_packet(yid, pkt, 0); … … 4413 4776 void yahoo_buddyicon_request(int id, const char *who) 4414 4777 { 4415 struct yahoo_input_data *yid = 4416 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4778 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4417 4779 struct yahoo_data *yd; 4418 4780 struct yahoo_packet *pkt; 4419 4781 4420 if (!yid)4782 if( !yid ) 4421 4783 return; 4422 4784 4423 4785 yd = yid->yd; 4424 4425 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, 4426 0); 4786 4787 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); 4427 4788 yahoo_packet_hash(pkt, 4, yd->user); 4428 4789 yahoo_packet_hash(pkt, 5, who); … … 4433 4794 } 4434 4795 4435 void yahoo_send_picture_info(int id, const char *who, const char *url, 4436 int checksum) 4437 { 4438 struct yahoo_input_data *yid = 4439 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4796 void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum) 4797 { 4798 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4440 4799 struct yahoo_data *yd; 4441 4800 struct yahoo_packet *pkt; 4442 4801 char checksum_str[10]; 4443 4802 4444 if (!yid)4803 if( !yid ) 4445 4804 return; 4446 4805 … … 4449 4808 snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); 4450 4809 4451 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, 4452 0); 4810 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); 4453 4811 yahoo_packet_hash(pkt, 1, yd->user); 4454 4812 yahoo_packet_hash(pkt, 4, yd->user); … … 4464 4822 void yahoo_send_picture_update(int id, const char *who, int type) 4465 4823 { 4466 struct yahoo_input_data *yid = 4467 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4824 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4468 4825 struct yahoo_data *yd; 4469 4826 struct yahoo_packet *pkt; 4470 4827 char type_str[10]; 4471 4828 4472 if (!yid)4829 if( !yid ) 4473 4830 return; 4474 4831 … … 4477 4834 snprintf(type_str, sizeof(type_str), "%d", type); 4478 4835 4479 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, 4480 YPACKET_STATUS_DEFAULT, 0); 4836 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0); 4481 4837 yahoo_packet_hash(pkt, 1, yd->user); 4482 4838 yahoo_packet_hash(pkt, 5, who); … … 4489 4845 void yahoo_send_picture_checksum(int id, const char *who, int checksum) 4490 4846 { 4491 struct yahoo_input_data *yid = 4492 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4847 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4493 4848 struct yahoo_data *yd; 4494 4849 struct yahoo_packet *pkt; 4495 4850 char checksum_str[10]; 4496 4851 4497 if (!yid)4852 if( !yid ) 4498 4853 return; 4499 4854 4500 4855 yd = yid->yd; 4501 4856 4502 4857 snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); 4503 4858 4504 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, 4505 YPACKET_STATUS_DEFAULT, 0); 4859 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0); 4506 4860 yahoo_packet_hash(pkt, 1, yd->user); 4507 if (who != 0)4861 if( who != 0 ) 4508 4862 yahoo_packet_hash(pkt, 5, who); 4509 4863 yahoo_packet_hash(pkt, 192, checksum_str); … … 4516 4870 void yahoo_webcam_close_feed(int id, const char *who) 4517 4871 { 4518 struct yahoo_input_data *yid = 4519 find_input_by_id_and_webcam_user(id, who); 4520 4521 if (yid) 4872 struct yahoo_input_data *yid = find_input_by_id_and_webcam_user(id, who); 4873 4874 if(yid) 4522 4875 yahoo_input_close(yid); 4523 4876 } … … 4525 4878 void yahoo_webcam_get_feed(int id, const char *who) 4526 4879 { 4527 struct yahoo_input_data *yid = 4528 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4880 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4529 4881 struct yahoo_data *yd; 4530 4882 struct yahoo_packet *pkt; 4531 4532 if 4883 4884 if(!yid) 4533 4885 return; 4534 4886 … … 4540 4892 * The queue is popped in yahoo_process_webcam_key 4541 4893 */ 4542 webcam_queue = y_list_append(webcam_queue, who ? strdup(who) :NULL);4894 webcam_queue = y_list_append(webcam_queue, who?strdup(who):NULL); 4543 4895 4544 4896 yd = yid->yd; 4545 4897 4546 pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YPACKET_STATUS_DEFAULT, 4547 yd->session_id); 4898 pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YAHOO_STATUS_AVAILABLE, yd->session_id); 4548 4899 4549 4900 yahoo_packet_hash(pkt, 1, yd->user); … … 4555 4906 } 4556 4907 4557 void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, 4558 unsigned int timestamp) 4559 { 4560 struct yahoo_input_data *yid = 4561 find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); 4908 void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, unsigned int timestamp) 4909 { 4910 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); 4562 4911 unsigned char *packet; 4563 4912 unsigned char header_len = 13; … … 4571 4920 packet[pos++] = header_len; 4572 4921 packet[pos++] = 0; 4573 packet[pos++] = 5; 4922 packet[pos++] = 5; /* version byte?? */ 4574 4923 packet[pos++] = 0; 4575 4924 pos += yahoo_put32(packet + pos, length); 4576 packet[pos++] = 2; 4925 packet[pos++] = 2; /* packet type, image */ 4577 4926 pos += yahoo_put32(packet + pos, timestamp); 4578 4927 yahoo_add_to_send_queue(yid, packet, header_len); … … 4583 4932 } 4584 4933 4585 void yahoo_webcam_accept_viewer(int id, const char *who, int accept) 4586 { 4587 struct yahoo_input_data *yid = 4588 find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); 4934 void yahoo_webcam_accept_viewer(int id, const char* who, int accept) 4935 { 4936 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); 4589 4937 char *packet = NULL; 4590 4938 char *data = NULL; … … 4597 4945 4598 4946 data = strdup("u="); 4599 data = y_string_append(data, (char 4947 data = y_string_append(data, (char*)who); 4600 4948 data = y_string_append(data, "\r\n"); 4601 4949 len = strlen(data); … … 4604 4952 packet[pos++] = header_len; 4605 4953 packet[pos++] = 0; 4606 packet[pos++] = 5; 4954 packet[pos++] = 5; /* version byte?? */ 4607 4955 packet[pos++] = 0; 4608 4956 pos += yahoo_put32(packet + pos, len); 4609 packet[pos++] = 0; 4957 packet[pos++] = 0; /* packet type */ 4610 4958 pos += yahoo_put32(packet + pos, accept); 4611 4959 memcpy(packet + pos, data, len); … … 4617 4965 void yahoo_webcam_invite(int id, const char *who) 4618 4966 { 4619 struct yahoo_input_data *yid = 4620 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4967 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4621 4968 struct yahoo_packet *pkt; 4622 4623 if (!yid) 4624 return; 4625 4626 pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, 4627 yid->yd->session_id); 4969 4970 if(!yid) 4971 return; 4972 4973 pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yid->yd->session_id); 4628 4974 4629 4975 yahoo_packet_hash(pkt, 49, "WEBCAMINVITE"); … … 4637 4983 } 4638 4984 4639 static void yahoo_search_internal(int id, int t, const char *text, int g, 4640 int ar, int photo, int yahoo_only, int startpos, int total) 4985 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) 4641 4986 { 4642 4987 struct yahoo_data *yd = find_conn_by_id(id); … … 4646 4991 char *ctext, *p; 4647 4992 4648 if 4993 if(!yd) 4649 4994 return; 4650 4995 … … 4654 4999 4655 5000 /* 4656 age range 4657 .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ 4658 */ 4659 4660 snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, 4661 startpos); 5001 age range 5002 .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ 5003 */ 5004 5005 snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, startpos); 4662 5006 4663 5007 ctext = strdup(text); 4664 while 5008 while((p = strchr(ctext, ' '))) 4665 5009 *p = '+'; 4666 5010 4667 snprintf(url, 1024, 4668 "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", 4669 ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", 4670 startpos ? buff : ""); 5011 snprintf(url, 1024, "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", 5012 ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", 5013 startpos ? buff : ""); 4671 5014 4672 5015 FREE(ctext); … … 4675 5018 4676 5019 inputs = y_list_prepend(inputs, yid); 4677 yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, 4678 _yahoo_http_connected, yid); 4679 } 4680 4681 void yahoo_search(int id, enum yahoo_search_type t, const char *text, 4682 enum yahoo_search_gender g, enum yahoo_search_agerange ar, int photo, 4683 int yahoo_only) 4684 { 4685 struct yahoo_input_data *yid = 4686 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 5020 yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); 5021 } 5022 5023 void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo_search_gender g, enum yahoo_search_agerange ar, 5024 int photo, int yahoo_only) 5025 { 5026 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4687 5027 struct yahoo_search_state *yss; 4688 5028 4689 if 4690 return; 4691 4692 if 5029 if(!yid) 5030 return; 5031 5032 if(!yid->ys) 4693 5033 yid->ys = y_new0(struct yahoo_search_state, 1); 4694 5034 … … 4708 5048 void yahoo_search_again(int id, int start) 4709 5049 { 4710 struct yahoo_input_data *yid = 4711 find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 5050 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4712 5051 struct yahoo_search_state *yss; 4713 5052 4714 if 5053 if(!yid || !yid->ys) 4715 5054 return; 4716 5055 4717 5056 yss = yid->ys; 4718 5057 4719 if 5058 if(start == -1) 4720 5059 start = yss->lsearch_nstart + yss->lsearch_nfound; 4721 5060 4722 yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text, 4723 yss->lsearch_gender, yss->lsearch_agerange, 4724 yss->lsearch_photo, yss->lsearch_yahoo_only, 4725 start, yss->lsearch_ntotal); 4726 } 4727 4728 void yahoo_send_picture(int id, const char *name, unsigned long size, 4729 yahoo_get_fd_callback callback, void *data) 4730 { 4731 /* Not Implemented */ 4732 } 4733 4734 /* File Transfer */ 4735 static YList *active_file_transfers = NULL; 4736 4737 enum { 4738 FT_STATE_HEAD = 1, 4739 FT_STATE_RECV, 4740 FT_STATE_RECV_START, 4741 FT_STATE_SEND 5061 yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text, 5062 yss->lsearch_gender, yss->lsearch_agerange, 5063 yss->lsearch_photo, yss->lsearch_yahoo_only, 5064 start, yss->lsearch_ntotal); 5065 } 5066 5067 struct send_file_data { 5068 struct yahoo_packet *pkt; 5069 yahoo_get_fd_callback callback; 5070 void *user_data; 4742 5071 }; 4743 5072 4744 struct send_file_data { 4745 int client_id; 4746 char *id; 4747 char *who; 4748 char *filename; 4749 char *ip_addr; 4750 char *token; 4751 int size; 4752 4753 struct yahoo_input_data *yid; 4754 int state; 4755 4756 yahoo_get_fd_callback callback; 4757 void *data; 4758 }; 4759 4760 static char *yahoo_get_random(void) 4761 { 4762 int i = 0; 4763 int r = 0; 4764 int c = 0; 4765 char out[25]; 4766 4767 out[24] = '\0'; 4768 out[23] = '$'; 4769 out[22] = '$'; 4770 4771 for (i = 0; i < 22; i++) { 4772 if(r == 0) 4773 r = rand(); 4774 4775 c = r%61; 4776 4777 if(c<26) 4778 out[i] = c + 'a'; 4779 else if (c<52) 4780 out[i] = c - 26 + 'A'; 4781 else 4782 out[i] = c - 52 + '0'; 4783 4784 r /= 61; 4785 } 4786 4787 return strdup(out); 4788 } 4789 4790 static int _are_same_id(const void *sfd1, const void *id) 4791 { 4792 return strcmp(((struct send_file_data *)sfd1)->id, (char *)id); 4793 } 4794 4795 static int _are_same_yid(const void *sfd1, const void *yid) 4796 { 4797 if(((struct send_file_data *)sfd1)->yid == yid) 4798 return 0; 4799 else 4800 return 1; 4801 } 4802 4803 static struct send_file_data *yahoo_get_active_transfer(char *id) 4804 { 4805 YList *l = y_list_find_custom(active_file_transfers, id, 4806 _are_same_id); 4807 4808 if(l) 4809 return (struct send_file_data *)l->data; 4810 4811 return NULL; 4812 } 4813 4814 static struct send_file_data *yahoo_get_active_transfer_with_yid(void *yid) 4815 { 4816 YList *l = y_list_find_custom(active_file_transfers, yid, 4817 _are_same_yid); 4818 4819 if(l) 4820 return (struct send_file_data *)l->data; 4821 4822 return NULL; 4823 } 4824 4825 static void yahoo_add_active_transfer(struct send_file_data *sfd) 4826 { 4827 active_file_transfers = y_list_prepend(active_file_transfers, sfd); 4828 } 4829 4830 static void yahoo_remove_active_transfer(struct send_file_data *sfd) 4831 { 4832 active_file_transfers = y_list_remove(active_file_transfers, sfd); 4833 free(sfd->id); 4834 free(sfd->who); 4835 free(sfd->filename); 4836 free(sfd->ip_addr); 4837 FREE(sfd); 4838 } 4839 4840 static void _yahoo_ft_upload_connected(int id, void *fd, int error, void *data) 4841 { 5073 static void _yahoo_send_picture_connected(int id, int fd, int error, void *data) 5074 { 5075 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); 4842 5076 struct send_file_data *sfd = data; 4843 struct yahoo_input_data *yid = sfd->yid; 4844 4845 if (!fd) { 5077 struct yahoo_packet *pkt = sfd->pkt; 5078 unsigned char buff[1024]; 5079 5080 if(fd <= 0) { 5081 sfd->callback(id, fd, error, sfd->user_data); 5082 FREE(sfd); 5083 yahoo_packet_free(pkt); 4846 5084 inputs = y_list_remove(inputs, yid); 4847 5085 FREE(yid); … … 4849 5087 } 4850 5088 4851 sfd->callback(id, fd, error, sfd->data);4852 4853 5089 yid->fd = fd; 4854 yid->read_tag = 4855 YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, 4856 YAHOO_INPUT_READ, yid); 4857 } 4858 4859 static void yahoo_file_transfer_upload(struct yahoo_data *yd, 4860 struct send_file_data *sfd) 4861 { 4862 char url[256]; 4863 char buff[4096]; 4864 char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; 4865 4866 struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); 4867 5090 yahoo_send_packet(yid, pkt, 8); 5091 yahoo_packet_free(pkt); 5092 5093 snprintf((char *)buff, sizeof(buff), "29"); 5094 buff[2] = 0xc0; 5095 buff[3] = 0x80; 5096 5097 write(yid->fd, buff, 4); 5098 5099 /* YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */ 5100 5101 sfd->callback(id, fd, error, sfd->user_data); 5102 FREE(sfd); 5103 inputs = y_list_remove(inputs, yid); 5104 /* 5105 while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { 5106 if(!strcmp(buff, "")) 5107 break; 5108 } 5109 5110 */ 5111 yahoo_input_close(yid); 5112 } 5113 5114 void yahoo_send_picture(int id, const char *name, unsigned long size, 5115 yahoo_get_fd_callback callback, void *data) 5116 { 5117 struct yahoo_data *yd = find_conn_by_id(id); 5118 struct yahoo_input_data *yid; 5119 struct yahoo_server_settings *yss; 5120 struct yahoo_packet *pkt = NULL; 5121 char size_str[10]; 5122 char expire_str[10]; 5123 long content_length=0; 5124 unsigned char buff[1024]; 5125 char url[255]; 5126 struct send_file_data *sfd; 5127 5128 if(!yd) 5129 return; 5130 5131 yss = yd->server_settings; 5132 5133 yid = y_new0(struct yahoo_input_data, 1); 4868 5134 yid->yd = yd; 4869 5135 yid->type = YAHOO_CONNECTION_FT; 4870 5136 5137 pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id); 5138 5139 snprintf(size_str, sizeof(size_str), "%ld", size); 5140 snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800); 5141 5142 yahoo_packet_hash(pkt, 0, yd->user); 5143 yahoo_packet_hash(pkt, 1, yd->user); 5144 yahoo_packet_hash(pkt, 14, ""); 5145 yahoo_packet_hash(pkt, 27, name); 5146 yahoo_packet_hash(pkt, 28, size_str); 5147 yahoo_packet_hash(pkt, 38, expire_str); 5148 5149 5150 content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); 5151 5152 snprintf(url, sizeof(url), "http://%s:%d/notifyft", 5153 yss->filetransfer_host, yss->filetransfer_port); 5154 snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", 5155 yd->cookie_y, yd->cookie_t); 4871 5156 inputs = y_list_prepend(inputs, yid); 4872 sfd->yid = yid; 4873 sfd->state = FT_STATE_SEND; 4874 4875 token_enc = yahoo_urlencode(sfd->token); 4876 sender_enc = yahoo_urlencode(yd->user); 4877 recv_enc = yahoo_urlencode(sfd->who); 4878 4879 snprintf(url, sizeof(url), 4880 "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, 4881 token_enc, sender_enc, recv_enc); 4882 4883 snprintf(buff, sizeof(buff), "T=%s; Y=%s", yd->cookie_t, yd->cookie_y); 4884 4885 yahoo_http_post(yd->client_id, url, buff, sfd->size, 4886 _yahoo_ft_upload_connected, sfd); 4887 4888 FREE(token_enc); 4889 FREE(sender_enc); 4890 FREE(recv_enc); 4891 } 4892 4893 static void yahoo_init_ft_recv(struct yahoo_data *yd, 4894 struct send_file_data *sfd) 4895 { 4896 char url[256]; 4897 char buff[1024]; 4898 char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; 4899 4900 struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); 4901 5157 5158 sfd = y_new0(struct send_file_data, 1); 5159 sfd->pkt = pkt; 5160 sfd->callback = callback; 5161 sfd->user_data = data; 5162 yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, 5163 _yahoo_send_picture_connected, sfd); 5164 } 5165 5166 static void _yahoo_send_file_connected(int id, int fd, int error, void *data) 5167 { 5168 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); 5169 struct send_file_data *sfd = data; 5170 struct yahoo_packet *pkt = sfd->pkt; 5171 unsigned char buff[1024]; 5172 5173 if(fd <= 0) { 5174 sfd->callback(id, fd, error, sfd->user_data); 5175 FREE(sfd); 5176 yahoo_packet_free(pkt); 5177 inputs = y_list_remove(inputs, yid); 5178 FREE(yid); 5179 return; 5180 } 5181 5182 yid->fd = fd; 5183 yahoo_send_packet(yid, pkt, 8); 5184 yahoo_packet_free(pkt); 5185 5186 snprintf((char *)buff, sizeof(buff), "29"); 5187 buff[2] = 0xc0; 5188 buff[3] = 0x80; 5189 5190 write(yid->fd, buff, 4); 5191 5192 /* YAHOO_CALLBACK(ext_yahoo_add_handler)(nyd->fd, YAHOO_INPUT_READ); */ 5193 5194 sfd->callback(id, fd, error, sfd->user_data); 5195 FREE(sfd); 5196 inputs = y_list_remove(inputs, yid); 5197 /* 5198 while(yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { 5199 if(!strcmp(buff, "")) 5200 break; 5201 } 5202 5203 */ 5204 yahoo_input_close(yid); 5205 } 5206 5207 void yahoo_send_file(int id, const char *who, const char *msg, 5208 const char *name, unsigned long size, 5209 yahoo_get_fd_callback callback, void *data) 5210 { 5211 struct yahoo_data *yd = find_conn_by_id(id); 5212 struct yahoo_input_data *yid; 5213 struct yahoo_server_settings *yss; 5214 struct yahoo_packet *pkt = NULL; 5215 char size_str[10]; 5216 long content_length=0; 5217 unsigned char buff[1024]; 5218 char url[255]; 5219 struct send_file_data *sfd; 5220 5221 if(!yd) 5222 return; 5223 5224 yss = yd->server_settings; 5225 5226 yid = y_new0(struct yahoo_input_data, 1); 4902 5227 yid->yd = yd; 4903 5228 yid->type = YAHOO_CONNECTION_FT; 4904 5229 4905 inputs = y_list_prepend(inputs, yid); 4906 sfd->yid = yid; 4907 sfd->state = FT_STATE_HEAD; 4908 4909 token_enc = yahoo_urlencode(sfd->token); 4910 sender_enc = yahoo_urlencode(sfd->who); 4911 recv_enc = yahoo_urlencode(yd->user); 4912 4913 snprintf(url, sizeof(url), 4914 "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, 4915 token_enc, sender_enc, recv_enc); 4916 4917 snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); 4918 4919 yahoo_http_head(yid->yd->client_id, url, buff, 0, NULL, 4920 _yahoo_http_connected, yid); 4921 4922 FREE(token_enc); 4923 FREE(sender_enc); 4924 FREE(recv_enc); 4925 } 4926 4927 static void yahoo_file_transfer_accept(struct yahoo_input_data *yid, 4928 struct send_file_data *sfd) 4929 { 4930 struct yahoo_packet *pkt; 4931 4932 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, 4933 YPACKET_STATUS_DEFAULT, yid->yd->session_id); 4934 4935 yahoo_packet_hash(pkt, 1, yid->yd->user); 4936 yahoo_packet_hash(pkt, 5, sfd->who); 4937 yahoo_packet_hash(pkt, 265, sfd->id); 4938 yahoo_packet_hash(pkt, 27, sfd->filename); 4939 yahoo_packet_hash(pkt, 249, "3"); 4940 yahoo_packet_hash(pkt, 251, sfd->token); 4941 4942 yahoo_send_packet(yid, pkt, 0); 4943 4944 yahoo_packet_free(pkt); 4945 4946 yahoo_init_ft_recv(yid->yd, sfd); 4947 } 4948 4949 static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, 4950 struct yahoo_packet *pkt) 4951 { 4952 YList *l; 4953 struct send_file_data *sfd; 4954 char *who = NULL; 4955 char *filename = NULL; 4956 char *id = NULL; 4957 char *token = NULL; 4958 4959 for (l = pkt->hash; l; l = l->next) { 4960 struct yahoo_pair *pair = l->data; 4961 switch (pair->key) { 4962 case 4: 4963 who = pair->value; 4964 break; 4965 case 5: 4966 /* Me... don't care */ 4967 break; 4968 case 249: 4969 break; 4970 case 265: 4971 id = pair->value; 4972 break; 4973 case 251: 4974 token = pair->value; 4975 break; 4976 case 27: 4977 filename = pair->value; 4978 break; 4979 } 4980 } 4981 4982 sfd = yahoo_get_active_transfer(id); 4983 4984 if (sfd) { 4985 sfd->token = strdup(token); 4986 4987 yahoo_file_transfer_upload(yid->yd, sfd); 4988 } 4989 else { 4990 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 4991 (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, 4992 sfd->data); 4993 4994 yahoo_remove_active_transfer(sfd); 4995 } 4996 } 4997 4998 static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, 4999 struct yahoo_packet *pkt) 5000 { 5001 YList *l; 5002 char *who = NULL; 5003 char *filename = NULL; 5004 char *id = NULL; 5005 char *token = NULL; 5006 char *ip_addr = NULL; 5007 5008 struct send_file_data *sfd; 5009 5010 for (l = pkt->hash; l; l = l->next) { 5011 struct yahoo_pair *pair = l->data; 5012 switch (pair->key) { 5013 case 1: 5014 case 4: 5015 who = pair->value; 5016 break; 5017 case 5: 5018 /* Me... don't care */ 5019 break; 5020 case 249: 5021 break; 5022 case 265: 5023 id = pair->value; 5024 break; 5025 case 250: 5026 ip_addr = pair->value; 5027 break; 5028 case 251: 5029 token = pair->value; 5030 break; 5031 case 27: 5032 filename = pair->value; 5033 break; 5034 } 5035 } 5036 5037 sfd = yahoo_get_active_transfer(id); 5038 5039 if (sfd) { 5040 sfd->token = strdup(token); 5041 sfd->ip_addr = strdup(ip_addr); 5042 5043 yahoo_file_transfer_accept(yid, sfd); 5044 } 5045 else { 5046 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 5047 (yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, 5048 sfd->data); 5049 5050 yahoo_remove_active_transfer(sfd); 5051 } 5052 } 5053 5054 static void yahoo_send_filetransferinfo(struct yahoo_data *yd, 5055 struct send_file_data *sfd) 5056 { 5057 struct yahoo_input_data *yid; 5058 struct yahoo_packet *pkt; 5059 5060 yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); 5061 sfd->ip_addr = YAHOO_CALLBACK(ext_yahoo_get_ip_addr)("relay.yahoo.com"); 5062 5063 if (!sfd->ip_addr) { 5064 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 5065 (yd->client_id, YAHOO_FILE_TRANSFER_RELAY, sfd->data); 5066 5067 yahoo_remove_active_transfer(sfd); 5068 5069 return; 5070 } 5071 5072 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERINFO, 5073 YPACKET_STATUS_DEFAULT, yd->session_id); 5074 5075 yahoo_packet_hash(pkt, 1, yd->user); 5076 yahoo_packet_hash(pkt, 5, sfd->who); 5077 yahoo_packet_hash(pkt, 265, sfd->id); 5078 yahoo_packet_hash(pkt, 27, sfd->filename); 5079 yahoo_packet_hash(pkt, 249, "3"); 5080 yahoo_packet_hash(pkt, 250, sfd->ip_addr); 5081 5082 yahoo_send_packet(yid, pkt, 0); 5083 5084 yahoo_packet_free(pkt); 5085 } 5086 5087 static void yahoo_process_filetransfer(struct yahoo_input_data *yid, 5088 struct yahoo_packet *pkt) 5089 { 5090 YList *l; 5091 char *who = NULL; 5092 char *filename = NULL; 5093 char *msg = NULL; 5094 char *id = NULL; 5095 int action = 0; 5096 int size = 0; 5097 struct yahoo_data *yd = yid->yd; 5098 5099 struct send_file_data *sfd; 5100 5101 for (l = pkt->hash; l; l = l->next) { 5102 struct yahoo_pair *pair = l->data; 5103 switch (pair->key) { 5104 case 4: 5105 who = pair->value; 5106 break; 5107 case 5: 5108 /* Me... don't care */ 5109 break; 5110 case 222: 5111 action = atoi(pair->value); 5112 break; 5113 case 265: 5114 id = pair->value; 5115 break; 5116 case 266: /* Don't know */ 5117 break; 5118 case 302: /* Start Data? */ 5119 break; 5120 case 300: 5121 break; 5122 case 27: 5123 filename = pair->value; 5124 break; 5125 case 28: 5126 size = atoi(pair->value); 5127 break; 5128 case 14: 5129 msg = pair->value; 5130 case 301: /* End Data? */ 5131 break; 5132 case 303: 5133 break; 5134 5135 } 5136 } 5137 5138 if (action == YAHOO_FILE_TRANSFER_INIT) { 5139 /* Received a FT request from buddy */ 5140 sfd = y_new0(struct send_file_data, 1); 5141 5142 sfd->client_id = yd->client_id; 5143 sfd->id = strdup(id); 5144 sfd->who = strdup(who); 5145 sfd->filename = strdup(filename); 5146 sfd->size = size; 5147 5148 yahoo_add_active_transfer(sfd); 5149 5150 YAHOO_CALLBACK(ext_yahoo_got_file) (yd->client_id, yd->user, 5151 who, msg, filename, size, sfd->id); 5152 } 5153 else { 5154 /* Response to our request */ 5155 sfd = yahoo_get_active_transfer(id); 5156 5157 if (sfd && action == YAHOO_FILE_TRANSFER_ACCEPT) { 5158 yahoo_send_filetransferinfo(yd, sfd); 5159 } 5160 else if (!sfd || action == YAHOO_FILE_TRANSFER_REJECT) { 5161 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 5162 (yd->client_id, YAHOO_FILE_TRANSFER_REJECT, 5163 sfd->data); 5164 5165 yahoo_remove_active_transfer(sfd); 5166 } 5167 } 5168 } 5169 5170 void yahoo_send_file(int id, const char *who, const char *msg, 5171 const char *name, unsigned long size, 5172 yahoo_get_fd_callback callback, void *data) 5173 { 5174 struct yahoo_packet *pkt = NULL; 5175 char size_str[10]; 5176 struct yahoo_input_data *yid; 5177 struct yahoo_data *yd; 5178 struct send_file_data *sfd; 5179 5180 yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 5181 yd = find_conn_by_id(id); 5182 sfd = y_new0(struct send_file_data, 1); 5183 5184 sfd->client_id = id; 5185 sfd->id = yahoo_get_random(); 5186 sfd->who = strdup(who); 5187 sfd->filename = strdup(name); 5188 sfd->size = size; 5189 sfd->callback = callback; 5190 sfd->data = data; 5191 5192 yahoo_add_active_transfer(sfd); 5193 5194 if (!yd) 5195 return; 5196 5197 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, 5198 YPACKET_STATUS_DEFAULT, yd->session_id); 5230 pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id); 5199 5231 5200 5232 snprintf(size_str, sizeof(size_str), "%ld", size); 5201 5233 5202 yahoo_packet_hash(pkt, 1, yd->user);5234 yahoo_packet_hash(pkt, 0, yd->user); 5203 5235 yahoo_packet_hash(pkt, 5, who); 5204 yahoo_packet_hash(pkt, 265, sfd->id); 5205 yahoo_packet_hash(pkt, 222, "1"); 5206 yahoo_packet_hash(pkt, 266, "1"); 5207 yahoo_packet_hash(pkt, 302, "268"); 5208 yahoo_packet_hash(pkt, 300, "268"); 5236 yahoo_packet_hash(pkt, 14, msg); 5209 5237 yahoo_packet_hash(pkt, 27, name); 5210 5238 yahoo_packet_hash(pkt, 28, size_str); 5211 yahoo_packet_hash(pkt, 301, "268"); 5212 yahoo_packet_hash(pkt, 303, "268"); 5213 5214 yahoo_send_packet(yid, pkt, 0); 5215 5216 yahoo_packet_free(pkt); 5217 } 5218 5219 void yahoo_send_file_transfer_response(int client_id, int response, char *id, void *data) 5220 { 5221 struct yahoo_packet *pkt = NULL; 5222 char resp[2]; 5223 struct yahoo_input_data *yid; 5224 5225 struct send_file_data *sfd = yahoo_get_active_transfer(id); 5226 5227 sfd->data = data; 5228 5229 yid = find_input_by_id_and_type(client_id, YAHOO_CONNECTION_PAGER); 5230 5231 pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, 5232 YPACKET_STATUS_DEFAULT, yid->yd->session_id); 5233 5234 snprintf(resp, sizeof(resp), "%d", response); 5235 5236 yahoo_packet_hash(pkt, 1, yid->yd->user); 5237 yahoo_packet_hash(pkt, 5, sfd->who); 5238 yahoo_packet_hash(pkt, 265, sfd->id); 5239 yahoo_packet_hash(pkt, 222, resp); 5240 5241 yahoo_send_packet(yid, pkt, 0); 5242 5243 yahoo_packet_free(pkt); 5244 5245 if(response == YAHOO_FILE_TRANSFER_REJECT) 5246 yahoo_remove_active_transfer(sfd); 5247 } 5248 5249 static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) 5250 { 5251 struct send_file_data *sfd; 5252 struct yahoo_data *yd = yid->yd; 5253 5254 sfd = yahoo_get_active_transfer_with_yid(yid); 5255 5256 if (!sfd) { 5257 LOG(("Something funny happened. yid %p has no sfd.\n", yid)); 5258 return; 5259 } 5260 5261 /* 5262 * We want to handle only the complete data with HEAD since we don't 5263 * want a situation where both the GET and HEAD are active. 5264 * With SEND, we really can't do much with partial response 5265 */ 5266 if ((sfd->state == FT_STATE_HEAD || sfd->state == FT_STATE_SEND) 5267 && !over) 5268 return; 5269 5270 if (sfd->state == FT_STATE_HEAD) { 5271 /* Do a GET */ 5272 char url[256]; 5273 char buff[1024]; 5274 char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; 5275 5276 struct yahoo_input_data *yid_ft = 5277 y_new0(struct yahoo_input_data, 1); 5278 5279 yid_ft->yd = yid->yd; 5280 yid_ft->type = YAHOO_CONNECTION_FT; 5281 5282 inputs = y_list_prepend(inputs, yid_ft); 5283 sfd->yid = yid_ft; 5284 sfd->state = FT_STATE_RECV; 5285 5286 token_enc = yahoo_urlencode(sfd->token); 5287 sender_enc = yahoo_urlencode(sfd->who); 5288 recv_enc = yahoo_urlencode(yd->user); 5289 5290 snprintf(url, sizeof(url), 5291 "http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, 5292 token_enc, sender_enc, recv_enc); 5293 5294 snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, 5295 yd->cookie_t); 5296 5297 5298 yahoo_http_get(yd->client_id, url, buff, 1, 1, 5299 _yahoo_http_connected, yid_ft); 5300 5301 FREE(token_enc); 5302 FREE(sender_enc); 5303 FREE(recv_enc); 5304 } 5305 else if (sfd->state == FT_STATE_RECV || 5306 sfd->state == FT_STATE_RECV_START) { 5307 5308 unsigned char *data_begin = NULL; 5309 5310 if (yid->rxlen == 0) 5311 yahoo_remove_active_transfer(sfd); 5312 5313 if (sfd->state != FT_STATE_RECV_START && 5314 (data_begin = 5315 (unsigned char *)strstr((char *)yid->rxqueue, 5316 "\r\n\r\n"))) { 5317 5318 sfd->state = FT_STATE_RECV_START; 5319 5320 yid->rxlen -= 4+(data_begin-yid->rxqueue)/sizeof(char); 5321 data_begin += 4; 5322 5323 if (yid->rxlen > 0) 5324 YAHOO_CALLBACK(ext_yahoo_got_ft_data) 5325 (yd->client_id, data_begin, 5326 yid->rxlen, sfd->data); 5327 } 5328 else if (sfd->state == FT_STATE_RECV_START) 5329 YAHOO_CALLBACK(ext_yahoo_got_ft_data) (yd->client_id, 5330 yid->rxqueue, yid->rxlen, sfd->data); 5331 5332 FREE(yid->rxqueue); 5333 yid->rxqueue = NULL; 5334 yid->rxlen = 0; 5335 } 5336 else if (sfd->state == FT_STATE_SEND) { 5337 /* Sent file completed */ 5338 int len = 0; 5339 char *off = strstr((char *)yid->rxqueue, "Content-Length: "); 5340 5341 if (off) { 5342 off += 16; 5343 len = atoi(off); 5344 } 5345 5346 if (len < sfd->size) 5347 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 5348 (yd->client_id, 5349 YAHOO_FILE_TRANSFER_FAILED, sfd->data); 5350 else 5351 YAHOO_CALLBACK(ext_yahoo_file_transfer_done) 5352 (yd->client_id, 5353 YAHOO_FILE_TRANSFER_DONE, sfd->data); 5354 5355 yahoo_remove_active_transfer(sfd); 5356 } 5357 } 5358 5359 /* End File Transfer */ 5239 5240 content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); 5241 5242 snprintf(url, sizeof(url), "http://%s:%d/notifyft", 5243 yss->filetransfer_host, yss->filetransfer_port); 5244 snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", 5245 yd->cookie_y, yd->cookie_t); 5246 inputs = y_list_prepend(inputs, yid); 5247 5248 sfd = y_new0(struct send_file_data, 1); 5249 sfd->pkt = pkt; 5250 sfd->callback = callback; 5251 sfd->user_data = data; 5252 yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, 5253 _yahoo_send_file_connected, sfd); 5254 } 5255 5360 5256 5361 5257 enum yahoo_status yahoo_current_status(int id) 5362 5258 { 5363 5259 struct yahoo_data *yd = find_conn_by_id(id); 5364 if 5260 if(!yd) 5365 5261 return YAHOO_STATUS_OFFLINE; 5366 5262 return yd->current_status; 5367 5263 } 5368 5264 5369 const YList * yahoo_get_buddylist(int id)5265 const YList * yahoo_get_buddylist(int id) 5370 5266 { 5371 5267 struct yahoo_data *yd = find_conn_by_id(id); 5372 if 5268 if(!yd) 5373 5269 return NULL; 5374 5270 return yd->buddies; 5375 5271 } 5376 5272 5377 const YList * yahoo_get_ignorelist(int id)5273 const YList * yahoo_get_ignorelist(int id) 5378 5274 { 5379 5275 struct yahoo_data *yd = find_conn_by_id(id); 5380 if 5276 if(!yd) 5381 5277 return NULL; 5382 5278 return yd->ignore; 5383 5279 } 5384 5280 5385 const YList * yahoo_get_identities(int id)5281 const YList * yahoo_get_identities(int id) 5386 5282 { 5387 5283 struct yahoo_data *yd = find_conn_by_id(id); 5388 if 5284 if(!yd) 5389 5285 return NULL; 5390 5286 return yd->identities; 5391 5287 } 5392 5288 5393 const char * yahoo_get_cookie(int id, const char *which)5289 const char * yahoo_get_cookie(int id, const char *which) 5394 5290 { 5395 5291 struct yahoo_data *yd = find_conn_by_id(id); 5396 if 5292 if(!yd) 5397 5293 return NULL; 5398 if 5294 if(!strncasecmp(which, "y", 1)) 5399 5295 return yd->cookie_y; 5400 if (!strncasecmp(which, "b", 1)) 5401 return yd->cookie_b; 5402 if (!strncasecmp(which, "t", 1)) 5296 if(!strncasecmp(which, "t", 1)) 5403 5297 return yd->cookie_t; 5404 if 5298 if(!strncasecmp(which, "c", 1)) 5405 5299 return yd->cookie_c; 5406 if 5300 if(!strncasecmp(which, "login", 5)) 5407 5301 return yd->login_cookie; 5408 5302 return NULL; 5409 5303 } 5410 5304 5411 const char *yahoo_get_profile_url(void) 5305 void yahoo_get_url_handle(int id, const char *url, 5306 yahoo_get_url_handle_callback callback, void *data) 5307 { 5308 struct yahoo_data *yd = find_conn_by_id(id); 5309 if(!yd) 5310 return; 5311 5312 yahoo_get_url_fd(id, url, yd, callback, data); 5313 } 5314 5315 const char * yahoo_get_profile_url( void ) 5412 5316 { 5413 5317 return profile_url; 5414 5318 } 5319
Note: See TracChangeset
for help on using the changeset viewer.