Changeset e374dee for libfaim/icq.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/icq.c

    r862371b re374dee  
    7171}
    7272
     73faim_export int aim_icq_hideip(aim_session_t *sess)
     74{
     75        aim_conn_t *conn;
     76        aim_frame_t *fr;
     77        aim_snacid_t snacid;
     78        int bslen;
     79
     80        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
     81                return -EINVAL;
     82
     83        bslen = 2+4+2+2+2+4;
     84
     85        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
     86                return -ENOMEM;
     87
     88        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
     89        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
     90
     91        /* For simplicity, don't bother using a tlvlist */
     92        aimbs_put16(&fr->data, 0x0001);
     93        aimbs_put16(&fr->data, bslen);
     94
     95        aimbs_putle16(&fr->data, bslen - 2);
     96        aimbs_putle32(&fr->data, atoi(sess->sn));
     97        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
     98        aimbs_putle16(&fr->data, snacid); /* eh. */
     99        aimbs_putle16(&fr->data, 0x0424); /* shrug. */
     100        aimbs_putle16(&fr->data, 0x0001);
     101        aimbs_putle16(&fr->data, 0x0001);
     102
     103        aim_tx_enqueue(sess, fr);
     104
     105        return 0;
     106}
     107
     108/**
     109 * Change your ICQ password.
     110 *
     111 * @param sess The oscar session
     112 * @param passwd The new password.  If this is longer than 8 characters it
     113 *        will be truncated.
     114 * @return Return 0 if no errors, otherwise return the error number.
     115 */
     116faim_export int aim_icq_changepasswd(aim_session_t *sess, const char *passwd)
     117{
     118        aim_conn_t *conn;
     119        aim_frame_t *fr;
     120        aim_snacid_t snacid;
     121        int bslen, passwdlen;
     122
     123        if (!passwd)
     124                return -EINVAL;
     125
     126        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
     127                return -EINVAL;
     128
     129        passwdlen = strlen(passwd);
     130        if (passwdlen > MAXICQPASSLEN)
     131                passwdlen = MAXICQPASSLEN;
     132        bslen = 2+4+2+2+2+2+passwdlen+1;
     133
     134        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
     135                return -ENOMEM;
     136
     137        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
     138        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
     139
     140        /* For simplicity, don't bother using a tlvlist */
     141        aimbs_put16(&fr->data, 0x0001);
     142        aimbs_put16(&fr->data, bslen);
     143
     144        aimbs_putle16(&fr->data, bslen - 2);
     145        aimbs_putle32(&fr->data, atoi(sess->sn));
     146        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
     147        aimbs_putle16(&fr->data, snacid); /* eh. */
     148        aimbs_putle16(&fr->data, 0x042e); /* shrug. */
     149        aimbs_putle16(&fr->data, passwdlen+1);
     150        aimbs_putraw(&fr->data, passwd, passwdlen);
     151        aimbs_putle8(&fr->data, '\0');
     152
     153        aim_tx_enqueue(sess, fr);
     154
     155        return 0;
     156}
     157
     158faim_export int aim_icq_getallinfo(aim_session_t *sess, const char *uin)
     159{
     160        aim_conn_t *conn;
     161        aim_frame_t *fr;
     162        aim_snacid_t snacid;
     163        int bslen;
     164        struct aim_icq_info *info;
     165
     166        if (!uin || uin[0] < '0' || uin[0] > '9')
     167                return -EINVAL;
     168
     169        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
     170                return -EINVAL;
     171
     172        bslen = 2 + 4 + 2 + 2 + 2 + 4;
     173
     174        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
     175                return -ENOMEM;
     176
     177        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
     178        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
     179
     180        /* For simplicity, don't bother using a tlvlist */
     181        aimbs_put16(&fr->data, 0x0001);
     182        aimbs_put16(&fr->data, bslen);
     183
     184        aimbs_putle16(&fr->data, bslen - 2);
     185        aimbs_putle32(&fr->data, atoi(sess->sn));
     186        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
     187        aimbs_putle16(&fr->data, snacid); /* eh. */
     188        aimbs_putle16(&fr->data, 0x04b2); /* shrug. */
     189        aimbs_putle32(&fr->data, atoi(uin));
     190
     191        aim_tx_enqueue(sess, fr);
     192
     193        /* Keep track of this request and the ICQ number and request ID */
     194        info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
     195        info->reqid = snacid;
     196        info->uin = atoi(uin);
     197        info->next = sess->icq_info;
     198        sess->icq_info = info;
     199
     200        return 0;
     201}
     202
     203faim_export int aim_icq_getalias(aim_session_t *sess, const char *uin)
     204{
     205        aim_conn_t *conn;
     206        aim_frame_t *fr;
     207        aim_snacid_t snacid;
     208        int bslen;
     209        struct aim_icq_info *info;
     210
     211        if (!uin || uin[0] < '0' || uin[0] > '9')
     212                return -EINVAL;
     213
     214        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
     215                return -EINVAL;
     216
     217        bslen = 2 + 4 + 2 + 2 + 2 + 4;
     218
     219        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
     220                return -ENOMEM;
     221
     222        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
     223        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
     224
     225        /* For simplicity, don't bother using a tlvlist */
     226        aimbs_put16(&fr->data, 0x0001);
     227        aimbs_put16(&fr->data, bslen);
     228
     229        aimbs_putle16(&fr->data, bslen - 2);
     230        aimbs_putle32(&fr->data, atoi(sess->sn));
     231        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
     232        aimbs_putle16(&fr->data, snacid); /* eh. */
     233        aimbs_putle16(&fr->data, 0x04ba); /* shrug. */
     234        aimbs_putle32(&fr->data, atoi(uin));
     235
     236        aim_tx_enqueue(sess, fr);
     237
     238        /* Keep track of this request and the ICQ number and request ID */
     239        info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
     240        info->reqid = snacid;
     241        info->uin = atoi(uin);
     242        info->next = sess->icq_info;
     243        sess->icq_info = info;
     244
     245        return 0;
     246}
     247
     248faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
     249{
     250        aim_conn_t *conn;
     251        aim_frame_t *fr;
     252        aim_snacid_t snacid;
     253        int bslen;
     254
     255        if (!uin || uin[0] < '0' || uin[0] > '9')
     256                return -EINVAL;
     257
     258        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
     259                return -EINVAL;
     260
     261        bslen = 2 + 4 + 2 + 2 + 2 + 4;
     262
     263        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
     264                return -ENOMEM;
     265
     266        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
     267        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
     268
     269        /* For simplicity, don't bother using a tlvlist */
     270        aimbs_put16(&fr->data, 0x0001);
     271        aimbs_put16(&fr->data, bslen);
     272
     273        aimbs_putle16(&fr->data, bslen - 2);
     274        aimbs_putle32(&fr->data, atoi(sess->sn));
     275        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
     276        aimbs_putle16(&fr->data, snacid); /* eh. */
     277        aimbs_putle16(&fr->data, 0x051f); /* shrug. */
     278        aimbs_putle32(&fr->data, atoi(uin));
     279
     280        aim_tx_enqueue(sess, fr);
     281
     282        return 0;
     283}
     284
    73285faim_export int aim_icq_sendxmlreq(aim_session_t *sess, const char *xml)
    74286{
     
    109321}
    110322
    111 faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
    112 {
    113         aim_conn_t *conn;
    114         aim_frame_t *fr;
    115         aim_snacid_t snacid;
    116         int bslen;
    117 
    118         if (!uin || uin[0] < '0' || uin[0] > '9')
    119                 return -EINVAL;
    120 
    121         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
    122                 return -EINVAL;
    123 
    124         bslen = 2 + 4 + 2 + 2 + 2 + 4;
    125 
    126         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
    127                 return -ENOMEM;
    128 
    129         snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
    130         aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
    131 
    132         /* For simplicity, don't bother using a tlvlist */
    133         aimbs_put16(&fr->data, 0x0001);
    134         aimbs_put16(&fr->data, bslen);
    135 
    136         aimbs_putle16(&fr->data, bslen - 2);
    137         aimbs_putle32(&fr->data, atoi(sess->sn));
    138         aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
    139         aimbs_putle16(&fr->data, snacid); /* eh. */
    140         aimbs_putle16(&fr->data, 0x051f); /* shrug. */
    141         aimbs_putle32(&fr->data, atoi(uin));
    142 
    143         aim_tx_enqueue(sess, fr);
    144 
    145         return 0;
    146 }
    147 
    148 /*
    149  * Response to 15/2, contains an ICQ packet.
     323static void aim_icq_freeinfo(struct aim_icq_info *info) {
     324        int i;
     325
     326        if (!info)
     327                return;
     328        free(info->nick);
     329        free(info->first);
     330        free(info->last);
     331        free(info->email);
     332        free(info->homecity);
     333        free(info->homestate);
     334        free(info->homephone);
     335        free(info->homefax);
     336        free(info->homeaddr);
     337        free(info->mobile);
     338        free(info->homezip);
     339        free(info->personalwebpage);
     340        if (info->email2)
     341                for (i = 0; i < info->numaddresses; i++)
     342                        free(info->email2[i]);
     343        free(info->email2);
     344        free(info->workcity);
     345        free(info->workstate);
     346        free(info->workphone);
     347        free(info->workfax);
     348        free(info->workaddr);
     349        free(info->workzip);
     350        free(info->workcompany);
     351        free(info->workdivision);
     352        free(info->workposition);
     353        free(info->workwebpage);
     354        free(info->info);
     355        free(info);
     356}
     357
     358/**
     359 * Subtype 0x0003 - Response to 0x0015/0x002, contains an ICQesque packet.
    150360 */
    151361static int icqresponse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
     
    173383        faimdprintf(sess, 1, "icq response: %d bytes, %ld, 0x%04x, 0x%04x\n", cmdlen, ouruin, cmd, reqid);
    174384
    175         if (cmd == 0x0041) {
    176                 fu16_t msglen;
     385        if (cmd == 0x0041) { /* offline message */
    177386                struct aim_icq_offlinemsg msg;
    178387                aim_rxcallback_t userfunc;
     
    186395                msg.hour = aimbs_getle8(&qbs);
    187396                msg.minute = aimbs_getle8(&qbs);
    188                 msg.type = aimbs_getle16(&qbs);
    189                 msglen = aimbs_getle16(&qbs);
    190                 msg.msg = aimbs_getstr(&qbs, msglen);
     397                msg.type = aimbs_getle8(&qbs);
     398                msg.flags = aimbs_getle8(&qbs);
     399                msg.msglen = aimbs_getle16(&qbs);
     400                msg.msg = aimbs_getstr(&qbs, msg.msglen);
    191401
    192402                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG)))
     
    200410                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE)))
    201411                        ret = userfunc(sess, rx);
    202         } else if (cmd == 0x07da) {
     412
     413        } else if (cmd == 0x07da) { /* information */
    203414                fu16_t subtype;
     415                struct aim_icq_info *info;
     416                aim_rxcallback_t userfunc;
    204417
    205418                subtype = aimbs_getle16(&qbs);
    206 
    207                 if (subtype == 0x019a) {
    208                         fu16_t tlen;
    209                         struct aim_icq_simpleinfo info;
    210                         aim_rxcallback_t userfunc;
    211 
    212                         memset(&info, 0, sizeof(info));
    213 
    214                         aimbs_getle8(&qbs); /* no clue */
    215                         aimbs_getle16(&qbs); /* no clue */
    216                         info.uin = aimbs_getle32(&qbs);
    217                         tlen = aimbs_getle16(&qbs);
    218                         info.nick = aimbs_getstr(&qbs, tlen);
    219                         tlen = aimbs_getle16(&qbs);
    220                         info.first = aimbs_getstr(&qbs, tlen);
    221                         tlen = aimbs_getle16(&qbs);
    222                         info.last = aimbs_getstr(&qbs, tlen);
    223                         tlen = aimbs_getle16(&qbs);
    224                         info.email = aimbs_getstr(&qbs, tlen);
    225                         /* no clue what the rest of it is */
    226 
    227                         if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SIMPLEINFO)))
    228                                 ret = userfunc(sess, rx, &info);
    229 
    230                         free(info.nick);
    231                         free(info.first);
    232                         free(info.last);
    233                         free(info.email);
     419                aim_bstream_advance(&qbs, 1); /* 0x0a */
     420
     421                /* find other data from the same request */
     422                for (info = sess->icq_info; info && (info->reqid != reqid); info = info->next);
     423                if (!info) {
     424                        info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
     425                        info->reqid = reqid;
     426                        info->next = sess->icq_info;
     427                        sess->icq_info = info;
    234428                }
    235429
     430                switch (subtype) {
     431                case 0x00a0: { /* hide ip status */
     432                        /* nothing */
     433                } break;
     434
     435                case 0x00aa: { /* password change status */
     436                        /* nothing */
     437                } break;
     438
     439                case 0x00c8: { /* general and "home" information */
     440                        info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     441                        info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     442                        info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     443                        info->email = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     444                        info->homecity = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     445                        info->homestate = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     446                        info->homephone = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     447                        info->homefax = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     448                        info->homeaddr = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     449                        info->mobile = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     450                        info->homezip = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     451                        info->homecountry = aimbs_getle16(&qbs);
     452                        /* 0x0a 00 02 00 */
     453                        /* 1 byte timezone? */
     454                        /* 1 byte hide email flag? */
     455                } break;
     456
     457                case 0x00dc: { /* personal information */
     458                        info->age = aimbs_getle8(&qbs);
     459                        info->unknown = aimbs_getle8(&qbs);
     460                        info->gender = aimbs_getle8(&qbs);
     461                        info->personalwebpage = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     462                        info->birthyear = aimbs_getle16(&qbs);
     463                        info->birthmonth = aimbs_getle8(&qbs);
     464                        info->birthday = aimbs_getle8(&qbs);
     465                        info->language1 = aimbs_getle8(&qbs);
     466                        info->language2 = aimbs_getle8(&qbs);
     467                        info->language3 = aimbs_getle8(&qbs);
     468                        /* 0x00 00 01 00 00 01 00 00 00 00 00 */
     469                } break;
     470
     471                case 0x00d2: { /* work information */
     472                        info->workcity = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     473                        info->workstate = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     474                        info->workphone = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     475                        info->workfax = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     476                        info->workaddr = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     477                        info->workzip = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     478                        info->workcountry = aimbs_getle16(&qbs);
     479                        info->workcompany = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     480                        info->workdivision = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     481                        info->workposition = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     482                        aim_bstream_advance(&qbs, 2); /* 0x01 00 */
     483                        info->workwebpage = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     484                } break;
     485
     486                case 0x00e6: { /* additional personal information */
     487                        info->info = aimbs_getstr(&qbs, aimbs_getle16(&qbs)-1);
     488                } break;
     489
     490                case 0x00eb: { /* email address(es) */
     491                        int i;
     492                        info->numaddresses = aimbs_getle16(&qbs);
     493                        info->email2 = (char **)calloc(info->numaddresses, sizeof(char *));
     494                        for (i = 0; i < info->numaddresses; i++) {
     495                                info->email2[i] = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     496                                if (i+1 != info->numaddresses)
     497                                        aim_bstream_advance(&qbs, 1); /* 0x00 */
     498                        }
     499                } break;
     500
     501                case 0x00f0: { /* personal interests */
     502                } break;
     503
     504                case 0x00fa: { /* past background and current organizations */
     505                } break;
     506
     507                case 0x0104: { /* alias info */
     508                        info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     509                        info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     510                        info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     511                        aim_bstream_advance(&qbs, aimbs_getle16(&qbs)); /* email address? */
     512                        /* Then 0x00 02 00 */
     513                } break;
     514
     515                case 0x010e: { /* unknown */
     516                        /* 0x00 00 */
     517                } break;
     518
     519                case 0x019a: { /* simple info */
     520                        aim_bstream_advance(&qbs, 2);
     521                        info->uin = aimbs_getle32(&qbs);
     522                        info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     523                        info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     524                        info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     525                        info->email = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
     526                        /* Then 0x00 02 00 00 00 00 00 */
     527                } break;
     528                } /* End switch statement */
     529
     530                if (!(snac->flags & 0x0001)) {
     531                        if (subtype != 0x0104)
     532                                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_INFO)))
     533                                        ret = userfunc(sess, rx, info);
     534
     535                        if (info->uin && info->nick)
     536                                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_ALIAS)))
     537                                        ret = userfunc(sess, rx, info);
     538
     539                        if (sess->icq_info == info) {
     540                                sess->icq_info = info->next;
     541                        } else {
     542                                struct aim_icq_info *cur;
     543                                for (cur=sess->icq_info; (cur->next && (cur->next!=info)); cur=cur->next);
     544                                if (cur->next)
     545                                        cur->next = cur->next->next;
     546                        }
     547                        aim_icq_freeinfo(info);
     548                }
    236549        }
    237550
     
    248561
    249562        return 0;
     563}
     564
     565static void icq_shutdown(aim_session_t *sess, aim_module_t *mod)
     566{
     567        struct aim_icq_info *del;
     568
     569        while (sess->icq_info) {
     570                del = sess->icq_info;
     571                sess->icq_info = sess->icq_info->next;
     572                aim_icq_freeinfo(del);
     573        }
     574
     575        return;
    250576}
    251577
     
    256582        mod->version = 0x0001;
    257583        mod->toolid = 0x0110;
    258         mod->toolversion = 0x047b;
     584        mod->toolversion = 0x047c;
    259585        mod->flags = 0;
    260586        strncpy(mod->name, "icq", sizeof(mod->name));
    261587        mod->snachandler = snachandler;
    262 
    263         return 0;
    264 }
     588        mod->shutdown = icq_shutdown;
     589
     590        return 0;
     591}
Note: See TracChangeset for help on using the changeset viewer.