Changeset e374dee for libfaim/info.c


Ignore:
Timestamp:
Oct 10, 2003, 5:12:30 PM (21 years ago)
Author:
James M. Kretchmar <kretch@mit.edu>
Branches:
master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
fe6f1d3
Parents:
f4d0975
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfaim/info.c

    r862371b re374dee  
    99#define FAIM_INTERNAL
    1010#include <aim.h>
     11#ifdef _WIN32
     12#include "win32dep.h"
     13#endif
    1114
    1215struct aim_priv_inforeq {
     
    3033 *
    3134 * Gives BOS your profile.
     35 *
     36 * profile_encoding and awaymsg_encoding MUST be set if profile or
     37 * away are set, respectively, and their value may or may not be
     38 * restricted to a few choices.  I am currently aware of:
    3239 *
    33  */
    34 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, fu32_t caps)
    35 {
    36         static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""};
     40 * us-ascii             Just that
     41 * unicode-2-0          UCS2-BE
     42 *
     43 * profile_len and awaymsg_len MUST be set similarly, and they MUST
     44 * be the length of their respective strings in bytes.
     45 *
     46 * To get the previous behavior of awaymsg == "" un-setting the away
     47 * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the
     48 * obvious equivalent).
     49 *
     50 */
     51faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn,
     52                                  const char *profile_encoding, const char *profile, const int profile_len,
     53                                  const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len,
     54                                  fu32_t caps)
     55{
     56        static const char defencoding[] = {"text/aolrtf; charset=\"%s\""};
    3757        aim_frame_t *fr;
    3858        aim_tlvlist_t *tl = NULL;
    3959        aim_snacid_t snacid;
     60        char *encoding;
     61
     62        if ((profile && profile_encoding == NULL) || (awaymsg && awaymsg_len && awaymsg_encoding == NULL)) {
     63                return -EINVAL;
     64        }
    4065
    4166        /* Build to packet first to get real length */
    4267        if (profile) {
    43                 aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), defencoding);
    44                 aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), profile);
     68                /* no + 1 here because of %s */
     69                encoding = malloc(strlen(defencoding) + strlen(profile_encoding));
     70                if (encoding == NULL) {
     71                        return -ENOMEM;
     72                }
     73                snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding);
     74                aim_addtlvtochain_raw(&tl, 0x0001, strlen(encoding), encoding);
     75                aim_addtlvtochain_raw(&tl, 0x0002, profile_len, profile);
     76                free(encoding);
    4577        }
    4678
     
    5486         */
    5587        if (awaymsg) {
    56                 if (strlen(awaymsg)) {
    57                         aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), defencoding);
    58                         aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), awaymsg);
     88                if (awaymsg_len) {
     89                        encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding));
     90                        if (encoding == NULL) {
     91                                return -ENOMEM;
     92                        }
     93                        snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding);
     94                        aim_addtlvtochain_raw(&tl, 0x0003, strlen(encoding), encoding);
     95                        aim_addtlvtochain_raw(&tl, 0x0004, awaymsg_len, awaymsg);
     96                        free(encoding);
    5997                } else
    6098                        aim_addtlvtochain_noval(&tl, 0x0004);
     
    205243
    206244        /*
    207          * Chat is oddball.
    208          */
    209         {AIM_CAPS_CHAT,
    210          {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1,
    211           0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
    212 
    213         /*
    214          * These are mostly in order.
    215          */
     245         * These are in ascending numerical order.
     246         */
     247        {AIM_CAPS_ICHAT,
     248         {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1,
     249          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     250
     251        {AIM_CAPS_SECUREIM,
     252         {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1,
     253          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     254
     255        {AIM_CAPS_HIPTOP,
     256         {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1,
     257          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     258
    216259        {AIM_CAPS_VOICE,
    217260         {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1,
     
    229272          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
    230273
    231         {AIM_CAPS_IMIMAGE,
     274        {AIM_CAPS_DIRECTIM,
    232275         {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1,
    233276          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     
    237280          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
    238281
     282        /*
     283         * Windows AIM calls this "Add-ins," which is probably more accurate
     284         */
    239285        {AIM_CAPS_SAVESTOCKS,
    240286         {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1,
     
    266312          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
    267313
    268         /* from ICQ2002a
    269         {AIM_CAPS_ICQUNKNOWN2,
     314        /*
     315         * Setting this lets AIM users receive messages from ICQ users, and ICQ
     316         * users receive messages from AIM users.  It also lets ICQ users show
     317         * up in buddy lists for AIM users, and AIM users show up in buddy lists
     318         * for ICQ users.  And ICQ privacy/invisibility acts like AIM privacy,
     319         * in that if you add a user to your deny list, you will not be able to
     320         * see them as online (previous you could still see them, but they
     321         * couldn't see you.
     322         */
     323        {AIM_CAPS_INTEROPERATE,
     324         {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1,
     325          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     326
     327        {AIM_CAPS_ICQUTF8,
    270328         {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1,
    271           0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, */
     329          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     330
     331        {AIM_CAPS_ICQUTF8OLD,
     332         {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,
     333          0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},
     334
     335        /*
     336         * Chat is oddball.
     337         */
     338        {AIM_CAPS_CHAT,
     339         {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1,
     340          0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
     341
     342        /*
     343        {AIM_CAPS_ICQ2GO,
     344         {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd,
     345          0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}},
     346        */
    272347
    273348        {AIM_CAPS_ICQRTF,
    274          {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 
     349         {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34,
    275350          0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}},
    276351
     
    280355          0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}}, */
    281356
    282         {AIM_CAPS_ICQUNKNOWN,
    283          {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,
    284           0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},
     357        {AIM_CAPS_APINFO,
     358         {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6,
     359          0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}},
     360
     361        {AIM_CAPS_TRILLIANCRYPT,
     362         {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,
     363          0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},
    285364
    286365        {AIM_CAPS_EMPTY,
    287366         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    288367          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
    289 
    290         {AIM_CAPS_TRILLIANCRYPT,
    291          {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,
    292           0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},
    293 
    294         {AIM_CAPS_APINFO,
    295          {0xAA, 0x4A, 0x32, 0xB5, 0xF8, 0x84, 0x48, 0xc6,
    296           0xA3, 0xD7, 0x8C, 0x50, 0x97, 0x19, 0xFD, 0x5B}},
    297368
    298369        {AIM_CAPS_LAST}
     
    385456}
    386457
     458faim_internal void aim_info_free(aim_userinfo_t *info)
     459{
     460        free(info->iconcsum);
     461        free(info->availmsg_encoding);
     462        free(info->availmsg);
     463}
     464
    387465/*
    388466 * AIM is fairly regular about providing user info.  This is a generic
    389467 * routine to extract it in its standard form.
    390468 */
    391 faim_internal int aim_extractuserinfo(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo)
     469faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo)
    392470{
    393471        int curtlv, tlvcnt;
     
    478556                         * Type = 0x0004: Idle time.
    479557                         *
    480                          * Number of seconds since the user actively used the
     558                         * Number of minutes since the user actively used the
    481559                         * service.
    482560                         *
     
    530608                         * apparently a port number, and some Other Stuff.
    531609                         *
     610                         * Format is:
     611                         * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43
     612                         *
     613                         *
    532614                         */
    533615                        aimbs_getrawbuf(bs, outinfo->icqinfo.crap, 0x25);
     
    570652                        outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;
    571653
     654                } else if (type == 0x0019) {
     655/*                      faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV type 0x0019: from %s\n", outinfo->sn); */
     656
     657                } else if (type == 0x001b) {
     658/*                      faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV type 0x001b: from %s\n", outinfo->sn); */
     659
    572660                } else if (type == 0x001d) {
    573661                        /*
    574                          * Type 29: Unknown.
    575                          *
    576                          * Currently very rare. Always 18 bytes of mostly zero.
    577                          */
     662                         * Type = 0x001d
     663                         *
     664                         * Buddy icon information and available messages.
     665                         *
     666                         * This almost seems like the AIM protocol guys gave
     667                         * the iChat guys a Type, and the iChat guys tried to
     668                         * cram as much cool shit into it as possible.  Then
     669                         * the Windows AIM guys were like, "hey, that's
     670                         * pretty neat, let's copy those prawns."
     671                         *
     672                         * In that spirit, this can contain a custom message,
     673                         * kind of like an away message, but you're not away
     674                         * (it's called an "available" message).  Or it can
     675                         * contain information about the buddy icon the user
     676                         * has stored on the server.
     677                         */
     678                        int type2, number, length2;
     679
     680                        while (aim_bstream_curpos(bs) < endpos) {
     681                                type2 = aimbs_get16(bs);
     682                                number = aimbs_get8(bs);
     683                                length2 = aimbs_get8(bs);
     684
     685                                switch (type2) {
     686                                        case 0x0000: { /* This is an official buddy icon? */
     687                                                /* This is always 5 bytes of "0x02 01 d2 04 72"? */
     688                                                aim_bstream_advance(bs, length2);
     689                                        } break;
     690
     691                                        case 0x0001: { /* A buddy icon checksum */
     692                                                if ((length2 > 0) && (number == 0x01)) {
     693                                                        free(outinfo->iconcsum);
     694                                                        outinfo->iconcsum = aimbs_getraw(bs, length2);
     695                                                        outinfo->iconcsumlen = length2;
     696                                                } else
     697                                                        aim_bstream_advance(bs, length2);
     698                                        } break;
     699
     700                                        case 0x0002: { /* An available message */
     701                                                if (length2 > 4) {
     702                                                        free(outinfo->availmsg);
     703                                                        outinfo->availmsg_len = aimbs_get16(bs);
     704                                                        outinfo->availmsg = aimbs_getstr(bs, outinfo->availmsg_len);
     705                                                        if (aimbs_get16(bs) == 0x0001) { /* We have an encoding */
     706                                                                aimbs_get16(bs);
     707                                                                outinfo->availmsg_encoding = aimbs_getstr(bs, aimbs_get16(bs));
     708                                                        } else {
     709                                                                /* No explicit encoding, client should use UTF-8 */
     710                                                                outinfo->availmsg_encoding = NULL;
     711                                                        }
     712                                                } else
     713                                                        aim_bstream_advance(bs, length2);
     714                                        } break;
     715
     716                                        default: {
     717                                                aim_bstream_advance(bs, length2);
     718                                        } break;
     719                                }
     720                        }
    578721
    579722                } else if (type == 0x001e) {
     
    607750
    608751/*
    609  * Inverse of aim_extractuserinfo()
     752 * Inverse of aim_info_extract()
    610753 */
    611754faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info)
     
    713856        aim_userinfo_t userinfo;
    714857        char *text_encoding = NULL, *text = NULL;
     858        int textlen = 0;
    715859        aim_rxcallback_t userfunc;
    716860        aim_tlvlist_t *tlvlist;
     861        aim_tlv_t *text_tlv = NULL;
    717862        aim_snac_t *origsnac = NULL;
    718863        struct aim_priv_inforeq *inforeq;
     
    735880        }
    736881
    737         aim_extractuserinfo(sess, bs, &userinfo);
     882        aim_info_extract(sess, bs, &userinfo);
    738883
    739884        tlvlist = aim_readtlvchain(bs);
     
    748893        if (inforeq->infotype == AIM_GETINFO_GENERALINFO) {
    749894                text_encoding = aim_gettlv_str(tlvlist, 0x0001, 1);
    750                 text = aim_gettlv_str(tlvlist, 0x0002, 1);
     895                text_tlv = aim_gettlv(tlvlist, 0x0002, 1);
    751896        } else if (inforeq->infotype == AIM_GETINFO_AWAYMESSAGE) {
    752897                text_encoding = aim_gettlv_str(tlvlist, 0x0003, 1);
    753                 text = aim_gettlv_str(tlvlist, 0x0004, 1);
     898                text_tlv = aim_gettlv(tlvlist, 0x0004, 1);
    754899        } else if (inforeq->infotype == AIM_GETINFO_CAPABILITIES) {
    755900                aim_tlv_t *ct;
     
    765910        }
    766911
     912        if (text_tlv) {
     913                text = text_tlv->value;
     914                textlen = text_tlv->length;
     915        }
     916
    767917        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
    768                 ret = userfunc(sess, rx, &userinfo, inforeq->infotype, text_encoding, text);
    769 
     918                ret = userfunc(sess, rx, &userinfo, inforeq->infotype, text_encoding, text, textlen);
     919
     920        aim_info_free(&userinfo);
    770921        free(text_encoding);
    771         free(text);
    772 
    773922        aim_freetlvchain(&tlvlist);
    774 
    775923        if (origsnac)
    776924                free(origsnac->data);
     
    8871035        mod->family = 0x0002;
    8881036        mod->version = 0x0001;
    889         mod->toolid = 0x0101;
    890         mod->toolversion = 0x047b;
     1037        mod->toolid = 0x0110;
     1038        mod->toolversion = 0x0629;
    8911039        mod->flags = 0;
    8921040        strncpy(mod->name, "locate", sizeof(mod->name));
Note: See TracChangeset for help on using the changeset viewer.