Changeset 6042a54
- Timestamp:
- 2012-10-19T23:38:33Z (12 years ago)
- Branches:
- master
- Children:
- 509cf60
- Parents:
- 386042c
- Location:
- protocols/oscar
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/oscar/aim.h
r386042c r6042a54 410 410 #define AIM_USERINFO_PRESENT_SESSIONLEN 0x00000100 411 411 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 421 412 #define AIM_FLAG_UNCONFIRMED 0x0001 /* "damned transients" */ 422 413 #define AIM_FLAG_ADMINISTRATOR 0x0002 … … 474 465 int aim_addtlvtochain16(aim_tlvlist_t **list, const guint16 t, const guint16 v); 475 466 int 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);477 467 int aim_addtlvtochain_raw(aim_tlvlist_t **list, const guint16 t, const guint16 l, const guint8 *v); 478 468 int aim_addtlvtochain_caps(aim_tlvlist_t **list, const guint16 t, const guint32 caps); … … 601 591 #define AIM_WARN_ANON 0x01 602 592 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 *);606 593 int 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 *);609 594 int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, guint32 caps); 610 595 int aim_bos_setgroupperm(aim_session_t *, aim_conn_t *, guint32 mask); … … 615 600 int aim_bos_reqbuddyrights(aim_session_t *, aim_conn_t *); 616 601 int 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);619 602 int aim_setextstatus(aim_session_t *sess, aim_conn_t *conn, guint32 status); 620 603 … … 644 627 #define AIM_SENDMEMBLOCK_FLAG_ISREQUEST 0 645 628 #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);648 629 649 630 #define AIM_GETINFO_GENERALINFO 0x00001 … … 672 653 #define AIM_TRANSFER_DENY_DECLINE 0x0001 673 654 #define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002 674 int aim_denytransfer(aim_session_t *sess, const char *sender, const guint8 *cookie, unsigned short code);675 655 aim_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); 676 656 677 657 int 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);680 658 681 659 #define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED 0x00000001 … … 745 723 int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen); 746 724 int 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);750 725 751 726 int aim_chatnav_reqrights(aim_session_t *sess, aim_conn_t *conn); … … 754 729 755 730 int 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);757 731 758 732 /* aim_util.c */ … … 810 784 811 785 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);816 786 int aim_sncmp(const char *a, const char *b); 817 787 -
protocols/oscar/aim_internal.h
r386042c r6042a54 112 112 int aim_putsnac(aim_bstream_t *, guint16 family, guint16 type, guint16 flags, aim_snacid_t id); 113 113 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 117 114 int aim_oft_buildheader(unsigned char *,struct aim_fileheader_t *); 118 115 … … 195 192 196 193 int 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);198 194 199 195 int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo); 200 196 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);203 197 void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn); 204 198 void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn); … … 210 204 int aim_reqrates(aim_session_t *, aim_conn_t *); 211 205 int aim_rates_addparam(aim_session_t *, aim_conn_t *); 212 int aim_rates_delparam(aim_session_t *, aim_conn_t *);213 206 214 207 #endif /* __AIM_INTERNAL_H__ */ -
protocols/oscar/buddylist.c
r386042c r6042a54 91 91 return 0; 92 92 } 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, its126 * 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 17 17 #define AIM_CB_BUD_DEFAULT 0xffff 18 18 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 23 19 #endif /* __OSCAR_BUDDYLIST_H__ */ -
protocols/oscar/chat.c
r386042c r6042a54 26 26 27 27 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;87 28 } 88 29 … … 250 191 outinfo->name = aimbs_getstr(bs, namelen); 251 192 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);264 193 265 194 return 0; -
protocols/oscar/conn.c
r386042c r6042a54 351 351 352 352 return cur; 353 }354 355 /**356 * aim_cloneconn - clone an aim_conn_t357 * @sess: session containing parent358 * @src: connection to clone359 *360 * A new connection is allocated, and the values are filled in361 * appropriately. Note that this function sets the new connnection's362 * ->priv pointer to be equal to that of its parent: only the pointer363 * is copied, not the data it points to.364 *365 * This function returns a pointer to the new aim_conn_t, or %NULL on366 * error367 */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 currently389 * this function only gets called for some of that rendezvous390 * crap, and not on SNAC connections, its probably okay for391 * now.392 *393 */394 }395 396 return conn;397 353 } 398 354 -
protocols/oscar/icq.c
r386042c r6042a54 65 65 aimbs_putle16(&fr->data, 0x003e); /* I command thee. */ 66 66 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);105 67 106 68 aim_tx_enqueue(sess, fr); … … 152 114 153 115 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;191 116 } 192 117 -
protocols/oscar/icq.h
r386042c r6042a54 94 94 int aim_icq_ackofflinemsgs(aim_session_t *sess); 95 95 int aim_icq_getallinfo(aim_session_t *sess, const char *uin); 96 int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin);97 96 98 97 #endif /* __OSCAR_ICQ_H__ */ -
protocols/oscar/im.c
r386042c r6042a54 23 23 #include "im.h" 24 24 #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 }41 25 42 26 /* … … 306 290 } 307 291 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 * Cookie337 */338 aimbs_putraw(&fr->data, ck, 8);339 340 /*341 * Channel (2)342 */343 aimbs_put16(&fr->data, 0x0002);344 345 /*346 * Dest sn347 */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, only393 * send it to clients advertising the RTF capability. In fact, if you send394 * it to a client that doesn't support that capability, the server will gladly395 * bounce it back to you.396 *397 * You'd think this would be in icq.c, but, well, I'm trying to stick with398 * the one-group-per-file scheme as much as possible. This could easily399 * 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 to401 * 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 * Cookie433 */434 aimbs_putraw(&fr->data, ck, 8);435 436 /*437 * Channel (2)438 */439 aimbs_put16(&fr->data, 0x0002);440 441 /*442 * Dest sn443 */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 TLV474 */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 cookie529 *530 * This cookie needs to be alphanumeric and NULL-terminated to be531 * 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 * Cookie612 */613 aimbs_putraw(&fr->data, ck, 8);614 615 /*616 * Channel (2)617 */618 aimbs_put16(&fr->data, 0x0002);619 620 /*621 * Dest sn622 */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 current681 * 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 785 292 /** 786 293 * answers status message requests … … 989 496 mpm->numparts++; 990 497 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 1046 498 return 0; 1047 499 } … … 1727 1179 1728 1180 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;1767 1181 } 1768 1182 -
protocols/oscar/im.h
r386042c r6042a54 47 47 48 48 int 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);52 49 void aim_mpmsg_free(aim_session_t *sess, aim_mpmsg_t *mpm); 53 50 … … 83 80 guint16 charset; 84 81 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 */95 82 }; 96 83 … … 183 170 }; 184 171 185 int aim_send_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args);186 172 int aim_send_im_ext(aim_session_t *sess, struct aim_sendimext_args *args); 187 173 int 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);190 174 int aim_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing); 191 175 int aim_send_im_direct(aim_session_t *, aim_conn_t *, const char *msg, int len); … … 194 178 aim_conn_t *aim_directim_connect(aim_session_t *, const char *sn, const char *addr, const guint8 *cookie); 195 179 196 int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type);197 180 int aim_im_sendmtn(aim_session_t *sess, guint16 type1, const char *sn, guint16 type2); 198 181 int 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 40 40 return 0; 41 41 } 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 115 42 116 43 /* … … 482 409 aim_bstream_setpos(bs, endpos); 483 410 } 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_SUPPORT510 if (atoi(info->sn) != 0) {511 aim_addtlvtochain16(&tlvlist, 0x0006, info->icqinfo.status);512 aim_addtlvtochain32(&tlvlist, 0x000a, info->icqinfo.ipaddr);513 }514 #endif515 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);591 411 592 412 return 0; -
protocols/oscar/info.h
r386042c r6042a54 40 40 #define AIM_CAPS_LAST 0x00200000 41 41 42 int aim_0002_000b(aim_session_t *sess, aim_conn_t *conn, const char *sn);43 44 42 #endif /* __OSCAR_INFO_H__ */ -
protocols/oscar/misc.c
r386042c r6042a54 13 13 14 14 #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 }65 15 66 16 /* … … 127 77 128 78 /* 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 /*163 79 * Generic routine for sending commands. 164 80 * … … 254 170 { 255 171 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;340 172 } 341 173 -
protocols/oscar/oscar_util.c
r386042c r6042a54 1 1 #include <aim.h> 2 2 #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 else34 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 }93 3 94 4 /* -
protocols/oscar/rxhandlers.c
r386042c r6042a54 286 286 } 287 287 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 300 288 static int aim_callhandler_noparam(aim_session_t *sess, aim_conn_t *conn,guint16 family, guint16 type, aim_frame_t *ptr) 301 289 { -
protocols/oscar/search.c
r386042c r6042a54 8 8 9 9 #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 }31 10 32 11 /* XXX can this be integrated with the rest of the error handling? */ -
protocols/oscar/search.h
r386042c r6042a54 2 2 #define __OSCAR_SEARCH_H__ 3 3 4 int aim_usersearch_address(aim_session_t *, aim_conn_t *, const char *);5 6 4 #endif /* __OSCAR_SEARCH_H__ */ -
protocols/oscar/service.c
r386042c r6042a54 352 352 snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0); 353 353 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);376 354 377 355 for (rc = ins->rates; rc; rc = rc->next) … … 431 409 } 432 410 433 /*434 * Service Pause Acknowledgement (group 1, type 0x0c)435 *436 * It is rather important that aim_sendpauseack() gets called for the exact437 * same connection that the Server Pause callback was called for, since438 * 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 what441 * 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 original459 * Host Online / Server Ready said this host supports. And460 * 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 470 411 /* Service Resume (group 1, type 0x0d) */ 471 412 static int serverresume(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) … … 517 458 518 459 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 should525 * never be called consecutively with a non-zero idle time. That makes526 * OSCAR do funny things. Instead, just set it once you go idle, and then527 * 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);533 460 } 534 461 … … 637 564 } 638 565 639 /*640 * No-op (group 1, type 0x16)641 *642 * WinAIM sends these every 4min or so to keep the connection alive. Its not643 * 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 }650 566 651 567 /* … … 807 723 g_free(modname); 808 724 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 have851 * at least one append. So thats why this doesn't look852 * 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 get866 * 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 #endif882 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 } else892 imcb_error(sess->aux_data, "Warning: unknown hash request");893 894 }895 896 aim_tx_enqueue(sess, fr);897 725 898 726 return 0; -
protocols/oscar/ssi.c
r386042c r6042a54 263 263 264 264 /** 265 * Locally find the presence flag item, and return the setting. The returned setting is a266 * bitmask of the user flags that you are visible to. See the AIM_FLAG_* #defines267 * in aim.h268 *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 /**287 265 * Add the given packet to the holding queue. We totally need to send SSI SNACs one at 288 266 * a time, so we have a local queue where packets get put before they are sent, and … … 345 323 346 324 /** 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 making380 * sure there ain't nothin' wrong with your SSI.381 * -Make sure all buddies are in a group, and all groups have the correct382 * additional data.383 * -Make sure there are no empty groups in the list. While there is nothing384 * 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 /**484 325 * Add an array of screen names to the given group. 485 326 * … … 999 840 } 1000 841 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 time1008 * @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 1052 842 /* 1053 843 * Request SSI Rights. … … 1070 860 1071 861 return ret; 1072 }1073 1074 /*1075 * Request SSI Data.1076 *1077 * The data will only be sent if it is newer than the posted local1078 * 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;1103 862 } 1104 863 -
protocols/oscar/ssi.h
r386042c r6042a54 45 45 /* These build the actual SNACs and queue them to be sent */ 46 46 int 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);48 47 int aim_ssi_reqalldata(aim_session_t *sess, aim_conn_t *conn); 49 48 int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn); … … 57 56 struct aim_ssi_item *aim_ssi_itemlist_findparent(struct aim_ssi_item *list, char *sn); 58 57 int aim_ssi_getpermdeny(struct aim_ssi_item *list); 59 guint32 aim_ssi_getpresence(struct aim_ssi_item *list);60 58 61 59 /* Send packets */ 62 int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn);63 60 int aim_ssi_addbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num, unsigned int flags); 64 61 int aim_ssi_addmastergroup(aim_session_t *sess, aim_conn_t *conn); … … 69 66 int aim_ssi_delmastergroup(aim_session_t *sess, aim_conn_t *conn); 70 67 int 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);72 68 int 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);74 69 int aim_ssi_auth_request(aim_session_t *sess, aim_conn_t *conn, char *uin, char *reason); 75 70 int aim_ssi_auth_reply(aim_session_t *sess, aim_conn_t *conn, char *uin, int yesno, char *reason); -
protocols/oscar/tlv.c
r386042c r6042a54 223 223 224 224 /** 225 * aim_addtlvtochain_availmsg - Add a ICQ availability message to a TLV chain226 * @list: Destination chain227 * @type: TLV type to add228 * @val: Value to add229 *230 * Adds a available message to a TLV chain231 *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 /**258 225 * aim_addtlvtochain_caps - Add a capability block to a TLV chain 259 226 * @list: Destination chain … … 278 245 279 246 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);292 247 } 293 248
Note: See TracChangeset
for help on using the changeset viewer.