Mercurial > pidgin.yaz
comparison src/protocols/qq/qq.c @ 14049:8294485b79db
[gaim-migrate @ 16662]
Enhanced protocol testing tools, primarily by designing a more useful interface for sending customized packets.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Huetsch <markhuetsch> |
---|---|
date | Mon, 07 Aug 2006 06:17:13 +0000 |
parents | 80891029f5dd |
children | f78289db8977 |
comparison
equal
deleted
inserted
replaced
14048:9c4bec886220 | 14049:8294485b79db |
---|---|
26 #define random rand | 26 #define random rand |
27 #endif | 27 #endif |
28 | 28 |
29 #include "accountopt.h" | 29 #include "accountopt.h" |
30 #include "debug.h" | 30 #include "debug.h" |
31 #include "gtkroomlist.h" | |
31 #include "notify.h" | 32 #include "notify.h" |
32 #include "prefs.h" | 33 #include "prefs.h" |
33 #include "prpl.h" | 34 #include "prpl.h" |
34 #include "request.h" | 35 #include "request.h" |
35 #include "server.h" | 36 #include "server.h" |
584 _("Locate an IP address"), NULL, fields, | 585 _("Locate an IP address"), NULL, fields, |
585 _("Check"), G_CALLBACK(_qq_menu_locate_ip_cb), _("Cancel"), NULL, gc); | 586 _("Check"), G_CALLBACK(_qq_menu_locate_ip_cb), _("Cancel"), NULL, gc); |
586 } | 587 } |
587 */ | 588 */ |
588 | 589 |
589 /* | |
590 static void _qq_menu_search_or_add_permanent_group(GaimPluginAction * action) | 590 static void _qq_menu_search_or_add_permanent_group(GaimPluginAction * action) |
591 { | 591 { |
592 gaim_gtk_roomlist_dialog_show(); | 592 gaim_gtk_roomlist_dialog_show(); |
593 } | 593 } |
594 */ | |
595 | 594 |
596 /* | 595 /* |
597 static void _qq_menu_create_permanent_group(GaimPluginAction * action) | 596 static void _qq_menu_create_permanent_group(GaimPluginAction * action) |
598 { | 597 { |
599 GaimConnection *gc = (GaimConnection *) action->context; | 598 GaimConnection *gc = (GaimConnection *) action->context; |
657 g_return_if_fail (gc != NULL && gc->proto_data != NULL); | 656 g_return_if_fail (gc != NULL && gc->proto_data != NULL); |
658 qq_send_file(gc, buddy->name, NULL); | 657 qq_send_file(gc, buddy->name, NULL); |
659 // } | 658 // } |
660 } | 659 } |
661 */ | 660 */ |
662 /* | 661 |
663 static void _qq_send_custom_packet(GaimConnection *gc, const gchar *packet) | 662 static gboolean _qq_parse_custom_packet_field(GaimRequestFields *fields, |
664 { | 663 const gchar *id, guint8 **value) |
665 guint16 cmd; | 664 { |
666 guint8 *buffer; | 665 GaimRequestField *field; |
667 gint len; | 666 const gchar *str; |
668 | 667 gint len, i; |
669 if (!packet) { | 668 gboolean success; |
670 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Null packet inputted!\n"); | 669 |
670 success = FALSE; | |
671 field = gaim_request_fields_get_field(fields, id); | |
672 str = gaim_request_field_string_get_value(field); | |
673 if (str) { | |
674 success = TRUE; | |
675 if (strcmp(id, "uid") != 0) { | |
676 *value = hex_str_to_bytes(str, &len); | |
677 if (!*value || len != 2) | |
678 success = FALSE; | |
679 } else { | |
680 for (i = 0; i < strlen(str); i++) { | |
681 if (!g_ascii_isdigit(str[i])) { | |
682 success = FALSE; | |
683 break; | |
684 } | |
685 } | |
686 if (success) { | |
687 *(guint32 *) value = strtoul(str, NULL, 10); | |
688 if (errno == ERANGE) | |
689 success = FALSE; | |
690 } | |
691 } | |
692 } | |
693 if (!success) | |
694 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Invalid entry: %s\n", id); | |
695 return success; | |
696 } | |
697 | |
698 static gboolean _qq_parse_custom_packet_fields(GaimRequestFields *fields, | |
699 guint8 **client, guint8 **cmd, guint8 **seq, guint32 *uid, | |
700 guint8 **body, gint *body_len) | |
701 { | |
702 GaimRequestField *field; | |
703 gboolean success; | |
704 | |
705 success = TRUE; | |
706 *client = *cmd = *seq = *body = NULL; | |
707 *uid = 0; | |
708 success = _qq_parse_custom_packet_field(fields, "client", client); | |
709 if (success) | |
710 success = _qq_parse_custom_packet_field(fields, "cmd", cmd); | |
711 if (success) | |
712 success = _qq_parse_custom_packet_field(fields, "uid", (guint8 **) uid); | |
713 if (success) | |
714 success = _qq_parse_custom_packet_field(fields, "seq", seq); | |
715 if (success) { | |
716 field = gaim_request_fields_get_field(fields, "body"); | |
717 *body = hex_str_to_bytes(gaim_request_field_string_get_value(field), | |
718 body_len); | |
719 } else { | |
720 if (*client) | |
721 g_free(*client); | |
722 if (*cmd) | |
723 g_free(*cmd); | |
724 if (*seq) | |
725 g_free(*seq); | |
726 } | |
727 return success; | |
728 } | |
729 | |
730 static void _qq_send_custom_packet_cb(GaimConnection *gc, GaimRequestFields *fields) | |
731 { | |
732 guint32 uid; | |
733 guint8 *buf, *client, *cmd, *seq, *body, *cursor; | |
734 gint bytes, len; | |
735 qq_data *qd; | |
736 gboolean success; | |
737 | |
738 qd = (qq_data *) gc->proto_data; | |
739 | |
740 success = _qq_parse_custom_packet_fields(fields, &client, &cmd, | |
741 &seq, &uid, &body, &len); | |
742 if (!success) { | |
743 gaim_notify_error(gc, _("Error"), _("Invalid packet entry"), NULL); | |
671 return; | 744 return; |
672 } | 745 } |
673 if (strlen(packet) > MAX_PACKET_SIZE * 2) { | 746 |
674 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Packet inputted is too large!\n"); | 747 if (body) |
675 return; | 748 g_return_if_fail(len+12 <= MAX_PACKET_SIZE); |
749 | |
750 bytes = 0; | |
751 buf = g_newa(guint8, MAX_PACKET_SIZE); | |
752 cursor = buf; | |
753 /* QQ TCP packet has two bytes in the beginning to define packet length | |
754 * so I leave room here for size */ | |
755 if (qd->use_tcp) | |
756 bytes += create_packet_w(buf, &cursor, 0x0000); | |
757 bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAG); | |
758 bytes += create_packet_w(buf, &cursor, *(guint16 *) client); | |
759 bytes += create_packet_w(buf, &cursor, *(guint16 *) cmd); | |
760 bytes += create_packet_w(buf, &cursor, *(guint16 *) seq); | |
761 bytes += create_packet_dw(buf, &cursor, uid); | |
762 if (body) { | |
763 bytes += create_packet_data(buf, &cursor, body, len); | |
764 g_free(body); | |
676 } | 765 } |
677 if (strlen(packet) < 4) { | 766 bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAIL); |
678 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Packet is impossibly short!\n"); | 767 |
679 return; | 768 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Custom packet of length %i\n", bytes); |
680 } | 769 _qq_show_packet("Outgoing custom packet", buf, bytes); |
681 | 770 |
682 buffer = hex_str_to_bytes(packet); | 771 _qq_send_packet(gc, buf, bytes, *(guint16 *) cmd); |
683 if (!buffer) { | 772 g_free(client); |
684 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Invalid packet inputted!\n"); | 773 g_free(cmd); |
685 return; | 774 g_free(seq); |
686 } | 775 } |
687 // big endian | |
688 cmd = 256 * buffer[0] + buffer[1]; | |
689 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Inputted CMD: %d\n", cmd); | |
690 | |
691 len = strlen(buffer) - 2; | |
692 packet = buffer + 2; | |
693 | |
694 qq_send_cmd(gc, cmd, TRUE, 0, TRUE, packet, len); | |
695 | |
696 g_free(buffer); | |
697 } | |
698 */ | |
699 | 776 |
700 /* send a custom packet to the server - for protocol testing */ | 777 /* send a custom packet to the server - for protocol testing */ |
701 /* | |
702 static void _qq_menu_send_custom_packet(GaimPluginAction *action) | 778 static void _qq_menu_send_custom_packet(GaimPluginAction *action) |
703 { | 779 { |
704 GaimConnection *gc = (GaimConnection *) action->context; | 780 GaimConnection *gc; |
705 g_return_if_fail(gc != NULL); | 781 GaimRequestFields *fields; |
706 gaim_request_input(gc, _("Send Custom Packet"), | 782 GaimRequestFieldGroup *group; |
707 _("Enter the packet in hex here"), | 783 GaimRequestField *field; |
708 _("Include the command and everything following"), | 784 gchar *tmp; |
709 NULL, FALSE, FALSE, NULL, | 785 qq_data *qd; |
710 _("Send"), G_CALLBACK(_qq_send_custom_packet), _("Cancel"), NULL, gc); | 786 |
711 } | 787 gc = (GaimConnection *) action->context; |
712 */ | 788 qd = (qq_data *) gc->proto_data; |
789 g_return_if_fail(gc != NULL && qd != NULL); | |
790 | |
791 fields = gaim_request_fields_new(); | |
792 group = gaim_request_field_group_new(_("Packet Elements")); | |
793 gaim_request_fields_add_group(fields, group); | |
794 tmp = g_strdup_printf("%04X", QQ_CLIENT); | |
795 field = gaim_request_field_string_new("client", _("Client (hex)"), tmp, FALSE); | |
796 g_free(tmp); | |
797 gaim_request_field_group_add_field(group, field); | |
798 field = gaim_request_field_string_new("cmd", _("Command (hex)"), "0000", FALSE); | |
799 gaim_request_field_group_add_field(group, field); | |
800 field = gaim_request_field_string_new("seq", _("Sequence (hex)"), "0000", FALSE); | |
801 gaim_request_field_group_add_field(group, field); | |
802 tmp = g_strdup_printf("%u", qd->uid); | |
803 field = gaim_request_field_string_new("uid", _("QQ Number (decimal)"), tmp, FALSE); | |
804 g_free(tmp); | |
805 gaim_request_field_group_add_field(group, field); | |
806 field = gaim_request_field_string_new("body", _("Body (hex)"), NULL, FALSE); | |
807 gaim_request_field_group_add_field(group, field); | |
808 | |
809 gaim_request_fields(gc, _("Send a custom packet"), | |
810 _("Send a custom packet"), NULL, fields, | |
811 _("Send"), G_CALLBACK(_qq_send_custom_packet_cb), | |
812 _("Cancel"), NULL, | |
813 gc); | |
814 } | |
713 | 815 |
714 /* protocol related menus */ | 816 /* protocol related menus */ |
715 static GList *_qq_actions(GaimPlugin *plugin, gpointer context) | 817 static GList *_qq_actions(GaimPlugin *plugin, gpointer context) |
716 { | 818 { |
717 GList *m; | 819 GList *m; |
725 m = g_list_append(m, act); | 827 m = g_list_append(m, act); |
726 | 828 |
727 act = gaim_plugin_action_new(_("Show Login Information"), _qq_menu_show_login_info); | 829 act = gaim_plugin_action_new(_("Show Login Information"), _qq_menu_show_login_info); |
728 m = g_list_append(m, act); | 830 m = g_list_append(m, act); |
729 | 831 |
730 /* | 832 /* |
731 act = gaim_plugin_action_new(_("Send Custom Packet"), _qq_menu_send_custom_packet); | 833 act = gaim_plugin_action_new(_("Send Custom Packet"), _qq_menu_send_custom_packet); |
732 m = g_list_append(m, act); | 834 m = g_list_append(m, act); |
733 */ | 835 */ |
734 | 836 |
735 /* XXX consider re-enabling this | 837 /* XXX consider re-enabling this |
736 act = gaim_plugin_action_new(_("Show System Message"), _qq_menu_show_system_message); | 838 act = gaim_plugin_action_new(_("Show System Message"), _qq_menu_show_system_message); |
737 m = g_list_append(m, act); | 839 m = g_list_append(m, act); |
738 */ | 840 */ |
739 | 841 |
740 /* XXX the old group gtk code needs to moved to the gaim UI before this can be used | 842 /* |
741 act = gaim_plugin_action_new(_("Qun: Search a permanent Qun"), _qq_menu_search_or_add_permanent_group); | 843 act = gaim_plugin_action_new(_("Qun: Search a permanent Qun"), _qq_menu_search_or_add_permanent_group); |
742 m = g_list_append(m, act); | 844 m = g_list_append(m, act); |
743 | 845 |
744 act = gaim_plugin_action_new(_("Qun: Create a permanent Qun"), _qq_menu_create_permanent_group); | 846 act = gaim_plugin_action_new(_("Qun: Create a permanent Qun"), _qq_menu_create_permanent_group); |
745 m = g_list_append(m, act); | 847 m = g_list_append(m, act); |