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

📄 yahoochat.c

📁 yahoo message protocol stack
💻 C
📖 第 1 页 / 共 3 页
字号:
			serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)),					gaim_connection_get_display_name(gc), 0, what, time(NULL));	}	return ret;}GList *yahoo_c_info(GaimConnection *gc){	GList *m = NULL;	struct proto_chat_entry *pce;	pce = g_new0(struct proto_chat_entry, 1);	pce->label = _("_Room:");	pce->identifier = "room";	m = g_list_append(m, pce);	return m;}GHashTable *yahoo_c_info_defaults(GaimConnection *gc, const char *chat_name){	GHashTable *defaults;	defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);	if (chat_name != NULL)		g_hash_table_insert(defaults, "room", g_strdup(chat_name));	return defaults;}char *yahoo_get_chat_name(GHashTable *data){	return g_strdup(g_hash_table_lookup(data, "room"));}void yahoo_c_join(GaimConnection *gc, GHashTable *data){	struct yahoo_data *yd;	char *room, *topic, *members, *type;	int id;	GaimConversation *c;	yd = (struct yahoo_data *) gc->proto_data;	if (!yd)		return;	room = g_hash_table_lookup(data, "room");	if (!room)		return;	topic = g_hash_table_lookup(data, "topic");	if (!topic)		topic = "";	members = g_hash_table_lookup(data, "members");	if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) {		id = yd->conf_id++;		c = serv_got_joined_chat(gc, id, room);		yd->confs = g_slist_prepend(yd->confs, c);		gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), gaim_connection_get_display_name(gc), topic);		yahoo_conf_join(yd, c, gaim_connection_get_display_name(gc), room, topic, members);		return;	} else {		if (yd->in_chat)			yahoo_chat_leave(gc, room,					gaim_connection_get_display_name(gc),					FALSE);		if (!yd->chat_online)			yahoo_chat_online(gc);		yahoo_chat_join(gc, gaim_connection_get_display_name(gc), room, topic);		return;	}}void yahoo_c_invite(GaimConnection *gc, int id, const char *msg, const char *name){	GaimConversation *c;	c = gaim_find_chat(gc, id);	if (!c || !c->name)		return;	if (id != YAHOO_CHAT_ID) {		yahoo_conf_invite(gc, c, gaim_connection_get_display_name(gc), name,							gaim_conversation_get_name(c), msg);	} else {		yahoo_chat_invite(gc, gaim_connection_get_display_name(gc), name,							gaim_conversation_get_name(c), msg);	}}struct yahoo_roomlist {	int fd;	int inpa;	guchar *rxqueue;	int rxlen;	gboolean started;	char *path;	char *host;	GaimRoomlist *list;	GaimRoomlistRoom *cat;	GaimRoomlistRoom *ucat;	GMarkupParseContext *parse;};static void yahoo_roomlist_destroy(struct yahoo_roomlist *yrl){	if (yrl->inpa)		gaim_input_remove(yrl->inpa);	if (yrl->rxqueue)		g_free(yrl->rxqueue);	if (yrl->path)		g_free(yrl->path);	if (yrl->host)		g_free(yrl->host);	if (yrl->parse)		g_markup_parse_context_free(yrl->parse);}enum yahoo_room_type {	yrt_yahoo,	yrt_user,};struct yahoo_chatxml_state {	GaimRoomlist *list;	struct yahoo_roomlist *yrl;	GQueue *q;	struct {		enum yahoo_room_type type;		char *name;		char *topic;		char *id;		int users, voices, webcams;	} room;};struct yahoo_lobby {	int count, users, voices, webcams;};static struct yahoo_chatxml_state *yahoo_chatxml_state_new(GaimRoomlist *list, struct yahoo_roomlist *yrl){	struct yahoo_chatxml_state *s;	s = g_new0(struct yahoo_chatxml_state, 1);	s->list = list;	s->yrl = yrl;	s->q = g_queue_new();	return s;}static void yahoo_chatxml_state_destroy(struct yahoo_chatxml_state *s){	g_queue_free(s->q);	if (s->room.name)		g_free(s->room.name);	if (s->room.topic)		g_free(s->room.topic);	if (s->room.id)		g_free(s->room.id);	g_free(s);}static void yahoo_chatlist_start_element(GMarkupParseContext *context, const gchar *ename,                                  const gchar **anames, const gchar **avalues,                                  gpointer user_data, GError **error){	struct yahoo_chatxml_state *s = user_data;	GaimRoomlist *list = s->list;	GaimRoomlistRoom *r;	GaimRoomlistRoom *parent;	int i;	if (!strcmp(ename, "category")) {		const gchar *name = NULL, *id = NULL;		for (i = 0; anames[i]; i++) {			if (!strcmp(anames[i], "id"))				id = avalues[i];			if (!strcmp(anames[i], "name"))				name = avalues[i];		}		if (!name || !id)			return;		parent = g_queue_peek_head(s->q);		r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, name, parent);		gaim_roomlist_room_add_field(list, r, (gpointer)name);		gaim_roomlist_room_add_field(list, r, (gpointer)id);		gaim_roomlist_room_add(list, r);		g_queue_push_head(s->q, r);	} else if (!strcmp(ename, "room")) {		s->room.users = s->room.voices = s->room.webcams = 0;		for (i = 0; anames[i]; i++) {			if (!strcmp(anames[i], "id")) {				if (s->room.id)					g_free(s->room.id);				s->room.id = g_strdup(avalues[i]);			} else if (!strcmp(anames[i], "name")) {				if (s->room.name)					g_free(s->room.name);				s->room.name = g_strdup(avalues[i]);			} else if (!strcmp(anames[i], "topic")) {				if (s->room.topic)					g_free(s->room.topic);				s->room.topic = g_strdup(avalues[i]);			} else if (!strcmp(anames[i], "type")) {				if (!strcmp("yahoo", avalues[i]))					s->room.type = yrt_yahoo;				else					s->room.type = yrt_user;			}		}	} else if (!strcmp(ename, "lobby")) {		struct yahoo_lobby *lob = g_new0(struct yahoo_lobby, 1);		for (i = 0; anames[i]; i++) {			if (!strcmp(anames[i], "count")) {				lob->count = strtol(avalues[i], NULL, 10);			} else if (!strcmp(anames[i], "users")) {				s->room.users += lob->users = strtol(avalues[i], NULL, 10);			} else if (!strcmp(anames[i], "voices")) {				s->room.voices += lob->voices = strtol(avalues[i], NULL, 10);			} else if (!strcmp(anames[i], "webcams")) {				s->room.webcams += lob->webcams = strtol(avalues[i], NULL, 10);			}		}		g_queue_push_head(s->q, lob);	}}static void yahoo_chatlist_end_element(GMarkupParseContext *context, const gchar *ename,                                       gpointer user_data, GError **error){	struct yahoo_chatxml_state *s = user_data;	if (!strcmp(ename, "category")) {		g_queue_pop_head(s->q);	} else if (!strcmp(ename, "room")) {		struct yahoo_lobby *lob;		GaimRoomlistRoom *r, *l;		if (s->room.type == yrt_yahoo)			r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY|GAIM_ROOMLIST_ROOMTYPE_ROOM,		                                   s->room.name, s->yrl->cat);		else			r = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY|GAIM_ROOMLIST_ROOMTYPE_ROOM,		                                   s->room.name, s->yrl->ucat);		gaim_roomlist_room_add_field(s->list, r, s->room.name);		gaim_roomlist_room_add_field(s->list, r, s->room.id);		gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.users));		gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.voices));		gaim_roomlist_room_add_field(s->list, r, GINT_TO_POINTER(s->room.webcams));		gaim_roomlist_room_add_field(s->list, r, s->room.topic);		gaim_roomlist_room_add(s->list, r);		while ((lob = g_queue_pop_head(s->q))) {			char *name = g_strdup_printf("%s:%d", s->room.name, lob->count);			l = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_ROOM, name, r);			gaim_roomlist_room_add_field(s->list, l, name);			gaim_roomlist_room_add_field(s->list, l, s->room.id);			gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->users));			gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->voices));			gaim_roomlist_room_add_field(s->list, l, GINT_TO_POINTER(lob->webcams));			gaim_roomlist_room_add_field(s->list, l, s->room.topic);			gaim_roomlist_room_add(s->list, l);			g_free(name);			g_free(lob);		}	}}static GMarkupParser parser = {	yahoo_chatlist_start_element,	yahoo_chatlist_end_element,	NULL,	NULL,	NULL};static void yahoo_roomlist_cleanup(GaimRoomlist *list, struct yahoo_roomlist *yrl){	gaim_roomlist_set_in_progress(list, FALSE);	if (yrl) {		list->proto_data = g_list_remove(list->proto_data, yrl);		yahoo_roomlist_destroy(yrl);	}	gaim_roomlist_unref(list);}static void yahoo_roomlist_pending(gpointer data, gint source, GaimInputCondition cond){	struct yahoo_roomlist *yrl = data;	GaimRoomlist *list = yrl->list;	char buf[1024];	int len;	guchar *start;	struct yahoo_chatxml_state *s;	len = read(yrl->fd, buf, sizeof(buf));	if (len <= 0) {		if (yrl->parse)			g_markup_parse_context_end_parse(yrl->parse, NULL);		yahoo_roomlist_cleanup(list, yrl);		return;	}	yrl->rxqueue = g_realloc(yrl->rxqueue, len + yrl->rxlen);	memcpy(yrl->rxqueue + yrl->rxlen, buf, len);	yrl->rxlen += len;	if (!yrl->started) {		yrl->started = TRUE;		start = g_strstr_len(yrl->rxqueue, yrl->rxlen, "\r\n\r\n");		if (!start || (start - yrl->rxqueue + 4) >= yrl->rxlen)			return;		start += 4;	} else {		start = yrl->rxqueue;	}	if (yrl->parse == NULL) {		s = yahoo_chatxml_state_new(list, yrl);		yrl->parse = g_markup_parse_context_new(&parser, 0, s,		             (GDestroyNotify)yahoo_chatxml_state_destroy);	}	if (!g_markup_parse_context_parse(yrl->parse, start, (yrl->rxlen - (start - yrl->rxqueue)), NULL)) {		yahoo_roomlist_cleanup(list, yrl);		return;	}	yrl->rxlen = 0;}static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond){	struct yahoo_roomlist *yrl = data;	GaimRoomlist *list = yrl->list;	char *buf, *cookie;	struct yahoo_data *yd = gaim_account_get_connection(list->account)->proto_data;	if (source < 0) {		gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed."));		yahoo_roomlist_cleanup(list, yrl);		return;	}	yrl->fd = source;	cookie = g_strdup_printf("Y=%s; T=%s", yd->cookie_y, yd->cookie_t);	buf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\nCookie: %s\r\n\r\n", yrl->path, yrl->host, cookie);	write(yrl->fd, buf, strlen(buf));	g_free(cookie);	g_free(buf);	yrl->inpa = gaim_input_add(yrl->fd, GAIM_INPUT_READ, yahoo_roomlist_pending, yrl);}GaimRoomlist *yahoo_roomlist_get_list(GaimConnection *gc){	struct yahoo_roomlist *yrl;	GaimRoomlist *rl;	char *url;	GList *fields = NULL;	GaimRoomlistField *f;	url = g_strdup_printf("%s?chatcat=0",	                      gaim_account_get_string(	                      gaim_connection_get_account(gc),	                      "room_list", YAHOO_ROOMLIST_URL));	yrl = g_new0(struct yahoo_roomlist, 1);	rl = gaim_roomlist_new(gaim_connection_get_account(gc));	yrl->list = rl;	gaim_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);	g_free(url);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "room", TRUE);	fields = g_list_append(fields, f);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "id", TRUE);	fields = g_list_append(fields, f);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE);	fields = g_list_append(fields, f);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Voices"), "voices", FALSE);	fields = g_list_append(fields, f);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Webcams"), "webcams", FALSE);	fields = g_list_append(fields, f);	f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE);	fields = g_list_append(fields, f);	gaim_roomlist_set_fields(rl, fields);	if (gaim_proxy_connect(gaim_connection_get_account(gc),	                       yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0)	{		gaim_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list."));		yahoo_roomlist_cleanup(rl, yrl);		return NULL;	}	rl->proto_data = g_list_append(rl->proto_data, yrl);	gaim_roomlist_set_in_progress(rl, TRUE);	return rl;}void yahoo_roomlist_cancel(GaimRoomlist *list){	GList *l, *k;	k = l = list->proto_data;	list->proto_data = NULL;	gaim_roomlist_set_in_progress(list, FALSE);	for (; l; l = l->next) {		yahoo_roomlist_destroy(l->data);		gaim_roomlist_unref(l->data);	}	g_list_free(k);}void yahoo_roomlist_expand_category(GaimRoomlist *list, GaimRoomlistRoom *category){	struct yahoo_roomlist *yrl;	char *url;	char *id;	if (category->type != GAIM_ROOMLIST_ROOMTYPE_CATEGORY)		return;	if (!(id = g_list_nth_data(category->fields, 1))) {		gaim_roomlist_set_in_progress(list, FALSE);		return;	}	url = g_strdup_printf("%s?chatroom_%s=0",	                      gaim_account_get_string(	                      list->account,	                      "room_list", YAHOO_ROOMLIST_URL), id);	yrl = g_new0(struct yahoo_roomlist, 1);	yrl->list = list;	yrl->cat = category;	list->proto_data = g_list_append(list->proto_data, yrl);	gaim_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL);	g_free(url);	yrl->ucat = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat);	gaim_roomlist_room_add(list, yrl->ucat);	if (gaim_proxy_connect(list->account,	                       yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0)	{		gaim_notify_error(gaim_account_get_connection(list->account),		                  NULL, _("Connection problem"), _("Unable to fetch room list."));		yahoo_roomlist_cleanup(list, yrl);		return;	}	gaim_roomlist_set_in_progress(list, TRUE);	gaim_roomlist_ref(list);}

⌨️ 快捷键说明

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