source: libfaim/icq.c @ 5d9c664

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 5d9c664 was 862371b, checked in by James M. Kretchmar <kretch@mit.edu>, 21 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Family 0x0015 - Encapsulated ICQ.
3 *
4 */
5
6#define FAIM_INTERNAL
7#include <aim.h>
8
9faim_export int aim_icq_reqofflinemsgs(aim_session_t *sess)
10{
11        aim_conn_t *conn;
12        aim_frame_t *fr;
13        aim_snacid_t snacid;
14        int bslen;
15
16        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
17                return -EINVAL;
18
19        bslen = 2 + 4 + 2 + 2;
20
21        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
22                return -ENOMEM;
23
24        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
25        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
26
27        /* For simplicity, don't bother using a tlvlist */
28        aimbs_put16(&fr->data, 0x0001);
29        aimbs_put16(&fr->data, bslen);
30
31        aimbs_putle16(&fr->data, bslen - 2);
32        aimbs_putle32(&fr->data, atoi(sess->sn));
33        aimbs_putle16(&fr->data, 0x003c); /* I command thee. */
34        aimbs_putle16(&fr->data, snacid); /* eh. */
35
36        aim_tx_enqueue(sess, fr);
37
38        return 0;
39}
40
41faim_export int aim_icq_ackofflinemsgs(aim_session_t *sess)
42{
43        aim_conn_t *conn;
44        aim_frame_t *fr;
45        aim_snacid_t snacid;
46        int bslen;
47
48        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
49                return -EINVAL;
50
51        bslen = 2 + 4 + 2 + 2;
52
53        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
54                return -ENOMEM;
55
56        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
57        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
58
59        /* For simplicity, don't bother using a tlvlist */
60        aimbs_put16(&fr->data, 0x0001);
61        aimbs_put16(&fr->data, bslen);
62
63        aimbs_putle16(&fr->data, bslen - 2);
64        aimbs_putle32(&fr->data, atoi(sess->sn));
65        aimbs_putle16(&fr->data, 0x003e); /* I command thee. */
66        aimbs_putle16(&fr->data, snacid); /* eh. */
67
68        aim_tx_enqueue(sess, fr);
69
70        return 0;
71}
72
73faim_export 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, xml, strlen(xml) + 1);
105
106        aim_tx_enqueue(sess, fr);
107
108        return 0;
109}
110
111faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
112{
113        aim_conn_t *conn;
114        aim_frame_t *fr;
115        aim_snacid_t snacid;
116        int bslen;
117
118        if (!uin || uin[0] < '0' || uin[0] > '9')
119                return -EINVAL;
120
121        if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
122                return -EINVAL;
123
124        bslen = 2 + 4 + 2 + 2 + 2 + 4;
125
126        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
127                return -ENOMEM;
128
129        snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
130        aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
131
132        /* For simplicity, don't bother using a tlvlist */
133        aimbs_put16(&fr->data, 0x0001);
134        aimbs_put16(&fr->data, bslen);
135
136        aimbs_putle16(&fr->data, bslen - 2);
137        aimbs_putle32(&fr->data, atoi(sess->sn));
138        aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
139        aimbs_putle16(&fr->data, snacid); /* eh. */
140        aimbs_putle16(&fr->data, 0x051f); /* shrug. */
141        aimbs_putle32(&fr->data, atoi(uin));
142
143        aim_tx_enqueue(sess, fr);
144
145        return 0;
146}
147
148/*
149 * Response to 15/2, contains an ICQ packet.
150 */
151static int icqresponse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
152{
153        int ret = 0;
154        aim_tlvlist_t *tl;
155        aim_tlv_t *datatlv;
156        aim_bstream_t qbs;
157        fu32_t ouruin;
158        fu16_t cmdlen, cmd, reqid;
159
160        if (!(tl = aim_readtlvchain(bs)) || !(datatlv = aim_gettlv(tl, 0x0001, 1))) {
161                aim_freetlvchain(&tl);
162                faimdprintf(sess, 0, "corrupt ICQ response\n");
163                return 0;
164        }
165
166        aim_bstream_init(&qbs, datatlv->value, datatlv->length);
167
168        cmdlen = aimbs_getle16(&qbs);
169        ouruin = aimbs_getle32(&qbs);
170        cmd = aimbs_getle16(&qbs);
171        reqid = aimbs_getle16(&qbs);
172
173        faimdprintf(sess, 1, "icq response: %d bytes, %ld, 0x%04x, 0x%04x\n", cmdlen, ouruin, cmd, reqid);
174
175        if (cmd == 0x0041) {
176                fu16_t msglen;
177                struct aim_icq_offlinemsg msg;
178                aim_rxcallback_t userfunc;
179
180                memset(&msg, 0, sizeof(msg));
181
182                msg.sender = aimbs_getle32(&qbs);
183                msg.year = aimbs_getle16(&qbs);
184                msg.month = aimbs_getle8(&qbs);
185                msg.day = aimbs_getle8(&qbs);
186                msg.hour = aimbs_getle8(&qbs);
187                msg.minute = aimbs_getle8(&qbs);
188                msg.type = aimbs_getle16(&qbs);
189                msglen = aimbs_getle16(&qbs);
190                msg.msg = aimbs_getstr(&qbs, msglen);
191
192                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG)))
193                        ret = userfunc(sess, rx, &msg);
194
195                free(msg.msg);
196
197        } else if (cmd == 0x0042) {
198                aim_rxcallback_t userfunc;
199
200                if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE)))
201                        ret = userfunc(sess, rx);
202        } else if (cmd == 0x07da) {
203                fu16_t subtype;
204
205                subtype = aimbs_getle16(&qbs);
206
207                if (subtype == 0x019a) {
208                        fu16_t tlen;
209                        struct aim_icq_simpleinfo info;
210                        aim_rxcallback_t userfunc;
211
212                        memset(&info, 0, sizeof(info));
213
214                        aimbs_getle8(&qbs); /* no clue */
215                        aimbs_getle16(&qbs); /* no clue */
216                        info.uin = aimbs_getle32(&qbs);
217                        tlen = aimbs_getle16(&qbs);
218                        info.nick = aimbs_getstr(&qbs, tlen);
219                        tlen = aimbs_getle16(&qbs);
220                        info.first = aimbs_getstr(&qbs, tlen);
221                        tlen = aimbs_getle16(&qbs);
222                        info.last = aimbs_getstr(&qbs, tlen);
223                        tlen = aimbs_getle16(&qbs);
224                        info.email = aimbs_getstr(&qbs, tlen);
225                        /* no clue what the rest of it is */
226
227                        if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SIMPLEINFO)))
228                                ret = userfunc(sess, rx, &info);
229
230                        free(info.nick);
231                        free(info.first);
232                        free(info.last);
233                        free(info.email);
234                }
235
236        }
237
238        aim_freetlvchain(&tl);
239
240        return ret;
241}
242
243static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
244{
245
246        if (snac->subtype == 0x0003)
247                return icqresponse(sess, mod, rx, snac, bs);
248
249        return 0;
250}
251
252faim_internal int icq_modfirst(aim_session_t *sess, aim_module_t *mod)
253{
254
255        mod->family = 0x0015;
256        mod->version = 0x0001;
257        mod->toolid = 0x0110;
258        mod->toolversion = 0x047b;
259        mod->flags = 0;
260        strncpy(mod->name, "icq", sizeof(mod->name));
261        mod->snachandler = snachandler;
262
263        return 0;
264}
Note: See TracBrowser for help on using the repository browser.