Changeset 6042a54


Ignore:
Timestamp:
2012-10-19T23:38:33Z (7 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
509cf60
Parents:
386042c
Message:

Massive cleanup in OSCAR.

Location:
protocols/oscar
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • protocols/oscar/aim.h

    r386042c r6042a54  
    410410#define AIM_USERINFO_PRESENT_SESSIONLEN   0x00000100
    411411
    412 const char *aim_userinfo_sn(aim_userinfo_t *ui);
    413 guint16 aim_userinfo_flags(aim_userinfo_t *ui);
    414 guint16 aim_userinfo_idle(aim_userinfo_t *ui);
    415 float aim_userinfo_warnlevel(aim_userinfo_t *ui);
    416 time_t aim_userinfo_membersince(aim_userinfo_t *ui);
    417 time_t aim_userinfo_onlinesince(aim_userinfo_t *ui);
    418 guint32 aim_userinfo_sessionlen(aim_userinfo_t *ui);
    419 int aim_userinfo_hascap(aim_userinfo_t *ui, guint32 cap);
    420 
    421412#define AIM_FLAG_UNCONFIRMED    0x0001 /* "damned transients" */
    422413#define AIM_FLAG_ADMINISTRATOR  0x0002
     
    474465int aim_addtlvtochain16(aim_tlvlist_t **list, const guint16 t, const guint16 v);
    475466int aim_addtlvtochain32(aim_tlvlist_t **list, const guint16 type, const guint32 v);
    476 int aim_addtlvtochain_availmsg(aim_tlvlist_t **list, const guint16 type, const char *msg);
    477467int aim_addtlvtochain_raw(aim_tlvlist_t **list, const guint16 t, const guint16 l, const guint8 *v);
    478468int aim_addtlvtochain_caps(aim_tlvlist_t **list, const guint16 t, const guint32 caps);
     
    601591#define AIM_WARN_ANON                     0x01
    602592
    603 int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn);
    604 int aim_send_warning(aim_session_t *sess, aim_conn_t *conn, const char *destsn, guint32 flags);
    605 int aim_nop(aim_session_t *, aim_conn_t *);
    606593int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn);
    607 int aim_bos_setidle(aim_session_t *, aim_conn_t *, guint32);
    608 int aim_bos_setbuddylist(aim_session_t *, aim_conn_t *, const char *);
    609594int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, guint32 caps);
    610595int aim_bos_setgroupperm(aim_session_t *, aim_conn_t *, guint32 mask);
     
    615600int aim_bos_reqbuddyrights(aim_session_t *, aim_conn_t *);
    616601int aim_bos_reqlocaterights(aim_session_t *, aim_conn_t *);
    617 int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy);
    618 int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy);
    619602int aim_setextstatus(aim_session_t *sess, aim_conn_t *conn, guint32 status);
    620603
     
    644627#define AIM_SENDMEMBLOCK_FLAG_ISREQUEST  0
    645628#define AIM_SENDMEMBLOCK_FLAG_ISHASH     1
    646 
    647 int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag);
    648629
    649630#define AIM_GETINFO_GENERALINFO 0x00001
     
    672653#define AIM_TRANSFER_DENY_DECLINE 0x0001
    673654#define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002
    674 int aim_denytransfer(aim_session_t *sess, const char *sender, const guint8 *cookie, unsigned short code);
    675655aim_conn_t *aim_accepttransfer(aim_session_t *sess, aim_conn_t *conn, const char *sn, const guint8 *cookie, const guint8 *ip, guint16 listingfiles, guint16 listingtotsize, guint16 listingsize, guint32 listingchecksum, guint16 rendid);
    676656
    677657int aim_getinfo(aim_session_t *, aim_conn_t *, const char *, unsigned short);
    678 int aim_sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info);
    679 int aim_sendbuddyoffgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn);
    680658
    681659#define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED       0x00000001
     
    745723int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen);
    746724int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);
    747 int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);
    748 char *aim_chat_getname(aim_conn_t *conn);
    749 aim_conn_t *aim_chat_getconn(aim_session_t *, const char *name);
    750725
    751726int aim_chatnav_reqrights(aim_session_t *sess, aim_conn_t *conn);
     
    754729
    755730int aim_chatnav_createroom(aim_session_t *sess, aim_conn_t *conn, const char *name, guint16 exchange);
    756 int aim_chat_leaveroom(aim_session_t *sess, const char *name);
    757731
    758732/* aim_util.c */
     
    810784
    811785
    812 int aimutil_putstr(u_char *, const char *, int);
    813 int aimutil_tokslen(char *toSearch, int index, char dl);
    814 int aimutil_itemcnt(char *toSearch, char dl);
    815 char *aimutil_itemidx(char *toSearch, int index, char dl);
    816786int aim_sncmp(const char *a, const char *b);
    817787
  • protocols/oscar/aim_internal.h

    r386042c r6042a54  
    112112int aim_putsnac(aim_bstream_t *, guint16 family, guint16 type, guint16 flags, aim_snacid_t id);
    113113
    114 aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src);
    115 void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src);
    116 
    117114int aim_oft_buildheader(unsigned char *,struct aim_fileheader_t *);
    118115
     
    195192
    196193int aim_extractuserinfo(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *);
    197 int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info);
    198194
    199195int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo);
    200196
    201 int aim_request_directim(aim_session_t *sess, const char *destsn, guint8 *ip, guint16 port, guint8 *ckret);
    202 int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, guint16 numfiles, guint32 totsize, guint8 *ip, guint16 port, guint8 *ckret);
    203197void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn);
    204198void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn);
     
    210204int aim_reqrates(aim_session_t *, aim_conn_t *);
    211205int aim_rates_addparam(aim_session_t *, aim_conn_t *);
    212 int aim_rates_delparam(aim_session_t *, aim_conn_t *);
    213206
    214207#endif /* __AIM_INTERNAL_H__ */
  • protocols/oscar/buddylist.c

    r386042c r6042a54  
    9191        return 0;
    9292}
    93 
    94 /*
    95  * aim_add_buddy()
    96  *
    97  * Adds a single buddy to your buddy list after login.
    98  *
    99  * XXX this should just be an extension of setbuddylist()
    100  *
    101  */
    102 int aim_add_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    103 {
    104         aim_frame_t *fr;
    105         aim_snacid_t snacid;
    106 
    107         if (!sn || !strlen(sn))
    108                 return -EINVAL;
    109 
    110         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    111                 return -ENOMEM;
    112 
    113         snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
    114         aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
    115 
    116         aimbs_put8(&fr->data, strlen(sn));
    117         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    118 
    119         aim_tx_enqueue(sess, fr);
    120 
    121         return 0;
    122 }
    123 
    124 /*
    125  * XXX generalise to support removing multiple buddies (basically, its
    126  * the same as setbuddylist() but with a different snac subtype).
    127  *
    128  */
    129 int aim_remove_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    130 {
    131         aim_frame_t *fr;
    132         aim_snacid_t snacid;
    133 
    134         if (!sn || !strlen(sn))
    135                 return -EINVAL;
    136 
    137         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    138                 return -ENOMEM;
    139 
    140         snacid = aim_cachesnac(sess, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
    141         aim_putsnac(&fr->data, 0x0003, 0x0005, 0x0000, snacid);
    142 
    143         aimbs_put8(&fr->data, strlen(sn));
    144         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    145 
    146         aim_tx_enqueue(sess, fr);
    147 
    148         return 0;
    149 }
    150 
  • protocols/oscar/buddylist.h

    r386042c r6042a54  
    1717#define AIM_CB_BUD_DEFAULT 0xffff
    1818
    19 /* aim_buddylist.c */
    20 int aim_add_buddy(aim_session_t *, aim_conn_t *, const char *);
    21 int aim_remove_buddy(aim_session_t *, aim_conn_t *, const char *);
    22 
    2319#endif /* __OSCAR_BUDDYLIST_H__ */
  • protocols/oscar/chat.c

    r386042c r6042a54  
    2626
    2727        return;
    28 }
    29 
    30 char *aim_chat_getname(aim_conn_t *conn)
    31 {
    32         struct chatconnpriv *ccp;
    33 
    34         if (!conn)
    35                 return NULL;
    36 
    37         if (conn->type != AIM_CONN_TYPE_CHAT)
    38                 return NULL;
    39 
    40         ccp = (struct chatconnpriv *)conn->priv;
    41 
    42         return ccp->name;
    43 }
    44 
    45 /* XXX get this into conn.c -- evil!! */
    46 aim_conn_t *aim_chat_getconn(aim_session_t *sess, const char *name)
    47 {
    48         aim_conn_t *cur;
    49 
    50         for (cur = sess->connlist; cur; cur = cur->next) {
    51                 struct chatconnpriv *ccp = (struct chatconnpriv *)cur->priv;
    52 
    53                 if (cur->type != AIM_CONN_TYPE_CHAT)
    54                         continue;
    55                 if (!cur->priv) {
    56                         imcb_error(sess->aux_data, "chat connection with no name!");
    57                         continue;
    58                 }
    59 
    60                 if (strcmp(ccp->name, name) == 0)
    61                         break;
    62         }
    63 
    64         return cur;
    65 }
    66 
    67 int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance)
    68 {
    69         struct chatconnpriv *ccp;
    70 
    71         if (!conn || !roomname)
    72                 return -EINVAL;
    73 
    74         if (conn->priv)
    75                 g_free(conn->priv);
    76 
    77         if (!(ccp = g_malloc(sizeof(struct chatconnpriv))))
    78                 return -ENOMEM;
    79 
    80         ccp->exchange = exchange;
    81         ccp->name = g_strdup(roomname);
    82         ccp->instance = instance;
    83 
    84         conn->priv = (void *)ccp;
    85 
    86         return 0;
    8728}
    8829
     
    250191        outinfo->name = aimbs_getstr(bs, namelen);
    251192        outinfo->instance = aimbs_get16(bs);
    252 
    253         return 0;
    254 }
    255 
    256 int aim_chat_leaveroom(aim_session_t *sess, const char *name)
    257 {
    258         aim_conn_t *conn;
    259 
    260         if (!(conn = aim_chat_getconn(sess, name)))
    261                 return -ENOENT;
    262 
    263         aim_conn_close(conn);
    264193
    265194        return 0;
  • protocols/oscar/conn.c

    r386042c r6042a54  
    351351
    352352        return cur;
    353 }
    354 
    355 /**
    356  * aim_cloneconn - clone an aim_conn_t
    357  * @sess: session containing parent
    358  * @src: connection to clone
    359  *
    360  * A new connection is allocated, and the values are filled in
    361  * appropriately. Note that this function sets the new connnection's
    362  * ->priv pointer to be equal to that of its parent: only the pointer
    363  * is copied, not the data it points to.
    364  *
    365  * This function returns a pointer to the new aim_conn_t, or %NULL on
    366  * error
    367  */
    368 aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src)
    369 {
    370         aim_conn_t *conn;
    371 
    372         if (!(conn = aim_conn_getnext(sess)))
    373                 return NULL;
    374 
    375         conn->fd = src->fd;
    376         conn->type = src->type;
    377         conn->subtype = src->subtype;
    378         conn->seqnum = src->seqnum;
    379         conn->priv = src->priv;
    380         conn->internal = src->internal;
    381         conn->lastactivity = src->lastactivity;
    382         conn->forcedlatency = src->forcedlatency;
    383         conn->sessv = src->sessv;
    384         aim_clonehandlers(sess, conn, src);
    385 
    386         if (src->inside) {
    387                 /*
    388                  * XXX should clone this section as well, but since currently
    389                  * this function only gets called for some of that rendezvous
    390                  * crap, and not on SNAC connections, its probably okay for
    391                  * now.
    392                  *
    393                  */
    394         }
    395 
    396         return conn;
    397353}
    398354
  • protocols/oscar/icq.c

    r386042c r6042a54  
    6565        aimbs_putle16(&fr->data, 0x003e); /* I command thee. */
    6666        aimbs_putle16(&fr->data, snacid); /* eh. */
    67 
    68         aim_tx_enqueue(sess, fr);
    69 
    70         return 0;
    71 }
    72 
    73 int aim_icq_sendxmlreq(aim_session_t *sess, const char *xml)
    74 {
    75         aim_conn_t *conn;
    76         aim_frame_t *fr;
    77         aim_snacid_t snacid;
    78         int bslen;
    79 
    80         if (!xml || !strlen(xml))
    81                 return -EINVAL;
    82 
    83         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
    84                 return -EINVAL;
    85 
    86         bslen = 2 + 10 + 2 + strlen(xml) + 1;
    87 
    88         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
    89                 return -ENOMEM;
    90 
    91         snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
    92         aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
    93 
    94         /* For simplicity, don't bother using a tlvlist */
    95         aimbs_put16(&fr->data, 0x0001);
    96         aimbs_put16(&fr->data, bslen);
    97 
    98         aimbs_putle16(&fr->data, bslen - 2);
    99         aimbs_putle32(&fr->data, atoi(sess->sn));
    100         aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
    101         aimbs_putle16(&fr->data, snacid); /* eh. */
    102         aimbs_putle16(&fr->data, 0x0998); /* shrug. */
    103         aimbs_putle16(&fr->data, strlen(xml) + 1);
    104         aimbs_putraw(&fr->data, (guint8 *)xml, strlen(xml) + 1);
    10567
    10668        aim_tx_enqueue(sess, fr);
     
    152114
    153115        return 0;
    154 }
    155 
    156 int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
    157 {
    158         aim_conn_t *conn;
    159         aim_frame_t *fr;
    160         aim_snacid_t snacid;
    161         int bslen;
    162 
    163         if (!uin || uin[0] < '0' || uin[0] > '9')
    164                 return -EINVAL;
    165 
    166         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
    167                 return -EINVAL;
    168 
    169         bslen = 2 + 4 + 2 + 2 + 2 + 4;
    170 
    171         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
    172                 return -ENOMEM;
    173 
    174         snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
    175         aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
    176 
    177         /* For simplicity, don't bother using a tlvlist */
    178         aimbs_put16(&fr->data, 0x0001);
    179         aimbs_put16(&fr->data, bslen);
    180 
    181         aimbs_putle16(&fr->data, bslen - 2);
    182         aimbs_putle32(&fr->data, atoi(sess->sn));
    183         aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
    184         aimbs_putle16(&fr->data, snacid); /* eh. */
    185         aimbs_putle16(&fr->data, 0x051f); /* shrug. */
    186         aimbs_putle32(&fr->data, atoi(uin));
    187 
    188         aim_tx_enqueue(sess, fr);
    189 
    190         return 0;
    191116}
    192117
  • protocols/oscar/icq.h

    r386042c r6042a54  
    9494int aim_icq_ackofflinemsgs(aim_session_t *sess);
    9595int aim_icq_getallinfo(aim_session_t *sess, const char *uin);
    96 int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin);
    9796
    9897#endif /* __OSCAR_ICQ_H__ */
  • protocols/oscar/im.c

    r386042c r6042a54  
    2323#include "im.h"
    2424#include "info.h"
    25 
    26 /* This should be endian-safe now... but who knows... */
    27 guint16 aim_iconsum(const guint8 *buf, int buflen)
    28 {
    29         guint32 sum;
    30         int i;
    31 
    32         for (i = 0, sum = 0; i + 1 < buflen; i += 2)
    33                 sum += (buf[i+1] << 8) + buf[i];
    34         if (i < buflen)
    35                 sum += buf[i];
    36 
    37         sum = ((sum & 0xffff0000) >> 16) + (sum & 0x0000ffff);
    38 
    39         return (guint16)sum;
    40 }
    4125
    4226/*
     
    306290}
    307291
    308 /*
    309  * This is also performance sensitive. (If you can believe it...)
    310  *
    311  */
    312 int aim_send_icon(aim_session_t *sess, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum)
    313 {
    314         aim_conn_t *conn;
    315         int i;
    316         guint8 ck[8];
    317         aim_frame_t *fr;
    318         aim_snacid_t snacid;
    319 
    320         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    321                 return -EINVAL;
    322 
    323         if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))
    324                 return -EINVAL;
    325 
    326         for (i = 0; i < 8; i++)
    327                 aimutil_put8(ck+i, (guint8) rand());
    328 
    329         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2)))
    330                 return -ENOMEM;
    331 
    332         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    333         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    334 
    335         /*
    336          * Cookie
    337          */
    338         aimbs_putraw(&fr->data, ck, 8);
    339 
    340         /*
    341          * Channel (2)
    342          */
    343         aimbs_put16(&fr->data, 0x0002);
    344 
    345         /*
    346          * Dest sn
    347          */
    348         aimbs_put8(&fr->data, strlen(sn));
    349         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    350 
    351         /*
    352          * TLV t(0005)
    353          *
    354          * Encompasses everything below.
    355          */
    356         aimbs_put16(&fr->data, 0x0005);
    357         aimbs_put16(&fr->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));
    358 
    359         aimbs_put16(&fr->data, 0x0000);
    360         aimbs_putraw(&fr->data, ck, 8);
    361         aim_putcap(&fr->data, AIM_CAPS_BUDDYICON);
    362 
    363         /* TLV t(000a) */
    364         aimbs_put16(&fr->data, 0x000a);
    365         aimbs_put16(&fr->data, 0x0002);
    366         aimbs_put16(&fr->data, 0x0001);
    367 
    368         /* TLV t(000f) */
    369         aimbs_put16(&fr->data, 0x000f);
    370         aimbs_put16(&fr->data, 0x0000);
    371 
    372         /* TLV t(2711) */
    373         aimbs_put16(&fr->data, 0x2711);
    374         aimbs_put16(&fr->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT));
    375         aimbs_put16(&fr->data, 0x0000);
    376         aimbs_put16(&fr->data, iconsum);
    377         aimbs_put32(&fr->data, iconlen);
    378         aimbs_put32(&fr->data, stamp);
    379         aimbs_putraw(&fr->data, icon, iconlen);
    380         aimbs_putraw(&fr->data, (guint8 *)AIM_ICONIDENT, strlen(AIM_ICONIDENT));
    381 
    382         /* TLV t(0003) */
    383         aimbs_put16(&fr->data, 0x0003);
    384         aimbs_put16(&fr->data, 0x0000);
    385 
    386         aim_tx_enqueue(sess, fr);
    387 
    388         return 0;
    389 }
    390 
    391 /*
    392  * This only works for ICQ 2001b (thats 2001 not 2000).  Better, only
    393  * send it to clients advertising the RTF capability.  In fact, if you send
    394  * it to a client that doesn't support that capability, the server will gladly
    395  * bounce it back to you.
    396  *
    397  * You'd think this would be in icq.c, but, well, I'm trying to stick with
    398  * the one-group-per-file scheme as much as possible.  This could easily
    399  * be an exception, since Rendezvous IMs are external of the Oscar core,
    400  * and therefore are undefined.  Really I just need to think of a good way to
    401  * make an interface similar to what AOL actually uses.  But I'm not using COM.
    402  *
    403  */
    404 int aim_send_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args)
    405 {
    406         const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* AIM_CAPS_ICQRTF capability in string form */
    407         aim_conn_t *conn;
    408         int i;
    409         guint8 ck[8];
    410         aim_frame_t *fr;
    411         aim_snacid_t snacid;
    412         int servdatalen;
    413 
    414         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    415                 return -EINVAL;
    416 
    417         if (!args || !args->destsn || !args->rtfmsg)
    418                 return -EINVAL;
    419 
    420         servdatalen = 2+2+16+2+4+1+2  +  2+2+4+4+4  +  2+4+2+strlen(args->rtfmsg)+1  +  4+4+4+strlen(rtfcap)+1;
    421 
    422         for (i = 0; i < 8; i++)
    423                 aimutil_put8(ck+i, (guint8) rand());
    424 
    425         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+128+servdatalen)))
    426                 return -ENOMEM;
    427 
    428         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    429         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    430 
    431         /*
    432          * Cookie
    433          */
    434         aimbs_putraw(&fr->data, ck, 8);
    435 
    436         /*
    437          * Channel (2)
    438          */
    439         aimbs_put16(&fr->data, 0x0002);
    440 
    441         /*
    442          * Dest sn
    443          */
    444         aimbs_put8(&fr->data, strlen(args->destsn));
    445         aimbs_putraw(&fr->data, (guint8 *)args->destsn, strlen(args->destsn));
    446 
    447         /*
    448          * TLV t(0005)
    449          *
    450          * Encompasses everything below.
    451          */
    452         aimbs_put16(&fr->data, 0x0005);
    453         aimbs_put16(&fr->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);
    454 
    455         aimbs_put16(&fr->data, 0x0000);
    456         aimbs_putraw(&fr->data, ck, 8);
    457         aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
    458 
    459         /*
    460          * t(000a) l(0002) v(0001)
    461          */
    462         aimbs_put16(&fr->data, 0x000a);
    463         aimbs_put16(&fr->data, 0x0002);
    464         aimbs_put16(&fr->data, 0x0001);
    465 
    466         /*
    467          * t(000f) l(0000) v()
    468          */
    469         aimbs_put16(&fr->data, 0x000f);
    470         aimbs_put16(&fr->data, 0x0000);
    471 
    472         /*
    473          * Service Data TLV
    474          */
    475         aimbs_put16(&fr->data, 0x2711);
    476         aimbs_put16(&fr->data, servdatalen);
    477 
    478         aimbs_putle16(&fr->data, 11 + 16 /* 11 + (sizeof CLSID) */);
    479         aimbs_putle16(&fr->data, 9);
    480         aim_putcap(&fr->data, AIM_CAPS_EMPTY);
    481         aimbs_putle16(&fr->data, 0);
    482         aimbs_putle32(&fr->data, 0);
    483         aimbs_putle8(&fr->data, 0);
    484         aimbs_putle16(&fr->data, 0x03ea); /* trid1 */
    485 
    486         aimbs_putle16(&fr->data, 14);
    487         aimbs_putle16(&fr->data, 0x03eb); /* trid2 */
    488         aimbs_putle32(&fr->data, 0);
    489         aimbs_putle32(&fr->data, 0);
    490         aimbs_putle32(&fr->data, 0);
    491 
    492         aimbs_putle16(&fr->data, 0x0001);
    493         aimbs_putle32(&fr->data, 0);
    494         aimbs_putle16(&fr->data, strlen(args->rtfmsg)+1);
    495         aimbs_putraw(&fr->data, (guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1);
    496 
    497         aimbs_putle32(&fr->data, args->fgcolor);
    498         aimbs_putle32(&fr->data, args->bgcolor);
    499         aimbs_putle32(&fr->data, strlen(rtfcap)+1);
    500         aimbs_putraw(&fr->data, (guint8 *)rtfcap, strlen(rtfcap)+1);
    501 
    502         aim_tx_enqueue(sess, fr);
    503 
    504         return 0;
    505 }
    506 
    507 int aim_request_directim(aim_session_t *sess, const char *destsn, guint8 *ip, guint16 port, guint8 *ckret)
    508 {
    509         aim_conn_t *conn;
    510         guint8 ck[8];
    511         aim_frame_t *fr;
    512         aim_snacid_t snacid;
    513         aim_tlvlist_t *tl = NULL, *itl = NULL;
    514         int hdrlen, i;
    515         guint8 *hdr;
    516         aim_bstream_t hdrbs;
    517 
    518         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    519                 return -EINVAL;
    520 
    521         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(destsn))))
    522                 return -ENOMEM;
    523 
    524         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    525         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    526 
    527         /*
    528          * Generate a random message cookie
    529          *
    530          * This cookie needs to be alphanumeric and NULL-terminated to be
    531          * TOC-compatible.
    532          *
    533          * XXX have I mentioned these should be generated in msgcookie.c?
    534          *
    535          */
    536         for (i = 0; i < 7; i++)
    537                 ck[i] = 0x30 + ((guint8) rand() % 10);
    538         ck[7] = '\0';
    539 
    540         if (ckret)
    541                 memcpy(ckret, ck, 8);
    542 
    543         /* Cookie */
    544         aimbs_putraw(&fr->data, ck, 8);
    545 
    546         /* Channel */
    547         aimbs_put16(&fr->data, 0x0002);
    548 
    549         /* Destination SN */
    550         aimbs_put8(&fr->data, strlen(destsn));
    551         aimbs_putraw(&fr->data, (guint8 *)destsn, strlen(destsn));
    552 
    553         aim_addtlvtochain_noval(&tl, 0x0003);
    554 
    555         hdrlen = 2+8+16+6+8+6+4;
    556         hdr = g_malloc(hdrlen);
    557         aim_bstream_init(&hdrbs, hdr, hdrlen);
    558 
    559         aimbs_put16(&hdrbs, 0x0000);
    560         aimbs_putraw(&hdrbs, ck, 8);
    561         aim_putcap(&hdrbs, AIM_CAPS_IMIMAGE);
    562 
    563         aim_addtlvtochain16(&itl, 0x000a, 0x0001);
    564         aim_addtlvtochain_raw(&itl, 0x0003, 4, ip);
    565         aim_addtlvtochain16(&itl, 0x0005, port);
    566         aim_addtlvtochain_noval(&itl, 0x000f);
    567        
    568         aim_writetlvchain(&hdrbs, &itl);
    569 
    570         aim_addtlvtochain_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
    571 
    572         aim_writetlvchain(&fr->data, &tl);
    573 
    574         g_free(hdr);
    575         aim_freetlvchain(&itl);
    576         aim_freetlvchain(&tl);
    577 
    578         aim_tx_enqueue(sess, fr);
    579 
    580         return 0;
    581 }
    582 
    583 int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, guint16 numfiles, guint32 totsize, guint8 *ip, guint16 port, guint8 *ckret)
    584 {
    585         aim_conn_t *conn;
    586         int i;
    587         guint8 ck[8];
    588         aim_frame_t *fr;
    589         aim_snacid_t snacid;
    590 
    591         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    592                 return -EINVAL;
    593 
    594         if (!sn || !filename)
    595                 return -EINVAL;
    596 
    597         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4)))
    598                 return -ENOMEM;
    599 
    600         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    601         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    602 
    603         for (i = 0; i < 7; i++)
    604                 aimutil_put8(ck+i, 0x30 + ((guint8) rand() % 10));
    605         ck[7] = '\0';
    606 
    607         if (ckret)
    608                 memcpy(ckret, ck, 8);
    609 
    610         /*
    611          * Cookie
    612          */
    613         aimbs_putraw(&fr->data, ck, 8);
    614 
    615         /*
    616          * Channel (2)
    617          */
    618         aimbs_put16(&fr->data, 0x0002);
    619 
    620         /*
    621          * Dest sn
    622          */
    623         aimbs_put8(&fr->data, strlen(sn));
    624         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    625 
    626         /*
    627          * TLV t(0005)
    628          *
    629          * Encompasses everything below. Gee.
    630          */
    631         aimbs_put16(&fr->data, 0x0005);
    632         aimbs_put16(&fr->data, 2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4);
    633 
    634         aimbs_put16(&fr->data, 0x0000);
    635         aimbs_putraw(&fr->data, ck, 8);
    636         aim_putcap(&fr->data, AIM_CAPS_SENDFILE);
    637 
    638         /* TLV t(000a) */
    639         aimbs_put16(&fr->data, 0x000a);
    640         aimbs_put16(&fr->data, 0x0002);
    641         aimbs_put16(&fr->data, 0x0001);
    642 
    643         /* TLV t(0003) (IP) */
    644         aimbs_put16(&fr->data, 0x0003);
    645         aimbs_put16(&fr->data, 0x0004);
    646         aimbs_putraw(&fr->data, ip, 4);
    647 
    648         /* TLV t(0005) (port) */
    649         aimbs_put16(&fr->data, 0x0005);
    650         aimbs_put16(&fr->data, 0x0002);
    651         aimbs_put16(&fr->data, port);
    652 
    653         /* TLV t(000f) */
    654         aimbs_put16(&fr->data, 0x000f);
    655         aimbs_put16(&fr->data, 0x0000);
    656 
    657         /* TLV t(2711) */
    658         aimbs_put16(&fr->data, 0x2711);
    659         aimbs_put16(&fr->data, 2+2+4+strlen(filename)+4);
    660 
    661         /* ? */
    662         aimbs_put16(&fr->data, 0x0001);
    663         aimbs_put16(&fr->data, numfiles);
    664         aimbs_put32(&fr->data, totsize);
    665         aimbs_putraw(&fr->data, (guint8 *)filename, strlen(filename));
    666 
    667         /* ? */
    668         aimbs_put32(&fr->data, 0x00000000);
    669 
    670         aim_tx_enqueue(sess, fr);
    671 
    672         return 0;
    673 }
    674 
    675 /**
    676  * Request the status message of the given ICQ user.
    677  *
    678  * @param sess The oscar session.
    679  * @param sn The UIN of the user of whom you wish to request info.
    680  * @param type The type of info you wish to request.  This should be the current
    681  *        state of the user, as one of the AIM_ICQ_STATE_* defines.
    682  * @return Return 0 if no errors, otherwise return the error number.
    683  */
    684 int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type)
    685 {
    686         aim_conn_t *conn;
    687         int i;
    688         guint8 ck[8];
    689         aim_frame_t *fr;
    690         aim_snacid_t snacid;
    691 
    692         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !sn)
    693                 return -EINVAL;
    694 
    695         for (i = 0; i < 8; i++)
    696                 aimutil_put8(ck+i, (guint8) rand());
    697 
    698         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4)))
    699                 return -ENOMEM;
    700 
    701         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    702         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    703 
    704         /* Cookie */
    705         aimbs_putraw(&fr->data, ck, 8);
    706 
    707         /* Channel (2) */
    708         aimbs_put16(&fr->data, 0x0002);
    709 
    710         /* Dest sn */
    711         aimbs_put8(&fr->data, strlen(sn));
    712         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    713 
    714         /* TLV t(0005) - Encompasses almost everything below. */
    715         aimbs_put16(&fr->data, 0x0005); /* T */
    716         aimbs_put16(&fr->data, 0x005e); /* L */
    717         { /* V */
    718                 aimbs_put16(&fr->data, 0x0000);
    719 
    720                 /* Cookie */
    721                 aimbs_putraw(&fr->data, ck, 8);
    722 
    723                 /* Put the 16 byte server relay capability */
    724                 aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
    725 
    726                 /* TLV t(000a) */
    727                 aimbs_put16(&fr->data, 0x000a);
    728                 aimbs_put16(&fr->data, 0x0002);
    729                 aimbs_put16(&fr->data, 0x0001);
    730 
    731                 /* TLV t(000f) */
    732                 aimbs_put16(&fr->data, 0x000f);
    733                 aimbs_put16(&fr->data, 0x0000);
    734 
    735                 /* TLV t(2711) */
    736                 aimbs_put16(&fr->data, 0x2711);
    737                 aimbs_put16(&fr->data, 0x0036);
    738                 { /* V */
    739                         aimbs_putle16(&fr->data, 0x001b); /* L */
    740                         aimbs_putle16(&fr->data, 0x0008); /* AAA - Protocol version */
    741                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    742                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    743                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    744                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    745                         aimbs_putle16(&fr->data, 0x0000); /* Unknown */
    746                         aimbs_putle16(&fr->data, 0x0003); /* Client features? */
    747                         aimbs_putle16(&fr->data, 0x0000); /* Unknown */
    748                         aimbs_putle8(&fr->data, 0x00); /* Unkizown */
    749                         aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
    750 
    751                         aimbs_putle16(&fr->data, 0x000e); /* L */
    752                         aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
    753                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    754                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    755                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    756 
    757                         /* The type of status message being requested */
    758                         if (type & AIM_ICQ_STATE_CHAT)
    759                                 aimbs_putle16(&fr->data, 0x03ec);
    760                         else if(type & AIM_ICQ_STATE_DND)
    761                                 aimbs_putle16(&fr->data, 0x03eb);
    762                         else if(type & AIM_ICQ_STATE_OUT)
    763                                 aimbs_putle16(&fr->data, 0x03ea);
    764                         else if(type & AIM_ICQ_STATE_BUSY)
    765                                 aimbs_putle16(&fr->data, 0x03e9);
    766                         else if(type & AIM_ICQ_STATE_AWAY)
    767                                 aimbs_putle16(&fr->data, 0x03e8);
    768 
    769                         aimbs_putle16(&fr->data, 0x0000); /* Status? */
    770                         aimbs_putle16(&fr->data, 0x0001); /* Priority of this message? */
    771                         aimbs_putle16(&fr->data, 0x0001); /* L? */
    772                         aimbs_putle8(&fr->data, 0x00); /* Null termination? */
    773                 } /* End TLV t(2711) */
    774         } /* End TLV t(0005) */
    775 
    776         /* TLV t(0003) */
    777         aimbs_put16(&fr->data, 0x0003);
    778         aimbs_put16(&fr->data, 0x0000);
    779 
    780         aim_tx_enqueue(sess, fr);
    781 
    782         return 0;
    783 }
    784 
    785292/**
    786293 * answers status message requests
     
    989496        mpm->numparts++;
    990497
    991         return 0;
    992 }
    993 
    994 int aim_mpmsg_addraw(aim_session_t *sess, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, const guint8 *data, guint16 datalen)
    995 {
    996         guint8 *dup;
    997 
    998         if (!(dup = g_malloc(datalen)))
    999                 return -1;
    1000         memcpy(dup, data, datalen);
    1001 
    1002         if (mpmsg_addsection(sess, mpm, charset, charsubset, dup, datalen) == -1) {
    1003                 g_free(dup);
    1004                 return -1;
    1005         }
    1006 
    1007         return 0;
    1008 }
    1009 
    1010 /* XXX should provide a way of saying ISO-8859-1 specifically */
    1011 int aim_mpmsg_addascii(aim_session_t *sess, aim_mpmsg_t *mpm, const char *ascii)
    1012 {
    1013         char *dup;
    1014 
    1015         if (!(dup = g_strdup(ascii)))
    1016                 return -1;
    1017 
    1018         if (mpmsg_addsection(sess, mpm, 0x0000, 0x0000, (guint8 *)dup, (guint16) strlen(ascii)) == -1) {
    1019                 g_free(dup);
    1020                 return -1;
    1021         }
    1022 
    1023         return 0;
    1024 }
    1025 
    1026 int aim_mpmsg_addunicode(aim_session_t *sess, aim_mpmsg_t *mpm, const guint16 *unicode, guint16 unicodelen)
    1027 {
    1028         guint8 *buf;
    1029         aim_bstream_t bs;
    1030         int i;
    1031 
    1032         if (!(buf = g_malloc(unicodelen * 2)))
    1033                 return -1;
    1034 
    1035         aim_bstream_init(&bs, buf, unicodelen * 2);
    1036 
    1037         /* We assume unicode is in /host/ byte order -- convert to network */
    1038         for (i = 0; i < unicodelen; i++)
    1039                 aimbs_put16(&bs, unicode[i]);
    1040 
    1041         if (mpmsg_addsection(sess, mpm, 0x0002, 0x0000, buf, aim_bstream_curpos(&bs)) == -1) {
    1042                 g_free(buf);
    1043                 return -1;
    1044         }
    1045        
    1046498        return 0;
    1047499}
     
    17271179
    17281180        return ret;
    1729 }
    1730 
    1731 /*
    1732  * Possible codes:
    1733  *    AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support"
    1734  *    AIM_TRANSFER_DENY_DECLINE -- "client has declined transfer"
    1735  *    AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers"
    1736  *
    1737  */
    1738 int aim_denytransfer(aim_session_t *sess, const char *sender, const guint8 *cookie, guint16 code)
    1739 {
    1740         aim_conn_t *conn;
    1741         aim_frame_t *fr;
    1742         aim_snacid_t snacid;
    1743         aim_tlvlist_t *tl = NULL;
    1744        
    1745         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    1746                 return -EINVAL;
    1747 
    1748         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sender)+6)))
    1749                 return -ENOMEM;
    1750 
    1751         snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0);
    1752         aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid);
    1753        
    1754         aimbs_putraw(&fr->data, cookie, 8);
    1755 
    1756         aimbs_put16(&fr->data, 0x0002); /* channel */
    1757         aimbs_put8(&fr->data, strlen(sender));
    1758         aimbs_putraw(&fr->data, (guint8 *)sender, strlen(sender));
    1759 
    1760         aim_addtlvtochain16(&tl, 0x0003, code);
    1761         aim_writetlvchain(&fr->data, &tl);
    1762         aim_freetlvchain(&tl);
    1763 
    1764         aim_tx_enqueue(sess, fr);
    1765 
    1766         return 0;
    17671181}
    17681182
  • protocols/oscar/im.h

    r386042c r6042a54  
    4747
    4848int aim_mpmsg_init(aim_session_t *sess, aim_mpmsg_t *mpm);
    49 int aim_mpmsg_addraw(aim_session_t *sess, aim_mpmsg_t *mpm, guint16 charset, guint16 charsubset, const guint8 *data, guint16 datalen);
    50 int aim_mpmsg_addascii(aim_session_t *sess, aim_mpmsg_t *mpm, const char *ascii);
    51 int aim_mpmsg_addunicode(aim_session_t *sess, aim_mpmsg_t *mpm, const guint16 *unicode, guint16 unicodelen);
    5249void aim_mpmsg_free(aim_session_t *sess, aim_mpmsg_t *mpm);
    5350
     
    8380        guint16 charset;
    8481        guint16 charsubset;
    85 };
    86 
    87 /*
    88  * Arguments to aim_send_rtfmsg().
    89  */
    90 struct aim_sendrtfmsg_args {
    91         const char *destsn;
    92         guint32 fgcolor;
    93         guint32 bgcolor;
    94         const char *rtfmsg; /* must be in RTF */
    9582};
    9683
     
    183170};
    184171
    185 int aim_send_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args);
    186172int aim_send_im_ext(aim_session_t *sess, struct aim_sendimext_args *args);
    187173int aim_send_im(aim_session_t *, const char *destsn, unsigned short flags, const char *msg);
    188 int aim_send_icon(aim_session_t *sess, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum);
    189 guint16 aim_iconsum(const guint8 *buf, int buflen);
    190174int aim_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing);
    191175int aim_send_im_direct(aim_session_t *, aim_conn_t *, const char *msg, int len);
     
    194178aim_conn_t *aim_directim_connect(aim_session_t *, const char *sn, const char *addr, const guint8 *cookie);
    195179
    196 int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type);
    197180int aim_im_sendmtn(aim_session_t *sess, guint16 type1, const char *sn, guint16 type2);
    198181int aim_send_im_ch2_statusmessage(aim_session_t *sess, const char *sender, const guint8 *cookie, const char *message, const guint8 state, const guint16 dc);
  • protocols/oscar/info.c

    r386042c r6042a54  
    4040        return 0;
    4141}
    42 
    43 const char *aim_userinfo_sn(aim_userinfo_t *ui)
    44 {
    45 
    46         if (!ui)
    47                 return NULL;
    48 
    49         return ui->sn;
    50 }
    51 
    52 guint16 aim_userinfo_flags(aim_userinfo_t *ui)
    53 {
    54 
    55         if (!ui)
    56                 return 0;
    57 
    58         return ui->flags;
    59 }
    60 
    61 guint16 aim_userinfo_idle(aim_userinfo_t *ui)
    62 {
    63 
    64         if (!ui)
    65                 return 0;
    66 
    67         return ui->idletime;
    68 }
    69 
    70 float aim_userinfo_warnlevel(aim_userinfo_t *ui)
    71 {
    72 
    73         if (!ui)
    74                 return 0.00;
    75 
    76         return (ui->warnlevel / 10);
    77 }
    78 
    79 time_t aim_userinfo_membersince(aim_userinfo_t *ui)
    80 {
    81 
    82         if (!ui)
    83                 return 0;
    84 
    85         return (time_t)ui->membersince;
    86 }
    87 
    88 time_t aim_userinfo_onlinesince(aim_userinfo_t *ui)
    89 {
    90 
    91         if (!ui)
    92                 return 0;
    93 
    94         return (time_t)ui->onlinesince;
    95 }
    96 
    97 guint32 aim_userinfo_sessionlen(aim_userinfo_t *ui)
    98 {
    99 
    100         if (!ui)
    101                 return 0;
    102 
    103         return ui->sessionlen;
    104 }
    105 
    106 int aim_userinfo_hascap(aim_userinfo_t *ui, guint32 cap)
    107 {
    108 
    109         if (!ui || !(ui->present & AIM_USERINFO_PRESENT_CAPABILITIES))
    110                 return -1;
    111 
    112         return !!(ui->capabilities & cap);
    113 }
    114 
    11542
    11643/*
     
    482409                aim_bstream_setpos(bs, endpos);
    483410        }
    484 
    485         return 0;
    486 }
    487 
    488 /*
    489  * Inverse of aim_extractuserinfo()
    490  */
    491 int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info)
    492 {
    493         aim_tlvlist_t *tlvlist = NULL;
    494 
    495         if (!bs || !info)
    496                 return -EINVAL;
    497 
    498         aimbs_put8(bs, strlen(info->sn));
    499         aimbs_putraw(bs, (guint8 *)info->sn, strlen(info->sn));
    500 
    501         aimbs_put16(bs, info->warnlevel);
    502 
    503 
    504         aim_addtlvtochain16(&tlvlist, 0x0001, info->flags);
    505         aim_addtlvtochain32(&tlvlist, 0x0002, info->membersince);
    506         aim_addtlvtochain32(&tlvlist, 0x0003, info->onlinesince);
    507         aim_addtlvtochain16(&tlvlist, 0x0004, info->idletime);
    508 
    509 #if ICQ_OSCAR_SUPPORT
    510         if (atoi(info->sn) != 0) {
    511                 aim_addtlvtochain16(&tlvlist, 0x0006, info->icqinfo.status);
    512                 aim_addtlvtochain32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
    513         }
    514 #endif
    515 
    516         aim_addtlvtochain_caps(&tlvlist, 0x000d, info->capabilities);
    517 
    518         aim_addtlvtochain32(&tlvlist, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
    519 
    520         aimbs_put16(bs, aim_counttlvchain(&tlvlist));
    521         aim_writetlvchain(bs, &tlvlist);
    522         aim_freetlvchain(&tlvlist);
    523 
    524         return 0;
    525 }
    526 
    527 int aim_sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info)
    528 {
    529         aim_frame_t *fr;
    530         aim_snacid_t snacid;
    531 
    532         if (!sess || !conn || !info)
    533                 return -EINVAL;
    534 
    535         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
    536                 return -ENOMEM;
    537 
    538         snacid = aim_cachesnac(sess, 0x0003, 0x000b, 0x0000, NULL, 0);
    539        
    540         aim_putsnac(&fr->data, 0x0003, 0x000b, 0x0000, snacid);
    541         aim_putuserinfo(&fr->data, info);
    542 
    543         aim_tx_enqueue(sess, fr);
    544 
    545         return 0;
    546 }
    547 
    548 int aim_sendbuddyoffgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    549 {
    550         aim_frame_t *fr;
    551         aim_snacid_t snacid;
    552 
    553         if (!sess || !conn || !sn)
    554                 return -EINVAL;
    555 
    556         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    557                 return -ENOMEM;
    558 
    559         snacid = aim_cachesnac(sess, 0x0003, 0x000c, 0x0000, NULL, 0);
    560        
    561         aim_putsnac(&fr->data, 0x0003, 0x000c, 0x0000, snacid);
    562         aimbs_put8(&fr->data, strlen(sn));
    563         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    564 
    565         aim_tx_enqueue(sess, fr);
    566 
    567         return 0;
    568 }
    569 
    570 /*
    571  * Huh? What is this?
    572  */
    573 int aim_0002_000b(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    574 {
    575         aim_frame_t *fr;
    576         aim_snacid_t snacid;
    577 
    578         if (!sess || !conn || !sn)
    579                 return -EINVAL;
    580 
    581         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    582                 return -ENOMEM;
    583 
    584         snacid = aim_cachesnac(sess, 0x0002, 0x000b, 0x0000, NULL, 0);
    585        
    586         aim_putsnac(&fr->data, 0x0002, 0x000b, 0x0000, snacid);
    587         aimbs_put8(&fr->data, strlen(sn));
    588         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    589 
    590         aim_tx_enqueue(sess, fr);
    591411
    592412        return 0;
  • protocols/oscar/info.h

    r386042c r6042a54  
    4040#define AIM_CAPS_LAST           0x00200000
    4141
    42 int aim_0002_000b(aim_session_t *sess, aim_conn_t *conn, const char *sn);
    43 
    4442#endif /* __OSCAR_INFO_H__ */
  • protocols/oscar/misc.c

    r386042c r6042a54  
    1313
    1414#include <aim.h>
    15 
    16 /*
    17  * aim_bos_setbuddylist(buddylist)
    18  *
    19  * This just builds the "set buddy list" command then queues it.
    20  *
    21  * buddy_list = "Screen Name One&ScreenNameTwo&";
    22  *
    23  * TODO: Clean this up. 
    24  *
    25  * XXX: I can't stress the TODO enough.
    26  *
    27  */
    28 int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)
    29 {
    30         aim_frame_t *fr;
    31         aim_snacid_t snacid;
    32         int len = 0;
    33         char *localcpy = NULL;
    34         char *tmpptr = NULL;
    35 
    36         if (!buddy_list || !(localcpy = g_strdup(buddy_list)))
    37                 return -EINVAL;
    38 
    39         for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
    40                 len += 1 + strlen(tmpptr);
    41                 tmpptr = strtok(NULL, "&");
    42         }
    43 
    44         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len)))
    45                 return -ENOMEM;
    46 
    47         snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
    48         aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
    49 
    50         strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
    51 
    52         for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
    53 
    54                 aimbs_put8(&fr->data, strlen(tmpptr));
    55                 aimbs_putraw(&fr->data, (guint8 *)tmpptr, strlen(tmpptr));
    56                 tmpptr = strtok(NULL, "&");
    57         }
    58 
    59         aim_tx_enqueue(sess, fr);
    60 
    61         g_free(localcpy);
    62 
    63         return 0;
    64 }
    6515
    6616/*
     
    12777
    12878/*
    129  * Send a warning to destsn.
    130  *
    131  * Flags:
    132  *  AIM_WARN_ANON  Send as an anonymous (doesn't count as much)
    133  *
    134  * returns -1 on error (couldn't alloc packet), 0 on success.
    135  *
    136  */
    137 int aim_send_warning(aim_session_t *sess, aim_conn_t *conn, const char *destsn, guint32 flags)
    138 {
    139         aim_frame_t *fr;
    140         aim_snacid_t snacid;
    141         guint16 outflags = 0x0000;
    142 
    143         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, strlen(destsn)+13)))
    144                 return -ENOMEM;
    145 
    146         snacid = aim_cachesnac(sess, 0x0004, 0x0008, 0x0000, destsn, strlen(destsn)+1);
    147 
    148         aim_putsnac(&fr->data, 0x0004, 0x0008, 0x0000, snacid);
    149 
    150         if (flags & AIM_WARN_ANON)
    151                 outflags |= 0x0001;
    152 
    153         aimbs_put16(&fr->data, outflags);
    154         aimbs_put8(&fr->data, strlen(destsn));
    155         aimbs_putraw(&fr->data, (guint8 *)destsn, strlen(destsn));
    156 
    157         aim_tx_enqueue(sess, fr);
    158 
    159         return 0;
    160 }
    161 
    162 /*
    16379 * Generic routine for sending commands.
    16480 *
     
    254170{
    255171        return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
    256 }
    257 
    258 /*
    259  * Set directory profile data (not the same as aim_bos_setprofile!)
    260  *
    261  * privacy: 1 to allow searching, 0 to disallow.
    262  */
    263 int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy)
    264 {
    265         aim_frame_t *fr;
    266         aim_snacid_t snacid;
    267         aim_tlvlist_t *tl = NULL;
    268 
    269 
    270         aim_addtlvtochain16(&tl, 0x000a, privacy);
    271 
    272         if (first)
    273                 aim_addtlvtochain_raw(&tl, 0x0001, strlen(first), (guint8 *)first);
    274         if (last)
    275                 aim_addtlvtochain_raw(&tl, 0x0002, strlen(last), (guint8 *)last);
    276         if (middle)
    277                 aim_addtlvtochain_raw(&tl, 0x0003, strlen(middle), (guint8 *)middle);
    278         if (maiden)
    279                 aim_addtlvtochain_raw(&tl, 0x0004, strlen(maiden), (guint8 *)maiden);
    280 
    281         if (state)
    282                 aim_addtlvtochain_raw(&tl, 0x0007, strlen(state), (guint8 *)state);
    283         if (city)
    284                 aim_addtlvtochain_raw(&tl, 0x0008, strlen(city), (guint8 *)city);
    285 
    286         if (nickname)
    287                 aim_addtlvtochain_raw(&tl, 0x000c, strlen(nickname), (guint8 *)nickname);
    288         if (zip)
    289                 aim_addtlvtochain_raw(&tl, 0x000d, strlen(zip), (guint8 *)zip);
    290 
    291         if (street)
    292                 aim_addtlvtochain_raw(&tl, 0x0021, strlen(street), (guint8 *)street);
    293 
    294         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
    295                 return -ENOMEM;
    296 
    297         snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0);
    298        
    299         aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid);
    300         aim_writetlvchain(&fr->data, &tl);
    301         aim_freetlvchain(&tl);
    302 
    303         aim_tx_enqueue(sess, fr);
    304 
    305         return 0;
    306 }
    307 
    308 /* XXX pass these in better */
    309 int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy)
    310 {
    311         aim_frame_t *fr;
    312         aim_tlvlist_t *tl = NULL;
    313 
    314         /* ?? privacy ?? */
    315         aim_addtlvtochain16(&tl, 0x000a, privacy);
    316 
    317         if (interest1)
    318                 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest1), (guint8 *)interest1);
    319         if (interest2)
    320                 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest2), (guint8 *)interest2);
    321         if (interest3)
    322                 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest3), (guint8 *)interest3);
    323         if (interest4)
    324                 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest4), (guint8 *)interest4);
    325         if (interest5)
    326                 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest5), (guint8 *)interest5);
    327 
    328         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
    329                 return -ENOMEM;
    330 
    331         aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);
    332 
    333         aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);
    334         aim_writetlvchain(&fr->data, &tl);
    335         aim_freetlvchain(&tl);
    336 
    337         aim_tx_enqueue(sess, fr);
    338 
    339         return 0;
    340172}
    341173
  • protocols/oscar/oscar_util.c

    r386042c r6042a54  
    11#include <aim.h>
    22#include <ctype.h>
    3 
    4 int aimutil_putstr(u_char *dest, const char *src, int len)
    5 {
    6         memcpy(dest, src, len);
    7         return len;
    8 }
    9 
    10 /*
    11  * Tokenizing functions.  Used to portably replace strtok/sep.
    12  *   -- DMP.
    13  *
    14  */
    15 int aimutil_tokslen(char *toSearch, int index, char dl)
    16 {
    17         int curCount = 1;
    18         char *next;
    19         char *last;
    20         int toReturn;
    21 
    22         last = toSearch;
    23         next = strchr(toSearch, dl);
    24 
    25         while(curCount < index && next != NULL) {
    26                 curCount++;
    27                 last = next + 1;
    28                 next = strchr(last, dl);
    29         }
    30 
    31         if ((curCount < index) || (next == NULL))
    32                 toReturn = strlen(toSearch) - (curCount - 1);
    33         else
    34                 toReturn = next - toSearch - (curCount - 1);
    35 
    36         return toReturn;
    37 }
    38 
    39 int aimutil_itemcnt(char *toSearch, char dl)
    40 {
    41         int curCount;
    42         char *next;
    43 
    44         curCount = 1;
    45 
    46         next = strchr(toSearch, dl);
    47 
    48         while(next != NULL) {
    49                 curCount++;
    50                 next = strchr(next + 1, dl);
    51         }
    52 
    53         return curCount;
    54 }
    55 
    56 char *aimutil_itemidx(char *toSearch, int index, char dl)
    57 {
    58         int curCount;
    59         char *next;
    60         char *last;
    61         char *toReturn;
    62 
    63         curCount = 0;
    64 
    65         last = toSearch;
    66         next = strchr(toSearch, dl);
    67 
    68         while (curCount < index && next != NULL) {
    69                 curCount++;
    70                 last = next + 1;
    71                 next = strchr(last, dl);
    72         }
    73 
    74         if (curCount < index) {
    75                 toReturn = g_strdup("");
    76         }
    77         next = strchr(last, dl);
    78 
    79         if (curCount < index) {
    80                 toReturn = g_strdup("");
    81         } else {
    82                 if (next == NULL) {
    83                         toReturn = g_malloc((strlen(last) + 1) * sizeof(char));
    84                         strcpy(toReturn, last);
    85                 } else {
    86                         toReturn = g_malloc((next - last + 1) * sizeof(char));
    87                         memcpy(toReturn, last, (next - last));
    88                         toReturn[next - last] = '\0';
    89                 }
    90         }
    91         return toReturn;
    92 }
    933
    944/*
  • protocols/oscar/rxhandlers.c

    r386042c r6042a54  
    286286}
    287287
    288 void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src)
    289 {
    290         struct aim_rxcblist_s *cur;
    291 
    292         for (cur = (struct aim_rxcblist_s *)src->handlerlist; cur; cur = cur->next) {
    293                 aim_conn_addhandler(sess, dest, cur->family, cur->type,
    294                                                 cur->handler, cur->flags);
    295         }
    296 
    297         return;
    298 }
    299 
    300288static int aim_callhandler_noparam(aim_session_t *sess, aim_conn_t *conn,guint16 family, guint16 type, aim_frame_t *ptr)
    301289{
  • protocols/oscar/search.c

    r386042c r6042a54  
    88
    99#include <aim.h>
    10 
    11 int aim_usersearch_address(aim_session_t *sess, aim_conn_t *conn, const char *address)
    12 {
    13         aim_frame_t *fr;
    14         aim_snacid_t snacid;
    15 
    16         if (!sess || !conn || !address)
    17                 return -EINVAL;
    18 
    19         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+strlen(address))))
    20                 return -ENOMEM;
    21 
    22         snacid = aim_cachesnac(sess, 0x000a, 0x0002, 0x0000, g_strdup(address), strlen(address)+1);
    23         aim_putsnac(&fr->data, 0x000a, 0x0002, 0x0000, snacid);
    24        
    25         aimbs_putraw(&fr->data, (guint8 *)address, strlen(address));
    26 
    27         aim_tx_enqueue(sess, fr);
    28 
    29         return 0;
    30 }
    3110
    3211/* XXX can this be integrated with the rest of the error handling? */
  • protocols/oscar/search.h

    r386042c r6042a54  
    22#define __OSCAR_SEARCH_H__
    33
    4 int aim_usersearch_address(aim_session_t *, aim_conn_t *, const char *);
    5 
    64#endif /* __OSCAR_SEARCH_H__ */
  • protocols/oscar/service.c

    r386042c r6042a54  
    352352        snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0);
    353353        aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid);
    354 
    355         for (rc = ins->rates; rc; rc = rc->next)
    356                 aimbs_put16(&fr->data, rc->classid);
    357 
    358         aim_tx_enqueue(sess, fr);
    359 
    360         return 0;
    361 }
    362 
    363 /* Delete Rate Parameter (group 1, type 9) */
    364 int aim_rates_delparam(aim_session_t *sess, aim_conn_t *conn)
    365 {
    366         aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
    367         aim_frame_t *fr;       
    368         aim_snacid_t snacid;
    369         struct rateclass *rc;
    370 
    371         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
    372                 return -ENOMEM;
    373 
    374         snacid = aim_cachesnac(sess, 0x0001, 0x0009, 0x0000, NULL, 0);
    375         aim_putsnac(&fr->data, 0x0001, 0x0009, 0x0000, snacid);
    376354
    377355        for (rc = ins->rates; rc; rc = rc->next)
     
    431409}
    432410
    433 /*
    434  * Service Pause Acknowledgement (group 1, type 0x0c)
    435  *
    436  * It is rather important that aim_sendpauseack() gets called for the exact
    437  * same connection that the Server Pause callback was called for, since
    438  * libfaim extracts the data for the SNAC from the connection structure.
    439  *
    440  * Of course, if you don't do that, more bad things happen than just what
    441  * libfaim can cause.
    442  *
    443  */
    444 int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn)
    445 {
    446         aim_frame_t *fr;
    447         aim_snacid_t snacid;
    448         aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
    449         struct snacgroup *sg;
    450 
    451         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1024)))
    452                 return -ENOMEM;
    453 
    454         snacid = aim_cachesnac(sess, 0x0001, 0x000c, 0x0000, NULL, 0);
    455         aim_putsnac(&fr->data, 0x0001, 0x000c, 0x0000, snacid);
    456 
    457         /*
    458          * This list should have all the groups that the original
    459          * Host Online / Server Ready said this host supports.  And
    460          * we want them all back after the migration.
    461          */
    462         for (sg = ins->groups; sg; sg = sg->next)
    463                 aimbs_put16(&fr->data, sg->group);
    464 
    465         aim_tx_enqueue(sess, fr);
    466 
    467         return 0;
    468 }
    469 
    470411/* Service Resume (group 1, type 0x0d) */
    471412static int serverresume(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
     
    517458
    518459        return 0;
    519 }
    520 
    521 /*
    522  * Idle Notification (group 1, type 0x11)
    523  *
    524  * Should set your current idle time in seconds.  Note that this should
    525  * never be called consecutively with a non-zero idle time.  That makes
    526  * OSCAR do funny things.  Instead, just set it once you go idle, and then
    527  * call it again with zero when you're back.
    528  *
    529  */
    530 int aim_bos_setidle(aim_session_t *sess, aim_conn_t *conn, guint32 idletime)
    531 {
    532         return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
    533460}
    534461
     
    637564}
    638565
    639 /*
    640  * No-op (group 1, type 0x16)
    641  *
    642  * WinAIM sends these every 4min or so to keep the connection alive.  Its not
    643  * real necessary.
    644  *
    645  */
    646 int aim_nop(aim_session_t *sess, aim_conn_t *conn)
    647 {
    648         return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
    649 }
    650566
    651567/*
     
    807723        g_free(modname);
    808724        aim_freetlvchain(&list);
    809 
    810         return 0;
    811 }
    812 
    813 /* Client verification reply (group 1, subtype 0x20) */
    814 int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag)
    815 {
    816         aim_frame_t *fr;
    817         aim_snacid_t snacid;
    818 
    819         if (!sess || !conn)
    820                 return -EINVAL;
    821 
    822         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+16)))
    823                 return -ENOMEM;
    824 
    825         snacid = aim_cachesnac(sess, 0x0001, 0x0020, 0x0000, NULL, 0);
    826 
    827         aim_putsnac(&fr->data, 0x0001, 0x0020, 0x0000, snacid);
    828         aimbs_put16(&fr->data, 0x0010); /* md5 is always 16 bytes */
    829 
    830         if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */
    831 
    832                 aimbs_putraw(&fr->data, buf, 0x10);
    833 
    834         } else if (buf && (len > 0)) { /* use input buffer */
    835                 md5_state_t state;
    836                 md5_byte_t digest[0x10];
    837 
    838                 md5_init(&state);       
    839                 md5_append(&state, (const md5_byte_t *)buf, len);
    840                 md5_finish(&state, digest);
    841 
    842                 aimbs_putraw(&fr->data, (guint8 *)digest, 0x10);
    843 
    844         } else if (len == 0) { /* no length, just hash NULL (buf is optional) */
    845                 md5_state_t state;
    846                 guint8 nil = '\0';
    847                 md5_byte_t digest[0x10];
    848 
    849                 /*
    850                  * These MD5 routines are stupid in that you have to have
    851                  * at least one append.  So thats why this doesn't look
    852                  * real logical.
    853                  */
    854                 md5_init(&state);
    855                 md5_append(&state, (const md5_byte_t *)&nil, 0);
    856                 md5_finish(&state, digest);
    857 
    858                 aimbs_putraw(&fr->data, (guint8 *)digest, 0x10);
    859 
    860         } else {
    861 
    862                 /*
    863                  * This data is correct for AIM 3.5.1670.
    864                  *
    865                  * Using these blocks is as close to "legal" as you can get
    866                  * without using an AIM binary.
    867                  *
    868                  */
    869                 if ((offset == 0x03ffffff) && (len == 0x03ffffff)) {
    870 
    871 #if 1 /* with "AnrbnrAqhfzcd" */
    872                         aimbs_put32(&fr->data, 0x44a95d26);
    873                         aimbs_put32(&fr->data, 0xd2490423);
    874                         aimbs_put32(&fr->data, 0x93b8821f);
    875                         aimbs_put32(&fr->data, 0x51c54b01);
    876 #else /* no filename */
    877                         aimbs_put32(&fr->data, 0x1df8cbae);
    878                         aimbs_put32(&fr->data, 0x5523b839);
    879                         aimbs_put32(&fr->data, 0xa0e10db3);
    880                         aimbs_put32(&fr->data, 0xa46d3b39);
    881 #endif
    882 
    883 /* len can't be 0 here anyway...
    884                 } else if ((offset == 0x00001000) && (len == 0x00000000)) {
    885 
    886                         aimbs_put32(&fr->data, 0xd41d8cd9);
    887                         aimbs_put32(&fr->data, 0x8f00b204);
    888                         aimbs_put32(&fr->data, 0xe9800998);
    889                         aimbs_put32(&fr->data, 0xecf8427e);
    890 */
    891                 } else
    892                         imcb_error(sess->aux_data, "Warning: unknown hash request");
    893 
    894         }
    895 
    896         aim_tx_enqueue(sess, fr);
    897725
    898726        return 0;
  • protocols/oscar/ssi.c

    r386042c r6042a54  
    263263
    264264/**
    265  * Locally find the presence flag item, and return the setting.  The returned setting is a
    266  * bitmask of the user flags that you are visible to.  See the AIM_FLAG_* #defines
    267  * in aim.h
    268  *
    269  * @param list A pointer to the current list of items.
    270  * @return Return the current visibility mask.
    271  */
    272 guint32 aim_ssi_getpresence(struct aim_ssi_item *list)
    273 {
    274         struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
    275         if (cur) {
    276                 aim_tlvlist_t *tlvlist = cur->data;
    277                 if (tlvlist) {
    278                         aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00c9, 1);
    279                         if (tlv && tlv->length)
    280                                 return aimutil_get32(tlv->value);
    281                 }
    282         }
    283         return 0xFFFFFFFF;
    284 }
    285 
    286 /**
    287265 * Add the given packet to the holding queue.  We totally need to send SSI SNACs one at
    288266 * a time, so we have a local queue where packets get put before they are sent, and
     
    345323
    346324/**
    347  * Send SNACs necessary to remove all SSI data from the server list,
    348  * and then free the local copy as well.
    349  *
    350  * @param sess The oscar session.
    351  * @param conn The bos connection for this session.
    352  * @return Return 0 if no errors, otherwise return the error number.
    353  */
    354 int aim_ssi_deletelist(aim_session_t *sess, aim_conn_t *conn)
    355 {
    356         int num;
    357         struct aim_ssi_item *cur, **items;
    358 
    359         for (cur=sess->ssi.items, num=0; cur; cur=cur->next)
    360                 num++;
    361 
    362         if (!(items = g_new0(struct aim_ssi_item *, num)))
    363                 return -ENOMEM;
    364 
    365         for (cur=sess->ssi.items, num=0; cur; cur=cur->next) {
    366                 items[num] = cur;
    367                 num++;
    368         }
    369 
    370         aim_ssi_addmoddel(sess, conn, items, num, AIM_CB_SSI_DEL);
    371         g_free(items);
    372         aim_ssi_dispatch(sess, conn);
    373         aim_ssi_freelist(sess);
    374 
    375         return 0;
    376 }
    377 
    378 /**
    379  * This "cleans" the ssi list.  It does a few things, with the intent of making
    380  * sure there ain't nothin' wrong with your SSI.
    381  *   -Make sure all buddies are in a group, and all groups have the correct
    382  *     additional data.
    383  *   -Make sure there are no empty groups in the list.  While there is nothing
    384  *     wrong empty groups in the SSI, it's wiser to not have them.
    385  *
    386  * @param sess The oscar session.
    387  * @param conn The bos connection for this session.
    388  * @return Return 0 if no errors, otherwise return the error number.
    389  */
    390 int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn)
    391 {
    392         unsigned int i;
    393         struct aim_ssi_item *cur, *parentgroup;
    394 
    395         /* Make sure we actually need to clean out the list */
    396         for (cur=sess->ssi.items, i=0; cur && !i; cur=cur->next)
    397                 /* Any buddies directly in the master group */
    398                 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->gid == 0x0000))
    399                         i++;
    400         if (!i)
    401                 return 0;
    402 
    403         /* Remove all the additional data from all groups */
    404         for (cur=sess->ssi.items; cur; cur=cur->next)
    405                 if ((cur->data) && (cur->type == AIM_SSI_TYPE_GROUP)) {
    406                         aim_freetlvchain((aim_tlvlist_t **)&cur->data);
    407                         cur->data = NULL;
    408                 }
    409 
    410         /* If there are buddies directly in the master group, make sure  */
    411         /* there is a group to put them in.  Any group, any group at all. */
    412         for (cur=sess->ssi.items; ((cur) && ((cur->type != AIM_SSI_TYPE_BUDDY) || (cur->gid != 0x0000))); cur=cur->next);
    413         if (!cur) {
    414                 for (parentgroup=sess->ssi.items; ((parentgroup) && (parentgroup->type!=AIM_SSI_TYPE_GROUP) && (parentgroup->gid==0x0000)); parentgroup=parentgroup->next);
    415                 if (!parentgroup) {
    416                         char *newgroup;
    417                         newgroup = (char*)g_malloc(strlen("Unknown")+1);
    418                         strcpy(newgroup, "Unknown");
    419                         aim_ssi_addgroups(sess, conn, &newgroup, 1);
    420                 }
    421         }
    422 
    423         /* Set parentgroup equal to any arbitray group */
    424         for (parentgroup=sess->ssi.items; parentgroup->gid==0x0000 || parentgroup->type!=AIM_SSI_TYPE_GROUP; parentgroup=parentgroup->next);
    425 
    426         /* If there are any buddies directly in the master group, put them in a real group */
    427         for (cur=sess->ssi.items; cur; cur=cur->next)
    428                 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->gid == 0x0000)) {
    429                         aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_DEL);
    430                         cur->gid = parentgroup->gid;
    431                         aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_ADD);
    432                 }
    433 
    434         /* Rebuild additional data for all groups */
    435         for (parentgroup=sess->ssi.items; parentgroup; parentgroup=parentgroup->next)
    436                 if (parentgroup->type == AIM_SSI_TYPE_GROUP)
    437                         aim_ssi_itemlist_rebuildgroup(&sess->ssi.items, parentgroup);
    438 
    439         /* Send a mod snac for all groups */
    440         i = 0;
    441         for (cur=sess->ssi.items; cur; cur=cur->next)
    442                 if (cur->type == AIM_SSI_TYPE_GROUP)
    443                         i++;
    444         if (i > 0) {
    445                 /* Allocate an array of pointers to each of the groups */
    446                 struct aim_ssi_item **groups;
    447                 if (!(groups = g_new0(struct aim_ssi_item *, i)))
    448                         return -ENOMEM;
    449 
    450                 for (cur=sess->ssi.items, i=0; cur; cur=cur->next)
    451                         if (cur->type == AIM_SSI_TYPE_GROUP)
    452                                 groups[i] = cur;
    453 
    454                 aim_ssi_addmoddel(sess, conn, groups, i, AIM_CB_SSI_MOD);
    455                 g_free(groups);
    456         }
    457 
    458         /* Send a del snac for any empty groups */
    459         i = 0;
    460         for (cur=sess->ssi.items; cur; cur=cur->next)
    461                 if ((cur->type == AIM_SSI_TYPE_GROUP) && !(cur->data))
    462                         i++;
    463         if (i > 0) {
    464                 /* Allocate an array of pointers to each of the groups */
    465                 struct aim_ssi_item **groups;
    466                 if (!(groups = g_new0(struct aim_ssi_item *, i)))
    467                         return -ENOMEM;
    468 
    469                 for (cur=sess->ssi.items, i=0; cur; cur=cur->next)
    470                         if ((cur->type == AIM_SSI_TYPE_GROUP) && !(cur->data))
    471                                 groups[i] = cur;
    472 
    473                 aim_ssi_addmoddel(sess, conn, groups, i, AIM_CB_SSI_DEL);
    474                 g_free(groups);
    475         }
    476 
    477         /* Begin sending SSI SNACs */
    478         aim_ssi_dispatch(sess, conn);
    479 
    480         return 0;
    481 }
    482 
    483 /**
    484325 * Add an array of screen names to the given group.
    485326 *
     
    999840}
    1000841
    1001 /**
    1002  * Stores your setting for whether you should show up as idle or not.
    1003  *
    1004  * @param sess The oscar session.
    1005  * @param conn The bos connection for this session.
    1006  * @param presence I think it's a bitmask, but I only know what one of the bits is:
    1007  *        0x00000400 - Allow others to see your idle time
    1008  * @return Return 0 if no errors, otherwise return the error number.
    1009  */
    1010 int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, guint32 presence) {
    1011         struct aim_ssi_item *cur; //, *tmp;
    1012 //      guint16 j;
    1013         aim_tlv_t *tlv;
    1014 
    1015         if (!sess || !conn)
    1016                 return -EINVAL;
    1017 
    1018         /* Look up the item */
    1019         cur = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
    1020 
    1021         if (cur) {
    1022                 /* The item exists */
    1023                 if (cur->data && (tlv = aim_gettlv(cur->data, 0x00c9, 1))) {
    1024                         /* Just change the value of the x00c9 TLV */
    1025                         if (tlv->length != 4) {
    1026                                 tlv->length = 4;
    1027                                 g_free(tlv->value);
    1028                                 tlv->value = (guint8 *)g_malloc(4*sizeof(guint8));
    1029                         }
    1030                         aimutil_put32(tlv->value, presence);
    1031                 } else {
    1032                         /* Need to add the x00c9 TLV to the TLV chain */
    1033                         aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00c9, presence);
    1034                 }
    1035 
    1036                 /* Send the mod item SNAC */
    1037                 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_MOD);
    1038         } else {
    1039                 /* Need to add the item */
    1040                 if (!(cur = aim_ssi_itemlist_add(&sess->ssi.items, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS)))
    1041                         return -ENOMEM;
    1042                 aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00c9, presence);
    1043                 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_ADD);
    1044         }
    1045 
    1046         /* Begin sending SSI SNACs */
    1047         aim_ssi_dispatch(sess, conn);
    1048 
    1049         return 0;
    1050 }
    1051 
    1052842/*
    1053843 * Request SSI Rights.
     
    1070860
    1071861        return ret;
    1072 }
    1073 
    1074 /*
    1075  * Request SSI Data.
    1076  *
    1077  * The data will only be sent if it is newer than the posted local
    1078  * timestamp and revision.
    1079  *
    1080  * Note that the client should never increment the revision, only the server.
    1081  *
    1082  */
    1083 int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t localstamp, guint16 localrev)
    1084 {
    1085         aim_frame_t *fr;
    1086         aim_snacid_t snacid;
    1087 
    1088         if (!sess || !conn)
    1089                 return -EINVAL;
    1090 
    1091         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))
    1092                 return -ENOMEM;
    1093 
    1094         snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQLIST, 0x0000, NULL, 0);
    1095 
    1096         aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQLIST, 0x0000, snacid);
    1097         aimbs_put32(&fr->data, localstamp);
    1098         aimbs_put16(&fr->data, localrev);
    1099 
    1100         aim_tx_enqueue(sess, fr);
    1101 
    1102         return 0;
    1103862}
    1104863
  • protocols/oscar/ssi.h

    r386042c r6042a54  
    4545/* These build the actual SNACs and queue them to be sent */
    4646int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn);
    47 int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t localstamp, guint16 localrev);
    4847int aim_ssi_reqalldata(aim_session_t *sess, aim_conn_t *conn);
    4948int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn);
     
    5756struct aim_ssi_item *aim_ssi_itemlist_findparent(struct aim_ssi_item *list, char *sn);
    5857int aim_ssi_getpermdeny(struct aim_ssi_item *list);
    59 guint32 aim_ssi_getpresence(struct aim_ssi_item *list);
    6058
    6159/* Send packets */
    62 int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn);
    6360int aim_ssi_addbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num, unsigned int flags);
    6461int aim_ssi_addmastergroup(aim_session_t *sess, aim_conn_t *conn);
     
    6966int aim_ssi_delmastergroup(aim_session_t *sess, aim_conn_t *conn);
    7067int aim_ssi_delgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num);
    71 int aim_ssi_deletelist(aim_session_t *sess, aim_conn_t *conn);
    7268int aim_ssi_delpord(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num, guint16 type);
    73 int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, guint32 presence);
    7469int aim_ssi_auth_request(aim_session_t *sess, aim_conn_t *conn, char *uin, char *reason);
    7570int aim_ssi_auth_reply(aim_session_t *sess, aim_conn_t *conn, char *uin, int yesno, char *reason);
  • protocols/oscar/tlv.c

    r386042c r6042a54  
    223223
    224224/**
    225  * aim_addtlvtochain_availmsg - Add a ICQ availability message to a TLV chain
    226  * @list: Destination chain
    227  * @type: TLV type to add
    228  * @val: Value to add
    229  *
    230  * Adds a available message to a TLV chain
    231  *
    232  */
    233 int aim_addtlvtochain_availmsg(aim_tlvlist_t **list, const guint16 t, const char *msg)
    234 {
    235         int ret;
    236         guint16 unknown_data = 0x00;
    237         guint8 add_data_len = 4;
    238         guint16 msg_len = strlen(msg);
    239         guint8 total_len = strlen(msg) + add_data_len;
    240         guint8 *data, *cur;
    241         guint8 alloc_len = msg_len + (3*sizeof(guint16)) + (2*sizeof(guint8));
    242         data = cur = g_malloc(alloc_len);
    243        
    244         cur += aimutil_put16(cur, 2);
    245         cur += aimutil_put8(cur, add_data_len);
    246         cur += aimutil_put8(cur, total_len);
    247         cur += aimutil_put16(cur, msg_len);
    248         cur += aimutil_putstr(cur, msg, msg_len);
    249         cur += aimutil_put16(cur, unknown_data);
    250 
    251         ret = aim_addtlvtochain_raw(list, t, alloc_len, data);
    252         g_free(data);
    253 
    254         return ret;
    255 }
    256 
    257 /**
    258225 * aim_addtlvtochain_caps - Add a capability block to a TLV chain
    259226 * @list: Destination chain
     
    278245
    279246        return aim_addtlvtochain_raw(list, t, aim_bstream_curpos(&bs), buf);
    280 }
    281 
    282 int aim_addtlvtochain_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *ui)
    283 {
    284         guint8 buf[1024]; /* bleh */
    285         aim_bstream_t bs;
    286 
    287         aim_bstream_init(&bs, buf, sizeof(buf));
    288 
    289         aim_putuserinfo(&bs, ui);
    290 
    291         return aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);
    292247}
    293248
Note: See TracChangeset for help on using the changeset viewer.