⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locate.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 3 页
字号:
 */faim_export int aim_locate_reqrights(aim_session_t *sess){	aim_conn_t *conn;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))		return -EINVAL;	return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_LOC, AIM_CB_LOC_REQRIGHTS);}/* * Subtype 0x0003 * * Normally contains: *   t(0001)  - short containing max profile length (value = 1024) *   t(0002)  - short - unknown (value = 16) [max MIME type length?] *   t(0003)  - short - unknown (value = 10) *   t(0004)  - short - unknown (value = 2048) [ICQ only?] */static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	aim_tlvlist_t *tlvlist;	aim_rxcallback_t userfunc;	int ret = 0;	fu16_t maxsiglen = 0;	tlvlist = aim_tlvlist_read(bs);	if (aim_tlv_gettlv(tlvlist, 0x0001, 1))		maxsiglen = aim_tlv_get16(tlvlist, 0x0001, 1);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, maxsiglen);	aim_tlvlist_free(&tlvlist);	return ret;}/* * Subtype 0x0004 * * Gives BOS your profile. * * profile_encoding and awaymsg_encoding MUST be set if profile or * away are set, respectively, and their value may or may not be * restricted to a few choices.  I am currently aware of: *  * us-ascii		Just that * unicode-2-0		UCS2-BE *  * profile_len and awaymsg_len MUST be set similarly, and they MUST * be the length of their respective strings in bytes. * * To get the previous behavior of awaymsg == "" un-setting the away * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the * obvious equivalent). *  */faim_export int aim_locate_setprofile(aim_session_t *sess,				  const char *profile_encoding, const char *profile, const int profile_len,				  const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl = NULL;	char *encoding;	static const char defencoding[] = {"text/aolrtf; charset=\"%s\""};	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))		return -EINVAL;	if (!profile && !awaymsg)		return -EINVAL;	if ((profile && profile_encoding == NULL) || (awaymsg && awaymsg_len && awaymsg_encoding == NULL)) {		return -EINVAL;	}	/* Build the packet first to get real length */	if (profile) {		/* no + 1 here because of %s */		encoding = malloc(strlen(defencoding) + strlen(profile_encoding));		if (encoding == NULL) {			return -ENOMEM;		}		snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding);		aim_tlvlist_add_raw(&tl, 0x0001, strlen(encoding), encoding);		aim_tlvlist_add_raw(&tl, 0x0002, profile_len, profile);		free(encoding);	}	/*	 * 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 (awaymsg_len) {			encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding));			if (encoding == NULL) {				return -ENOMEM;			}			snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding);			aim_tlvlist_add_raw(&tl, 0x0003, strlen(encoding), encoding);			aim_tlvlist_add_raw(&tl, 0x0004, awaymsg_len, awaymsg);			free(encoding);		} else			aim_tlvlist_add_noval(&tl, 0x0004);	}	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);	aim_tlvlist_write(&fr->data, &tl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x0004 - Set your client's capabilities. */faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl = NULL;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))		return -EINVAL;	aim_tlvlist_add_caps(&tl, 0x0005, caps);	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);	aim_tlvlist_write(&fr->data, &tl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x0005 - Request info of another AIM user. * * @param sn The screenname whose info you wish to request. * @param infotype The type of info you wish to request. *        0x0001 - Info/profile *        0x0003 - Away message *        0x0004 - Capabilities */faim_export int aim_locate_getinfo(aim_session_t *sess, const char *sn, fu16_t infotype){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 12+1+strlen(sn))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x0005, 0x0000, NULL, 0);		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 0x0006 */static int userinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	aim_userinfo_t *userinfo, *userinfo2;	aim_tlvlist_t *tlvlist;	aim_tlv_t *tlv = NULL;	int was_explicit;	userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t));	aim_info_extract(sess, bs, userinfo);	tlvlist = aim_tlvlist_read(bs);	/* Profile will be 1 and 2 */	userinfo->info_encoding = aim_tlv_getstr(tlvlist, 0x0001, 1);	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {		userinfo->info = (char *)malloc(tlv->length);		memcpy(userinfo->info, tlv->value, tlv->length);		userinfo->info_len = tlv->length;	}	/* Away message will be 3 and 4 */	userinfo->away_encoding = aim_tlv_getstr(tlvlist, 0x0003, 1);	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {		userinfo->away = (char *)malloc(tlv->length);		memcpy(userinfo->away, tlv->value, tlv->length);		userinfo->away_len = tlv->length;	}	/* Caps will be 5 */	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {		aim_bstream_t cbs;		aim_bstream_init(&cbs, tlv->value, tlv->length);		userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length);		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;	}	aim_tlvlist_free(&tlvlist);	aim_locate_adduserinfo(sess, userinfo);	userinfo2 = aim_locate_finduserinfo(sess, userinfo->sn);	aim_info_free(userinfo);	free(userinfo);	/*	 * Remove this screen name from our queue.  If the client requested 	 * this buddy's info explicitly, then notify them that we have info 	 * for this buddy.	 */	was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn);	if (was_explicit == TRUE)		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))			ret = userfunc(sess, rx, userinfo2);	return ret;}/*  * Subtype 0x0009 - Set directory profile data. * * This is not the same as aim_location_setprofile! * privacy: 1 to allow searching, 0 to disallow. * */faim_export int aim_locate_setdirinfo(aim_session_t *sess, 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) {	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl = NULL;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))		return -EINVAL;	aim_tlvlist_add_16(&tl, 0x000a, privacy);	if (first)		aim_tlvlist_add_raw(&tl, 0x0001, strlen(first), first);	if (last)		aim_tlvlist_add_raw(&tl, 0x0002, strlen(last), last);	if (middle)		aim_tlvlist_add_raw(&tl, 0x0003, strlen(middle), middle);	if (maiden)		aim_tlvlist_add_raw(&tl, 0x0004, strlen(maiden), maiden);	if (state)		aim_tlvlist_add_raw(&tl, 0x0007, strlen(state), state);	if (city)		aim_tlvlist_add_raw(&tl, 0x0008, strlen(city), city);	if (nickname)		aim_tlvlist_add_raw(&tl, 0x000c, strlen(nickname), nickname);	if (zip)		aim_tlvlist_add_raw(&tl, 0x000d, strlen(zip), zip);	if (street)		aim_tlvlist_add_raw(&tl, 0x0021, strlen(street), street);	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid);	aim_tlvlist_write(&fr->data, &tl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x000b - Huh? What is this? */faim_export int aim_locate_000b(aim_session_t *sess, const char *sn){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;		return -EINVAL;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x000b, 0x0000, NULL, 0);		aim_putsnac(&fr->data, 0x0002, 0x000b, 0x0000, snacid);	aimbs_put8(&fr->data, strlen(sn));	aimbs_putraw(&fr->data, sn, strlen(sn));	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x000f *  * XXX pass these in better * */faim_export int aim_locate_setinterests(aim_session_t *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl = NULL;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))		return -EINVAL;	/* ?? privacy ?? */	aim_tlvlist_add_16(&tl, 0x000a, privacy);	if (interest1)		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest1), interest1);	if (interest2)		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest2), interest2);	if (interest3)		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest3), interest3);	if (interest4)		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest4), interest4);	if (interest5)		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest5), interest5);	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);	aim_tlvlist_write(&fr->data, &tl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x0015 - Request the info a user using the short method.  This is  * what iChat uses.  It normally is VERY leniently rate limited. * * @param sn The screen name whose info you wish to request. * @param flags The bitmask which specifies the type of info you wish to request. *        0x00000001 - Info/profile. *        0x00000002 - Away message. *        0x00000004 - Capabilities. *        0x00000008 - Certification. * @return Return 0 if no errors, otherwise return the error number. */faim_export int aim_locate_getinfoshort(aim_session_t *sess, const char *sn, fu32_t flags){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);	aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, snacid);	aimbs_put32(&fr->data, flags);	aimbs_put8(&fr->data, strlen(sn));	aimbs_putraw(&fr->data, sn, strlen(sn));	aim_tx_enqueue(sess, fr);	return 0;}static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	if (snac->subtype == 0x0001)		return error(sess, mod, rx, snac, bs);	else if (snac->subtype == 0x0003)		return rights(sess, mod, rx, snac, bs);	else if (snac->subtype == 0x0006)		return userinfo(sess, mod, rx, snac, bs);	return 0;}static void locate_shutdown(aim_session_t *sess, aim_module_t *mod){	aim_userinfo_t *del;	while (sess->locate.userinfo) {		del = sess->locate.userinfo;		sess->locate.userinfo = sess->locate.userinfo->next;		aim_info_free(del);		free(del);	}}faim_internal int locate_modfirst(aim_session_t *sess, aim_module_t *mod){	mod->family = AIM_CB_FAM_LOC;	mod->version = 0x0001;	mod->toolid = 0x0110;	mod->toolversion = 0x0629;	mod->flags = 0;	strncpy(mod->name, "locate", sizeof(mod->name));	mod->snachandler = snachandler;	mod->shutdown = locate_shutdown;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -