Esempio n. 1
0
/* Subtype 0x0006 */
static int
userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
	int ret = 0;
	aim_rxcallback_t userfunc;
	aim_userinfo_t *userinfo, *userinfo2;
	GSList *tlvlist;
	aim_tlv_t *tlv = NULL;
	int was_explicit;

	userinfo = (aim_userinfo_t *)g_malloc(sizeof(aim_userinfo_t));
	aim_info_extract(od, 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 *)g_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 *)g_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))) {
		ByteStream cbs;
		byte_stream_init(&cbs, tlv->value, tlv->length);
		userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length);
		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
	}
	aim_tlvlist_free(tlvlist);

	aim_locate_adduserinfo(od, userinfo);
	userinfo2 = aim_locate_finduserinfo(od, userinfo->sn);
	aim_info_free(userinfo);
	g_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.
	 */
	if (userinfo2 != NULL)
	{
		was_explicit = aim_locate_gotuserinfo(od, conn, userinfo2->sn);
		if (was_explicit == TRUE)
			if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
				ret = userfunc(od, conn, frame, userinfo2);
	}

	return ret;
}
/* Subtype 0x0006 */
static int
userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
	int ret = 0;
	aim_userinfo_t *userinfo, *userinfo2;
	GSList *tlvlist;
	aim_tlv_t *tlv = NULL;

	userinfo = (aim_userinfo_t *)g_malloc(sizeof(aim_userinfo_t));
	aim_info_extract(od, 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 *)g_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 *)g_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))) {
		ByteStream cbs;
		PurpleAccount *account = purple_connection_get_account(od->gc);
		const char *mood;

		byte_stream_init(&cbs, tlv->value, tlv->length);
		userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length);
		byte_stream_rewind(&cbs);
		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;

		mood = aim_receive_custom_icon(od, &cbs, tlv->length);
		if (mood)
			purple_prpl_got_user_status(account, userinfo->bn, "mood",
					PURPLE_MOOD_NAME, mood,
					NULL);
		else
			purple_prpl_got_user_status_deactive(account, userinfo->bn, "mood");
	}
	aim_tlvlist_free(tlvlist);

	aim_locate_adduserinfo(od, userinfo);
	userinfo2 = aim_locate_finduserinfo(od, userinfo->bn);
	aim_info_free(userinfo);
	g_free(userinfo);

	/* Show the info to the user */
	oscar_user_info_display_aim(od, userinfo2);

	return ret;
}
Esempio n. 3
0
/* Subtype 0x0006 */
static int
userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
	int ret = 0;
	aim_rxcallback_t userfunc;
	aim_userinfo_t *userinfo, *userinfo2;
	GSList *tlvlist;
	aim_tlv_t *tlv = NULL;

	userinfo = (aim_userinfo_t *)g_malloc(sizeof(aim_userinfo_t));
	aim_info_extract(od, 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 *)g_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 *)g_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))) {
		ByteStream cbs;
		byte_stream_init(&cbs, tlv->value, tlv->length);
		userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length);
		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
	}
	aim_tlvlist_free(tlvlist);

	aim_locate_adduserinfo(od, userinfo);
	userinfo2 = aim_locate_finduserinfo(od, userinfo->bn);
	aim_info_free(userinfo);
	g_free(userinfo);

	/* Show the info to the user */
	if (userinfo2 != NULL && ((userfunc = aim_callhandler(od, snac->family, snac->subtype))))
		ret = userfunc(od, conn, frame, userinfo2);

	return ret;
}
Esempio n. 4
0
void
oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
{
	OscarData *od;
	PurpleAccount *account;
	PurplePresence *presence = NULL;
	PurpleStatus *status = NULL;
	PurpleGroup *g = NULL;
	struct buddyinfo *bi = NULL;
	char *tmp;
	const char *bname = NULL, *gname = NULL;

	od = purple_connection_get_protocol_data(gc);
	account = purple_connection_get_account(gc);

	if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL)))
		return;

	if (userinfo == NULL)
		userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));

	if (b == NULL)
		b = purple_find_buddy(account, userinfo->bn);

	if (b != NULL) {
		bname = purple_buddy_get_name(b);
		g = purple_buddy_get_group(b);
		gname = purple_group_get_name(g);
		presence = purple_buddy_get_presence(b);
		status = purple_presence_get_active_status(presence);
	}

	if (userinfo != NULL)
		bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn));

	if ((bi != NULL) && (bi->ipaddr != 0)) {
		tmp =  g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
						(bi->ipaddr & 0xff000000) >> 24,
						(bi->ipaddr & 0x00ff0000) >> 16,
						(bi->ipaddr & 0x0000ff00) >> 8,
						(bi->ipaddr & 0x000000ff));
		oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
		g_free(tmp);
	}
Esempio n. 5
0
/*
 * Add the userinfo to our linked list.  If we already have userinfo
 * for this buddy, then just overwrite parts of the old data.
 *
 * @param userinfo Contains the new information for the buddy.
 */
static void
aim_locate_adduserinfo(OscarData *od, aim_userinfo_t *userinfo)
{
	aim_userinfo_t *cur;

	cur = aim_locate_finduserinfo(od, userinfo->bn);

	if (cur == NULL) {
		cur = (aim_userinfo_t *)g_new0(aim_userinfo_t, 1);
		cur->bn = g_strdup(userinfo->bn);
		cur->next = od->locate.userinfo;
		od->locate.userinfo = cur;
	}

	cur->warnlevel = userinfo->warnlevel;
	cur->idletime = userinfo->idletime;
	if (userinfo->flags != 0)
		cur->flags = userinfo->flags;
	if (userinfo->createtime != 0)
		cur->createtime = userinfo->createtime;
	if (userinfo->membersince != 0)
		cur->membersince = userinfo->membersince;
	if (userinfo->onlinesince != 0)
		cur->onlinesince = userinfo->onlinesince;
	if (userinfo->sessionlen != 0)
		cur->sessionlen = userinfo->sessionlen;
	if (userinfo->capabilities != 0)
		cur->capabilities = userinfo->capabilities;
	cur->present |= userinfo->present;

	if (userinfo->iconcsumlen > 0) {
		g_free(cur->iconcsum);
		cur->iconcsum = (guint8 *)g_malloc(userinfo->iconcsumlen);
		memcpy(cur->iconcsum, userinfo->iconcsum, userinfo->iconcsumlen);
		cur->iconcsumlen = userinfo->iconcsumlen;
	}

	if (userinfo->info != NULL) {
		g_free(cur->info);
		g_free(cur->info_encoding);
		if (userinfo->info_len > 0) {
			cur->info = (char *)g_malloc(userinfo->info_len);
			memcpy(cur->info, userinfo->info, userinfo->info_len);
		} else
			cur->info = NULL;
		cur->info_encoding = g_strdup(userinfo->info_encoding);
		cur->info_len = userinfo->info_len;
	}

	if (userinfo->status != NULL) {
		g_free(cur->status);
		g_free(cur->status_encoding);
		if (userinfo->status_len > 0) {
			cur->status = (char *)g_malloc(userinfo->status_len);
			memcpy(cur->status, userinfo->status, userinfo->status_len);
		} else
			cur->status = NULL;
		if (userinfo->status_encoding != NULL)
			cur->status_encoding = g_strdup(userinfo->status_encoding);
		else
			cur->status_encoding = NULL;
		cur->status_len = userinfo->status_len;
	}

	if (userinfo->itmsurl != NULL) {
		g_free(cur->itmsurl);
		g_free(cur->itmsurl_encoding);
		if (userinfo->itmsurl_len > 0) {
			cur->itmsurl = (char *)g_malloc(userinfo->itmsurl_len);
			memcpy(cur->itmsurl, userinfo->itmsurl, userinfo->itmsurl_len);
		} else
			cur->itmsurl = NULL;
		if (userinfo->itmsurl_encoding != NULL)
			cur->itmsurl_encoding = g_strdup(userinfo->itmsurl_encoding);
		else
			cur->itmsurl_encoding = NULL;
		cur->itmsurl_len = userinfo->itmsurl_len;
	}

	if (userinfo->away != NULL) {
		g_free(cur->away);
		g_free(cur->away_encoding);
		if (userinfo->away_len > 0) {
			cur->away = (char *)g_malloc(userinfo->away_len);
			memcpy(cur->away, userinfo->away, userinfo->away_len);
		} else
			cur->away = NULL;
		cur->away_encoding = g_strdup(userinfo->away_encoding);
		cur->away_len = userinfo->away_len;

	} else {
		/*
		 * We don't have an away message specified in this user_info
		 * block, so clear any cached away message now.
		 */
		if (cur->away) {
			g_free(cur->away);
			cur->away = NULL;
		}
		if (cur->away_encoding) {
			g_free(cur->away_encoding);
			cur->away_encoding = NULL;
		}
		cur->away_len = 0;
	}
}
Esempio n. 6
0
/*
 * Add the userinfo to our linked list.  If we already have userinfo
 * for this buddy, then just overwrite parts of the old data.
 *
 * @param userinfo Contains the new information for the buddy.
 */
static void
aim_locate_adduserinfo(OscarData *od, aim_userinfo_t *userinfo)
{
	aim_userinfo_t *cur;
	FlapConnection *conn;
	aim_rxcallback_t userfunc;

	cur = aim_locate_finduserinfo(od, userinfo->sn);

	if (cur == NULL) {
		cur = (aim_userinfo_t *)g_new0(aim_userinfo_t, 1);
		cur->sn = g_strdup(userinfo->sn);
		cur->next = od->locate.userinfo;
		od->locate.userinfo = cur;
	}

	cur->warnlevel = userinfo->warnlevel;
	cur->idletime = userinfo->idletime;
	if (userinfo->flags != 0)
		cur->flags = userinfo->flags;
	if (userinfo->createtime != 0)
		cur->createtime = userinfo->createtime;
	if (userinfo->membersince != 0)
		cur->membersince = userinfo->membersince;
	if (userinfo->onlinesince != 0)
		cur->onlinesince = userinfo->onlinesince;
	if (userinfo->sessionlen != 0)
		cur->sessionlen = userinfo->sessionlen;
	if (userinfo->capabilities != 0)
		cur->capabilities = userinfo->capabilities;
	cur->present |= userinfo->present;

	if (userinfo->iconcsumlen > 0) {
		g_free(cur->iconcsum);
		cur->iconcsum = (guint8 *)g_malloc(userinfo->iconcsumlen);
		memcpy(cur->iconcsum, userinfo->iconcsum, userinfo->iconcsumlen);
		cur->iconcsumlen = userinfo->iconcsumlen;
	}

	if (userinfo->info != NULL) {
		g_free(cur->info);
		g_free(cur->info_encoding);
		if (userinfo->info_len > 0) {
			cur->info = (char *)g_malloc(userinfo->info_len);
			memcpy(cur->info, userinfo->info, userinfo->info_len);
		} else
			cur->info = NULL;
		cur->info_encoding = g_strdup(userinfo->info_encoding);
		cur->info_len = userinfo->info_len;
	}

	if (userinfo->status != NULL) {
		g_free(cur->status);
		g_free(cur->status_encoding);
		if (userinfo->status_len > 0) {
			cur->status = (char *)g_malloc(userinfo->status_len);
			memcpy(cur->status, userinfo->status, userinfo->status_len);
		} else
			cur->status = NULL;
		if (userinfo->status_encoding != NULL)
			cur->status_encoding = g_strdup(userinfo->status_encoding);
		else
			cur->status_encoding = NULL;
		cur->status_len = userinfo->status_len;
	}

	if (userinfo->itmsurl != NULL) {
		g_free(cur->itmsurl);
		g_free(cur->itmsurl_encoding);
		if (userinfo->itmsurl_len > 0) {
			cur->itmsurl = (char *)g_malloc(userinfo->itmsurl_len);
			memcpy(cur->itmsurl, userinfo->itmsurl, userinfo->itmsurl_len);
		} else
			cur->itmsurl = NULL;
		if (userinfo->itmsurl_encoding != NULL)
			cur->itmsurl_encoding = g_strdup(userinfo->itmsurl_encoding);
		else
			cur->itmsurl_encoding = NULL;
		cur->itmsurl_len = userinfo->itmsurl_len;
	}

	if (userinfo->away != NULL) {
		g_free(cur->away);
		g_free(cur->away_encoding);
		if (userinfo->away_len > 0) {
			cur->away = (char *)g_malloc(userinfo->away_len);
			memcpy(cur->away, userinfo->away, userinfo->away_len);
		} else
			cur->away = NULL;
		cur->away_encoding = g_strdup(userinfo->away_encoding);
		cur->away_len = userinfo->away_len;

	} else if (!(userinfo->flags & AIM_FLAG_AWAY)) {
		/*
		 * We don't have an away message specified in this user_info block.
		 * If the user is not away, clear any cached away message now.
		 */
		if (cur->away) {
			g_free(cur->away);
			cur->away = NULL;
		}
		if (cur->away_encoding) {
			g_free(cur->away_encoding);
			cur->away_encoding = NULL;
		}
		cur->away_len = 0;
	}

	/*
	 * This callback can be used by a client if they want to know whenever
	 * info for a buddy is updated.  For example, if a client shows away
	 * messages in its buddy list, then it would need to know if a user's
	 * away message changes.
	 */
	conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE);
	if ((userfunc = aim_callhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_GOTINFOBLOCK)))
		userfunc(od, conn, NULL, cur);
}
Esempio n. 7
0
/**
 * @brief Append the status information to a user_info struct
 *
 * The returned information is HTML-ready, appropriately escaped, as all information in a user_info struct should be HTML.
 *
 * @param gc The PurpleConnection
 * @param user_info A PurpleNotifyUserInfo object to which status information will be added
 * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status().
 * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status().
 * @param use_html_status If TRUE, prefer HTML-formatted away message over plaintext available message.
 */
void
oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean use_html_status)
{
	PurpleAccount *account = purple_connection_get_account(gc);
	OscarData *od;
	PurplePresence *presence = NULL;
	PurpleStatus *status = NULL;
	gchar *message = NULL, *itmsurl = NULL, *tmp;
	gboolean escaping_needed = TRUE;

	od = purple_connection_get_protocol_data(gc);

	if (b == NULL && userinfo == NULL)
		return;

	if (b == NULL)
		b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn);
	else
		userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));

	if (b) {
		presence = purple_buddy_get_presence(b);
		status = purple_presence_get_active_status(presence);
	}

	/* If we have both b and userinfo we favor userinfo, because if we're
	   viewing someone's profile then we want the HTML away message, and
	   the "message" attribute of the status contains only the plaintext
	   message. */
	if (userinfo) {
		if ((userinfo->flags & AIM_FLAG_AWAY) && use_html_status && userinfo->away_len > 0 && userinfo->away != NULL && userinfo->away_encoding != NULL) {
			/* Away message */
			message = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len);
			escaping_needed = FALSE;
		} else {
			/*
			 * Available message or non-HTML away message (because that's
			 * all we have right now.
			 */
			if ((userinfo->status != NULL) && userinfo->status[0] != '\0') {
				message = oscar_encoding_to_utf8(userinfo->status_encoding, userinfo->status, userinfo->status_len);
			}
#if defined (_WIN32) || defined (__APPLE__)
			if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) {
				itmsurl = oscar_encoding_to_utf8(userinfo->itmsurl_encoding, userinfo->itmsurl, userinfo->itmsurl_len);
			}
#endif
		}
	} else {
		message = g_strdup(purple_status_get_attr_string(status, "message"));
		itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
	}

	if (message) {
		tmp = oscar_util_format_string(message, purple_account_get_username(account));
		g_free(message);
		message = tmp;
		if (escaping_needed) {
			tmp = purple_markup_escape_text(message, -1);
			g_free(message);
			message = tmp;
		}
	}

	if (use_html_status && itmsurl) {
		tmp = g_strdup_printf("<a href=\"%s\">%s</a>", itmsurl, message);
		g_free(message);
		message = tmp;
	}

	if (b) {
		if (purple_presence_is_online(presence)) {
			gboolean is_away = ((status && !purple_status_is_available(status)) || (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
			if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) {
				/* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
				 * If the status name and the message are the same, only show one. */
				const char *status_name = purple_status_get_name(status);
				if (status_name && message && !strcmp(status_name, message))
					status_name = NULL;

				tmp = g_strdup_printf("%s%s%s",
									   status_name ? status_name : "",
									   ((status_name && message) && *message) ? ": " : "",
									   (message && *message) ? message : "");
				g_free(message);
				message = tmp;
			}

		} else if (aim_ssi_waitingforauth(od->ssi.local,
			aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)),
			purple_buddy_get_name(b)))
		{
			/* Note if an offline buddy is not authorized */
			tmp = g_strdup_printf("%s%s%s",
					_("Not Authorized"),
					(message && *message) ? ": " : "",
					(message && *message) ? message : "");
			g_free(message);
			message = tmp;
		} else {
			g_free(message);
			message = g_strdup(_("Offline"));
		}
	}

	if (presence) {
		const char *mood;
		const char *comment;
		char *description;
		status = purple_presence_get_status(presence, "mood");
		mood = icq_get_custom_icon_description(purple_status_get_attr_string(status, PURPLE_MOOD_NAME));
		if (mood) {
			comment = purple_status_get_attr_string(status, PURPLE_MOOD_COMMENT);
			if (comment) {
				char *escaped_comment = purple_markup_escape_text(comment, -1);
				description = g_strdup_printf("%s (%s)", _(mood), escaped_comment);
				g_free(escaped_comment);
			} else {
				description = g_strdup(_(mood));
			}
			purple_notify_user_info_add_pair(user_info, _("Mood"), description);
			g_free(description);
		}
	}

	purple_notify_user_info_add_pair(user_info, _("Status"), message);
	g_free(message);
}