Exemple #1
0
static void qq_modify_buddy_memo_from_menu_cb(PurpleBlistNode *node, gpointer data)
{
	PurpleBuddy *buddy;
	qq_buddy_data *bd;
	PurpleConnection *gc;
	guint32 bd_uid;

	g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));

	buddy = (PurpleBuddy *)node;
	g_return_if_fail(NULL != buddy);

	gc = purple_account_get_connection(purple_buddy_get_account(buddy));
	g_return_if_fail(NULL != gc);

	bd = (qq_buddy_data *)purple_buddy_get_protocol_data(buddy);
	g_return_if_fail(NULL != bd);
	bd_uid = bd->uid;

	/* param: gc, uid, update_class, action
	 * here, update_class is set to bd_uid. because some memo packages returned
	 * without uid, which will make us confused */
	qq_request_buddy_memo(gc, bd_uid, 0, QQ_BUDDY_MEMO_MODIFY);
}
Exemple #2
0
qq_buddy_data *qq_buddy_data_find(PurpleConnection *gc, guint32 uid)
{
	gchar *who;
	PurpleBuddy *buddy;
	qq_buddy_data *bd;

	g_return_val_if_fail(gc != NULL, NULL);

	who = uid_to_purple_name(uid);
	if (who == NULL)	return NULL;
	buddy = purple_find_buddy(purple_connection_get_account(gc), who);
	g_free(who);

	if (buddy == NULL) {
		purple_debug_error("QQ", "Can not find purple buddy of %u\n", uid);
		return NULL;
	}
	
	if ((bd = purple_buddy_get_protocol_data(buddy)) == NULL) {
		purple_debug_error("QQ", "Can not find buddy data of %u\n", uid);
		return NULL;
	}
	return bd;
}
Exemple #3
0
static void plainprpl_login(PurpleAccount *account)
{
	PurpleConnection *gc = purple_account_get_connection(account);

	purple_debug_info("plainprpl", "logging in %s\n", account->username);

	purple_connection_update_progress(gc, _("Connecting"), 0, 2);
	purple_connection_update_progress(gc, _("Connected"), 1, 2);
	purple_connection_set_state(gc, PURPLE_CONNECTED);

	/* Setup plugin data */
	plain_plugin_state *pstate = g_new0(plain_plugin_state, 1);

	/* General account data */
	const char *listen_af = purple_account_get_string(account, "listen_af", NULL);
	const char *listen_port = purple_account_get_string(account, "listen_port", NULL);

	//check port
	if (listen_port == NULL || atoi(listen_port) < 1 || atoi(listen_port) >= 65535) {
		listen_port = PLAIN_DEFAULT_PORT_STR;
		purple_account_set_string(account, "listen_port", listen_port);
	}

	//check protocol
	if (listen_af == NULL || (strcmp(listen_af, "ipv4") && strcmp(listen_af, "ipv6"))) {
		listen_af = "ipv4";
		purple_account_set_string(account, "listen_port", listen_af);
	}

	/* Select the address to listen on */
	const char *listen_addr = (strcmp(listen_af, "ipv4") == 0) ? "0.0.0.0" : "::1";
	pstate->sockaf = str_to_af(listen_af);
	pstate->sockfd = net_bind("plainprpl", listen_addr, listen_port, NULL, IPPROTO_UDP, pstate->sockaf);

	if (pstate->sockfd < 0) {
		purple_debug_info("plainprpl", "Failed to bind to %s\n", listen_addr);
		g_free(pstate);
		//TODO: diable plugin
		return;
	} else {
		purple_debug_info("plainprpl", "Bind to %s\n", listen_addr);
	}

	pstate->receive_timer = purple_timeout_add(80, plain_receive, gc);

	purple_connection_set_protocol_data(gc, pstate);

	/* Attach buddy data to each buddy */
	GSList *list = purple_find_buddies(account, NULL);
	purple_debug_info("plainprpl", "Buddies to load: %d\n", g_slist_length(list));

	GSList *iter = list;
	while (iter) {
		PurpleBuddy *buddy = iter->data;
		//purple_debug_info("plainprpl", "#plainprpl_login: attach custom data to buddy: %s\n", buddy->name);
		assert(purple_buddy_get_protocol_data(buddy) == NULL);

		const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
		if (addr_str != NULL && strlen(addr_str)) {
			add_buddy_sdata(buddy, pstate);
		} else {
			purple_debug_info("plainprpl", "Empty address for buddy: %s\n", buddy->name);
		}

		/* Set offline by default */
		purple_prpl_got_user_status(account, buddy->name, PLAIN_STATUS_OFFLINE, NULL);

		iter = iter->next;
	}
	g_slist_free(list);

	/* Call the on_login script - if it is set */
	const char *on_login = purple_account_get_string(account, "on_login", NULL);
	exec_process(on_login, NULL, NULL, gc, NULL);
}
Exemple #4
0
static gboolean plain_receive(gpointer data)
{
	purple_debug_info("plainprpl", "plain_receive called\n");

	char msgbuf[MAX_MESSAGE_SIZE];
	int msgbuf_len;
	IP addr;
	const char *status;
	PurpleConnection *gc;
	PurpleAccount *account;
	PurpleBuddy *buddy;
	plain_plugin_state *pstate;
	plain_buddy_state *bstate;

	/* Get time in seconds since 1970 */
	time_t now = time(NULL);

	gc = (PurpleConnection *) data;
	account = purple_connection_get_account(gc);
	pstate = purple_connection_get_protocol_data(gc);

	/* Check if we need to ping any buddy */
	ping_buddies(gc, now);

	msgbuf_len = sizeof(msgbuf);
	buddy = receive_msg(pstate, &addr, msgbuf, &msgbuf_len);

	/* Nothing to receive or error */
	if (msgbuf_len <= 0) {
		return TRUE;
	}

	if (!g_utf8_validate(msgbuf, -1, NULL)) {
		purple_debug_info("plainprpl", "Received invalid UTF8 message from %s - ignore.\n", str_addr(&addr));
		return TRUE;
	}

	/* We got a message and identified the sender */
	purple_debug_info("plainprpl", "Received message from %s (%d Bytes): %s\n", str_addr(&addr), strlen(msgbuf), msgbuf);

	/* We got a message from a source we don't know */
	gboolean allow_unknown = purple_account_get_bool(account, "allow_unknown", FALSE);
	if (buddy == NULL) {
		purple_debug_info("plainprpl", "Packet from unknown buddy from address %s.\n", str_addr(&addr));

		if (allow_unknown && !pstate->block_unknown) {
			//temporary disable the setting
			pstate->block_unknown = TRUE;
			plainprpl_add_buddy_by_contact_request(gc, str_addr(&addr), msgbuf);
		}
		return TRUE;
	}

	bstate = purple_buddy_get_protocol_data(buddy);
	if (bstate == NULL) {
		purple_debug_info("plainprpl", "bstate of buddy %s is NULL.\n", buddy->name);
		return TRUE;
	}

	status = PLAIN_STATUS_ONLINE;

	if (strcmp(msgbuf, "/ping") == 0) {
		/* Received a ping from a buddy */
		if ((bstate->time_recv + 5) < now) {
			/* Send pong at most every 5 seconds */
			send_msg(pstate, bstate, "/pong");
		} else {
			/* Ignore ping */
		}
	} else if (strcmp(msgbuf, "/pong") == 0) {
		/* Nothing to do */
	} else if (strcmp(msgbuf, "/bye") == 0) {
		status = PLAIN_STATUS_OFFLINE;
	} else if (msgbuf[0] != '/') {
		/* Display message */
		serv_got_im(gc, bstate->name, msgbuf, PURPLE_MESSAGE_RECV, now);
	} else {
		/* Unknown command - ignore */
	}

	bstate->time_recv = now;

	/* Set buddy status to online */
	purple_prpl_got_user_status(account, bstate->name, status, NULL);

	return TRUE; //continue loop
}
Exemple #5
0
/* Ping buddies a ping every 5 minutes if there is no traffic */
void ping_buddies(PurpleConnection *gc, time_t now)
{
	PurpleBuddy *buddy;
	PurpleAccount *account;
	plain_buddy_state *bstate;
	plain_plugin_state *pstate;
	time_t time_next;
	GSList *iter;

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

	if(pstate->time_next > now) {
		return;
	}

	time_next = now + (60*5); //max time we wait for another round
	const char *on_lookup = purple_account_get_string(account, "on_lookup", NULL);

	iter = pstate->all_buddies;
	while (iter) {
		buddy = iter->data;
		bstate = purple_buddy_get_protocol_data(buddy);

		//uninitialized buddy
		if(bstate == NULL) {
			purple_debug_info("plainprpl", "Buddy %s has no state set.\n", buddy->name);
			goto next;
		}

		//printf("Do ping_buddies for %s\n", buddy->name);

		int state = bstate->state;
		int state_step = bstate->state_step;
		time_t state_next = bstate->state_next;

		if(state == BUDDY_STATE_RESOLVE) {
			const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
			if(exec_process(on_lookup, addr_str, on_lookup_handle, gc, buddy) == 0) {
				/* Script was called - wait for answer some other time */
				purple_debug_info("plainprpl", "Lookup by SCRIPT succeded. Start to ping %s\n", str_addr(&bstate->addr));
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else if(addr_parse_full(&bstate->addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf) == 0) {
				purple_debug_info("plainprpl", "Lookup by DNS succeded (%s). Start to ping %s\n", addr_str, str_addr(&bstate->addr));
				//switch to ping state
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else {
				if(state_step == 0) {
					state_step = 4;
				} else if(state_step < (5*60)) {
					state_step *= 2;
				}

				purple_debug_info("plainprpl", "Resolve failed. Try again in %d seconds.\n", state_step);
				state_next = now + state_step;
			}
		} else if(state == BUDDY_STATE_PING) {
			//send ping
			if(bstate->time_recv < (now - (5*60))) {
				if(state_step < (5*60)) {
					state_step *= 2;
					state_next = now + state_step;

					send_msg(pstate, bstate, "/ping");

					/* Set buddy status to online */
					purple_prpl_got_user_status(account, bstate->name, PLAIN_STATUS_OFFLINE, NULL);
				} else {
					state = BUDDY_STATE_RESOLVE;
					state_step = 1;
					state_next = now + 1;
				}
			} else {
				state_step = 1;
				state_next = now + (5*60);
			}
		} else {
			purple_debug_info("plainprpl", "Invalid state: %d\n", state);
		}

		bstate->state = state;
		bstate->state_step = state_step;
		bstate->state_next = state_next;

		/* Get next time we need to do something here */
		if (state_next < time_next) {
			time_next = state_next;
		}

next:
		iter = iter->next;
	}

	pstate->time_next = time_next;
	purple_debug_info("plainprpl", "Next iteration in %d seconds.\n", (int)(time_next - now));
}
Exemple #6
0
void qq_process_add_buddy_no_auth(PurpleConnection *gc,
		guint8 *data, gint data_len, guint32 uid)
{
	qq_data *qd;
	gchar **segments;
	gchar *dest_uid, *reply;
	PurpleBuddy *buddy;
	qq_buddy_data *bd;

	g_return_if_fail(data != NULL && data_len != 0);
	g_return_if_fail(uid != 0);

	qd = (qq_data *) gc->proto_data;

	purple_debug_info("QQ", "Process buddy add for id [%u]\n", uid);
	qq_show_packet("buddy_add_no_auth", data, data_len);

	if (NULL == (segments = split_data(data, data_len, "\x1f", 2)))
		return;

	dest_uid = segments[0];
	reply = segments[1];
	if (strtoul(dest_uid, NULL, 10) != qd->uid) {	/* should not happen */
		purple_debug_error("QQ", "Add buddy reply is to [%s], not me!\n", dest_uid);
		g_strfreev(segments);
		return;
	}

	if (strtol(reply, NULL, 10) == 0) {
		/* add OK */
		qq_buddy_find_or_new(gc, uid);

		qq_request_buddy_info(gc, uid, 0, 0);
		if (qd->client_version >= 2007) {
			qq_request_get_level_2007(gc, uid);
		} else {
			qq_request_get_level(gc, uid);
		}
		qq_request_get_buddies_online(gc, 0, 0);

		purple_debug_info("QQ", "Successed adding into %u's buddy list\n", uid);
		g_strfreev(segments);
		return;
	}

	/* need auth */
	purple_debug_warning("QQ", "Failed adding buddy, need authorize\n");

	buddy = qq_buddy_find(gc, uid);
	if (buddy == NULL) {
		buddy = qq_buddy_new(gc, uid);
	}
	if (buddy != NULL && (bd = purple_buddy_get_protocol_data(buddy)) != NULL) {
		/* Not authorized now, free buddy data */
		qq_buddy_data_free(bd);
		purple_buddy_set_protocol_data(buddy, NULL);
	}

	add_buddy_authorize_input(gc, uid, NULL, 0);
	g_strfreev(segments);
}
Exemple #7
0
/* a floating text when mouse is on the icon, show connection status here */
static void qq_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
{
	qq_buddy_data *bd;
	gchar *tmp;
	GString *str;
	PurplePresence *presence;
	PurpleStatus *status;
	gchar *moodtext;

	g_return_if_fail(b != NULL);
	presence = purple_buddy_get_presence(b);
	bd = purple_buddy_get_protocol_data(b);
	if (bd == NULL)
		return;

	if (bd->level == NULL)
		qq_request_get_level(purple_account_get_connection(purple_buddy_get_account(b)), bd->uid);

	/* if (PURPLE_BUDDY_IS_ONLINE(b) && bd != NULL) */
	if (bd->ip.s_addr != 0) {
		str = g_string_new(NULL);
		g_string_printf(str, "%s:%d", inet_ntoa(bd->ip), bd->port);
		if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) {
			g_string_append(str, " TCP");
		} else {
			g_string_append(str, " UDP");
		}
		g_string_free(str, TRUE);
	}

	tmp = g_strdup_printf("%d", bd->age);
	purple_notify_user_info_add_pair(user_info, _("Age"), tmp);
	g_free(tmp);

	switch (bd->gender) {
		case QQ_BUDDY_GENDER_GG:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Male"));
			break;
		case QQ_BUDDY_GENDER_MM:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Female"));
			break;
		default:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Unknown"));
	}

	if (bd->level) {
		tmp = g_strdup_printf("%d", bd->level);
		purple_notify_user_info_add_pair(user_info, _("Level"), tmp);
		g_free(tmp);
	}

	str = g_string_new(NULL);
	if (bd->comm_flag & QQ_COMM_FLAG_QQ_MEMBER) {
		g_string_append( str, _("Member") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_QQ_VIP) {
		g_string_append( str, _(" VIP") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) {
		g_string_append( str, _(" TCP") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_MOBILE) {
		g_string_append( str, _(" FromMobile") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_BIND_MOBILE) {
		g_string_append( str, _(" BindMobile") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_VIDEO) {
		g_string_append( str, _(" Video") );
	}
	if (bd->ext_flag & QQ_EXT_FLAG_ZONE) {
		g_string_append( str, _(" Zone") );
	}

	purple_notify_user_info_add_pair(user_info, _("Flag"), str->str);
	g_string_free(str, TRUE);

	status = purple_presence_get_status(presence, PURPLE_MOOD_NAME);
	moodtext = purple_status_get_attr_string(status, PURPLE_MOOD_COMMENT);
	if (moodtext)
	{
		purple_notify_user_info_add_pair(user_info, _("Signature"), moodtext);
	}

#ifdef DEBUG
	tmp = g_strdup_printf( "%s (%04X)",
			qq_get_ver_desc(bd->client_tag),
			bd->client_tag );
	purple_notify_user_info_add_pair(user_info, _("Ver"), tmp);
	g_free(tmp);

	tmp = g_strdup_printf( "Ext 0x%X, Comm 0x%X",
			bd->ext_flag, bd->comm_flag );
	purple_notify_user_info_add_pair(user_info, _("Flag"), tmp);
	g_free(tmp);
#endif
}
static void
_browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface,
		  AvahiProtocol protocol, AvahiBrowserEvent event,
		  const char *name, const char *type, const char *domain,
		  AvahiLookupResultFlags flags, void *userdata) {

	PurpleAccount *account = userdata;
	PurpleBuddy *pb = NULL;

	switch (event) {
		case AVAHI_BROWSER_FAILURE:
			purple_debug_error("bonjour", "_browser_callback - Failure: %s\n",
				avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
			/* TODO: This is an error that should be handled. */
			break;
		case AVAHI_BROWSER_NEW:
			/* A new peer has joined the network and uses iChat bonjour */
			purple_debug_info("bonjour", "_browser_callback - new service\n");
			/* Make sure it isn't us */
			if (purple_utf8_strcasecmp(name, bonjour_get_jid(account)) != 0) {
				if (!avahi_service_resolver_new(avahi_service_browser_get_client(b),
						interface, protocol, name, type, domain, protocol,
						0, _resolver_callback, account)) {
					purple_debug_warning("bonjour", "_browser_callback -- Error initiating resolver: %s\n",
						avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
				}
			}
			break;
		case AVAHI_BROWSER_REMOVE:
			purple_debug_info("bonjour", "_browser_callback - Remove service\n");
			pb = purple_find_buddy(account, name);
			if (pb != NULL) {
				BonjourBuddy *bb = purple_buddy_get_protocol_data(pb);
				AvahiBuddyImplData *b_impl;
				GSList *l;
				AvahiSvcResolverData *rd_search;

				g_return_if_fail(bb != NULL);

				b_impl = bb->mdns_impl_data;

				/* There may be multiple presences, we should only get rid of this one */

				rd_search = g_new0(AvahiSvcResolverData, 1);
				rd_search->interface = interface;
				rd_search->protocol = protocol;
				rd_search->name = (gchar *) name;
				rd_search->type = (gchar *) type;
				rd_search->domain = (gchar *) domain;

				l = g_slist_find_custom(b_impl->resolvers, rd_search, _find_resolver_data);

				g_free(rd_search);

				if (l != NULL) {
					AvahiSvcResolverData *rd = l->data;
					b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd);
					/* This IP is no longer available */
					if (rd->ip != NULL) {
						bb->ips = g_slist_remove(bb->ips, rd->ip);
						g_free((gchar *) rd->ip);
					}
					_cleanup_resolver_data(rd);

					/* If this was the last resolver, remove the buddy */
					if (b_impl->resolvers == NULL)
						bonjour_buddy_signed_off(pb);
				}
			}
			break;
		case AVAHI_BROWSER_ALL_FOR_NOW:
		case AVAHI_BROWSER_CACHE_EXHAUSTED:
			break;
		default:
			purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event);
	}
}
static void
_resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol,
		  AvahiResolverEvent event, const char *name, const char *type, const char *domain,
		  const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt,
		  AvahiLookupResultFlags flags, void *userdata) {

	PurpleBuddy *pb;
	BonjourBuddy *bb;
	PurpleAccount *account = userdata;
	AvahiStringList *l;
	size_t size;
	char *key, *value;
	char ip[AVAHI_ADDRESS_STR_MAX];
	AvahiBuddyImplData *b_impl;
	AvahiSvcResolverData *rd;
	GSList *res;

	g_return_if_fail(r != NULL);

	pb = purple_find_buddy(account, name);
	bb = (pb != NULL) ? purple_buddy_get_protocol_data(pb) : NULL;

	switch (event) {
		case AVAHI_RESOLVER_FAILURE:
			purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n",
				avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));

			avahi_service_resolver_free(r);
			if (bb != NULL) {
				b_impl = bb->mdns_impl_data;
				res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver);
				if (res != NULL) {
					rd = res->data;
					b_impl->resolvers = g_slist_remove_link(b_impl->resolvers, res);

					/* We've already freed the resolver */
					rd->resolver = NULL;
					_cleanup_resolver_data(rd);

					/* If this was the last resolver, remove the buddy */
					if (b_impl->resolvers == NULL)
						bonjour_buddy_signed_off(pb);
				}
			}
			break;
		case AVAHI_RESOLVER_FOUND:

			purple_debug_info("bonjour", "_resolve_callback - name:%s account:%p bb:%p\n",
				name, account, bb);

			/* create a buddy record */
			if (bb == NULL)
				bb = bonjour_buddy_new(name, account);
			b_impl = bb->mdns_impl_data;

			/* If we're reusing an existing buddy, it may be a new resolver or an existing one. */
			res = g_slist_find_custom(b_impl->resolvers, r, _find_resolver_data_by_resolver);
			if (res != NULL)
				rd = res->data;
			else {
				rd = g_new0(AvahiSvcResolverData, 1);
				rd->resolver = r;
				rd->interface = interface;
				rd->protocol = protocol;
				rd->name = g_strdup(name);
				rd->type = g_strdup(type);
				rd->domain = g_strdup(domain);

				b_impl->resolvers = g_slist_prepend(b_impl->resolvers, rd);
			}


			/* Get the ip as a string */
			ip[0] = '\0';
			avahi_address_snprint(ip, AVAHI_ADDRESS_STR_MAX, a);

			purple_debug_info("bonjour", "_resolve_callback - name:%s ip:%s prev_ip:%s\n",
				name, ip, rd->ip);

			if (rd->ip == NULL || strcmp(rd->ip, ip) != 0) {
				/* We store duplicates in bb->ips, so we always remove the one */
				if (rd->ip != NULL) {
					bb->ips = g_slist_remove(bb->ips, rd->ip);
					g_free((gchar *) rd->ip);
				}
				/* IPv6 goes at the front of the list and IPv4 at the end so that we "prefer" IPv6, if present */
				if (protocol == AVAHI_PROTO_INET6) {
					rd->ip = g_strdup_printf("%s%%%d", ip, interface);
					bb->ips = g_slist_prepend(bb->ips, (gchar *) rd->ip);
				} else {
					rd->ip = g_strdup(ip);
					bb->ips = g_slist_append(bb->ips, (gchar *) rd->ip);
				}
			}

			bb->port_p2pj = port;

			/* Obtain the parameters from the text_record */
			clear_bonjour_buddy_values(bb);
			for(l = txt; l != NULL; l = l->next) {
				if (avahi_string_list_get_pair(l, &key, &value, &size) < 0)
					continue;
				set_bonjour_buddy_value(bb, key, value, size);
				/* TODO: Since we're using the glib allocator, I think we
				 * can use the values instead of re-copying them */
				avahi_free(key);
				avahi_free(value);
			}

			if (!bonjour_buddy_check(bb)) {
				b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd);
				_cleanup_resolver_data(rd);
				/* If this was the last resolver, remove the buddy */
				if (b_impl->resolvers == NULL) {
					if (pb != NULL)
						bonjour_buddy_signed_off(pb);
					else
						bonjour_buddy_delete(bb);
				}
			} else
				/* Add or update the buddy in our buddy list */
				bonjour_buddy_add_to_purple(bb, pb);

			break;
		default:
			purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event);
	}

}
Exemple #10
0
static void
skypeweb_got_info(SkypeWebAccount *sa, JsonNode *node, gpointer user_data)
{
	gchar *username = user_data;
	PurpleNotifyUserInfo *user_info;
	JsonObject *userobj;
	PurpleBuddy *buddy;
	SkypeWebBuddy *sbuddy;
	const gchar *new_avatar;
	
	if (node == NULL || json_node_get_node_type(node) != JSON_NODE_OBJECT)
		return;
	userobj = json_node_get_object(node);
	
	user_info = purple_notify_user_info_new();
	
#define _SKYPE_USER_INFO(prop, key) if (prop && json_object_has_member(userobj, (prop)) && !json_object_get_null_member(userobj, (prop))) \
	purple_notify_user_info_add_pair_html(user_info, _(key), json_object_get_string_member(userobj, (prop)));
	
	_SKYPE_USER_INFO("firstname", "First Name");
	_SKYPE_USER_INFO("lastname", "Last Name");
	_SKYPE_USER_INFO("birthday", "Birthday");
	//_SKYPE_USER_INFO("gender", "Gender");
	if (json_object_has_member(userobj, "gender") && !json_object_get_null_member(userobj, "gender")) {
		const gchar *gender = json_object_get_string_member(userobj, "gender");
		const gchar *gender_output;
		if (*gender == '1') {
			gender_output = _("Male");
		} else if (*gender == '2') {
			gender_output = _("Female");
		} else {
			gender_output = _("Unknown");
		}
		purple_notify_user_info_add_pair_html(user_info, _("Gender"), gender_output);
	}
	_SKYPE_USER_INFO("language", "Language");
	_SKYPE_USER_INFO("country", "Country");
	_SKYPE_USER_INFO("province", "Province");
	_SKYPE_USER_INFO("city", "City");
	_SKYPE_USER_INFO("homepage", "Homepage");
	_SKYPE_USER_INFO("about", "About");
	_SKYPE_USER_INFO("jobtitle", "Job Title");
	_SKYPE_USER_INFO("phoneMobile", "Phone - Mobile");
	_SKYPE_USER_INFO("phoneHome", "Phone - Home");
	_SKYPE_USER_INFO("phoneOffice", "Phone - Office");
	//_SKYPE_USER_INFO("mood", "Mood");
	//_SKYPE_USER_INFO("richMood", "Mood");
	//_SKYPE_USER_INFO("avatarUrl", "Avatar");
	
	buddy = purple_find_buddy(sa->account, username);
	if (buddy) {
		sbuddy = purple_buddy_get_protocol_data(buddy);
		if (sbuddy == NULL) {
			sbuddy = g_new0(SkypeWebBuddy, 1);
			purple_buddy_set_protocol_data(buddy, sbuddy);
			sbuddy->skypename = g_strdup(username);
			sbuddy->sa = sa;
		}
		
		new_avatar = json_object_get_string_member(userobj, "avatarUrl");
		if (new_avatar && (!sbuddy->avatar_url || !g_str_equal(sbuddy->avatar_url, new_avatar))) {
			g_free(sbuddy->avatar_url);
			sbuddy->avatar_url = g_strdup(new_avatar);			
			skypeweb_get_icon(buddy);
		}
		
		g_free(sbuddy->mood); sbuddy->mood = g_strdup(json_object_get_string_member(userobj, "mood"));
	}
	
	purple_notify_userinfo(sa->pc, username, user_info, NULL, NULL);
	
	g_free(username);
}
Exemple #11
0
/* process received extended (2007) text IM */
static void process_extend_im_text(PurpleConnection *gc, guint8 *data, gint len, qq_im_header *im_header)
{
	qq_data *qd;
	guint16 purple_msg_type;
	gchar *who;
	gchar *msg_smiley, *msg_fmt, *msg_utf8;
	PurpleBuddy *buddy;
	qq_buddy_data *bd;
	gint bytes, tail_len;
	qq_im_format *fmt = NULL;

	struct {
		/* now comes the part for text only */
		guint16 msg_seq;
		guint32 send_time;
		guint16 sender_icon;
		guint32 has_font_attr;
		guint8 unknown1[8];
		guint8 fragment_count;
		guint8 fragment_index;
		guint8 msg_id;
		guint8 unknown2;
		guint8 msg_type;
		gchar *msg;		/* no fixed length, ends with 0x00 */
		guint8 fromMobileQQ;
	} im_text;

	g_return_if_fail (data != NULL && len > 0);
	g_return_if_fail(im_header != NULL);

	qd = (qq_data *) gc->proto_data;
	memset(&im_text, 0, sizeof(im_text));

	/* qq_show_packet("Extend IM text", data, len); */
	bytes = 0;
	bytes += qq_get16(&(im_text.msg_seq), data + bytes);
	bytes += qq_get32(&(im_text.send_time), data + bytes);
	bytes += qq_get16(&(im_text.sender_icon), data + bytes);
	bytes += qq_get32(&(im_text.has_font_attr), data + bytes);
	bytes += qq_getdata(im_text.unknown1, sizeof(im_text.unknown1), data + bytes);
	bytes += qq_get8(&(im_text.fragment_count), data + bytes);
	bytes += qq_get8(&(im_text.fragment_index), data + bytes);
	bytes += qq_get8(&(im_text.msg_id), data + bytes);
	bytes += 1; 	/* skip 0x00 */
	bytes += qq_get8(&(im_text.msg_type), data + bytes);
	purple_debug_info("QQ", "IM Seq %u, id %04X, fragment %d-%d, type %d, %s\n",
			im_text.msg_seq, im_text.msg_id,
			im_text.fragment_count, im_text.fragment_index,
			im_text.msg_type,
			im_text.has_font_attr ? "exist font atrr" : "");

	if (im_text.has_font_attr) {
		fmt = qq_im_fmt_new();
		tail_len = qq_get_im_tail(fmt, data + bytes, len - bytes);
		im_text.msg = g_strndup((gchar *)(data + bytes), len - tail_len);
	} else	{
		im_text.msg = g_strndup((gchar *)(data + bytes), len - bytes);
	}
	/* qq_show_packet("IM text", (guint8 *)im_text.msg , strlen(im_text.msg)); */

	if(im_text.fragment_count == 0) 	im_text.fragment_count = 1;

	who = uid_to_purple_name(im_header->uid_from);
	buddy = purple_find_buddy(gc->account, who);
	if (buddy == NULL) {
		/* create no-auth buddy */
		buddy = qq_buddy_new(gc, im_header->uid_from);
	}
	bd = (buddy == NULL) ? NULL : purple_buddy_get_protocol_data(buddy);
	if (bd != NULL) {
		bd->client_tag = im_header->version_from;
		bd->face = im_text.sender_icon;
		qq_update_buddy_icon(gc->account, who, bd->face);
	}

	purple_msg_type = 0;

	msg_smiley = qq_emoticon_to_purple(im_text.msg);
	if (fmt != NULL) {
		msg_fmt = qq_im_fmt_to_purple(fmt, msg_smiley);
		msg_utf8 =  qq_to_utf8(msg_fmt, QQ_CHARSET_DEFAULT);
		g_free(msg_fmt);
		qq_im_fmt_free(fmt);
	} else {
		msg_utf8 =  qq_to_utf8(msg_smiley, QQ_CHARSET_DEFAULT);
	}
	g_free(msg_smiley);

	/* send encoded to purple, note that we use im_text.send_time,
	 * not the time we receive the message
	 * as it may have been delayed when I am not online. */
	serv_got_im(gc, who, msg_utf8, purple_msg_type, (time_t) im_text.send_time);

	g_free(msg_utf8);
	g_free(who);
	g_free(im_text.msg);
}
Exemple #12
0
/* a floating text when mouse is on the icon, show connection status here */
static void qq_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
{
	qq_buddy_data *bd;
	gchar *tmp;
	GString *str;

	g_return_if_fail(b != NULL);

	bd = purple_buddy_get_protocol_data(b);
	if (bd == NULL)
		return;

	/* if (PURPLE_BUDDY_IS_ONLINE(b) && bd != NULL) */
	if (bd->ip.s_addr != 0) {
		str = g_string_new(NULL);
		g_string_printf(str, "%s:%d", inet_ntoa(bd->ip), bd->port);
		if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) {
			g_string_append(str, " TCP");
		} else {
			g_string_append(str, " UDP");
		}
		g_string_free(str, TRUE);
	}

	tmp = g_strdup_printf("%d", bd->age);
	purple_notify_user_info_add_pair(user_info, _("Age"), tmp);
	g_free(tmp);

	switch (bd->gender) {
		case QQ_BUDDY_GENDER_GG:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Male"));
			break;
		case QQ_BUDDY_GENDER_MM:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Female"));
			break;
		case QQ_BUDDY_GENDER_UNKNOWN:
			purple_notify_user_info_add_pair(user_info, _("Gender"), _("Unknown"));
			break;
		default:
			tmp = g_strdup_printf("Error (%d)", bd->gender);
			purple_notify_user_info_add_pair(user_info, _("Gender"), tmp);
			g_free(tmp);
	}

	if (bd->level) {
		tmp = g_strdup_printf("%d", bd->level);
		purple_notify_user_info_add_pair(user_info, _("Level"), tmp);
		g_free(tmp);
	}

	str = g_string_new(NULL);
	if (bd->comm_flag & QQ_COMM_FLAG_QQ_MEMBER) {
		g_string_append( str, _("Member") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_QQ_VIP) {
		g_string_append( str, _(" VIP") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_TCP_MODE) {
		g_string_append( str, _(" TCP") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_MOBILE) {
		g_string_append( str, _(" FromMobile") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_BIND_MOBILE) {
		g_string_append( str, _(" BindMobile") );
	}
	if (bd->comm_flag & QQ_COMM_FLAG_VIDEO) {
		g_string_append( str, _(" Video") );
	}

	if (bd->ext_flag & QQ_EXT_FLAG_ZONE) {
		g_string_append( str, _(" Zone") );
	}
	purple_notify_user_info_add_pair(user_info, _("Flag"), str->str);

	g_string_free(str, TRUE);

#ifdef DEBUG
	tmp = g_strdup_printf( "%s (%04X)",
			qq_get_ver_desc(bd->client_tag),
			bd->client_tag );
	purple_notify_user_info_add_pair(user_info, _("Ver"), tmp);
	g_free(tmp);

	tmp = g_strdup_printf( "Ext 0x%X, Comm 0x%X",
			bd->ext_flag, bd->comm_flag );
	purple_notify_user_info_add_pair(user_info, _("Flag"), tmp);
	g_free(tmp);
#endif
}