5 * TODO: Seperate a lot of this into an aim_bos.c.
19 * Should set your current idle time in seconds. Idealy, OSCAR should
20 * do this for us. But, it doesn't. The client must call this to set idle
24 u_long aim_bos_setidle(struct aim_conn_t *conn, u_long idletime)
26 return aim_genericreq_l(conn, 0x0001, 0x0011, &idletime);
31 * aim_bos_changevisibility(conn, changtype, namelist)
33 * Changes your visibility depending on changetype:
35 * AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
36 * AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
37 * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
38 * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
40 * list should be a list of
41 * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
43 * Equivelents to options in WinAIM:
44 * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
45 * with only your name on it.
46 * - Allow only users on my Buddy List: Send an
47 * AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
49 * - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
50 * with everyone listed that you want to see you.
51 * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
52 * yourself in the list
53 * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
54 * the list of users to be blocked
58 u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *denylist)
60 struct command_tx_struct newpacket;
63 char *localcpy = NULL;
74 newpacket.conn = conn;
76 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
78 newpacket.type = 0x02;
80 localcpy = (char *) malloc(strlen(denylist)+1);
81 memcpy(localcpy, denylist, strlen(denylist)+1);
83 listcount = aimutil_itemcnt(localcpy, '&');
84 newpacket.commandlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
87 newpacket.data = (char *) malloc(newpacket.commandlen);
88 memset(newpacket.data, 0x00, newpacket.commandlen);
92 case AIM_VISIBILITYCHANGE_PERMITADD: subtype = 0x05; break;
93 case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break;
94 case AIM_VISIBILITYCHANGE_DENYADD: subtype = 0x07; break;
95 case AIM_VISIBILITYCHANGE_DENYREMOVE: subtype = 0x08; break;
101 /* We actually DO NOT send a SNAC ID with this one! */
102 aim_putsnac(newpacket.data, 0x0009, subtype, 0x00, 0);
104 j = 10; /* the next byte */
106 for (i=0; (i < (listcount - 1)) && (i < 99); i++)
108 tmpptr = aimutil_itemidx(localcpy, i, '&');
110 newpacket.data[j] = strlen(tmpptr);
111 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
112 j += strlen(tmpptr)+1;
119 aim_tx_enqueue(&newpacket);
121 return (aim_snac_nextid); /* dont increment */
128 * aim_bos_setbuddylist(buddylist)
130 * This just builds the "set buddy list" command then queues it.
132 * buddy_list = "Screen Name One&ScreenNameTwo&";
134 * TODO: Clean this up.
137 u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list)
141 struct command_tx_struct newpacket;
143 int packet_login_phase3c_hi_b_len = 0;
145 char *localcpy = NULL;
148 packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */
150 /* bail out if we can't make the packet */
151 if (buddy_list == NULL)
153 printf("\nNO BUDDIES! ARE YOU THAT LONELY???\n");
157 printf("****buddy list: %s\n", buddy_list);
158 printf("****buddy list len: %d (%x)\n", strlen(buddy_list), strlen(buddy_list));
161 localcpy = (char *) malloc(strlen(buddy_list)+1);
162 memcpy(localcpy, buddy_list, strlen(buddy_list)+1);
165 tmpptr = strtok(localcpy, "&");
166 while ((tmpptr != NULL) && (i < 100))
169 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
171 packet_login_phase3c_hi_b_len += strlen(tmpptr)+1;
173 tmpptr = strtok(NULL, "&");
176 printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len);
180 newpacket.type = 0x02;
182 newpacket.conn = conn;
184 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
185 newpacket.commandlen = packet_login_phase3c_hi_b_len - 6;
188 newpacket.data = (char *) malloc(newpacket.commandlen);
190 aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, aim_snac_nextid);
192 j = 10; /* the next byte */
195 tmpptr = strtok(buddy_list, "&");
196 while ((tmpptr != NULL) & (i < 100))
199 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
201 newpacket.data[j] = strlen(tmpptr);
202 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
203 j += strlen(tmpptr)+1;
205 tmpptr = strtok(NULL, "&");
210 aim_tx_enqueue(&newpacket);
212 return (aim_snac_nextid++);
216 * aim_bos_setprofile(profile)
218 * Gives BOS your profile.
221 u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile)
223 int packet_profile_len = 0;
224 struct command_tx_struct newpacket;
228 packet_profile_len = 10;
229 /* len: T+L (where t(0001)) */
230 packet_profile_len += 2 + 2;
231 /* len: V (where t(0001)) */
232 packet_profile_len += strlen("text/x-aolrtf");
233 /* len: T+L (where t(0002)) */
234 packet_profile_len += 2 + 2;
235 /* len: V (where t(0002)) */
236 packet_profile_len += strlen(profile);
238 newpacket.type = 0x02;
240 newpacket.conn = conn;
242 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
243 newpacket.commandlen = packet_profile_len;
244 newpacket.data = (char *) malloc(packet_profile_len);
248 i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, aim_snac_nextid);
251 newpacket.data[i++] = 0x00;
252 newpacket.data[i++] = 0x01;
254 newpacket.data[i++] = 0x00;
255 newpacket.data[i++] = 0x0d;
256 /* TLV v(text/x-aolrtf) */
257 memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
261 newpacket.data[i++] = 0x00;
262 newpacket.data[i++] = 0x02;
264 newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
265 newpacket.data[i++] = (strlen(profile) & 0xFF);
267 memcpy(&(newpacket.data[i]), profile, strlen(profile));
269 aim_tx_enqueue(&newpacket);
271 return (aim_snac_nextid++);
275 * aim_bos_setgroupperm(mask)
277 * Set group permisson mask. Normally 0x1f.
280 u_long aim_bos_setgroupperm(struct aim_conn_t *conn, u_long mask)
282 return aim_genericreq_l(conn, 0x0009, 0x0004, &mask);
286 * aim_bos_clientready()
293 u_long aim_bos_clientready(struct aim_conn_t *conn)
295 u_char command_2[] = {
296 /* placeholders for dynamic data */
297 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
300 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
301 0x00, 0x13, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01,
302 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
303 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01,
304 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
305 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
306 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
307 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01,
308 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x01,
311 int command_2_len = 0x52;
312 struct command_tx_struct newpacket;
316 newpacket.conn = conn;
318 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
319 newpacket.type = 0x02;
320 newpacket.commandlen = command_2_len;
321 newpacket.data = (char *) malloc (newpacket.commandlen);
322 memcpy(newpacket.data, command_2, newpacket.commandlen);
324 /* This write over the dynamic parts of the byte block */
325 aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, aim_snac_nextid);
327 aim_tx_enqueue(&newpacket);
329 return (aim_snac_nextid++);
333 * send_login_phase3(int socket)
335 * Request Rate Information.
337 * TODO: Move to aim_conn.
338 * TODO: Move to SNAC interface.
340 u_long aim_bos_reqrate(struct aim_conn_t *conn)
342 return aim_genericreq_n(conn, 0x0001, 0x0006);
346 * send_login_phase3b(int socket)
348 * Rate Information Response Acknowledge.
351 u_long aim_bos_ackrateresp(struct aim_conn_t *conn)
353 struct command_tx_struct newpacket;
357 newpacket.conn = conn;
359 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
360 newpacket.type = 0x02;
361 newpacket.commandlen = 18;
363 newpacket.data = (char *) malloc(newpacket.commandlen);
364 aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, aim_snac_nextid);
366 newpacket.data[10] = 0x00;
367 newpacket.data[11] = 0x01;
368 newpacket.data[12] = 0x00;
369 newpacket.data[13] = 0x02;
370 newpacket.data[14] = 0x00;
371 newpacket.data[15] = 0x03;
372 newpacket.data[16] = 0x00;
373 newpacket.data[17] = 0x04;
375 aim_tx_enqueue(&newpacket);
377 return (aim_snac_nextid++);
381 * aim_bos_setprivacyflags()
383 * Sets privacy flags. Normally 0x03.
385 * Bit 1: Allows other AIM users to see how long you've been idle.
389 u_long aim_bos_setprivacyflags(struct aim_conn_t *conn, u_long flags)
391 return aim_genericreq_l(conn, 0x0001, 0x0014, &flags);
395 * aim_bos_reqpersonalinfo()
397 * Requests the current user's information. Can't go generic on this one
398 * because aparently it uses SNAC flags.
401 u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn)
403 struct command_tx_struct newpacket;
407 newpacket.conn = conn;
409 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
410 newpacket.type = 0x02;
411 newpacket.commandlen = 12;
413 newpacket.data = (char *) malloc(newpacket.commandlen);
414 aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, aim_snac_nextid);
416 newpacket.data[10] = 0x0d;
417 newpacket.data[11] = 0xda;
419 aim_tx_enqueue(&newpacket);
421 return (aim_snac_nextid++);
425 * aim_bos_reqservice(serviceid)
430 u_long aim_bos_reqservice(struct aim_conn_t *conn, u_short serviceid)
432 return aim_genericreq_s(conn, 0x0001, 0x0004, &serviceid);
436 * aim_bos_reqrights()
438 * Request BOS rights.
441 u_long aim_bos_reqrights(struct aim_conn_t *conn)
443 return aim_genericreq_n(conn, 0x0009, 0x0002);
447 * aim_bos_reqbuddyrights()
449 * Request Buddy List rights.
452 u_long aim_bos_reqbuddyrights(struct aim_conn_t *conn)
454 return aim_genericreq_n(conn, 0x0003, 0x0002);
458 * Generic routine for sending commands.
461 * I know I can do this in a smarter way...but I'm not thinking straight
464 * I had one big function that handled all three cases, but then it broke
465 * and I split it up into three. But then I fixed it. I just never went
466 * back to the single. I don't see any advantage to doing it either way.
469 u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype)
471 struct command_tx_struct newpacket;
476 newpacket.conn = conn;
478 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
479 newpacket.type = 0x02;
481 newpacket.commandlen = 10;
483 newpacket.data = (char *) malloc(newpacket.commandlen);
484 memset(newpacket.data, 0x00, newpacket.commandlen);
486 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
488 aim_tx_enqueue(&newpacket);
489 return (aim_snac_nextid++);
496 u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype, u_long *longdata)
498 struct command_tx_struct newpacket;
501 /* If we don't have data, there's no reason to use this function */
503 return aim_genericreq_n(conn, family, subtype);
508 newpacket.conn = conn;
510 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
511 newpacket.type = 0x02;
513 newpacket.commandlen = 10+sizeof(u_long);
515 newpacket.data = (char *) malloc(newpacket.commandlen);
516 memset(newpacket.data, 0x00, newpacket.commandlen);
518 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
521 newlong = htonl(*longdata);
522 memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
524 aim_tx_enqueue(&newpacket);
525 return (aim_snac_nextid++);
528 u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype, u_short *shortdata)
530 struct command_tx_struct newpacket;
533 /* If we don't have data, there's no reason to use this function */
535 return aim_genericreq_n(conn, family, subtype);
540 newpacket.conn = conn;
542 newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
543 newpacket.type = 0x02;
545 newpacket.commandlen = 10+sizeof(u_short);
547 newpacket.data = (char *) malloc(newpacket.commandlen);
548 memset(newpacket.data, 0x00, newpacket.commandlen);
550 aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid);
553 newshort = htons(*shortdata);
554 memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
556 aim_tx_enqueue(&newpacket);
557 return (aim_snac_nextid++);
561 * aim_bos_reqlocaterights()
563 * Request Location services rights.
566 u_long aim_bos_reqlocaterights(struct aim_conn_t *conn)
568 return aim_genericreq_n(conn, 0x0002, 0x0002);
572 * aim_bos_reqicbmparaminfo()
574 * Request ICBM parameter information.
577 u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *conn)
579 return aim_genericreq_n(conn, 0x0004, 0x0004);