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_session_t *sess,
25 struct aim_conn_t *conn,
28 return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
33 * aim_bos_changevisibility(conn, changtype, namelist)
35 * Changes your visibility depending on changetype:
37 * AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
38 * AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
39 * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
40 * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
42 * list should be a list of
43 * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
45 * Equivelents to options in WinAIM:
46 * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
47 * with only your name on it.
48 * - Allow only users on my Buddy List: Send an
49 * AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
51 * - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
52 * with everyone listed that you want to see you.
53 * - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
54 * yourself in the list
55 * - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
56 * the list of users to be blocked
60 u_long aim_bos_changevisibility(struct aim_session_t *sess,
61 struct aim_conn_t *conn,
62 int changetype, char *denylist)
64 struct command_tx_struct newpacket;
67 char *localcpy = NULL;
78 newpacket.conn = conn;
80 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
82 newpacket.type = 0x02;
84 localcpy = (char *) malloc(strlen(denylist)+1);
85 memcpy(localcpy, denylist, strlen(denylist)+1);
87 listcount = aimutil_itemcnt(localcpy, '&');
88 newpacket.commandlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
91 newpacket.data = (char *) malloc(newpacket.commandlen);
92 memset(newpacket.data, 0x00, newpacket.commandlen);
96 case AIM_VISIBILITYCHANGE_PERMITADD: subtype = 0x05; break;
97 case AIM_VISIBILITYCHANGE_PERMITREMOVE: subtype = 0x06; break;
98 case AIM_VISIBILITYCHANGE_DENYADD: subtype = 0x07; break;
99 case AIM_VISIBILITYCHANGE_DENYREMOVE: subtype = 0x08; break;
101 free(newpacket.data);
105 /* We actually DO NOT send a SNAC ID with this one! */
106 aim_putsnac(newpacket.data, 0x0009, subtype, 0x00, 0);
108 j = 10; /* the next byte */
110 for (i=0; (i < (listcount - 1)) && (i < 99); i++)
112 tmpptr = aimutil_itemidx(localcpy, i, '&');
114 newpacket.data[j] = strlen(tmpptr);
115 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
116 j += strlen(tmpptr)+1;
123 aim_tx_enqueue(sess, &newpacket);
125 return (sess->snac_nextid); /* dont increment */
132 * aim_bos_setbuddylist(buddylist)
134 * This just builds the "set buddy list" command then queues it.
136 * buddy_list = "Screen Name One&ScreenNameTwo&";
138 * TODO: Clean this up.
141 u_long aim_bos_setbuddylist(struct aim_session_t *sess,
142 struct aim_conn_t *conn,
147 struct command_tx_struct newpacket;
149 int packet_login_phase3c_hi_b_len = 0;
151 char *localcpy = NULL;
154 packet_login_phase3c_hi_b_len = 16; /* 16b for FLAP and SNAC headers */
156 /* bail out if we can't make the packet */
157 if (buddy_list == NULL)
159 printf("\nNO BUDDIES! ARE YOU THAT LONELY???\n");
163 printf("****buddy list: %s\n", buddy_list);
164 printf("****buddy list len: %d (%x)\n", strlen(buddy_list), strlen(buddy_list));
167 localcpy = (char *) malloc(strlen(buddy_list)+1);
168 memcpy(localcpy, buddy_list, strlen(buddy_list)+1);
171 tmpptr = strtok(localcpy, "&");
172 while ((tmpptr != NULL) && (i < 100))
175 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
177 packet_login_phase3c_hi_b_len += strlen(tmpptr)+1;
179 tmpptr = strtok(NULL, "&");
182 printf("*** send buddy list len: %d (%x)\n", packet_login_phase3c_hi_b_len, packet_login_phase3c_hi_b_len);
186 newpacket.type = 0x02;
188 newpacket.conn = conn;
190 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
191 newpacket.commandlen = packet_login_phase3c_hi_b_len - 6;
194 newpacket.data = (char *) malloc(newpacket.commandlen);
196 aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid);
198 j = 10; /* the next byte */
201 tmpptr = strtok(buddy_list, "&");
202 while ((tmpptr != NULL) & (i < 100))
205 printf("---adding %s (%d)\n", tmpptr, strlen(tmpptr));
207 newpacket.data[j] = strlen(tmpptr);
208 memcpy(&(newpacket.data[j+1]), tmpptr, strlen(tmpptr));
209 j += strlen(tmpptr)+1;
211 tmpptr = strtok(NULL, "&");
216 aim_tx_enqueue(sess, &newpacket);
218 return (sess->snac_nextid++);
222 * aim_bos_setprofile(profile)
224 * Gives BOS your profile.
227 u_long aim_bos_setprofile(struct aim_session_t *sess,
228 struct aim_conn_t *conn,
231 int packet_profile_len = 0;
232 struct command_tx_struct newpacket;
236 packet_profile_len = 10;
237 /* len: T+L (where t(0001)) */
238 packet_profile_len += 2 + 2;
239 /* len: V (where t(0001)) */
240 packet_profile_len += strlen("text/x-aolrtf");
241 /* len: T+L (where t(0002)) */
242 packet_profile_len += 2 + 2;
243 /* len: V (where t(0002)) */
244 packet_profile_len += strlen(profile);
246 newpacket.type = 0x02;
248 newpacket.conn = conn;
250 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
252 newpacket.commandlen = packet_profile_len;
253 newpacket.data = (char *) malloc(packet_profile_len);
257 i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
260 newpacket.data[i++] = 0x00;
261 newpacket.data[i++] = 0x01;
263 newpacket.data[i++] = 0x00;
264 newpacket.data[i++] = 0x0d;
265 /* TLV v(text/x-aolrtf) */
266 memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
270 newpacket.data[i++] = 0x00;
271 newpacket.data[i++] = 0x02;
273 newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
274 newpacket.data[i++] = (strlen(profile) & 0xFF);
276 memcpy(&(newpacket.data[i]), profile, strlen(profile));
278 aim_tx_enqueue(sess, &newpacket);
280 return (sess->snac_nextid++);
284 * aim_bos_setgroupperm(mask)
286 * Set group permisson mask. Normally 0x1f.
289 u_long aim_bos_setgroupperm(struct aim_session_t *sess,
290 struct aim_conn_t *conn,
293 return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
297 * aim_bos_clientready()
304 u_long aim_bos_clientready(struct aim_session_t *sess,
305 struct aim_conn_t *conn)
307 u_char command_2[] = {
308 /* placeholders for dynamic data */
309 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
312 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
313 0x00, 0x13, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01,
314 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
315 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01,
316 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
317 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
318 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01,
319 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01,
320 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x01,
323 int command_2_len = 0x52;
324 struct command_tx_struct newpacket;
328 newpacket.conn = conn;
330 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
331 newpacket.type = 0x02;
332 newpacket.commandlen = command_2_len;
333 newpacket.data = (char *) malloc (newpacket.commandlen);
334 memcpy(newpacket.data, command_2, newpacket.commandlen);
336 /* This write over the dynamic parts of the byte block */
337 aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
339 aim_tx_enqueue(sess, &newpacket);
341 return (sess->snac_nextid++);
345 * send_login_phase3(int socket)
347 * Request Rate Information.
349 * TODO: Move to aim_conn.
350 * TODO: Move to SNAC interface.
352 u_long aim_bos_reqrate(struct aim_session_t *sess,
353 struct aim_conn_t *conn)
355 return aim_genericreq_n(sess, conn, 0x0001, 0x0006);
359 * send_login_phase3b(int socket)
361 * Rate Information Response Acknowledge.
364 u_long aim_bos_ackrateresp(struct aim_session_t *sess,
365 struct aim_conn_t *conn)
367 struct command_tx_struct newpacket;
371 newpacket.conn = conn;
373 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
374 newpacket.type = 0x02;
375 newpacket.commandlen = 18;
377 newpacket.data = (char *) malloc(newpacket.commandlen);
378 aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid);
380 newpacket.data[10] = 0x00;
381 newpacket.data[11] = 0x01;
382 newpacket.data[12] = 0x00;
383 newpacket.data[13] = 0x02;
384 newpacket.data[14] = 0x00;
385 newpacket.data[15] = 0x03;
386 newpacket.data[16] = 0x00;
387 newpacket.data[17] = 0x04;
389 aim_tx_enqueue(sess, &newpacket);
391 return (sess->snac_nextid++);
395 * aim_bos_setprivacyflags()
397 * Sets privacy flags. Normally 0x03.
399 * Bit 1: Allows other AIM users to see how long you've been idle.
403 u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
404 struct aim_conn_t *conn,
407 return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
411 * aim_bos_reqpersonalinfo()
413 * Requests the current user's information. Can't go generic on this one
414 * because aparently it uses SNAC flags.
417 u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess,
418 struct aim_conn_t *conn)
420 struct command_tx_struct newpacket;
424 newpacket.conn = conn;
426 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
427 newpacket.type = 0x02;
428 newpacket.commandlen = 12;
430 newpacket.data = (char *) malloc(newpacket.commandlen);
431 aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid);
433 newpacket.data[10] = 0x0d;
434 newpacket.data[11] = 0xda;
436 aim_tx_enqueue(sess, &newpacket);
438 return (sess->snac_nextid++);
442 * aim_bos_reqservice(serviceid)
447 u_long aim_bos_reqservice(struct aim_session_t *sess,
448 struct aim_conn_t *conn,
451 return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
455 * aim_bos_reqrights()
457 * Request BOS rights.
460 u_long aim_bos_reqrights(struct aim_session_t *sess,
461 struct aim_conn_t *conn)
463 return aim_genericreq_n(sess, conn, 0x0009, 0x0002);
467 * aim_bos_reqbuddyrights()
469 * Request Buddy List rights.
472 u_long aim_bos_reqbuddyrights(struct aim_session_t *sess,
473 struct aim_conn_t *conn)
475 return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
479 * Generic routine for sending commands.
482 * I know I can do this in a smarter way...but I'm not thinking straight
485 * I had one big function that handled all three cases, but then it broke
486 * and I split it up into three. But then I fixed it. I just never went
487 * back to the single. I don't see any advantage to doing it either way.
490 u_long aim_genericreq_n(struct aim_session_t *sess,
491 struct aim_conn_t *conn,
492 u_short family, u_short subtype)
494 struct command_tx_struct newpacket;
499 newpacket.conn = conn;
501 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
502 newpacket.type = 0x02;
504 newpacket.commandlen = 10;
506 newpacket.data = (char *) malloc(newpacket.commandlen);
507 memset(newpacket.data, 0x00, newpacket.commandlen);
509 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
511 aim_tx_enqueue(sess, &newpacket);
512 return (sess->snac_nextid++);
519 u_long aim_genericreq_l(struct aim_session_t *sess,
520 struct aim_conn_t *conn,
521 u_short family, u_short subtype, u_long *longdata)
523 struct command_tx_struct newpacket;
526 /* If we don't have data, there's no reason to use this function */
528 return aim_genericreq_n(sess, conn, family, subtype);
533 newpacket.conn = conn;
535 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
537 newpacket.type = 0x02;
539 newpacket.commandlen = 10+sizeof(u_long);
541 newpacket.data = (char *) malloc(newpacket.commandlen);
542 memset(newpacket.data, 0x00, newpacket.commandlen);
544 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
547 newlong = htonl(*longdata);
548 memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long));
550 aim_tx_enqueue(sess, &newpacket);
551 return (sess->snac_nextid++);
554 u_long aim_genericreq_s(struct aim_session_t *sess,
555 struct aim_conn_t *conn,
556 u_short family, u_short subtype, u_short *shortdata)
558 struct command_tx_struct newpacket;
561 /* If we don't have data, there's no reason to use this function */
563 return aim_genericreq_n(sess, conn, family, subtype);
568 newpacket.conn = conn;
570 newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
572 newpacket.type = 0x02;
574 newpacket.commandlen = 10+sizeof(u_short);
576 newpacket.data = (char *) malloc(newpacket.commandlen);
577 memset(newpacket.data, 0x00, newpacket.commandlen);
579 aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid);
582 newshort = htons(*shortdata);
583 memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short));
585 aim_tx_enqueue(sess, &newpacket);
586 return (sess->snac_nextid++);
590 * aim_bos_reqlocaterights()
592 * Request Location services rights.
595 u_long aim_bos_reqlocaterights(struct aim_session_t *sess,
596 struct aim_conn_t *conn)
598 return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
602 * aim_bos_reqicbmparaminfo()
604 * Request ICBM parameter information.
607 u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess,
608 struct aim_conn_t *conn)
610 return aim_genericreq_n(sess, conn, 0x0004, 0x0004);