Mercurial > pidgin
comparison libpurple/protocols/oscar/family_icbm.c @ 29458:a538cb73f897
propagate from branch 'im.pidgin.pidgin' (head b0098e2250f135d121960d8152e144e7e344125e)
to branch 'im.pidgin.cpw.rekkanoryo.icqxstatus' (head dcd3ab65d5cfcd79b00a7b95ab5fe788da64c112)
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Sun, 07 Feb 2010 19:31:56 +0000 |
parents | 28d73d34d792 5391094529c6 |
children | a0fb6798d87c |
comparison
equal
deleted
inserted
replaced
28982:791606778223 | 29458:a538cb73f897 |
---|---|
2622 aim_rxcallback_t userfunc; | 2622 aim_rxcallback_t userfunc; |
2623 guint16 channel, reason; | 2623 guint16 channel, reason; |
2624 char *bn; | 2624 char *bn; |
2625 guchar *cookie; | 2625 guchar *cookie; |
2626 guint8 bnlen; | 2626 guint8 bnlen; |
2627 char *xml = NULL; | |
2628 int hdrlen; | |
2629 int curpos; | |
2630 int num1,num2; | |
2631 char *desc, *title, *temp; | |
2632 PurpleAccount *account; | |
2633 PurpleBuddy *buddy; | |
2634 PurplePresence *presence; | |
2635 PurpleStatus *status; | |
2627 | 2636 |
2628 cookie = byte_stream_getraw(bs, 8); | 2637 cookie = byte_stream_getraw(bs, 8); |
2629 channel = byte_stream_get16(bs); | 2638 channel = byte_stream_get16(bs); |
2630 bnlen = byte_stream_get8(bs); | 2639 bnlen = byte_stream_get8(bs); |
2631 bn = byte_stream_getstr(bs, bnlen); | 2640 bn = byte_stream_getstr(bs, bnlen); |
2632 reason = byte_stream_get16(bs); | 2641 reason = byte_stream_get16(bs); |
2633 | 2642 |
2634 if (channel == 0x0002) | 2643 if (channel == 0x0002) |
2635 { | 2644 { |
2636 if (reason == 0x0003) /* channel-specific */ | 2645 hdrlen = byte_stream_getle16(bs); |
2637 /* parse status note text */ | 2646 if ( ((hdrlen == 27 ) && (bs->len > (27 + 51)))) { |
2638 parse_status_note_text(od, cookie, bn, bs); | 2647 byte_stream_advance(bs, 51); |
2639 | 2648 num1 = byte_stream_getle16(bs); |
2640 byte_stream_get16(bs); /* Unknown */ | 2649 num2 = byte_stream_getle16(bs); |
2641 byte_stream_get16(bs); /* Unknown */ | 2650 purple_debug_misc("oscar", "X-Status: Num1 %i, num2 %i\n",num1, num2); |
2642 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) | 2651 |
2643 ret = userfunc(od, conn, frame, channel, bn, reason, cookie); | 2652 if(((num1 == 0x4f00)&&(num2 == 0x3b00))) { |
2653 byte_stream_advance(bs, 86); | |
2654 curpos = byte_stream_curpos(bs); | |
2655 xml = byte_stream_getstr(bs, bs->len - curpos); | |
2656 purple_debug_misc("oscar", "X-Status: Received XML reply\n"); | |
2657 if(xml) { | |
2658 /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", (const char*) xml); */ | |
2659 if ((desc=strstr(xml,"<desc>")) != NULL) { | |
2660 temp=strstr(xml,"</desc>"); | |
2661 temp[0]=0; | |
2662 desc=desc+12; | |
2663 } | |
2664 if ((title=strstr(xml,"<title>")) != NULL) { | |
2665 temp=strstr(xml,"</title>"); | |
2666 temp[0]=0; | |
2667 title=title+13; | |
2668 } else { | |
2669 title=""; | |
2670 } | |
2671 strcpy(xml,title); | |
2672 if (desc) { | |
2673 strcat(xml, " - "); | |
2674 strcat(xml, desc); | |
2675 } | |
2676 purple_debug_misc("oscar", "X-Status reply: %s\n", (const char*)xml); | |
2677 account = purple_connection_get_account(od->gc); | |
2678 buddy = purple_find_buddy(account, sn); | |
2679 presence = purple_buddy_get_presence(buddy); | |
2680 status = purple_presence_get_active_status(presence); | |
2681 purple_prpl_got_user_status(account, sn, | |
2682 purple_status_get_id(status), "message", xml, NULL); | |
2683 } else { | |
2684 purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n"); | |
2685 } | |
2686 } else { | |
2687 purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n" ); | |
2688 /* if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) | |
2689 ret = userfunc(od, conn, frame, channel, sn, reason); */ | |
2690 } | |
2691 | |
2692 } | |
2644 | 2693 |
2645 } else if (channel == 0x0004) { /* ICQ message */ | 2694 } else if (channel == 0x0004) { /* ICQ message */ |
2646 switch (reason) { | 2695 switch (reason) { |
2647 case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ | 2696 case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ |
2648 guint8 statusmsgtype, *msg; | 2697 guint8 statusmsgtype, *msg; |
2697 } /* end switch */ | 2746 } /* end switch */ |
2698 } | 2747 } |
2699 | 2748 |
2700 g_free(cookie); | 2749 g_free(cookie); |
2701 g_free(bn); | 2750 g_free(bn); |
2751 g_free(xml); | |
2702 | 2752 |
2703 return ret; | 2753 return ret; |
2704 } | 2754 } |
2705 | 2755 |
2706 /* | 2756 /* |
2799 */ | 2849 */ |
2800 byte_stream_put16(&bs, event); | 2850 byte_stream_put16(&bs, event); |
2801 | 2851 |
2802 flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0014, 0x0000, snacid, &bs); | 2852 flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0014, 0x0000, snacid, &bs); |
2803 | 2853 |
2854 byte_stream_destroy(&bs); | |
2855 | |
2856 return 0; | |
2857 } | |
2858 | |
2859 /* | |
2860 * Subtype 0x0006 - Send eXtra Status request | |
2861 */ | |
2862 int icq_im_xstatus_request(OscarData *od, const char *sn) | |
2863 { | |
2864 FlapConnection *conn; | |
2865 aim_snacid_t snacid; | |
2866 guchar cookie[8]; | |
2867 GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; | |
2868 ByteStream bs, header, plugindata; | |
2869 PurpleAccount *account; | |
2870 const char *fmt; | |
2871 char *statxml; | |
2872 int xmllen; | |
2873 | |
2874 static const guint8 pluginid[] = | |
2875 { | |
2876 0x09, 0x46, 0x13, 0x49, 0x4C, 0x7F, 0x11, 0xD1, | |
2877 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 | |
2878 }; | |
2879 | |
2880 static const guint8 c_plugindata[] = | |
2881 { | |
2882 0x1B, 0x00, 0x0A, | |
2883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2884 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1, 0x00, 0x00, | |
2885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00, | |
2886 0x01, 0x00, 0x00, 0x4F, 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0, 0x9C, | |
2887 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x53, 0x63, 0x72, 0x69, 0x70, | |
2888 0x74, 0x20, 0x50, 0x6C, 0x75, 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74, | |
2889 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, | |
2890 0x72, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2891 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00 | |
2892 }; | |
2893 | |
2894 if (!od || !(conn = flap_connection_findbygroup(od, 0x0004))) | |
2895 return -EINVAL; | |
2896 | |
2897 if (!sn) | |
2898 return -EINVAL; | |
2899 | |
2900 fmt = "<N><QUERY><Q><PluginID>srvMng</PluginID></Q></QUERY><NOTIFY><srv><id>cAwaySrv</id><req><id>AwayStat</id><trans>2</trans><senderId>%s</senderId></req></srv></NOTIFY></N>\r\n"; | |
2901 | |
2902 account = purple_connection_get_account(od->gc); | |
2903 xmllen = strlen(fmt) - 2 + strlen(account->username); | |
2904 | |
2905 statxml = (char*) g_malloc(xmllen); | |
2906 snprintf(statxml, xmllen, fmt, account->username); | |
2907 | |
2908 aim_icbm_makecookie(cookie); | |
2909 | |
2910 byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2 | |
2911 + 2 + 2 + 8 + 16 + 2 + 2 + 2 + 2 + 2 | |
2912 + 2 + 2 + sizeof(c_plugindata) + xmllen | |
2913 + 2 + 2); | |
2914 | |
2915 snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); | |
2916 aim_im_puticbm(&bs, cookie, 0x0002, sn); | |
2917 | |
2918 byte_stream_new(&header, (7*2) + 16 + 8 + 2 + sizeof(c_plugindata) + xmllen); /* TLV 0x0005 Stream + Size */ | |
2919 byte_stream_new(&plugindata, (sizeof(c_plugindata) + xmllen)); | |
2920 | |
2921 byte_stream_put16(&header, 0x0000); /* Message Type: Request */ | |
2922 byte_stream_putraw(&header, cookie, sizeof(cookie)); /* Message ID */ | |
2923 byte_stream_putraw(&header, pluginid, sizeof(pluginid)); /* Plugin ID */ | |
2924 | |
2925 aim_tlvlist_add_16(&inner_tlvlist, 0x000a, 0x0001); | |
2926 aim_tlvlist_add_noval(&inner_tlvlist, 0x000f); | |
2927 | |
2928 /* Add Plugin Specific Data */ | |
2929 byte_stream_putraw(&plugindata, c_plugindata, sizeof(c_plugindata)); /* Content of TLV 0x2711 */ | |
2930 byte_stream_putstr(&plugindata, statxml); | |
2931 | |
2932 aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, (sizeof(c_plugindata) + xmllen), plugindata.data); | |
2933 | |
2934 aim_tlvlist_write(&header, &inner_tlvlist); | |
2935 | |
2936 | |
2937 aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&header), header.data); | |
2938 aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); /* Empty TLV 0x0003 */ | |
2939 | |
2940 aim_tlvlist_write(&bs, &outer_tlvlist); | |
2941 | |
2942 purple_debug_misc("oscar", "X-Status Request\n"); | |
2943 flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, TRUE); | |
2944 | |
2945 aim_tlvlist_free(inner_tlvlist); | |
2946 aim_tlvlist_free(outer_tlvlist); | |
2947 byte_stream_destroy(&header); | |
2948 byte_stream_destroy(&plugindata); | |
2949 byte_stream_destroy(&bs); | |
2950 g_free(statxml); | |
2951 | |
2952 return 0; | |
2953 } | |
2954 | |
2955 int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie) | |
2956 { | |
2957 FlapConnection *conn; | |
2958 ByteStream bs; | |
2959 aim_snacid_t snacid; | |
2960 PurpleAccount *account; | |
2961 PurpleStatus *status; | |
2962 const char *fmt; | |
2963 const char *formatted_msg; | |
2964 char *msg; | |
2965 char *statxml; | |
2966 const char *title; | |
2967 int len; | |
2968 | |
2969 static const guint8 plugindata[] = { | |
2970 0x1B, 0x00, | |
2971 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2973 0x01, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1, | |
2974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2975 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4F, | |
2976 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0, | |
2977 0x9C, 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00, | |
2978 0x00, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x50, 0x6C, 0x75, | |
2979 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74, | |
2980 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, | |
2981 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x72, 0x72, 0x69, 0x76, 0x65, 0x00, | |
2982 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
2983 0x00, 0x00, 0x00, 0xF3, 0x01, 0x00, 0x00, 0xEF, 0x01, 0x00, 0x00 | |
2984 }; | |
2985 | |
2986 fmt = "<NR><RES><ret event='OnRemoteNotification'><srv><id>cAwaySrv</id><val srv_id='cAwaySrv'><Root><CASXtraSetAwayMessage></CASXtraSetAwayMessage>&l t;uin>%s</uin><index>1</index><title>%s</title><desc>%s</desc></Root></val></srv><srv><id>cRandomizerSrv</id><val srv_id='cRandomizerSrv'>undefined</val></srv></ret></RES></NR>\r\n"; | |
2987 | |
2988 | |
2989 if (!od || !(conn = flap_connection_findbygroup(od, 0x0002))) | |
2990 return -EINVAL; | |
2991 | |
2992 if (!sn) | |
2993 return -EINVAL; | |
2994 | |
2995 account = purple_connection_get_account(od->gc); | |
2996 if(!account) return -EINVAL; | |
2997 | |
2998 /* if (!strcmp(account->username, sn)) | |
2999 icq_im_xstatus_request(od, sn); */ | |
3000 | |
3001 status = purple_presence_get_active_status(account->presence); | |
3002 if (!status) return -EINVAL; | |
3003 title = purple_status_get_name(status); | |
3004 if (!title) return -EINVAL; | |
3005 formatted_msg = purple_status_get_attr_string(status, "message"); | |
3006 if (!formatted_msg) return -EINVAL; | |
3007 msg = purple_markup_strip_html(formatted_msg); | |
3008 if (!msg) return -EINVAL; | |
3009 len = strlen(fmt)-6+strlen(account->username)+strlen(title)+strlen(msg); | |
3010 statxml = (char*) g_malloc(len); | |
3011 | |
3012 snprintf(statxml, len, fmt, | |
3013 account->username, title, msg); | |
3014 | |
3015 purple_debug_misc("oscar", "X-Status AutoReply: %s, %s\n", formatted_msg, msg); | |
3016 | |
3017 byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2 + sizeof(plugindata) + strlen(statxml)); /* 16 extra */ | |
3018 | |
3019 snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0); | |
3020 aim_im_puticbm(&bs, cookie, 0x0002, sn); | |
3021 byte_stream_put16(&bs, 0x0003); | |
3022 byte_stream_putraw(&bs, plugindata, sizeof(plugindata)); | |
3023 byte_stream_putraw(&bs, (const guint8*)statxml, strlen(statxml)); | |
3024 | |
3025 flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs, TRUE); | |
3026 | |
3027 g_free(statxml); | |
3028 g_free(msg); | |
2804 byte_stream_destroy(&bs); | 3029 byte_stream_destroy(&bs); |
2805 | 3030 |
2806 return 0; | 3031 return 0; |
2807 } | 3032 } |
2808 | 3033 |