Beispiel #1
0
/*
 *
 * I definitly recommend sending this.  If you don't, you'll be stuck
 * with the rather unreasonable defaults.  You don't want those.  Send this.
 * 
 */
int aim_seticbmparam(aim_session_t *sess, struct aim_icbmparameters *params)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
		return -EINVAL;

	if (!params)
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+16)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0004, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0004, 0x0002, 0x0000, snacid);

	/* This is read-only (see Parameter Reply). Must be set to zero here. */
	aimbs_put16(&fr->data, 0x0000);

	/* These are all read-write */
	aimbs_put32(&fr->data, params->flags); 
	aimbs_put16(&fr->data, params->maxmsglen);
	aimbs_put16(&fr->data, params->maxsenderwarn); 
	aimbs_put16(&fr->data, params->maxrecverwarn); 
	aimbs_put32(&fr->data, params->minmsginterval);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #2
0
faim_export int aim_getinfo(aim_session_t *sess, aim_conn_t *conn, const char *sn, fu16_t infotype)
{
	struct aim_priv_inforeq privdata;
	aim_frame_t *fr;
	aim_snacid_t snacid;

	if (!sess || !conn || !sn)
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 12+1+strlen(sn))))
		return -ENOMEM;

	strncpy(privdata.sn, sn, sizeof(privdata.sn));
	privdata.infotype = infotype;
	snacid = aim_cachesnac(sess, 0x0002, 0x0005, 0x0000, &privdata, sizeof(struct aim_priv_inforeq));
	
	aim_putsnac(&fr->data, 0x0002, 0x0005, 0x0000, snacid);
	aimbs_put16(&fr->data, infotype);
	aimbs_put8(&fr->data, strlen(sn));
	aimbs_putraw(&fr->data, sn, strlen(sn));

	aim_tx_enqueue(sess, fr);

	return 0;
}
/*
 * Subtype 0x0004 - Set your client's capabilities.
 */
int
aim_locate_setcaps(OscarData *od, guint64 caps)
{
	FlapConnection *conn;
	PurpleAccount *account = purple_connection_get_account(od->gc);
	PurplePresence *presence = purple_account_get_presence(account);
	PurpleStatus *status = purple_presence_get_status(presence, "mood");
	const char *mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
	ByteStream bs;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	if (!(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
		return -EINVAL;

	aim_tlvlist_add_caps(&tlvlist, 0x0005, caps, mood);

	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));

	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, NULL, 0);

	aim_tlvlist_write(&bs, &tlvlist);
	aim_tlvlist_free(tlvlist);

	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, snacid, &bs);

	byte_stream_destroy(&bs);

	return 0;
}
Beispiel #4
0
/*
 * Subtype 0x0006
 *
 * In AIM 3.5 protocol, the first stage of login is to request login from the
 * Authorizer, passing it the username for verification.  If the name is
 * invalid, a 0017/0003 is spit back, with the standard error contents.  If
 * valid, a 0017/0007 comes back, which is the signal to send it the main
 * login command (0017/0002).
 *
 */
int
aim_request_login(OscarData *od, FlapConnection *conn, const char *sn)
{
	FlapFrame *frame;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	if (!od || !conn || !sn)
		return -EINVAL;

#ifdef USE_XOR_FOR_ICQ
	if (aim_snvalid_icq(sn))
		return goddamnicq(od, conn, sn);
#endif

	frame = flap_frame_new(od, 0x02, 10+2+2+strlen(sn)+8);

	snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, 0x0006, 0x0000, NULL, 0);
	aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, 0x0006, 0x0000, snacid);

	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);

	/* Tell the server we support SecurID logins. */
	aim_tlvlist_add_noval(&tlvlist, 0x004b);

	/* Unknown.  Sent in recent WinAIM clients.*/
	aim_tlvlist_add_noval(&tlvlist, 0x005a);

	aim_tlvlist_write(&frame->data, &tlvlist);
	aim_tlvlist_free(tlvlist);

	flap_connection_send(conn, frame);

	return 0;
}
Beispiel #5
0
/*
 * In AIM 3.5 protocol, the first stage of login is to request login from the
 * Authorizer, passing it the screen name for verification.  If the name is
 * invalid, a 0017/0003 is spit back, with the standard error contents.  If
 * valid, a 0017/0007 comes back, which is the signal to send it the main
 * login command (0017/0002).
 *
 */
int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn)
{
	aim_frame_t *fr;
	aim_snacid_t snacid;
	aim_tlvlist_t *tl = NULL;
	struct im_connection *ic = sess->aux_data;

	if (!sess || !conn || !sn) {
		return -EINVAL;
	}

	if (g_ascii_isdigit(sn[0]) && set_getbool(&ic->acc->set, "old_icq_auth")) {
		return goddamnicq(sess, conn, sn);
	}

	sess->flags |= AIM_SESS_FLAGS_SNACLOGIN;

	aim_sendflapver(sess, conn);

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 2 + 2 + strlen(sn)))) {
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid);

	aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *) sn);
	aim_writetlvchain(&fr->data, &tl);
	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #6
0
faim_export int aim_icq_reqofflinemsgs(aim_session_t *sess)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 4 + 2 + 2;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x003c); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #7
0
int aim_admin_changepasswd(aim_session_t *sess, aim_conn_t *conn, const char *newpw, const char *curpw)
{
	aim_frame_t *tx;
	aim_tlvlist_t *tl = NULL;
	aim_snacid_t snacid;

	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + strlen(curpw) + 4 + strlen(newpw)))) {
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
	aim_putsnac(&tx->data, 0x0007, 0x0004, 0x0000, snacid);

	/* new password TLV t(0002) */
	aim_addtlvtochain_raw(&tl, 0x0002, strlen(newpw), (guint8 *) newpw);

	/* current password TLV t(0012) */
	aim_addtlvtochain_raw(&tl, 0x0012, strlen(curpw), (guint8 *) curpw);

	aim_writetlvchain(&tx->data, &tl);
	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, tx);

	return 0;
}
Beispiel #8
0
/*
 * In AIM 3.5 protocol, the first stage of login is to request login from the 
 * Authorizer, passing it the screen name for verification.  If the name is 
 * invalid, a 0017/0003 is spit back, with the standard error contents.  If 
 * valid, a 0017/0007 comes back, which is the signal to send it the main 
 * login command (0017/0002). 
 *
 */
int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn)
{
	aim_frame_t *fr;
	aim_snacid_t snacid;
	aim_tlvlist_t *tl = NULL;
	
	if (!sess || !conn || !sn)
		return -EINVAL;

	if ((sn[0] >= '0') && (sn[0] <= '9'))
		return goddamnicq(sess, conn, sn);

	sess->flags |= AIM_SESS_FLAGS_SNACLOGIN;

	aim_sendflapver(sess, conn);

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn))))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid);

	aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *)sn);
	aim_writetlvchain(&fr->data, &tl);
	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #9
0
/**
 * Subtype 0x000b
 *
 * Send SecurID response.
 */
int
aim_auth_securid_send(OscarData *od, const char *securid)
{
	FlapConnection *conn;
	FlapFrame *frame;
	aim_snacid_t snacid;
	int len;

	if (!od || !(conn = flap_connection_getbytype_all(od, SNAC_FAMILY_AUTH)) || !securid)
		return -EINVAL;

	len = strlen(securid);

	frame = flap_frame_new(od, 0x02, 10+2+len);

	snacid = aim_cachesnac(od, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_RESPONSE, 0x0000, NULL, 0);
	aim_putsnac(&frame->data, SNAC_FAMILY_AUTH, SNAC_SUBTYPE_AUTH_SECURID_RESPONSE, 0x0000, 0);

	byte_stream_put16(&frame->data, len);
	byte_stream_putstr(&frame->data, securid);

	flap_connection_send(conn, frame);

	return 0;
}
Beispiel #10
0
/*
 * Join a room of name roomname.  This is the first step to joining an 
 * already created room.  It's basically a Service Request for 
 * family 0x000e, with a little added on to specify the exchange and room 
 * name.
 */
faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance)
{
	aim_frame_t *fr;
	aim_snacid_t snacid;
	aim_tlvlist_t *tl = NULL;
	struct chatsnacinfo csi;
	
	if (!sess || !conn || !roomname || !strlen(roomname))
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
		return -ENOMEM;

	memset(&csi, 0, sizeof(csi));
	csi.exchange = exchange;
	strncpy(csi.name, roomname, sizeof(csi.name));
	csi.instance = instance;

	snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));
	aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid);

	/*
	 * Requesting service chat (0x000e)
	 */
	aimbs_put16(&fr->data, 0x000e);

	aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance);
	aim_writetlvchain(&fr->data, &tl);
	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, fr);

	return 0; 
}
Beispiel #11
0
/* XXX pass these in better */
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, guint16 privacy)
{
    aim_frame_t *fr;
    aim_tlvlist_t *tl = NULL;

    /* ?? privacy ?? */
    aim_addtlvtochain16(&tl, 0x000a, privacy);

    if (interest1)
        aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest1), (guint8 *)interest1);
    if (interest2)
        aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest2), (guint8 *)interest2);
    if (interest3)
        aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest3), (guint8 *)interest3);
    if (interest4)
        aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest4), (guint8 *)interest4);
    if (interest5)
        aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest5), (guint8 *)interest5);

    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
        return -ENOMEM;

    aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);

    aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);
    aim_writetlvchain(&fr->data, &tl);
    aim_freetlvchain(&tl);

    aim_tx_enqueue(sess, fr);

    return 0;
}
Beispiel #12
0
/*
 * Subtype 0x0004 - Set your client's capabilities.
 */
int
aim_locate_setcaps(OscarData *od, guint32 caps)
{
	FlapConnection *conn;
	FlapFrame *frame;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
		return -EINVAL;

	aim_tlvlist_add_caps(&tlvlist, 0x0005, caps);

	frame = flap_frame_new(od, 0x02, 10 + aim_tlvlist_size(tlvlist));

	snacid = aim_cachesnac(od, 0x0002, 0x0004, 0x0000, NULL, 0);
	aim_putsnac(&frame->data, 0x0002, 0x004, 0x0000, snacid);

	aim_tlvlist_write(&frame->data, &tlvlist);
	aim_tlvlist_free(tlvlist);

	flap_connection_send(conn, frame);

	return 0;
}
Beispiel #13
0
/**
 * Subtype 0x0004 - Request someone's icon.
 *
 * @param sess The oscar session.
 * @param conn The icon connection for this session.
 * @param sn The screen name of the person who's icon you are requesting.
 * @param iconcsum The MD5 checksum of the icon you are requesting.
 * @param iconcsumlen Length of the MD5 checksum given above.  Should be 10 bytes.
 * @return Return 0 if no errors, otherwise return the error number.
 */
faim_export int aim_bart_request(aim_session_t *sess, const char *sn, fu8_t iconcsumtype, const fu8_t *iconcsum, fu16_t iconcsumlen)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0010)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen)
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 4 + 1+iconcsumlen)))
		return -ENOMEM;
	snacid = aim_cachesnac(sess, 0x0010, 0x0004, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0010, 0x0004, 0x0000, snacid);

	/* Screen name */
	aimbs_put8(&fr->data, strlen(sn));
	aimbs_putraw(&fr->data, sn, strlen(sn));

	/* Some numbers.  You like numbers, right? */
	aimbs_put8(&fr->data, 0x01);
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put8(&fr->data, iconcsumtype);

	/* Icon string */
	aimbs_put8(&fr->data, iconcsumlen);
	aimbs_putraw(&fr->data, iconcsum, iconcsumlen);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #14
0
/**
 * Subtype 0x0002 - Upload your icon.
 *
 * @param sess The oscar session.
 * @param conn The icon connection for this session.
 * @param icon The raw data of the icon image file.
 * @param iconlen Length of the raw data of the icon image file.
 * @return Return 0 if no errors, otherwise return the error number.
 */
faim_export int aim_bart_upload(aim_session_t *sess, const fu8_t *icon, fu16_t iconlen)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0010)) || !icon || !iconlen)
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 2 + 2+iconlen)))
		return -ENOMEM;
	snacid = aim_cachesnac(sess, 0x0010, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0010, 0x0002, 0x0000, snacid);

	/* The reference number for the icon */
	aimbs_put16(&fr->data, 1);

	/* The icon */
	aimbs_put16(&fr->data, iconlen);
	aimbs_putraw(&fr->data, icon, iconlen);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #15
0
/**
 * answers status message requests
 * @param sess the oscar session
 * @param sender the guy whos asking
 * @param cookie message id which we are answering for
 * @param message away message
 * @param state our current away state the way icq requests it (0xE8 for away, 0xE9 occupied, ...)
 * @return 0 if no error
 */
int aim_send_im_ch2_statusmessage(aim_session_t *sess, const char *sender, const guint8 *cookie,
        const char *message, const guint8 state, const guint16 dc)
{
    aim_conn_t *conn;
    aim_frame_t *fr;
    aim_snacid_t snacid;

    if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
                return -EINVAL;
        
    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 
					10+8+2+1+strlen(sender)+2+0x1d+0x10+9+strlen(message)+1)))
                return -ENOMEM;

    snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0);
    aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid);
    
    aimbs_putraw(&fr->data, cookie, 8);
    
    aimbs_put16(&fr->data, 0x0002); /* channel */
    aimbs_put8(&fr->data, strlen(sender));
    aimbs_putraw(&fr->data, (guint8 *)sender, strlen(sender));

    aimbs_put16(&fr->data, 0x0003); /* reason: channel specific */

    aimbs_putle16(&fr->data, 0x001b); /* length of data SEQ1 */
    aimbs_putle16(&fr->data, 0x0008); /* protocol version */

    aimbs_putle32(&fr->data, 0x0000); /* no plugin -> 16 times 0x00 */ 
    aimbs_putle32(&fr->data, 0x0000); 
    aimbs_putle32(&fr->data, 0x0000); 
    aimbs_putle32(&fr->data, 0x0000);

    aimbs_putle16(&fr->data, 0x0000); /* unknown */
    aimbs_putle32(&fr->data, 0x0003); /* client features */
    aimbs_putle8(&fr->data, 0x00); /* unknown */
    aimbs_putle16(&fr->data, dc); /* Sequence number?  XXX - This should decrement by 1 with each request */
    /* end of SEQ1 */

    aimbs_putle16(&fr->data, 0x000e); /* Length of SEQ2 */
    aimbs_putle16(&fr->data, dc); /* Sequence number? same as above
                                       * XXX - This should decrement by 1 with each request */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    /* end of SEQ2 */

    /* now for the real fun */
    aimbs_putle8(&fr->data, state); /* away state */
    aimbs_putle8(&fr->data, 0x03); /* msg-flag: 03 for states */
    aimbs_putle16(&fr->data, 0x0000); /* status code ? */
    aimbs_putle16(&fr->data, 0x0000); /* priority code */
    aimbs_putle16(&fr->data, strlen(message) + 1); /* message length + termination */
    aimbs_putraw(&fr->data, (guint8 *) message, strlen(message) + 1); /* null terminated string */
    
    aim_tx_enqueue(sess, fr);


    return 0;
}
Beispiel #16
0
/*
 * Subtype 0x0004 - Set your client's capabilities.
 */
int
aim_locate_setcaps(OscarData *od, guint32 caps)
{
	FlapConnection *conn;
	ByteStream bs;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
		return -EINVAL;

	aim_tlvlist_add_caps(&tlvlist, 0x0005, caps);

	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));

	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, NULL, 0);

	aim_tlvlist_write(&bs, &tlvlist);
	aim_tlvlist_free(tlvlist);

	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0004, 0x0000, snacid, &bs);

	byte_stream_destroy(&bs);

	return 0;
}
Beispiel #17
0
/*
 * send_login(int socket, char *sn, char *password)
 *  
 * This is the initial login request packet.
 *
 * NOTE!! If you want/need to make use of the aim_sendmemblock() function,
 * then the client information you send here must exactly match the
 * executable that you're pulling the data from.
 *
 * WinAIM 4.8.2540
 *   clientstring = "AOL Instant Messenger (SM), version 4.8.2540/WIN32"
 *   clientid = 0x0109
 *   major = 0x0004
 *   minor = 0x0008
 *   point = 0x0000
 *   build = 0x09ec
 *   t(0x0014) = 0x000000af
 *   t(0x004a) = 0x01
 *
 * WinAIM 4.3.2188:
 *   clientstring = "AOL Instant Messenger (SM), version 4.3.2188/WIN32"
 *   clientid = 0x0109
 *   major = 0x0400
 *   minor = 0x0003
 *   point = 0x0000
 *   build = 0x088c
 *   unknown = 0x00000086
 *   lang = "en"
 *   country = "us"
 *   unknown4a = 0x01
 *
 * Latest WinAIM that libfaim can emulate without server-side buddylists:
 *   clientstring = "AOL Instant Messenger (SM), version 4.1.2010/WIN32"
 *   clientid = 0x0004
 *   major  = 0x0004
 *   minor  = 0x0001
 *   point = 0x0000
 *   build  = 0x07da
 *   unknown= 0x0000004b
 *
 * WinAIM 3.5.1670:
 *   clientstring = "AOL Instant Messenger (SM), version 3.5.1670/WIN32"
 *   clientid = 0x0004
 *   major =  0x0003
 *   minor =  0x0005
 *   point = 0x0000
 *   build =  0x0686
 *   unknown =0x0000002a
 *
 * Java AIM 1.1.19:
 *   clientstring = "AOL Instant Messenger (TM) version 1.1.19 for Java built 03/24/98, freeMem 215871 totalMem 1048567, i686, Linus, #2 SMP Sun Feb 11 03:41:17 UTC 2001 2.4.1-ac9, IBM Corporation, 1.1.8, 45.3, Tue Mar 27 12:09:17 PST 2001"
 *   clientid = 0x0001
 *   major  = 0x0001
 *   minor  = 0x0001
 *   point = (not sent)
 *   build  = 0x0013
 *   unknown= (not sent)
 *   
 * AIM for Linux 1.1.112:
 *   clientstring = "AOL Instant Messenger (SM)"
 *   clientid = 0x1d09
 *   major  = 0x0001
 *   minor  = 0x0001
 *   point = 0x0001
 *   build  = 0x0070
 *   unknown= 0x0000008b
 *   serverstore = 0x01
 *
 */
int aim_send_login(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *password, struct client_info_s *ci, const char *key)
{
	aim_frame_t *fr;
	aim_tlvlist_t *tl = NULL;
	guint8 digest[16];
	aim_snacid_t snacid;

	if (!ci || !sn || !password)
		return -EINVAL;

	/*
	 * What the XORLOGIN flag _really_ means is that its an ICQ login,
	 * which is really stupid and painful, so its not done here.
	 *
	 */
	if (sess->flags & AIM_SESS_FLAGS_XORLOGIN)
		return goddamnicq2(sess, conn, sn, password);


	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0017, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0017, 0x0002, 0x0000, snacid);

	aim_addtlvtochain_raw(&tl, 0x0001, strlen(sn), (guint8 *)sn);

	aim_encode_password_md5(password, key, digest);
	aim_addtlvtochain_raw(&tl, 0x0025, 16, digest);

	/*
	 * Newer versions of winaim have an empty type x004c TLV here.
	 */

	if (ci->clientstring)
		aim_addtlvtochain_raw(&tl, 0x0003, strlen(ci->clientstring), (guint8 *)ci->clientstring);
	aim_addtlvtochain16(&tl, 0x0016, (guint16)ci->clientid);
	aim_addtlvtochain16(&tl, 0x0017, (guint16)ci->major);
	aim_addtlvtochain16(&tl, 0x0018, (guint16)ci->minor);
	aim_addtlvtochain16(&tl, 0x0019, (guint16)ci->point);
	aim_addtlvtochain16(&tl, 0x001a, (guint16)ci->build);
	aim_addtlvtochain_raw(&tl, 0x000e, strlen(ci->country), (guint8 *)ci->country);
	aim_addtlvtochain_raw(&tl, 0x000f, strlen(ci->lang), (guint8 *)ci->lang);

	/*
	 * If set, old-fashioned buddy lists will not work. You will need
	 * to use SSI.
	 */
	aim_addtlvtochain8(&tl, 0x004a, 0x01);

	aim_writetlvchain(&fr->data, &tl);

	aim_freetlvchain(&tl);
	
	aim_tx_enqueue(sess, fr);

	return 0;
}
/*
 * Subtype 0x0008
 */
int aim_chatnav_createroom(OscarData *od, FlapConnection *conn, const char *name, guint16 exchange)
{
	static const char ck[] = {"create"};
	static const char lang[] = {"en"};
	static const char charset[] = {"us-ascii"};
	ByteStream bs;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	byte_stream_new(&bs, 1142);

	snacid = aim_cachesnac(od, SNAC_FAMILY_CHATNAV, 0x0008, 0x0000, NULL, 0);

	/* exchange */
	byte_stream_put16(&bs, exchange);

	/*
	 * This looks to be a big hack.  You'll note that this entire
	 * SNAC is just a room info structure, but the hard room name,
	 * here, is set to "create".
	 *
	 * Either this goes on the "list of questions concerning
	 * why-the-hell-did-you-do-that", or this value is completely
	 * ignored.  Without experimental evidence, but a good knowledge of
	 * AOL style, I'm going to guess that it is the latter, and that
	 * the value of the room name in create requests is ignored.
	 */
	byte_stream_put8(&bs, strlen(ck));
	byte_stream_putstr(&bs, ck);

	/*
	 * instance
	 *
	 * Setting this to 0xffff apparently assigns the last instance.
	 *
	 */
	byte_stream_put16(&bs, 0xffff);

	/* detail level */
	byte_stream_put8(&bs, 0x01);

	aim_tlvlist_add_str(&tlvlist, 0x00d3, name);
	aim_tlvlist_add_str(&tlvlist, 0x00d6, charset);
	aim_tlvlist_add_str(&tlvlist, 0x00d7, lang);

	/* tlvcount */
	byte_stream_put16(&bs, aim_tlvlist_count(tlvlist));
	aim_tlvlist_write(&bs, &tlvlist);

	aim_tlvlist_free(tlvlist);

	flap_connection_send_snac(od, conn, SNAC_FAMILY_CHATNAV, 0x0008, snacid, &bs);

	byte_stream_destroy(&bs);

	return 0;
}
Beispiel #19
0
faim_export int aim_chatnav_createroom(aim_session_t *sess, aim_conn_t *conn, const char *name, fu16_t exchange)
{
	static const char ck[] = {"create"};
	static const char lang[] = {"en"};
	static const char charset[] = {"us-ascii"};
	aim_frame_t *fr;
	aim_snacid_t snacid;
	aim_tlvlist_t *tl = NULL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x000d, 0x0008, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x000d, 0x0008, 0x0000, snacid);

	/* exchange */
	aimbs_put16(&fr->data, exchange);

	/*
	 * This looks to be a big hack.  You'll note that this entire
	 * SNAC is just a room info structure, but the hard room name,
	 * here, is set to "create".  
	 *
	 * Either this goes on the "list of questions concerning
	 * why-the-hell-did-you-do-that", or this value is completly
	 * ignored.  Without experimental evidence, but a good knowledge of
	 * AOL style, I'm going to guess that it is the latter, and that
	 * the value of the room name in create requests is ignored.
	 */
	aimbs_put8(&fr->data, strlen(ck));
	aimbs_putraw(&fr->data, ck, strlen(ck));

	/* 
	 * instance
	 * 
	 * Setting this to 0xffff apparently assigns the last instance.
	 *
	 */
	aimbs_put16(&fr->data, 0xffff);

	/* detail level */
	aimbs_put8(&fr->data, 0x01);

	aim_addtlvtochain_raw(&tl, 0x00d3, strlen(name), name);
	aim_addtlvtochain_raw(&tl, 0x00d6, strlen(charset), charset);
	aim_addtlvtochain_raw(&tl, 0x00d7, strlen(lang), lang);

	/* tlvcount */
	aimbs_put16(&fr->data, aim_counttlvchain(&tl));
	aim_writetlvchain(&fr->data, &tl);

	aim_freetlvchain(&tl);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #20
0
/*
 * Stubtypes 0x0005, 0x0006, 0x0007, and 0x0008 - Modify permit/deny lists.
 *
 * Changes your visibility depending on changetype:
 *
 *  AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
 *  AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
 *  AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
 *  AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
 *
 * list should be a list of 
 * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
 *
 * Equivelents to options in WinAIM:
 *   - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
 *      with only your name on it.
 *   - Allow only users on my Buddy List: Send an 
 *      AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
 *      buddy list
 *   - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD 
 *      with everyone listed that you want to see you.
 *   - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only 
 *      yourself in the list
 *   - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
 *      the list of users to be blocked
 *
 * XXX ye gods.
 */
faim_export int aim_bos_changevisibility(aim_session_t *sess, aim_conn_t *conn, int changetype, const char *denylist)
{
	aim_frame_t *fr;
	int packlen = 0;
	fu16_t subtype;
	char *localcpy = NULL, *tmpptr = NULL;
	int i;
	int listcount;
	aim_snacid_t snacid;

	if (!denylist)
		return -EINVAL;

	if (changetype == AIM_VISIBILITYCHANGE_PERMITADD)
		subtype = 0x05;
	else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE)
		subtype = 0x06;
	else if (changetype == AIM_VISIBILITYCHANGE_DENYADD)
		subtype = 0x07;
	else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE)
		subtype = 0x08;
	else
		return -EINVAL;

	localcpy = strdup(denylist);

	listcount = aimutil_itemcnt(localcpy, '&');
	packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, packlen))) {
		free(localcpy);
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0009, subtype, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0009, subtype, 0x00, snacid);

	for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
		tmpptr = aimutil_itemindex(localcpy, i, '&');

		aimbs_put8(&fr->data, strlen(tmpptr));
		aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));

		free(tmpptr);
	}
	free(localcpy);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #21
0
int aim_genericreq_n_snacid(aim_session_t *sess, aim_conn_t *conn, guint16 family, guint16 subtype)
{
    aim_frame_t *fr;
    aim_snacid_t snacid;

    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10)))
        return -ENOMEM;

    snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
    aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);

    aim_tx_enqueue(sess, fr);

    return 0;
}
Beispiel #22
0
/*
 * Stubtypes 0x0005, 0x0006, 0x0007, and 0x0008 - Modify permit/deny lists.
 *
 * Changes your visibility depending on changetype:
 *
 *  AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
 *  AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
 *  AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
 *  AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
 *
 * list should be a list of
 * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
 *
 * Equivelents to options in WinAIM:
 *   - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
 *      with only your name on it.
 *   - Allow only users on my Buddy List: Send an
 *      AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
 *      buddy list
 *   - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
 *      with everyone listed that you want to see you.
 *   - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
 *      yourself in the list
 *   - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
 *      the list of users to be blocked
 *
 * XXX ye gods.
 */
int aim_bos_changevisibility(OscarData *od, FlapConnection *conn, int changetype, const char *denylist)
{
	FlapFrame *frame;
	int packlen = 0;
	guint16 subtype;
	char *localcpy = NULL, *tmpptr = NULL;
	int i;
	int listcount;
	aim_snacid_t snacid;

	if (!denylist)
		return -EINVAL;

	if (changetype == AIM_VISIBILITYCHANGE_PERMITADD)
		subtype = 0x05;
	else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE)
		subtype = 0x06;
	else if (changetype == AIM_VISIBILITYCHANGE_DENYADD)
		subtype = 0x07;
	else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE)
		subtype = 0x08;
	else
		return -EINVAL;

	localcpy = g_strdup(denylist);

	listcount = aimutil_itemcnt(localcpy, '&');
	packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;

	frame = flap_frame_new(od, 0x02, packlen);

	snacid = aim_cachesnac(od, 0x0009, subtype, 0x0000, NULL, 0);
	aim_putsnac(&frame->data, 0x0009, subtype, 0x00, snacid);

	for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
		tmpptr = aimutil_itemindex(localcpy, i, '&');

		byte_stream_put8(&frame->data, strlen(tmpptr));
		byte_stream_putstr(&frame->data, tmpptr);

		g_free(tmpptr);
	}
	g_free(localcpy);

	flap_connection_send(conn, frame);

	return 0;
}
Beispiel #23
0
/*
 * Subtype 0x0009 - Set directory profile data.
 *
 * This is not the same as aim_location_setprofile!
 * privacy: 1 to allow searching, 0 to disallow.
 *
 */
int aim_locate_setdirinfo(OscarData *od, 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, guint16 privacy)
{
	FlapConnection *conn;
	ByteStream bs;
	aim_snacid_t snacid;
	GSList *tlvlist = NULL;

	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)))
		return -EINVAL;

	aim_tlvlist_add_16(&tlvlist, 0x000a, privacy);

	if (first)
		aim_tlvlist_add_str(&tlvlist, 0x0001, first);
	if (last)
		aim_tlvlist_add_str(&tlvlist, 0x0002, last);
	if (middle)
		aim_tlvlist_add_str(&tlvlist, 0x0003, middle);
	if (maiden)
		aim_tlvlist_add_str(&tlvlist, 0x0004, maiden);

	if (state)
		aim_tlvlist_add_str(&tlvlist, 0x0007, state);
	if (city)
		aim_tlvlist_add_str(&tlvlist, 0x0008, city);

	if (nickname)
		aim_tlvlist_add_str(&tlvlist, 0x000c, nickname);
	if (zip)
		aim_tlvlist_add_str(&tlvlist, 0x000d, zip);

	if (street)
		aim_tlvlist_add_str(&tlvlist, 0x0021, street);

	byte_stream_new(&bs, aim_tlvlist_size(tlvlist));

	snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, NULL, 0);

	aim_tlvlist_write(&bs, &tlvlist);
	aim_tlvlist_free(tlvlist);

	flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0009, 0x0000, snacid, &bs);

	byte_stream_destroy(&bs);

	return 0;
}
Beispiel #24
0
/*
 * Subtype 0x0014 - Send a mini typing notification (mtn) packet.
 *
 * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 
 * and Gaim 0.60 and newer.
 *
 */
int aim_im_sendmtn(aim_session_t *sess, guint16 type1, const char *sn, guint16 type2)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002)))
		return -EINVAL;

	if (!sn)
		return -EINVAL;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+11+strlen(sn)+2)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0004, 0x0014, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0004, 0x0014, 0x0000, snacid);

	/*
	 * 8 days of light
	 * Er, that is to say, 8 bytes of 0's
	 */
	aimbs_put16(&fr->data, 0x0000);
	aimbs_put16(&fr->data, 0x0000);
	aimbs_put16(&fr->data, 0x0000);
	aimbs_put16(&fr->data, 0x0000);

	/*
	 * Type 1 (should be 0x0001 for mtn)
	 */
	aimbs_put16(&fr->data, type1);

	/*
	 * Dest sn
	 */
	aimbs_put8(&fr->data, strlen(sn));
	aimbs_putraw(&fr->data, (const guint8*)sn, strlen(sn));

	/*
	 * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn)
	 */
	aimbs_put16(&fr->data, type2);

	aim_tx_enqueue(sess, fr);

	return 0;
}
Beispiel #25
0
/*
 * aim_bos_setprofile(profile)
 *
 * Gives BOS your profile.
 *
 */
int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, guint32 caps)
{
    static const char defencoding[] = {"text/aolrtf; charset=\"utf-8\""};
    aim_frame_t *fr;
    aim_tlvlist_t *tl = NULL;
    aim_snacid_t snacid;

    /* Build to packet first to get real length */
    if (profile) {
        aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), (guint8 *)defencoding);
        aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), (guint8 *)profile);
    }

    /*
     * So here's how this works:
     *   - You are away when you have a non-zero-length type 4 TLV stored.
     *   - You become unaway when you clear the TLV with a zero-length
     *       type 4 TLV.
     *   - If you do not send the type 4 TLV, your status does not change
     *       (that is, if you were away, you'll remain away).
     */
    if (awaymsg) {
        if (strlen(awaymsg)) {
            aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), (guint8 *)defencoding);
            aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), (guint8 *)awaymsg);
        } else
            aim_addtlvtochain_noval(&tl, 0x0004);
    }

    aim_addtlvtochain_caps(&tl, 0x0005, caps);

    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_sizetlvchain(&tl))))
        return -ENOMEM;

    snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);

    aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
    aim_writetlvchain(&fr->data, &tl);
    aim_freetlvchain(&tl);

    aim_tx_enqueue(sess, fr);

    return 0;
}
Beispiel #26
0
/*
 * Set directory profile data (not the same as aim_bos_setprofile!)
 *
 * privacy: 1 to allow searching, 0 to disallow.
 */
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, guint16 privacy)
{
    aim_frame_t *fr;
    aim_snacid_t snacid;
    aim_tlvlist_t *tl = NULL;


    aim_addtlvtochain16(&tl, 0x000a, privacy);

    if (first)
        aim_addtlvtochain_raw(&tl, 0x0001, strlen(first), (guint8 *)first);
    if (last)
        aim_addtlvtochain_raw(&tl, 0x0002, strlen(last), (guint8 *)last);
    if (middle)
        aim_addtlvtochain_raw(&tl, 0x0003, strlen(middle), (guint8 *)middle);
    if (maiden)
        aim_addtlvtochain_raw(&tl, 0x0004, strlen(maiden), (guint8 *)maiden);

    if (state)
        aim_addtlvtochain_raw(&tl, 0x0007, strlen(state), (guint8 *)state);
    if (city)
        aim_addtlvtochain_raw(&tl, 0x0008, strlen(city), (guint8 *)city);

    if (nickname)
        aim_addtlvtochain_raw(&tl, 0x000c, strlen(nickname), (guint8 *)nickname);
    if (zip)
        aim_addtlvtochain_raw(&tl, 0x000d, strlen(zip), (guint8 *)zip);

    if (street)
        aim_addtlvtochain_raw(&tl, 0x0021, strlen(street), (guint8 *)street);

    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
        return -ENOMEM;

    snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0);

    aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid);
    aim_writetlvchain(&fr->data, &tl);
    aim_freetlvchain(&tl);

    aim_tx_enqueue(sess, fr);

    return 0;
}
Beispiel #27
0
faim_export int aim_icq_getalias(aim_session_t *sess, const char *uin)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;
	struct aim_icq_info *info;

	if (!uin || uin[0] < '0' || uin[0] > '9')
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 4 + 2 + 2 + 2 + 4;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_putle16(&fr->data, 0x04ba); /* shrug. */
	aimbs_putle32(&fr->data, atoi(uin));

	aim_tx_enqueue(sess, fr);

	/* Keep track of this request and the ICQ number and request ID */
	info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
	info->reqid = snacid;
	info->uin = atoi(uin);
	info->next = sess->icq_info;
	sess->icq_info = info;

	return 0;
}
Beispiel #28
0
/*
 * Subtype 0x0004 - Add multiple buddies to your buddy list.
 *
 * This just builds the "set buddy list" command then queues it.
 *
 * buddy_list = "Screen Name One&ScreenNameTwo&";
 *
 * XXX Clean this up.  
 *
 */
faim_export int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn,
	const char *buddy_list)
{
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int len = 0;
	char *localcpy = NULL;
	char *tmpptr = NULL;

	if (!buddy_list || !(localcpy = strdup(buddy_list)))
		return -EINVAL;

	for (tmpptr = strtok(localcpy, "&"); tmpptr;) {
		faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr,
			strlen(tmpptr));
		len += 1 + strlen(tmpptr);
		tmpptr = strtok(NULL, "&");
	}

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + len)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);

	strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);

	for (tmpptr = strtok(localcpy, "&"); tmpptr;) {

		faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr,
			strlen(tmpptr));

		aimbs_put8(&fr->data, strlen(tmpptr));
		aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));
		tmpptr = strtok(NULL, "&");
	}

	aim_tx_enqueue(sess, fr);

	free(localcpy);

	return 0;
}
Beispiel #29
0
/*
 * Request a bit of account info.
 *
 * The only known valid tag is 0x0011 (email address).
 *
 */
int aim_admin_getinfo(aim_session_t *sess, aim_conn_t *conn, guint16 info)
{
	aim_frame_t *tx;
	aim_snacid_t snacid;

	if (!(tx = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 14))) {
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0002, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&tx->data, 0x0007, 0x0002, 0x0000, snacid);

	aimbs_put16(&tx->data, info);
	aimbs_put16(&tx->data, 0x0000);

	aim_tx_enqueue(sess, tx);

	return 0;
}
Beispiel #30
0
/*
 * Subtype 0x0004 (SNAC_SUBTYPE_BUDDY_ADDBUDDY) - Add multiple buddies to your buddy list.
 *
 * This just builds the "set buddy list" command then queues it.
 *
 * buddy_list = "Screen Name One&ScreenNameTwo&";
 *
 * XXX Clean this up.
 *
 */
int
aim_buddylist_set(OscarData *od, FlapConnection *conn, const char *buddy_list)
{
	ByteStream bs;
	aim_snacid_t snacid;
	int len = 0;
	char *localcpy = NULL;
	char *tmpptr = NULL;

	if (!buddy_list || !(localcpy = g_strdup(buddy_list)))
		return -EINVAL;

	for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
		purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT
				")\n", tmpptr, strlen(tmpptr));
		len += 1 + strlen(tmpptr);
		tmpptr = strtok(NULL, "&");
	}

	byte_stream_new(&bs, len);

	strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);

	for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {

		purple_debug_misc("oscar", "---adding: %s (%" G_GSIZE_FORMAT
				")\n", tmpptr, strlen(tmpptr));

		byte_stream_put8(&bs, strlen(tmpptr));
		byte_stream_putstr(&bs, tmpptr);
		tmpptr = strtok(NULL, "&");
	}

	snacid = aim_cachesnac(od, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, NULL, 0);
	flap_connection_send_snac(od, conn, SNAC_FAMILY_BUDDY, 0x0004, 0x0000, snacid, &bs);

	byte_stream_destroy(&bs);

	g_free(localcpy);

	return 0;
}