| 134 * TODO: Clean this up. |
120 * TODO: Clean this up. |
| 135 * |
121 * |
| 136 * XXX: I can't stress the TODO enough. |
122 * XXX: I can't stress the TODO enough. |
| 137 * |
123 * |
| 138 */ |
124 */ |
| 139 faim_export unsigned long aim_bos_setbuddylist(struct aim_session_t *sess, |
125 faim_export int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list) |
| 140 struct aim_conn_t *conn, |
126 { |
| 141 char *buddy_list) |
127 aim_frame_t *fr; |
| 142 { |
128 aim_snacid_t snacid; |
| 143 int i, j; |
129 int i, len = 0; |
| 144 |
130 char *localcpy = NULL; |
| 145 struct command_tx_struct *newpacket; |
131 char *tmpptr = NULL; |
| 146 |
132 |
| 147 int len = 0; |
133 if (!buddy_list || !(localcpy = strdup(buddy_list))) |
| 148 |
134 return -EINVAL; |
| 149 char *localcpy = NULL; |
135 |
| 150 char *tmpptr = NULL; |
136 i = 0; |
| 151 |
137 tmpptr = strtok(localcpy, "&"); |
| 152 len = 10; /* 10B SNAC headers */ |
138 while ((tmpptr != NULL) && (i < 150)) { |
| 153 |
139 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
| 154 if (!buddy_list || !(localcpy = (char *) malloc(strlen(buddy_list)+1))) |
140 len += 1+strlen(tmpptr); |
| 155 return -1; |
141 i++; |
| 156 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); |
142 tmpptr = strtok(NULL, "&"); |
| 157 |
143 } |
| 158 i = 0; |
144 |
| 159 tmpptr = strtok(localcpy, "&"); |
145 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len))) |
| 160 while ((tmpptr != NULL) && (i < 150)) { |
146 return -ENOMEM; |
| 161 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
147 |
| 162 len += 1+strlen(tmpptr); |
148 snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0); |
| 163 i++; |
149 |
| 164 tmpptr = strtok(NULL, "&"); |
150 aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid); |
| 165 } |
151 |
| 166 faimdprintf(sess, 2, "*** send buddy list len: %d (%x)\n", len, len); |
152 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); |
| 167 |
153 i = 0; |
| 168 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, len))) |
154 tmpptr = strtok(localcpy, "&"); |
| 169 return -1; |
155 while ((tmpptr != NULL) & (i < 150)) { |
| 170 |
156 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
| 171 newpacket->lock = 1; |
157 |
| 172 |
158 aimbs_put8(&fr->data, strlen(tmpptr)); |
| 173 aim_putsnac(newpacket->data, 0x0003, 0x0004, 0x0000, 0); |
159 aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr)); |
| 174 |
160 i++; |
| 175 j = 10; /* the next byte */ |
161 tmpptr = strtok(NULL, "&"); |
| 176 |
162 } |
| 177 strncpy(localcpy, buddy_list, strlen(buddy_list)+1); |
163 |
| 178 i = 0; |
164 aim_tx_enqueue(sess, fr); |
| 179 tmpptr = strtok(localcpy, "&"); |
165 |
| 180 while ((tmpptr != NULL) & (i < 150)) { |
166 free(localcpy); |
| 181 faimdprintf(sess, 2, "---adding %d: %s (%d)\n", i, tmpptr, strlen(tmpptr)); |
167 |
| 182 newpacket->data[j] = strlen(tmpptr); |
168 return 0; |
| 183 memcpy(&(newpacket->data[j+1]), tmpptr, strlen(tmpptr)); |
|
| 184 j += 1+strlen(tmpptr); |
|
| 185 i++; |
|
| 186 tmpptr = strtok(NULL, "&"); |
|
| 187 } |
|
| 188 |
|
| 189 newpacket->lock = 0; |
|
| 190 |
|
| 191 aim_tx_enqueue(sess, newpacket); |
|
| 192 |
|
| 193 free(localcpy); |
|
| 194 |
|
| 195 return (sess->snac_nextid); |
|
| 196 } |
169 } |
| 197 |
170 |
| 198 /* |
171 /* |
| 199 * aim_bos_setprofile(profile) |
172 * aim_bos_setprofile(profile) |
| 200 * |
173 * |
| 201 * Gives BOS your profile. |
174 * Gives BOS your profile. |
| 202 * |
175 * |
| 203 * |
176 * |
| 204 */ |
177 */ |
| 205 faim_export unsigned long aim_bos_setprofile(struct aim_session_t *sess, |
178 faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, fu16_t caps) |
| 206 struct aim_conn_t *conn, |
179 { |
| 207 const char *profile, |
180 static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""}; |
| 208 const char *awaymsg, |
181 aim_frame_t *fr; |
| 209 unsigned short caps) |
182 aim_tlvlist_t *tl = NULL; |
| 210 { |
183 aim_snacid_t snacid; |
| 211 struct command_tx_struct *newpacket; |
184 |
| 212 int i = 0, tmp, caplen; |
185 /* Build to packet first to get real length */ |
| 213 static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""}; |
186 if (profile) { |
| 214 |
187 aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), defencoding); |
| 215 i = 10; |
188 aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), profile); |
| 216 if (profile) |
189 } |
| 217 i += 4+strlen(defencoding)+4+strlen(profile); |
190 |
| 218 if (awaymsg) |
191 if (awaymsg) { |
| 219 i += 4+strlen(defencoding)+4+strlen(awaymsg); |
192 aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), defencoding); |
| 220 i += 4+512; /* for capabilities */ |
193 aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), awaymsg); |
| 221 |
194 } |
| 222 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, i))) |
195 |
| 223 return -1; |
196 aim_addtlvtochain_caps(&tl, 0x0005, caps); |
| 224 |
197 |
| 225 i = aim_putsnac(newpacket->data, 0x0002, 0x004, 0x0000, sess->snac_nextid); |
198 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_sizetlvchain(&tl)))) |
| 226 |
199 return -ENOMEM; |
| 227 if (profile) { |
200 |
| 228 i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(defencoding), defencoding); |
201 snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); |
| 229 i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(profile), profile); |
202 |
| 230 } |
203 aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid); |
| 231 |
204 aim_writetlvchain(&fr->data, &tl); |
| 232 if (awaymsg) { |
205 aim_freetlvchain(&tl); |
| 233 i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(defencoding), defencoding); |
206 |
| 234 i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(awaymsg), awaymsg); |
207 aim_tx_enqueue(sess, fr); |
| 235 } |
208 |
| 236 |
209 return 0; |
| 237 /* Capability information. */ |
|
| 238 |
|
| 239 tmp = (i += aimutil_put16(newpacket->data+i, 0x0005)); |
|
| 240 i += aimutil_put16(newpacket->data+i, 0x0000); /* rewritten later */ |
|
| 241 i += (caplen = aim_putcap(newpacket->data+i, 512, caps)); |
|
| 242 aimutil_put16(newpacket->data+tmp, caplen); /* rewrite TLV size */ |
|
| 243 |
|
| 244 newpacket->commandlen = i; |
|
| 245 aim_tx_enqueue(sess, newpacket); |
|
| 246 |
|
| 247 return (sess->snac_nextid++); |
|
| 248 } |
210 } |
| 249 |
211 |
| 250 /* |
212 /* |
| 251 * aim_bos_clientready() |
213 * aim_bos_clientready() |
| 252 * |
214 * |
| 253 * Send Client Ready. |
215 * Send Client Ready. |
| 254 * |
216 * |
| 255 */ |
217 */ |
| 256 faim_export unsigned long aim_bos_clientready(struct aim_session_t *sess, |
218 faim_export int aim_bos_clientready(aim_session_t *sess, aim_conn_t *conn) |
| 257 struct aim_conn_t *conn) |
219 { |
| 258 { |
220 struct aim_tool_version tools[] = { |
| 259 struct aim_tool_version tools[] = { |
221 {0x0001, 0x0003, AIM_TOOL_WIN32, 0x0686}, |
| 260 {0x0001, 0x0003, AIM_TOOL_WIN32, 0x0686}, |
222 {0x0002, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 261 {0x0002, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
223 {0x0003, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 262 {0x0003, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
224 {0x0004, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 263 {0x0004, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
225 {0x0006, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 264 {0x0006, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
226 {0x0008, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 265 {0x0008, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
227 {0x0009, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 266 {0x0009, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
228 {0x000a, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
| 267 {0x000a, 0x0001, AIM_TOOL_WIN32, 0x0001}, |
229 {0x000b, 0x0001, AIM_TOOL_WIN32, 0x0001} |
| 268 {0x000b, 0x0001, AIM_TOOL_WIN32, 0x0001} |
230 }; |
| 269 }; |
231 int j; |
| 270 int i,j; |
232 aim_frame_t *fr; |
| 271 struct command_tx_struct *newpacket; |
233 aim_snacid_t snacid; |
| 272 int toolcount = sizeof(tools)/sizeof(struct aim_tool_version); |
234 int toolcount = sizeof(tools)/sizeof(struct aim_tool_version); |
| 273 |
235 |
| 274 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 1152))) |
236 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152))) |
| 275 return -1; |
237 return -ENOMEM; |
| 276 |
238 |
| 277 newpacket->lock = 1; |
239 snacid = aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); |
| 278 |
240 aim_putsnac(&fr->data, 0x0001, 0x0002, 0x0000, snacid); |
| 279 i = aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); |
241 |
| 280 aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0); |
242 for (j = 0; j < toolcount; j++) { |
| 281 |
243 aimbs_put16(&fr->data, tools[j].group); |
| 282 for (j = 0; j < toolcount; j++) { |
244 aimbs_put16(&fr->data, tools[j].version); |
| 283 i += aimutil_put16(newpacket->data+i, tools[j].group); |
245 aimbs_put16(&fr->data, tools[j].tool); |
| 284 i += aimutil_put16(newpacket->data+i, tools[j].version); |
246 aimbs_put16(&fr->data, tools[j].toolversion); |
| 285 i += aimutil_put16(newpacket->data+i, tools[j].tool); |
247 } |
| 286 i += aimutil_put16(newpacket->data+i, tools[j].toolversion); |
248 |
| 287 } |
249 aim_tx_enqueue(sess, fr); |
| 288 |
250 |
| 289 newpacket->commandlen = i; |
251 return 0; |
| 290 newpacket->lock = 0; |
|
| 291 |
|
| 292 aim_tx_enqueue(sess, newpacket); |
|
| 293 |
|
| 294 return sess->snac_nextid; |
|
| 295 } |
252 } |
| 296 |
253 |
| 297 /* |
254 /* |
| 298 * Request Rate Information. |
255 * Request Rate Information. |
| 299 * |
256 * |
| 300 */ |
257 */ |
| 301 faim_export unsigned long aim_bos_reqrate(struct aim_session_t *sess, |
258 faim_export int aim_bos_reqrate(aim_session_t *sess, aim_conn_t *conn) |
| 302 struct aim_conn_t *conn) |
259 { |
| 303 { |
260 return aim_genericreq_n(sess, conn, 0x0001, 0x0006); |
| 304 return aim_genericreq_n(sess, conn, 0x0001, 0x0006); |
|
| 305 } |
261 } |
| 306 |
262 |
| 307 /* |
263 /* |
| 308 * Rate Information Response Acknowledge. |
264 * Rate Information Response Acknowledge. |
| 309 * |
265 * |
| 310 */ |
266 */ |
| 311 faim_export unsigned long aim_bos_ackrateresp(struct aim_session_t *sess, |
267 faim_export int aim_bos_ackrateresp(aim_session_t *sess, aim_conn_t *conn) |
| 312 struct aim_conn_t *conn) |
268 { |
| 313 { |
269 aim_frame_t *fr; |
| 314 struct command_tx_struct *newpacket; |
270 aim_snacid_t snacid; |
| 315 int packlen = 20, i=0; |
271 |
| 316 |
272 if(!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+10))) |
| 317 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen))) |
273 return -ENOMEM; |
| 318 return (sess->snac_nextid); |
274 |
| 319 |
275 snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0); |
| 320 newpacket->lock = 1; |
276 |
| 321 |
277 aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid); |
| 322 i = aim_putsnac(newpacket->data, 0x0001, 0x0008, 0x0000, 0); |
278 aimbs_put16(&fr->data, 0x0001); |
| 323 i += aimutil_put16(newpacket->data+i, 0x0001); |
279 aimbs_put16(&fr->data, 0x0002); |
| 324 i += aimutil_put16(newpacket->data+i, 0x0002); |
280 aimbs_put16(&fr->data, 0x0003); |
| 325 i += aimutil_put16(newpacket->data+i, 0x0003); |
281 aimbs_put16(&fr->data, 0x0004); |
| 326 i += aimutil_put16(newpacket->data+i, 0x0004); |
282 aimbs_put16(&fr->data, 0x0005); |
| 327 i += aimutil_put16(newpacket->data+i, 0x0005); |
283 |
| 328 |
284 aim_tx_enqueue(sess, fr); |
| 329 newpacket->commandlen = i; |
285 |
| 330 newpacket->lock = 0; |
286 return 0; |
| 331 |
|
| 332 aim_tx_enqueue(sess, newpacket); |
|
| 333 |
|
| 334 return (sess->snac_nextid); |
|
| 335 } |
287 } |
| 336 |
288 |
| 337 /* |
289 /* |
| 338 * aim_bos_setprivacyflags() |
290 * aim_bos_setprivacyflags() |
| 339 * |
291 * |
| 341 * |
293 * |
| 342 * Bit 1: Allows other AIM users to see how long you've been idle. |
294 * Bit 1: Allows other AIM users to see how long you've been idle. |
| 343 * Bit 2: Allows other AIM users to see how long you've been a member. |
295 * Bit 2: Allows other AIM users to see how long you've been a member. |
| 344 * |
296 * |
| 345 */ |
297 */ |
| 346 faim_export unsigned long aim_bos_setprivacyflags(struct aim_session_t *sess, |
298 faim_export int aim_bos_setprivacyflags(aim_session_t *sess, aim_conn_t *conn, fu32_t flags) |
| 347 struct aim_conn_t *conn, |
299 { |
| 348 u_long flags) |
300 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); |
| 349 { |
|
| 350 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); |
|
| 351 } |
301 } |
| 352 |
302 |
| 353 /* |
303 /* |
| 354 * aim_bos_reqpersonalinfo() |
304 * aim_bos_reqpersonalinfo() |
| 355 * |
305 * |
| 356 * Requests the current user's information. Can't go generic on this one |
306 */ |
| 357 * because aparently it uses SNAC flags. |
307 faim_export int aim_bos_reqpersonalinfo(aim_session_t *sess, aim_conn_t *conn) |
| 358 * |
308 { |
| 359 */ |
309 return aim_genericreq_n(sess, conn, 0x0001, 0x000e); |
| 360 faim_export unsigned long aim_bos_reqpersonalinfo(struct aim_session_t *sess, |
310 } |
| 361 struct aim_conn_t *conn) |
311 |
| 362 { |
312 faim_export int aim_setversions(aim_session_t *sess, aim_conn_t *conn) |
| 363 return aim_genericreq_n(sess, conn, 0x0001, 0x000e); |
313 { |
| 364 } |
314 aim_frame_t *fr; |
| 365 |
315 aim_snacid_t snacid; |
| 366 faim_export unsigned long aim_setversions(struct aim_session_t *sess, |
316 static const struct version { |
| 367 struct aim_conn_t *conn) |
317 fu16_t group; |
| 368 { |
318 fu16_t version; |
| 369 struct command_tx_struct *newpacket; |
319 } versions[] = { |
| 370 int i; |
320 {0x0001, 0x0003}, |
| 371 |
321 {0x0002, 0x0001}, |
| 372 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + (4*16)))) |
322 {0x0003, 0x0001}, |
| 373 return -1; |
323 {0x0004, 0x0001}, |
| 374 |
324 {0x0006, 0x0001}, |
| 375 newpacket->lock = 1; |
325 {0x0008, 0x0001}, |
| 376 |
326 {0x0009, 0x0001}, |
| 377 i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid); |
327 {0x000a, 0x0001}, |
| 378 aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); |
328 {0x000b, 0x0002}, |
| 379 |
329 {0x000c, 0x0001}, |
| 380 i += aimutil_put16(newpacket->data+i, 0x0001); |
330 {0x0013, 0x0001}, |
| 381 i += aimutil_put16(newpacket->data+i, 0x0003); |
331 {0x0015, 0x0001}, |
| 382 |
332 }; |
| 383 i += aimutil_put16(newpacket->data+i, 0x0002); |
333 int numversions = sizeof(versions) / sizeof(struct version); |
| 384 i += aimutil_put16(newpacket->data+i, 0x0001); |
334 int i; |
| 385 |
335 |
| 386 i += aimutil_put16(newpacket->data+i, 0x0003); |
336 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + (4*numversions)))) |
| 387 i += aimutil_put16(newpacket->data+i, 0x0001); |
337 return -ENOMEM; |
| 388 |
338 |
| 389 i += aimutil_put16(newpacket->data+i, 0x0004); |
339 snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0); |
| 390 i += aimutil_put16(newpacket->data+i, 0x0001); |
340 |
| 391 |
341 aim_putsnac(&fr->data, 0x0001, 0x0017, 0x0000, snacid); |
| 392 i += aimutil_put16(newpacket->data+i, 0x0006); |
342 for (i = 0; i < numversions; i++) { |
| 393 i += aimutil_put16(newpacket->data+i, 0x0001); |
343 aimbs_put16(&fr->data, versions[i].group); |
| 394 |
344 aimbs_put16(&fr->data, versions[i].version); |
| 395 i += aimutil_put16(newpacket->data+i, 0x0008); |
345 } |
| 396 i += aimutil_put16(newpacket->data+i, 0x0001); |
346 |
| 397 |
347 aim_tx_enqueue(sess, fr); |
| 398 i += aimutil_put16(newpacket->data+i, 0x0009); |
348 |
| 399 i += aimutil_put16(newpacket->data+i, 0x0001); |
349 return 0; |
| 400 |
|
| 401 i += aimutil_put16(newpacket->data+i, 0x000a); |
|
| 402 i += aimutil_put16(newpacket->data+i, 0x0001); |
|
| 403 |
|
| 404 i += aimutil_put16(newpacket->data+i, 0x000b); |
|
| 405 i += aimutil_put16(newpacket->data+i, 0x0002); |
|
| 406 |
|
| 407 i += aimutil_put16(newpacket->data+i, 0x000c); |
|
| 408 i += aimutil_put16(newpacket->data+i, 0x0001); |
|
| 409 |
|
| 410 i += aimutil_put16(newpacket->data+i, 0x0013); |
|
| 411 i += aimutil_put16(newpacket->data+i, 0x0001); |
|
| 412 |
|
| 413 i += aimutil_put16(newpacket->data+i, 0x0015); |
|
| 414 i += aimutil_put16(newpacket->data+i, 0x0001); |
|
| 415 |
|
| 416 newpacket->commandlen = i; |
|
| 417 newpacket->lock = 0; |
|
| 418 aim_tx_enqueue(sess, newpacket); |
|
| 419 |
|
| 420 return sess->snac_nextid; |
|
| 421 } |
350 } |
| 422 |
351 |
| 423 |
352 |
| 424 /* |
353 /* |
| 425 * aim_bos_reqservice(serviceid) |
354 * aim_bos_reqservice(serviceid) |
| 426 * |
355 * |
| 427 * Service request. |
356 * Service request. |
| 428 * |
357 * |
| 429 */ |
358 */ |
| 430 faim_export unsigned long aim_bos_reqservice(struct aim_session_t *sess, |
359 faim_export int aim_bos_reqservice(aim_session_t *sess, aim_conn_t *conn, fu16_t serviceid) |
| 431 struct aim_conn_t *conn, |
360 { |
| 432 u_short serviceid) |
361 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); |
| 433 { |
|
| 434 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); |
|
| 435 } |
362 } |
| 436 |
363 |
| 437 /* |
364 /* |
| 438 * aim_bos_nop() |
365 * aim_bos_nop() |
| 439 * |
366 * |
| 440 * No-op. WinAIM sends these every 4min or so to keep |
367 * No-op. WinAIM sends these every 4min or so to keep |
| 441 * the connection alive. Its not real necessary. |
368 * the connection alive. Its not real necessary. |
| 442 * |
369 * |
| 443 */ |
370 */ |
| 444 faim_export unsigned long aim_bos_nop(struct aim_session_t *sess, |
371 faim_export int aim_bos_nop(aim_session_t *sess, aim_conn_t *conn) |
| 445 struct aim_conn_t *conn) |
372 { |
| 446 { |
373 return aim_genericreq_n(sess, conn, 0x0001, 0x0016); |
| 447 return aim_genericreq_n(sess, conn, 0x0001, 0x0016); |
|
| 448 } |
374 } |
| 449 |
375 |
| 450 /* |
376 /* |
| 451 * aim_flap_nop() |
377 * aim_flap_nop() |
| 452 * |
378 * |
| 453 * No-op. WinAIM 4.x sends these _every minute_ to keep |
379 * No-op. WinAIM 4.x sends these _every minute_ to keep |
| 454 * the connection alive. |
380 * the connection alive. |
| 455 */ |
381 */ |
| 456 faim_export unsigned long aim_flap_nop(struct aim_session_t *sess, |
382 faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn) |
| 457 struct aim_conn_t *conn) |
383 { |
| 458 { |
384 aim_frame_t *fr; |
| 459 struct command_tx_struct *newpacket; |
385 |
| 460 |
386 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) |
| 461 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0005, 0))) |
387 return -ENOMEM; |
| 462 return sess->snac_nextid; |
388 |
| 463 |
389 aim_tx_enqueue(sess, fr); |
| 464 newpacket->lock = 1; |
390 |
| 465 newpacket->commandlen = 0; |
391 return 0; |
| 466 newpacket->lock = 0; |
|
| 467 |
|
| 468 aim_tx_enqueue(sess, newpacket); |
|
| 469 |
|
| 470 return (sess->snac_nextid); |
|
| 471 } |
392 } |
| 472 |
393 |
| 473 /* |
394 /* |
| 474 * aim_bos_reqrights() |
395 * aim_bos_reqrights() |
| 475 * |
396 * |
| 476 * Request BOS rights. |
397 * Request BOS rights. |
| 477 * |
398 * |
| 478 */ |
399 */ |
| 479 faim_export unsigned long aim_bos_reqrights(struct aim_session_t *sess, |
400 faim_export int aim_bos_reqrights(aim_session_t *sess, aim_conn_t *conn) |
| 480 struct aim_conn_t *conn) |
401 { |
| 481 { |
402 return aim_genericreq_n(sess, conn, 0x0009, 0x0002); |
| 482 return aim_genericreq_n(sess, conn, 0x0009, 0x0002); |
|
| 483 } |
403 } |
| 484 |
404 |
| 485 /* |
405 /* |
| 486 * aim_bos_reqbuddyrights() |
406 * aim_bos_reqbuddyrights() |
| 487 * |
407 * |
| 488 * Request Buddy List rights. |
408 * Request Buddy List rights. |
| 489 * |
409 * |
| 490 */ |
410 */ |
| 491 faim_export unsigned long aim_bos_reqbuddyrights(struct aim_session_t *sess, |
411 faim_export int aim_bos_reqbuddyrights(aim_session_t *sess, aim_conn_t *conn) |
| 492 struct aim_conn_t *conn) |
412 { |
| 493 { |
413 return aim_genericreq_n(sess, conn, 0x0003, 0x0002); |
| 494 return aim_genericreq_n(sess, conn, 0x0003, 0x0002); |
|
| 495 } |
414 } |
| 496 |
415 |
| 497 /* |
416 /* |
| 498 * Send a warning to destsn. |
417 * Send a warning to destsn. |
| 499 * |
418 * |
| 557 * I had one big function that handled all three cases, but then it broke |
467 * I had one big function that handled all three cases, but then it broke |
| 558 * and I split it up into three. But then I fixed it. I just never went |
468 * and I split it up into three. But then I fixed it. I just never went |
| 559 * back to the single. I don't see any advantage to doing it either way. |
469 * back to the single. I don't see any advantage to doing it either way. |
| 560 * |
470 * |
| 561 */ |
471 */ |
| 562 faim_internal unsigned long aim_genericreq_n(struct aim_session_t *sess, |
472 faim_internal int aim_genericreq_n(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype) |
| 563 struct aim_conn_t *conn, |
473 { |
| 564 u_short family, u_short subtype) |
474 aim_frame_t *fr; |
| 565 { |
475 aim_snacid_t snacid = 0x00000000; |
| 566 struct command_tx_struct *newpacket; |
476 |
| 567 |
477 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10))) |
| 568 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10))) |
478 return -ENOMEM; |
| 569 return 0; |
479 |
| 570 |
480 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
| 571 newpacket->lock = 1; |
481 |
| 572 |
482 aim_tx_enqueue(sess, fr); |
| 573 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); |
483 |
| 574 |
484 return 0; |
| 575 aim_tx_enqueue(sess, newpacket); |
485 } |
| 576 |
486 |
| 577 return sess->snac_nextid; |
487 faim_internal int aim_genericreq_n_snacid(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype) |
| 578 } |
488 { |
| 579 |
489 aim_frame_t *fr; |
| 580 faim_internal unsigned long aim_genericreq_n_snacid(struct aim_session_t *sess, |
490 aim_snacid_t snacid; |
| 581 struct aim_conn_t *conn, |
491 |
| 582 unsigned short family, |
492 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10))) |
| 583 unsigned short subtype) |
493 return -ENOMEM; |
| 584 { |
494 |
| 585 struct command_tx_struct *newpacket; |
495 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
| 586 |
496 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
| 587 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10))) |
497 |
| 588 return 0; |
498 aim_tx_enqueue(sess, fr); |
| 589 |
499 |
| 590 newpacket->lock = 1; |
500 return 0; |
| 591 |
501 } |
| 592 aim_putsnac(newpacket->data, family, subtype, 0x0000, sess->snac_nextid); |
502 |
| 593 aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
503 /* |
| 594 |
504 * |
| 595 aim_tx_enqueue(sess, newpacket); |
505 * |
| 596 |
506 */ |
| 597 return sess->snac_nextid++; |
507 faim_internal int aim_genericreq_l(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu32_t *longdata) |
| 598 } |
508 { |
| 599 |
509 aim_frame_t *fr; |
| 600 /* |
510 aim_snacid_t snacid; |
| 601 * |
511 |
| 602 * |
512 if (!longdata) |
| 603 */ |
513 return aim_genericreq_n(sess, conn, family, subtype); |
| 604 faim_internal unsigned long aim_genericreq_l(struct aim_session_t *sess, |
514 |
| 605 struct aim_conn_t *conn, |
515 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4))) |
| 606 u_short family, u_short subtype, |
516 return -ENOMEM; |
| 607 u_long *longdata) |
517 |
| 608 { |
518 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
| 609 struct command_tx_struct *newpacket; |
519 |
| 610 u_long newlong; |
520 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
| 611 |
521 aimbs_put32(&fr->data, *longdata); |
| 612 /* If we don't have data, there's no reason to use this function */ |
522 |
| 613 if (!longdata) |
523 aim_tx_enqueue(sess, fr); |
| 614 return aim_genericreq_n(sess, conn, family, subtype); |
524 |
| 615 |
525 return 0; |
| 616 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+sizeof(u_long)))) |
526 } |
| 617 return -1; |
527 |
| 618 |
528 faim_internal int aim_genericreq_s(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu16_t *shortdata) |
| 619 newpacket->lock = 1; |
529 { |
| 620 |
530 aim_frame_t *fr; |
| 621 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); |
531 aim_snacid_t snacid; |
| 622 |
532 |
| 623 /* copy in data */ |
533 if (!shortdata) |
| 624 newlong = htonl(*longdata); |
534 return aim_genericreq_n(sess, conn, family, subtype); |
| 625 memcpy(&(newpacket->data[10]), &newlong, sizeof(u_long)); |
535 |
| 626 |
536 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2))) |
| 627 aim_tx_enqueue(sess, newpacket); |
537 return -ENOMEM; |
| 628 |
538 |
| 629 return sess->snac_nextid; |
539 snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0); |
| 630 } |
540 |
| 631 |
541 aim_putsnac(&fr->data, family, subtype, 0x0000, snacid); |
| 632 faim_internal unsigned long aim_genericreq_s(struct aim_session_t *sess, |
542 aimbs_put16(&fr->data, *shortdata); |
| 633 struct aim_conn_t *conn, |
543 |
| 634 u_short family, u_short subtype, |
544 aim_tx_enqueue(sess, fr); |
| 635 u_short *shortdata) |
545 |
| 636 { |
546 return 0; |
| 637 struct command_tx_struct *newpacket; |
|
| 638 u_short newshort; |
|
| 639 |
|
| 640 /* If we don't have data, there's no reason to use this function */ |
|
| 641 if (!shortdata) |
|
| 642 return aim_genericreq_n(sess, conn, family, subtype); |
|
| 643 |
|
| 644 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+sizeof(u_short)))) |
|
| 645 return -1; |
|
| 646 |
|
| 647 newpacket->lock = 1; |
|
| 648 |
|
| 649 aim_putsnac(newpacket->data, family, subtype, 0x0000, 0x00000000); |
|
| 650 |
|
| 651 /* copy in data */ |
|
| 652 newshort = htons(*shortdata); |
|
| 653 memcpy(&(newpacket->data[10]), &newshort, sizeof(u_short)); |
|
| 654 |
|
| 655 aim_tx_enqueue(sess, newpacket); |
|
| 656 |
|
| 657 return sess->snac_nextid; |
|
| 658 } |
547 } |
| 659 |
548 |
| 660 /* |
549 /* |
| 661 * aim_bos_reqlocaterights() |
550 * aim_bos_reqlocaterights() |
| 662 * |
551 * |
| 663 * Request Location services rights. |
552 * Request Location services rights. |
| 664 * |
553 * |
| 665 */ |
554 */ |
| 666 faim_export unsigned long aim_bos_reqlocaterights(struct aim_session_t *sess, |
555 faim_export int aim_bos_reqlocaterights(aim_session_t *sess, aim_conn_t *conn) |
| 667 struct aim_conn_t *conn) |
556 { |
| 668 { |
557 return aim_genericreq_n(sess, conn, 0x0002, 0x0002); |
| 669 return aim_genericreq_n(sess, conn, 0x0002, 0x0002); |
|
| 670 } |
558 } |
| 671 |
559 |
| 672 /* |
560 /* |
| 673 * Set directory profile data (not the same as aim_bos_setprofile!) |
561 * Set directory profile data (not the same as aim_bos_setprofile!) |
| 674 */ |
562 * |
| 675 faim_export unsigned long aim_setdirectoryinfo(struct aim_session_t *sess, struct aim_conn_t *conn, char *first, char *middle, char *last, char *maiden, char *nickname, char *street, char *city, char *state, char *zip, int country, unsigned short privacy) |
563 * privacy: 1 to allow searching, 0 to disallow. |
| 676 { |
564 */ |
| 677 struct command_tx_struct *newpacket; |
565 faim_export 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, fu16_t privacy) |
| 678 int packlen = 0, i = 0; |
566 { |
| 679 |
567 aim_frame_t *fr; |
| 680 packlen += 2+2+2; |
568 aim_snacid_t snacid; |
| 681 |
569 aim_tlvlist_t *tl = NULL; |
| 682 if(first) /* TLV 0001 */ |
570 |
| 683 packlen += (strlen(first) + 4); |
571 |
| 684 if(middle) |
572 aim_addtlvtochain16(&tl, 0x000a, privacy); |
| 685 packlen += (strlen(middle) + 4); |
573 |
| 686 if(last) |
574 if (first) |
| 687 packlen += (strlen(last) + 4); |
575 aim_addtlvtochain_raw(&tl, 0x0001, strlen(first), first); |
| 688 if(maiden) |
576 if (last) |
| 689 packlen += (strlen(maiden) + 4); |
577 aim_addtlvtochain_raw(&tl, 0x0002, strlen(last), last); |
| 690 if(nickname) |
578 if (middle) |
| 691 packlen += (strlen(nickname) + 4); |
579 aim_addtlvtochain_raw(&tl, 0x0003, strlen(middle), middle); |
| 692 if(street) |
580 if (maiden) |
| 693 packlen += (strlen(street) + 4); |
581 aim_addtlvtochain_raw(&tl, 0x0004, strlen(maiden), maiden); |
| 694 if(state) |
582 |
| 695 packlen += (strlen(state) + 4); |
583 if (state) |
| 696 if(city) |
584 aim_addtlvtochain_raw(&tl, 0x0007, strlen(state), state); |
| 697 packlen += (strlen(city) + 4); |
585 if (city) |
| 698 if(zip) |
586 aim_addtlvtochain_raw(&tl, 0x0008, strlen(city), city); |
| 699 packlen += (strlen(zip) + 4); |
587 |
| 700 |
588 if (nickname) |
| 701 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen+10))) |
589 aim_addtlvtochain_raw(&tl, 0x000c, strlen(nickname), nickname); |
| 702 return -1; |
590 if (zip) |
| 703 |
591 aim_addtlvtochain_raw(&tl, 0x000d, strlen(zip), zip); |
| 704 newpacket->lock = 1; |
592 |
| 705 |
593 if (street) |
| 706 i = aim_putsnac(newpacket->data, 0x0002, 0x0009, 0x0000, 0); |
594 aim_addtlvtochain_raw(&tl, 0x0021, strlen(street), street); |
| 707 |
595 |
| 708 /* 000a/0002: privacy: 1 to allow search/disp, 0 to disallow */ |
596 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl)))) |
| 709 i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); |
597 return -ENOMEM; |
| 710 |
598 |
| 711 |
599 snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0); |
| 712 if (first) |
600 |
| 713 i += aim_puttlv_str(newpacket->data+i, 0x0001, strlen(first), first); |
601 aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid); |
| 714 if (middle) |
602 aim_writetlvchain(&fr->data, &tl); |
| 715 i += aim_puttlv_str(newpacket->data+i, 0x0003, strlen(middle), middle); |
603 aim_freetlvchain(&tl); |
| 716 if (last) |
604 |
| 717 i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(last), last); |
605 aim_tx_enqueue(sess, fr); |
| 718 if (maiden) |
606 |
| 719 i += aim_puttlv_str(newpacket->data+i, 0x0004, strlen(maiden), maiden); |
607 return 0; |
| 720 if (nickname) |
608 } |
| 721 i += aim_puttlv_str(newpacket->data+i, 0x000c, strlen(nickname), nickname); |
609 |
| 722 if (street) |
610 /* XXX pass these in better */ |
| 723 i += aim_puttlv_str(newpacket->data+i, 0x0021, strlen(street), street); |
611 faim_export 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, fu16_t privacy) |
| 724 if (city) |
612 { |
| 725 i += aim_puttlv_str(newpacket->data+i, 0x0008, strlen(city), city); |
613 aim_frame_t *fr; |
| 726 if (state) |
614 aim_snacid_t snacid; |
| 727 i += aim_puttlv_str(newpacket->data+i, 0x0007, strlen(state), state); |
615 aim_tlvlist_t *tl = NULL; |
| 728 if (zip) |
616 |
| 729 i += aim_puttlv_str(newpacket->data+i, 0x000d, strlen(zip), zip); |
617 /* ?? privacy ?? */ |
| 730 |
618 aim_addtlvtochain16(&tl, 0x000a, privacy); |
| 731 newpacket->commandlen = i; |
619 |
| 732 newpacket->lock = 0; |
620 if (interest1) |
| 733 |
621 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest1), interest1); |
| 734 aim_tx_enqueue(sess, newpacket); |
622 if (interest2) |
| 735 |
623 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest2), interest2); |
| 736 return(sess->snac_nextid); |
624 if (interest3) |
| 737 } |
625 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest3), interest3); |
| 738 |
626 if (interest4) |
| 739 faim_export unsigned long aim_setuserinterests(struct aim_session_t *sess, struct aim_conn_t *conn, char *interest1, char *interest2, char *interest3, char *interest4, char *interest5, unsigned short privacy) |
627 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest4), interest4); |
| 740 { |
628 if (interest5) |
| 741 struct command_tx_struct *newpacket; |
629 aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest5), interest5); |
| 742 int packlen = 0, i = 0; |
630 |
| 743 |
631 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl)))) |
| 744 packlen += 2+2+2; |
632 return -ENOMEM; |
| 745 |
633 |
| 746 if(interest1) |
634 snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0); |
| 747 packlen += (strlen(interest1) + 4); |
635 |
| 748 if(interest2) |
636 aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0); |
| 749 packlen += (strlen(interest2) + 4); |
637 aim_writetlvchain(&fr->data, &tl); |
| 750 if(interest3) |
638 aim_freetlvchain(&tl); |
| 751 packlen += (strlen(interest3) + 4); |
639 |
| 752 if(interest4) |
640 aim_tx_enqueue(sess, fr); |
| 753 packlen += (strlen(interest4) + 4); |
641 |
| 754 if(interest5) |
642 return 0; |
| 755 packlen += (strlen(interest5) + 4) ; |
643 } |
| 756 |
644 |
| 757 |
645 faim_export int aim_icq_setstatus(aim_session_t *sess, aim_conn_t *conn, fu32_t status) |
| 758 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, packlen+10))) |
646 { |
| 759 return -1; |
647 aim_frame_t *fr; |
| 760 |
648 aim_snacid_t snacid; |
| 761 newpacket->lock = 1; |
649 aim_tlvlist_t *tl = NULL; |
| 762 |
650 fu32_t data; |
| 763 i = aim_putsnac(newpacket->data, 0x0002, 0x000f, 0x0000, 0); |
651 |
| 764 |
652 data = 0x00030000 | status; /* yay for error checking ;^) */ |
| 765 /* 000a/0002: 0000 ?? ?privacy? */ |
653 |
| 766 i += aim_puttlv_16(newpacket->data+i, 0x000a, privacy); |
654 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4))) |
| 767 |
655 return -ENOMEM; |
| 768 if(interest1) |
656 |
| 769 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest1); |
657 snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0); |
| 770 if(interest2) |
658 aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid); |
| 771 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest2), interest2); |
659 |
| 772 if(interest3) |
660 aim_addtlvtochain32(&tl, 0x0006, data); |
| 773 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest3), interest3); |
661 aim_writetlvchain(&fr->data, &tl); |
| 774 if(interest4) |
662 aim_freetlvchain(&tl); |
| 775 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest4), interest4); |
663 |
| 776 if(interest5) |
664 aim_tx_enqueue(sess, fr); |
| 777 i += aim_puttlv_str(newpacket->data+i, 0x000b, strlen(interest1), interest5); |
665 |
| 778 |
666 return 0; |
| 779 newpacket->commandlen = i; |
|
| 780 newpacket->lock = 0; |
|
| 781 |
|
| 782 aim_tx_enqueue(sess, newpacket); |
|
| 783 |
|
| 784 return(sess->snac_nextid); |
|
| 785 } |
|
| 786 |
|
| 787 faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess, |
|
| 788 struct aim_conn_t *conn, |
|
| 789 unsigned long status) |
|
| 790 { |
|
| 791 struct command_tx_struct *newpacket; |
|
| 792 int i; |
|
| 793 unsigned long data; |
|
| 794 |
|
| 795 data = 0x00030000 | status; /* yay for error checking ;^) */ |
|
| 796 |
|
| 797 if(!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10 + 4))) |
|
| 798 return -1; |
|
| 799 |
|
| 800 newpacket->lock = 1; |
|
| 801 |
|
| 802 i = aim_putsnac(newpacket->data, 0x0001, 0x001e, 0x0000, 0x0000001e); |
|
| 803 i += aim_puttlv_32(newpacket->data+i, 0x0006, data); |
|
| 804 |
|
| 805 newpacket->commandlen = i; |
|
| 806 newpacket->lock = 0; |
|
| 807 |
|
| 808 aim_tx_enqueue(sess, newpacket); |
|
| 809 |
|
| 810 return(sess->snac_nextid); |
|
| 811 } |
667 } |
| 812 |
668 |
| 813 /* |
669 /* |
| 814 * Should be generic enough to handle the errors for all families... |
670 * Should be generic enough to handle the errors for all families... |
| 815 * |
671 * |
| 816 */ |
672 */ |
| 817 static int generror(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) |
673 static int generror(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
| 818 { |
674 { |
| 819 int ret = 0; |
675 int ret = 0; |
| 820 int error = 0; |
676 int error = 0; |
| 821 aim_rxcallback_t userfunc; |
677 aim_rxcallback_t userfunc; |
| 822 struct aim_snac_t *snac2; |
678 aim_snac_t *snac2; |
| 823 |
679 |
| 824 snac2 = aim_remsnac(sess, snac->id); |
680 snac2 = aim_remsnac(sess, snac->id); |
| 825 |
681 |
| 826 if (datalen) |
682 if (aim_bstream_empty(bs)) |
| 827 error = aimutil_get16(data); |
683 error = aimbs_get16(bs); |
| 828 |
684 |
| 829 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
685 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
| 830 ret = userfunc(sess, rx, error, snac2?snac2->data:NULL); |
686 ret = userfunc(sess, rx, error, snac2 ? snac2->data : NULL); |
| 831 |
687 |
| 832 if (snac2) |
688 if (snac2) |
| 833 free(snac2->data); |
689 free(snac2->data); |
| 834 free(snac2); |
690 free(snac2); |
| 835 |
691 |
| 836 return ret; |
692 return ret; |
| 837 } |
693 } |
| 838 |
694 |
| 839 static int snachandler(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen) |
695 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
| 840 { |
696 { |
| 841 |
697 |
| 842 if (snac->subtype == 0x0001) |
698 if (snac->subtype == 0x0001) |
| 843 return generror(sess, mod, rx, snac, data, datalen); |
699 return generror(sess, mod, rx, snac, bs); |
| 844 else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) { |
700 else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) { |
| 845 aim_rxcallback_t userfunc; |
701 aim_rxcallback_t userfunc; |
| 846 |
702 |
| 847 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
703 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) |
| 848 return userfunc(sess, rx); |
704 return userfunc(sess, rx); |
| 849 } |
705 } |
| 850 |
706 |
| 851 return 0; |
707 return 0; |
| 852 } |
708 } |
| 853 |
709 |
| 854 faim_internal int misc_modfirst(struct aim_session_t *sess, aim_module_t *mod) |
710 faim_internal int misc_modfirst(aim_session_t *sess, aim_module_t *mod) |
| 855 { |
711 { |
| 856 |
712 |
| 857 mod->family = 0xffff; |
713 mod->family = 0xffff; |
| 858 mod->version = 0x0000; |
714 mod->version = 0x0000; |
| 859 mod->flags = AIM_MODFLAG_MULTIFAMILY; |
715 mod->flags = AIM_MODFLAG_MULTIFAMILY; |
| 860 strncpy(mod->name, "misc", sizeof(mod->name)); |
716 strncpy(mod->name, "misc", sizeof(mod->name)); |
| 861 mod->snachandler = snachandler; |
717 mod->snachandler = snachandler; |
| 862 |
718 |
| 863 return 0; |
719 return 0; |
| 864 } |
720 } |