Mercurial > pidgin.yaz
comparison src/protocols/oscar/chat.c @ 8225:9790cda80d52
[gaim-migrate @ 8948]
Various bits o' chat code cleanup for oscar.
Mostly I just wanted to re-use some code for incoming i18n chat messages.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 11 Feb 2004 04:06:16 +0000 |
parents | 862dc2839646 |
children | 4f70e8b3e05e |
comparison
equal
deleted
inserted
replaced
8224:ad524b8c9c71 | 8225:9790cda80d52 |
---|---|
83 conn->priv = (void *)ccp; | 83 conn->priv = (void *)ccp; |
84 | 84 |
85 return 0; | 85 return 0; |
86 } | 86 } |
87 | 87 |
88 static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance) | |
89 { | |
90 fu8_t *buf; | |
91 int buflen; | |
92 aim_bstream_t bs; | |
93 | |
94 buflen = 2 + 1 + strlen(roomname) + 2; | |
95 | |
96 if (!(buf = malloc(buflen))) | |
97 return 0; | |
98 | |
99 aim_bstream_init(&bs, buf, buflen); | |
100 | |
101 aimbs_put16(&bs, exchange); | |
102 aimbs_put8(&bs, strlen(roomname)); | |
103 aimbs_putraw(&bs, roomname, strlen(roomname)); | |
104 aimbs_put16(&bs, instance); | |
105 | |
106 aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf); | |
107 | |
108 free(buf); | |
109 | |
110 return 0; | |
111 } | |
112 | |
113 /* | |
114 * Join a room of name roomname. This is the first step to joining an | |
115 * already created room. It's basically a Service Request for | |
116 * family 0x000e, with a little added on to specify the exchange and room | |
117 * name. | |
118 */ | |
119 faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance) | |
120 { | |
121 aim_frame_t *fr; | |
122 aim_snacid_t snacid; | |
123 aim_tlvlist_t *tl = NULL; | |
124 struct chatsnacinfo csi; | |
125 | |
126 if (!sess || !conn || !roomname || !strlen(roomname)) | |
127 return -EINVAL; | |
128 | |
129 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512))) | |
130 return -ENOMEM; | |
131 | |
132 memset(&csi, 0, sizeof(csi)); | |
133 csi.exchange = exchange; | |
134 strncpy(csi.name, roomname, sizeof(csi.name)); | |
135 csi.instance = instance; | |
136 | |
137 snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi)); | |
138 aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid); | |
139 | |
140 /* | |
141 * Requesting service chat (0x000e) | |
142 */ | |
143 aimbs_put16(&fr->data, 0x000e); | |
144 | |
145 aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance); | |
146 aim_tlvlist_write(&fr->data, &tl); | |
147 aim_tlvlist_free(&tl); | |
148 | |
149 aim_tx_enqueue(sess, fr); | |
150 | |
151 return 0; | |
152 } | |
153 | |
154 faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo) | 88 faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo) |
155 { | 89 { |
156 int namelen; | 90 int namelen; |
157 | 91 |
158 if (!bs || !outinfo) | 92 if (!bs || !outinfo) |
172 | 106 |
173 if (!(conn = aim_chat_getconn(sess, name))) | 107 if (!(conn = aim_chat_getconn(sess, name))) |
174 return -ENOENT; | 108 return -ENOENT; |
175 | 109 |
176 aim_conn_close(conn); | 110 aim_conn_close(conn); |
177 | |
178 return 0; | |
179 } | |
180 | |
181 /* | |
182 * conn must be a BOS connection! | |
183 */ | |
184 faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance) | |
185 { | |
186 int i; | |
187 aim_frame_t *fr; | |
188 aim_msgcookie_t *cookie; | |
189 struct aim_invite_priv *priv; | |
190 fu8_t ckstr[8]; | |
191 aim_snacid_t snacid; | |
192 aim_tlvlist_t *otl = NULL, *itl = NULL; | |
193 fu8_t *hdr; | |
194 int hdrlen; | |
195 aim_bstream_t hdrbs; | |
196 | |
197 if (!sess || !conn || !sn || !msg || !roomname) | |
198 return -EINVAL; | |
199 | |
200 if (conn->type != AIM_CONN_TYPE_BOS) | |
201 return -EINVAL; | |
202 | |
203 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) | |
204 return -ENOMEM; | |
205 | |
206 snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1); | |
207 aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid); | |
208 | |
209 /* | |
210 * Cookie | |
211 */ | |
212 for (i = 0; i < 8; i++) | |
213 ckstr[i] = (fu8_t)rand(); | |
214 | |
215 /* XXX should be uncached by an unwritten 'invite accept' handler */ | |
216 if ((priv = malloc(sizeof(struct aim_invite_priv)))) { | |
217 priv->sn = strdup(sn); | |
218 priv->roomname = strdup(roomname); | |
219 priv->exchange = exchange; | |
220 priv->instance = instance; | |
221 } | |
222 | |
223 if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv))) | |
224 aim_cachecookie(sess, cookie); | |
225 else | |
226 free(priv); | |
227 | |
228 /* ICBM Header */ | |
229 aimbs_putraw(&fr->data, ckstr, 8); /* Cookie */ | |
230 aimbs_put16(&fr->data, 0x0002); /* Channel */ | |
231 aimbs_put8(&fr->data, strlen(sn)); /* Screename length */ | |
232 aimbs_putraw(&fr->data, sn, strlen(sn)); /* Screenname */ | |
233 | |
234 /* | |
235 * TLV t(0005) | |
236 * | |
237 * Everything else is inside this TLV. | |
238 * | |
239 * Sigh. AOL was rather inconsistent right here. So we have | |
240 * to play some minor tricks. Right inside the type 5 is some | |
241 * raw data, followed by a series of TLVs. | |
242 * | |
243 */ | |
244 hdrlen = 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2; | |
245 hdr = malloc(hdrlen); | |
246 aim_bstream_init(&hdrbs, hdr, hdrlen); | |
247 | |
248 aimbs_put16(&hdrbs, 0x0000); /* Unknown! */ | |
249 aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */ | |
250 aim_putcap(&hdrbs, AIM_CAPS_CHAT); | |
251 | |
252 aim_tlvlist_add_16(&itl, 0x000a, 0x0001); | |
253 aim_tlvlist_add_noval(&itl, 0x000f); | |
254 aim_tlvlist_add_raw(&itl, 0x000c, strlen(msg), msg); | |
255 aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance); | |
256 aim_tlvlist_write(&hdrbs, &itl); | |
257 | |
258 aim_tlvlist_add_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr); | |
259 | |
260 aim_tlvlist_write(&fr->data, &otl); | |
261 | |
262 free(hdr); | |
263 aim_tlvlist_free(&itl); | |
264 aim_tlvlist_free(&otl); | |
265 | |
266 aim_tx_enqueue(sess, fr); | |
267 | 111 |
268 return 0; | 112 return 0; |
269 } | 113 } |
270 | 114 |
271 /* | 115 /* |
581 * message tlv | 425 * message tlv |
582 * message string | 426 * message string |
583 * possibly others | 427 * possibly others |
584 * | 428 * |
585 */ | 429 */ |
586 static int incomingmsg(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) | 430 static int incomingim_ch3(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
587 { | 431 { |
432 int ret = 0, i; | |
433 aim_rxcallback_t userfunc; | |
588 aim_userinfo_t userinfo; | 434 aim_userinfo_t userinfo; |
589 aim_rxcallback_t userfunc; | 435 fu8_t cookie[8]; |
590 int ret = 0; | |
591 fu8_t *cookie; | |
592 fu16_t channel; | 436 fu16_t channel; |
593 aim_tlvlist_t *otl; | 437 aim_tlvlist_t *otl; |
594 char *msg = NULL; | 438 char *msg = NULL; |
595 int len; | 439 int len; |
596 char *charset = NULL; | 440 char *charset = NULL; |
597 aim_msgcookie_t *ck; | 441 aim_msgcookie_t *ck; |
598 | 442 |
599 memset(&userinfo, 0, sizeof(aim_userinfo_t)); | 443 memset(&userinfo, 0, sizeof(aim_userinfo_t)); |
600 | 444 |
601 /* | 445 /* |
602 * ICBM Cookie. Uncache it. | 446 * Read ICBM Cookie. |
603 */ | 447 */ |
604 cookie = aimbs_getraw(bs, 8); | 448 for (i = 0; i < 8; i++) |
449 cookie[i] = aimbs_get8(bs); | |
605 | 450 |
606 if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) { | 451 if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) { |
607 free(ck->data); | 452 free(ck->data); |
608 free(ck); | 453 free(ck); |
609 } | 454 } |
610 | 455 |
611 /* | 456 /* |
612 * Channel ID | 457 * Channel ID |
613 * | 458 * |
614 * Channels 1 and 2 are implemented in the normal ICBM | 459 * Channel 0x0003 is used for chat messages. |
615 * parser. | |
616 * | |
617 * We only do channel 3 here. | |
618 * | 460 * |
619 */ | 461 */ |
620 channel = aimbs_get16(bs); | 462 channel = aimbs_get16(bs); |
621 | 463 |
622 if (channel != 0x0003) { | 464 if (channel != 0x0003) { |
680 | 522 |
681 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) | 523 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
682 ret = userfunc(sess, rx, &userinfo, len, msg, charset); | 524 ret = userfunc(sess, rx, &userinfo, len, msg, charset); |
683 | 525 |
684 aim_info_free(&userinfo); | 526 aim_info_free(&userinfo); |
685 free(cookie); | |
686 free(msg); | 527 free(msg); |
687 aim_tlvlist_free(&otl); | 528 aim_tlvlist_free(&otl); |
688 | 529 |
689 return ret; | 530 return ret; |
690 } | 531 } |
695 if (snac->subtype == 0x0002) | 536 if (snac->subtype == 0x0002) |
696 return infoupdate(sess, mod, rx, snac, bs); | 537 return infoupdate(sess, mod, rx, snac, bs); |
697 else if ((snac->subtype == 0x0003) || (snac->subtype == 0x0004)) | 538 else if ((snac->subtype == 0x0003) || (snac->subtype == 0x0004)) |
698 return userlistchange(sess, mod, rx, snac, bs); | 539 return userlistchange(sess, mod, rx, snac, bs); |
699 else if (snac->subtype == 0x0006) | 540 else if (snac->subtype == 0x0006) |
700 return incomingmsg(sess, mod, rx, snac, bs); | 541 return incomingim_ch3(sess, mod, rx, snac, bs); |
701 | 542 |
702 return 0; | 543 return 0; |
703 } | 544 } |
704 | 545 |
705 faim_internal int chat_modfirst(aim_session_t *sess, aim_module_t *mod) | 546 faim_internal int chat_modfirst(aim_session_t *sess, aim_module_t *mod) |