]>
Commit | Line | Data |
---|---|---|
9de3ca7e | 1 | /* |
2 | * | |
3 | * | |
4 | * | |
5 | * | |
6 | */ | |
7 | ||
a25832e6 | 8 | #include <faim/aim.h> |
9de3ca7e | 9 | |
0c20631f | 10 | |
11 | /* | |
12 | * conn must be a chatnav connection! | |
13 | */ | |
14 | u_long aim_chatnav_reqrights(struct aim_session_t *sess, | |
15 | struct aim_conn_t *conn) | |
16 | { | |
17 | struct aim_snac_t snac; | |
18 | ||
19 | snac.id = aim_genericreq_n(sess, conn, 0x000d, 0x0002); | |
20 | ||
21 | snac.family = 0x000d; | |
22 | snac.type = 0x0002; | |
23 | snac.flags = 0x0000; | |
24 | snac.data = NULL; | |
25 | ||
26 | aim_newsnac(sess, &snac); | |
27 | ||
28 | return (sess->snac_nextid); /* already incremented */ | |
29 | } | |
30 | ||
31 | u_long aim_chatnav_clientready(struct aim_session_t *sess, | |
32 | struct aim_conn_t *conn) | |
33 | { | |
34 | struct command_tx_struct newpacket; | |
35 | int i; | |
36 | ||
37 | newpacket.lock = 1; | |
38 | if (conn) | |
39 | newpacket.conn = conn; | |
40 | else | |
41 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV); | |
42 | newpacket.type = 0x02; | |
43 | newpacket.commandlen = 0x20; | |
44 | ||
45 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
46 | i = aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); | |
47 | ||
48 | i+= aimutil_put16(newpacket.data+i, 0x000d); | |
49 | i+= aimutil_put16(newpacket.data+i, 0x0001); | |
50 | ||
51 | i+= aimutil_put16(newpacket.data+i, 0x0004); | |
52 | i+= aimutil_put16(newpacket.data+i, 0x0001); | |
53 | ||
54 | i+= aimutil_put16(newpacket.data+i, 0x0001); | |
55 | i+= aimutil_put16(newpacket.data+i, 0x0003); | |
56 | ||
57 | i+= aimutil_put16(newpacket.data+i, 0x0004); | |
58 | i+= aimutil_put16(newpacket.data+i, 0x0686); | |
59 | ||
60 | aim_tx_enqueue(sess, &newpacket); | |
61 | ||
62 | return (sess->snac_nextid++); | |
63 | } | |
64 | ||
65 | /* | |
66 | * Since multiple things can trigger this callback, | |
67 | * we must lookup the snacid to determine the original | |
68 | * snac subtype that was called. | |
69 | */ | |
70 | int aim_chatnav_parse_info(struct aim_session_t *sess, struct command_rx_struct *command) | |
71 | { | |
72 | struct aim_snac_t *snac; | |
73 | u_long snacid; | |
74 | rxcallback_t userfunc; | |
75 | ||
76 | snacid = aimutil_get32(command->data+6); | |
77 | snac = aim_remsnac(sess, snacid); | |
78 | ||
79 | if (!snac) | |
80 | { | |
81 | printf("faim: chatnav_parse_info: received response to unknown request! (%08lx)\n", snacid); | |
82 | return 1; | |
83 | } | |
84 | ||
85 | if (snac->family != 0x000d) | |
86 | { | |
87 | printf("faim: chatnav_parse_info: recieved response that maps to corrupt request! (fam=%04x)\n", snac->family); | |
88 | return 1; | |
89 | } | |
90 | ||
91 | /* | |
92 | * We now know what the original SNAC subtype was. | |
93 | */ | |
94 | switch(snac->type) | |
95 | { | |
96 | case 0x0002: /* request chat rights */ | |
97 | { | |
98 | struct aim_tlvlist_t *tlvlist; | |
99 | struct aim_chat_exchangeinfo *exchanges = NULL; | |
100 | int curexchange = 0; | |
101 | struct aim_tlv_t *exchangetlv; | |
102 | u_char maxrooms = 0; | |
103 | int ret = 1; | |
104 | struct aim_tlvlist_t *innerlist; | |
105 | ||
106 | tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10); | |
107 | ||
108 | /* | |
109 | * Type 0x0002: Maximum concurrent rooms. | |
110 | */ | |
111 | if (aim_gettlv(tlvlist, 0x0002, 1)) | |
112 | { | |
113 | struct aim_tlv_t *maxroomstlv; | |
114 | maxroomstlv = aim_gettlv(tlvlist, 0x0002, 1); | |
115 | maxrooms = aimutil_get8(maxroomstlv->value); | |
116 | } | |
117 | ||
118 | /* | |
119 | * Type 0x0003: Exchange information | |
120 | * | |
121 | * There can be any number of these, each one | |
122 | * representing another exchange. | |
123 | * | |
124 | */ | |
125 | curexchange = 0; | |
126 | while ((exchangetlv = aim_gettlv(tlvlist, 0x0003, curexchange+1))) | |
127 | { | |
128 | curexchange++; | |
129 | exchanges = realloc(exchanges, curexchange * sizeof(struct aim_chat_exchangeinfo)); | |
130 | ||
131 | /* exchange number */ | |
132 | exchanges[curexchange-1].number = aimutil_get16(exchangetlv->value); | |
133 | innerlist = aim_readtlvchain(exchangetlv->value+2, exchangetlv->length-2); | |
134 | ||
135 | /* | |
136 | * Type 0x000d: Unknown. | |
137 | */ | |
138 | if (aim_gettlv(innerlist, 0x000d, 1)) | |
139 | ; | |
140 | ||
141 | /* | |
142 | * Type 0x0004: Unknown | |
143 | */ | |
144 | if (aim_gettlv(innerlist, 0x0004, 1)) | |
145 | ; | |
146 | ||
147 | /* | |
148 | * Type 0x00c9: Unknown | |
149 | */ | |
150 | if (aim_gettlv(innerlist, 0x00c9, 1)) | |
151 | ; | |
152 | ||
153 | /* | |
154 | * Type 0x00ca: Creation Date | |
155 | */ | |
156 | if (aim_gettlv(innerlist, 0x00ca, 1)) | |
157 | ; | |
158 | ||
159 | /* | |
160 | * Type 0x00d0: Unknown | |
161 | */ | |
162 | if (aim_gettlv(innerlist, 0x00d0, 1)) | |
163 | ; | |
164 | ||
165 | /* | |
166 | * Type 0x00d1: Maximum Message length | |
167 | */ | |
168 | if (aim_gettlv(innerlist, 0x00d1, 1)) | |
169 | ; | |
170 | ||
171 | /* | |
172 | * Type 0x00d2: Unknown | |
173 | */ | |
174 | if (aim_gettlv(innerlist, 0x00d2, 1)) | |
175 | ; | |
176 | ||
177 | /* | |
178 | * Type 0x00d3: Exchange Name | |
179 | */ | |
180 | if (aim_gettlv(innerlist, 0x00d3, 1)) | |
181 | exchanges[curexchange-1].name = aim_gettlv_str(innerlist, 0x00d3, 1); | |
182 | else | |
183 | exchanges[curexchange-1].name = NULL; | |
184 | ||
185 | /* | |
186 | * Type 0x00d5: Unknown | |
187 | */ | |
188 | if (aim_gettlv(innerlist, 0x00d5, 1)) | |
189 | ; | |
190 | ||
191 | /* | |
192 | * Type 0x00d6: Character Set (First Time) | |
193 | */ | |
194 | if (aim_gettlv(innerlist, 0x00d6, 1)) | |
195 | exchanges[curexchange-1].charset1 = aim_gettlv_str(innerlist, 0x00d6, 1); | |
196 | else | |
197 | exchanges[curexchange-1].charset1 = NULL; | |
198 | ||
199 | /* | |
200 | * Type 0x00d7: Language (First Time) | |
201 | */ | |
202 | if (aim_gettlv(innerlist, 0x00d7, 1)) | |
203 | exchanges[curexchange-1].lang1 = aim_gettlv_str(innerlist, 0x00d7, 1); | |
204 | else | |
205 | exchanges[curexchange-1].lang1 = NULL; | |
206 | ||
207 | /* | |
208 | * Type 0x00d8: Character Set (Second Time) | |
209 | */ | |
210 | if (aim_gettlv(innerlist, 0x00d8, 1)) | |
211 | exchanges[curexchange-1].charset2 = aim_gettlv_str(innerlist, 0x00d8, 1); | |
212 | else | |
213 | exchanges[curexchange-1].charset2 = NULL; | |
214 | ||
215 | /* | |
216 | * Type 0x00d9: Language (Second Time) | |
217 | */ | |
218 | if (aim_gettlv(innerlist, 0x00d9, 1)) | |
219 | exchanges[curexchange-1].lang2 = aim_gettlv_str(innerlist, 0x00d9, 1); | |
220 | else | |
221 | exchanges[curexchange-1].lang2 = NULL; | |
222 | ||
223 | } | |
224 | ||
225 | /* | |
226 | * Call client. | |
227 | */ | |
228 | userfunc = aim_callhandler(command->conn, 0x000d, 0x0009); | |
229 | if (userfunc) | |
230 | ret = userfunc(sess, | |
231 | command, | |
232 | snac->type, | |
233 | maxrooms, | |
234 | curexchange, | |
235 | exchanges); | |
236 | curexchange--; | |
237 | while(curexchange) | |
238 | { | |
239 | if (exchanges[curexchange].name) | |
240 | free(exchanges[curexchange].name); | |
241 | if (exchanges[curexchange].charset1) | |
242 | free(exchanges[curexchange].charset1); | |
243 | if (exchanges[curexchange].lang1) | |
244 | free(exchanges[curexchange].lang1); | |
245 | if (exchanges[curexchange].charset2) | |
246 | free(exchanges[curexchange].charset2); | |
247 | if (exchanges[curexchange].lang2) | |
248 | free(exchanges[curexchange].lang2); | |
249 | curexchange--; | |
250 | } | |
251 | free(exchanges); | |
252 | aim_freetlvchain(&innerlist); | |
253 | aim_freetlvchain(&tlvlist); | |
254 | return ret; | |
255 | } | |
256 | case 0x0003: /* request exchange info */ | |
257 | printf("faim: chatnav_parse_info: resposne to exchange info\n"); | |
258 | return 1; | |
259 | case 0x0004: /* request room info */ | |
260 | printf("faim: chatnav_parse_info: response to room info\n"); | |
261 | return 1; | |
262 | case 0x0005: /* request more room info */ | |
263 | printf("faim: chatnav_parse_info: response to more room info\n"); | |
264 | return 1; | |
265 | case 0x0006: /* request occupant list */ | |
266 | printf("faim: chatnav_parse_info: response to occupant info\n"); | |
267 | return 1; | |
268 | case 0x0007: /* search for a room */ | |
269 | printf("faim: chatnav_parse_info: search results\n"); | |
270 | return 1; | |
271 | case 0x0008: /* create room */ | |
272 | printf("faim: chatnav_parse_info: response to create room\n"); | |
273 | return 1; | |
274 | default: /* unknown */ | |
275 | printf("faim: chatnav_parse_info: unknown request subtype (%04x)\n", snac->type); | |
276 | } | |
277 | ||
278 | return 1; /* shouldn't get here */ | |
279 | } | |
280 | ||
281 | u_long aim_chatnav_createroom(struct aim_session_t *sess, | |
282 | struct aim_conn_t *conn, | |
283 | char *name, | |
284 | u_short exchange) | |
285 | { | |
286 | struct command_tx_struct newpacket; | |
287 | int i; | |
288 | struct aim_snac_t snac; | |
289 | ||
290 | newpacket.lock = 1; | |
291 | if (conn) | |
292 | newpacket.conn = conn; | |
293 | else | |
294 | newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV); | |
295 | newpacket.type = 0x02; | |
296 | ||
297 | newpacket.commandlen = 10 + 12 + strlen("invite") + strlen(name); | |
298 | ||
299 | newpacket.data = (char *) malloc(newpacket.commandlen); | |
300 | i = aim_putsnac(newpacket.data, 0x000d, 0x0008, 0x0000, sess->snac_nextid); | |
301 | ||
302 | /* exchange */ | |
303 | i+= aimutil_put16(newpacket.data+i, exchange); | |
304 | ||
305 | /* room cookie */ | |
306 | i+= aimutil_put8(newpacket.data+i, strlen("invite")); | |
307 | i+= aimutil_putstr(newpacket.data+i, "invite", strlen("invite")); | |
308 | ||
309 | /* instance */ | |
310 | i+= aimutil_put16(newpacket.data+i, 0xffff); | |
311 | ||
312 | /* detail level */ | |
313 | i+= aimutil_put8(newpacket.data+i, 0x01); | |
314 | ||
315 | /* tlvcount */ | |
316 | i+= aimutil_put16(newpacket.data+i, 0x0001); | |
317 | ||
318 | /* room name */ | |
319 | i+= aim_puttlv_str(newpacket.data+i, 0x00d3, strlen(name), name); | |
320 | ||
321 | snac.id = sess->snac_nextid; | |
322 | snac.family = 0x000d; | |
323 | snac.type = 0x0008; | |
324 | snac.flags = 0x0000; | |
325 | snac.data = NULL; | |
326 | ||
327 | aim_newsnac(sess, &snac); | |
328 | ||
329 | aim_tx_enqueue(sess, &newpacket); | |
330 | ||
331 | return (sess->snac_nextid++); | |
332 | } |