comparison src/protocols/yahoo/yahoo.c @ 6687:d524232faed8

[gaim-migrate @ 7213] Nandan Dixit writes: " This patch has huge improvements for the yahoo protocol in gaim. Among the things it fixes are, Offline message receiving support. Proper support for buddy list (lists greater than 1024 chars) SMS and away embles on custom status" committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Tue, 02 Sep 2003 02:39:17 +0000
parents 0b286eace44c
children 306790891ce7
comparison
equal deleted inserted replaced
6686:0b286eace44c 6687:d524232faed8
107 YAHOO_STATUS_ONVACATION, 107 YAHOO_STATUS_ONVACATION,
108 YAHOO_STATUS_OUTTOLUNCH, 108 YAHOO_STATUS_OUTTOLUNCH,
109 YAHOO_STATUS_STEPPEDOUT, 109 YAHOO_STATUS_STEPPEDOUT,
110 YAHOO_STATUS_INVISIBLE = 12, 110 YAHOO_STATUS_INVISIBLE = 12,
111 YAHOO_STATUS_CUSTOM = 99, 111 YAHOO_STATUS_CUSTOM = 99,
112 YAHOO_STATUS_CUSTOM_ICON = 100,
113 YAHOO_STATUS_CUSTOM_SMS = 101,
112 YAHOO_STATUS_IDLE = 999, 114 YAHOO_STATUS_IDLE = 999,
113 YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ 115 YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */
114 YAHOO_STATUS_TYPING = 0x16 116 YAHOO_STATUS_TYPING = 0x16
115 }; 117 };
116 #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */ 118 #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */
121 int rxlen; 123 int rxlen;
122 GHashTable *hash; 124 GHashTable *hash;
123 GHashTable *games; 125 GHashTable *games;
124 int current_status; 126 int current_status;
125 gboolean logged_in; 127 gboolean logged_in;
128 GString *partial_buddy_list;
126 }; 129 };
127 130
128 struct yahoo_pair { 131 struct yahoo_pair {
129 int key; 132 int key;
130 char *value; 133 char *value;
358 361
359 static void yahoo_process_status(GaimConnection *gc, struct yahoo_packet *pkt) 362 static void yahoo_process_status(GaimConnection *gc, struct yahoo_packet *pkt)
360 { 363 {
361 struct yahoo_data *yd = gc->proto_data; 364 struct yahoo_data *yd = gc->proto_data;
362 GSList *l = pkt->hash; 365 GSList *l = pkt->hash;
366 GSList *l_tmp;
363 char *name = NULL; 367 char *name = NULL;
364 int state = 0; 368 int state = 0;
365 int gamestate = 0; 369 int gamestate = 0;
366 char *msg = NULL; 370 char *msg = NULL;
371 char *icon_state = NULL;
372 char *wireless = NULL;
367 int away = 0; 373 int away = 0;
368 int idle = 0; 374 int idle = 0;
369 375
370 while (l) { 376 while (l) {
371 struct yahoo_pair *pair = l->data; 377 struct yahoo_pair *pair = l->data;
436 } 442 }
437 if (state == YAHOO_STATUS_AVAILABLE) 443 if (state == YAHOO_STATUS_AVAILABLE)
438 serv_got_update(gc, name, 1, 0, 0, 0, gamestate); 444 serv_got_update(gc, name, 1, 0, 0, 0, gamestate);
439 else if (state == YAHOO_STATUS_IDLE) 445 else if (state == YAHOO_STATUS_IDLE)
440 serv_got_update(gc, name, 1, 0, 0, (idle?idle:time(NULL)), (state << 2) | UC_UNAVAILABLE | gamestate); 446 serv_got_update(gc, name, 1, 0, 0, (idle?idle:time(NULL)), (state << 2) | UC_UNAVAILABLE | gamestate);
447 else if ((state == YAHOO_STATUS_CUSTOM)&&(icon_state)){
448 if (icon_state[0]=='0') serv_got_update(gc, name, 1, 0, 0, 0,
449 (state << 2)| UC_UNAVAILABLE | gamestate);
450 else serv_got_update(gc, name, 1, 0, 0, 0,
451 (YAHOO_STATUS_CUSTOM_ICON << 2) | UC_UNAVAILABLE | gamestate);
452 }
441 else { 453 else {
442 if (away) 454 if (away)
443 serv_got_update(gc, name, 1, 0, 0, idle, (state << 2) | UC_UNAVAILABLE | gamestate); 455 serv_got_update(gc, name, 1, 0, 0, idle, (state << 2) | UC_UNAVAILABLE | gamestate);
444 else 456 else
445 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | gamestate); 457 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | gamestate);
446 } 458 }
459
447 away = 0; 460 away = 0;
448 idle = 0; 461 idle = 0;
449 break; 462 msg=NULL;
450 case 60: /* SMS, but comes after 13. but name hasnt been destroyed yet. */ 463 icon_state=NULL;
451 break; 464 break;
465 case 47: /* custom message */
466 icon_state = pair->value;
467 break;
468 case 60: /* SMS, comes after 13. but name hasnt been destroyed yet. :) */
469 wireless = pair->value;
470 if(wireless[0]=='1')
471 serv_got_update(gc, name, 1, 0, 0, 0, (YAHOO_STATUS_CUSTOM_SMS << 2) | UC_UNAVAILABLE | gamestate);
472 break;
452 case 16: /* Custom error message */ 473 case 16: /* Custom error message */
453 gaim_notify_error(gc, NULL, pair->value, NULL); 474 gaim_notify_error(gc, NULL, pair->value, NULL);
454 break; 475 break;
455 default: 476 default:
456 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", 477 gaim_debug(GAIM_DEBUG_ERROR, "yahoo",
466 { 487 {
467 GSList *l = pkt->hash; 488 GSList *l = pkt->hash;
468 gboolean export = FALSE; 489 gboolean export = FALSE;
469 struct buddy *b; 490 struct buddy *b;
470 struct group *g; 491 struct group *g;
471 492 struct yahoo_data *yd = (struct yahoo_data*) gc->proto_data;
472 while (l) { 493
473 char **lines; 494 while(l) {
474 char **split; 495 struct yahoo_pair *tmp_pair = l->data;
475 char **buddies; 496 l=l->next;
476 char **tmp, **bud; 497 if (tmp_pair->key == 87) {
477 498 if( yd->partial_buddy_list )
478 struct yahoo_pair *pair = l->data; 499 g_string_append(yd->partial_buddy_list,tmp_pair->value);
479 l = l->next; 500 else
480 501 yd->partial_buddy_list=g_string_new(tmp_pair->value); }
481 if (pair->key != 87) 502 else if((tmp_pair->key == 59) && (yd->partial_buddy_list)){
482 continue; 503 char *full_buddy_list;
483 504 if(yd->partial_buddy_list) full_buddy_list=yd->partial_buddy_list->str;
484 lines = g_strsplit(pair->value, "\n", -1); 505 else full_buddy_list=tmp_pair->value;
485 for (tmp = lines; *tmp; tmp++) { 506
486 split = g_strsplit(*tmp, ":", 2); 507 char **lines;
487 if (!split) 508 char **split;
488 continue; 509 char **buddies;
489 if (!split[0] || !split[1]) { 510 char **tmp, **bud;
490 g_strfreev(split); 511
491 continue; 512 lines = g_strsplit(full_buddy_list, "\n", -1);
492 } 513 for (tmp = lines; *tmp; tmp++) {
493 buddies = g_strsplit(split[1], ",", -1); 514 split = g_strsplit(*tmp, ":", 2);
494 for (bud = buddies; bud && *bud; bud++) 515 if (!split)
495 if (!(b = gaim_find_buddy(gc->account, *bud))) { 516 continue;
496 if (!(g = gaim_find_group(split[0]))) { 517 if (!split[0] || !split[1]) {
497 g = gaim_group_new(split[0]); 518 g_strfreev(split);
498 gaim_blist_add_group(g, NULL); 519 continue;
520 }
521 buddies = g_strsplit(split[1], ",", -1);
522 for (bud = buddies; bud && *bud; bud++)
523 if (!(b = gaim_find_buddy(gc->account, *bud))) {
524 if (!(g = gaim_find_group(split[0]))) {
525 g = gaim_group_new(split[0]);
526 gaim_blist_add_group(g, NULL);
527 }
528 b = gaim_buddy_new(gc->account, *bud, NULL);
529 gaim_blist_add_buddy(b, g, NULL);
530 export = TRUE;
499 } 531 }
500 b = gaim_buddy_new(gc->account, *bud, NULL); 532 g_strfreev(buddies);
501 gaim_blist_add_buddy(b, g, NULL); 533 g_strfreev(split);
502 export = TRUE; 534 }
503 } 535 g_strfreev(lines);
504 g_strfreev(buddies); 536 g_free(yd->partial_buddy_list);
505 g_strfreev(split); 537 }
506 } 538 }
507 g_strfreev(lines);
508 }
509 539
510 if (export) 540 if (export)
511 gaim_blist_save(); 541 gaim_blist_save();
512 } 542 }
513 543
572 static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt) 602 static void yahoo_process_message(GaimConnection *gc, struct yahoo_packet *pkt)
573 { 603 {
574 char *msg = NULL; 604 char *msg = NULL;
575 char *from = NULL; 605 char *from = NULL;
576 time_t tm = time(NULL); 606 time_t tm = time(NULL);
577 GSList *l = pkt->hash; 607 /*GSList *l = pkt->hash;*/
578 608 GList *l;
579 if (pkt->status <= 1 || pkt->status == 5) { 609 GList * messages = NULL;
580 while (l) { 610 struct _m {
581 struct yahoo_pair *pair = l->data; 611 int i_31;
582 if (pair->key == 4) 612 int i_32;
583 from = pair->value; 613 char *to;
584 if (pair->key == 15) 614 char *from;
585 tm = strtol(pair->value, NULL, 10); 615 long tm;
586 if (pair->key == 14) { 616 char *msg;
587 char *m; 617 int utf8;
588 618 };
589 msg = pair->value; 619
590 620 if ((pkt->status <= 1) || (pkt->status == 5)) {
591 strip_linefeed(msg); 621 struct _m *message = g_new0(struct _m, 1);
592 m = yahoo_codes_to_html(msg); 622
593 serv_got_im(gc, from, m, 0, tm, -1); 623 for (l = pkt->hash; l; l = l->next) {
594 g_free(m); 624 struct yahoo_pair *pair = l->data;
595 625 if (pair->key == 1 || pair->key == 4)
596 tm = time(NULL); 626 message->from = pair->value;
627 else if (pair->key == 5)
628 message->to = pair->value;
629 else if (pair->key == 15)
630 message->tm = strtol(pair->value, NULL, 10);
631 else if (pair->key == 97)
632 message->utf8 = atoi(pair->value);
633 /* user message */ /* sys message */
634 else if (pair->key == 14 || pair->key == 16)
635 message->msg = pair->value;
636 else if (pair->key == 31) {
637 if(message->i_31) {
638 messages = g_list_append(messages, message);
639 message = g_new0(struct _m, 1);
640 }
641 message->i_31 = atoi(pair->value);
597 } 642 }
598 l = l->next; 643 else if (pair->key == 32)
599 } 644 message->i_32 = atoi(pair->value);
645 else ;
646 /* LOG(("yahoo_process_message: status: %d, key: %d, value: %s",
647 pkt->status, pair->key, pair->value));*/
648 }
649
650 messages = g_list_append(messages, message);
651
652 /*printf("Message vector made!\n");*/
653
654 l=messages;
655 while(l){
656 message = l->data;
657 char *m;
658 int i, j;
659
660 m = message->msg;
661 /*printf("Stripping linefeed!\n");*/
662
663 strip_linefeed(m);
664 /*printf("Stripped!\n");*/
665
666 for (i = 0, j = 0; m[i]; i++) {
667 if (m[i] == 033) {
668 while (m[i] && (m[i] != 'm'))
669 i++;
670 if (!m[i])
671 i--;
672 continue;
673 }
674 m[j++] = m[i];
675 }
676 m[j] = 0;
677 if (message->tm) tm = message->tm;
678 else tm = time(NULL);
679 serv_got_im(gc, message->from, message->msg, 0, tm, -1);
680 l=l->next;
681 }
682 for (l = messages; l; l=l->next) {
683 free(l->data);
684 }
685 g_list_free(messages);
686
600 } else if (pkt->status == 2) { 687 } else if (pkt->status == 2) {
601 gaim_notify_error(gc, NULL, 688 gaim_notify_error(gc, NULL,
602 _("Your Yahoo! message did not get sent."), NULL); 689 _("Your Yahoo! message did not get sent."), NULL);
603 } 690 }
604 } 691 }
1070 } 1157 }
1071 1158
1072 static void yahoo_list_emblems(struct buddy *b, char **se, char **sw, char **nw, char **ne) 1159 static void yahoo_list_emblems(struct buddy *b, char **se, char **sw, char **nw, char **ne)
1073 { 1160 {
1074 int i = 0; 1161 int i = 0;
1162 int status=(b->uc >> 2);
1075 char *emblems[4] = {NULL,NULL,NULL,NULL}; 1163 char *emblems[4] = {NULL,NULL,NULL,NULL};
1076 if (b->present == GAIM_BUDDY_OFFLINE) { 1164 if (b->present == GAIM_BUDDY_OFFLINE) {
1077 *se = "offline"; 1165 *se = "offline";
1078 return; 1166 return;
1079 } else { 1167 } else {
1080 if (b->uc & UC_UNAVAILABLE) 1168 switch(status){
1081 emblems[i++] = "away"; 1169 case YAHOO_STATUS_BRB:
1170 case YAHOO_STATUS_BUSY:
1171 case YAHOO_STATUS_NOTATHOME:
1172 case YAHOO_STATUS_NOTATDESK:
1173 case YAHOO_STATUS_NOTINOFFICE:
1174 case YAHOO_STATUS_ONPHONE:
1175 case YAHOO_STATUS_ONVACATION:
1176 case YAHOO_STATUS_OUTTOLUNCH:
1177 case YAHOO_STATUS_STEPPEDOUT:
1178 case YAHOO_STATUS_CUSTOM_ICON :
1179 emblems[i++]="offline";
1180 break;
1181 case YAHOO_STATUS_CUSTOM_SMS :
1182 emblems[i++]="wireless";
1183 break;
1184 case YAHOO_STATUS_CUSTOM :
1185 emblems[i++] = "away";
1186 break;
1187 case YAHOO_STATUS_AVAILABLE:
1188 case YAHOO_STATUS_TYPING:
1189 case YAHOO_STATUS_INVISIBLE:
1190 case YAHOO_STATUS_IDLE :
1191 case YAHOO_STATUS_OFFLINE:
1192 default:
1193 break;
1194 }
1195 /* if (b->uc & UC_UNAVAILABLE)
1196 * emblems[i++] = "away";*/
1197
1082 if (b->uc & YAHOO_STATUS_GAME) 1198 if (b->uc & YAHOO_STATUS_GAME)
1083 emblems[i++] = "game"; 1199 emblems[i++] = "game";
1084 } 1200 }
1085 *se = emblems[0]; 1201 *se = emblems[0];
1086 *sw = emblems[1]; 1202 *sw = emblems[1];
1136 } 1252 }
1137 1253
1138 static char *yahoo_status_text(struct buddy *b) 1254 static char *yahoo_status_text(struct buddy *b)
1139 { 1255 {
1140 struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data; 1256 struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data;
1141 1257 if (b->uc & UC_UNAVAILABLE) {
1142 if ((b->uc & UC_UNAVAILABLE) && ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) 1258 if (((b->uc >> 2) != YAHOO_STATUS_CUSTOM)
1143 && ((b->uc >> 2) != YAHOO_STATUS_IDLE)) 1259 && ((b->uc >> 2) != YAHOO_STATUS_CUSTOM_ICON)
1260 && ((b->uc >> 2) != YAHOO_STATUS_CUSTOM_SMS))
1144 return g_strdup(yahoo_get_status_string(b->uc >> 2)); 1261 return g_strdup(yahoo_get_status_string(b->uc >> 2));
1145 else if ((b->uc >> 2) == YAHOO_STATUS_CUSTOM) { 1262 else if ((b->uc >> 2) == YAHOO_STATUS_CUSTOM) {
1146 char *stripped = strip_html(g_hash_table_lookup(yd->hash, b->name)); 1263 char *stripped = strip_html(g_hash_table_lookup(yd->hash, b->name));
1147 if(stripped) { 1264 if(stripped) {
1148 char *ret = g_markup_escape_text(stripped, strlen(stripped)); 1265 char *ret = g_markup_escape_text(stripped, strlen(stripped));
1285 { 1402 {
1286 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; 1403 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;
1287 struct yahoo_packet *pkt; 1404 struct yahoo_packet *pkt;
1288 int service; 1405 int service;
1289 char s[4]; 1406 char s[4];
1290 1407 char icon_state[2];
1408
1291 if (gc->away) { 1409 if (gc->away) {
1292 g_free(gc->away); 1410 g_free(gc->away);
1293 gc->away = NULL; 1411 gc->away = NULL;
1294 } 1412 }
1295 1413
1342 else 1460 else
1343 service = YAHOO_SERVICE_ISAWAY; 1461 service = YAHOO_SERVICE_ISAWAY;
1344 pkt = yahoo_packet_new(service, yd->current_status, 0); 1462 pkt = yahoo_packet_new(service, yd->current_status, 0);
1345 g_snprintf(s, sizeof(s), "%d", yd->current_status); 1463 g_snprintf(s, sizeof(s), "%d", yd->current_status);
1346 yahoo_packet_hash(pkt, 10, s); 1464 yahoo_packet_hash(pkt, 10, s);
1347 if (yd->current_status == YAHOO_STATUS_CUSTOM) { 1465 if (yd->current_status == YAHOO_STATUS_CUSTOM){
1348 yahoo_packet_hash(pkt, 47, "1"); 1466 if (msg[0]=='!'){
1349 yahoo_packet_hash(pkt, 19, msg); 1467 yahoo_packet_hash(pkt, 19, msg + 1 );
1468 strcpy(icon_state,"1");
1469 yahoo_packet_hash(pkt, 47, icon_state);
1470
1471 }
1472 else{
1473 yahoo_packet_hash(pkt, 19, msg);
1474 strcpy(icon_state,"0");
1475 yahoo_packet_hash(pkt, 47, icon_state);
1476 }
1350 } 1477 }
1351 1478
1352 yahoo_send_packet(yd, pkt); 1479 yahoo_send_packet(yd, pkt);
1353 yahoo_packet_free(pkt); 1480 yahoo_packet_free(pkt);
1354 } 1481 }