changeset 1920:5bed3bc833b5

[gaim-migrate @ 1930] in addition, frombase64 mods, needed for buddy icon in toc. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Wed, 30 May 2001 18:26:52 +0000
parents 4dcaa4afc6c0
children a84a41ecf380
files ChangeLog plugins/jabber/jabber.c src/buddy_chat.c src/gaim.h src/prpl.h src/server.c src/toc.c src/util.c
diffstat 8 files changed, 171 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed May 30 07:59:35 2001 +0000
+++ b/ChangeLog	Wed May 30 18:26:52 2001 +0000
@@ -1,5 +1,8 @@
 GAIM: The Pimpin' Penguin IM Clone thats good for the soul! 
 
+version 0.11.0-pre13:
+	* Can view/set chat topic in Jabber (thanks faceprint)
+
 version 0.11.0-pre12 (05/29/2001):
 	* Fixed a funny bug with auto responses when queued messages
 	  are enabled.
--- a/plugins/jabber/jabber.c	Wed May 30 07:59:35 2001 +0000
+++ b/plugins/jabber/jabber.c	Wed May 30 18:26:52 2001 +0000
@@ -580,9 +580,9 @@
 
 static void jabber_handlemessage(gjconn j, jpacket p)
 {
-	xmlnode y, xmlns;
+	xmlnode y, xmlns, subj;
 
-	char *from = NULL, *msg = NULL, *type = NULL;
+	char *from = NULL, *msg = NULL, *type = NULL, *topic = NULL;
 	char m[BUF_LONG * 2];
 
 	type = xmlnode_get_attrib(p->x, "type");
@@ -658,6 +658,11 @@
 		}
 
 		msg = utf8_to_str(msg);
+		
+		if ((subj = xmlnode_get_tag(p->x, "subject"))) {
+		   	topic = xmlnode_get_data(subj);
+		} 
+		topic = utf8_to_str(topic);
 
 		jc = find_existing_chat(GJ_GC(j), p->from);
 		if (!jc) {
@@ -688,12 +693,27 @@
 				}
 			} else if (jc->b && msg) {
 				char buf[8192];
+
+				if (topic) {
+					char tbuf[8192];
+					g_snprintf(tbuf, sizeof(tbuf), "%s", topic);
+					chat_set_topic(jc->b, p->from->resource, tbuf);
+				}
+				
+
 				g_snprintf(buf, sizeof(buf), "%s", msg);
 				serv_got_chat_in(GJ_GC(j), jc->b->id, p->from->resource, 0, buf, time(NULL));
 			}
+		} else { /* message from the server */
+		   	if(jc->b && topic) {
+			   	char tbuf[8192];
+				g_snprintf(tbuf, sizeof(tbuf), "%s", topic);
+				chat_set_topic(jc->b, "", tbuf);
+			}
 		}
 
 		free(msg);
+		free(topic);
 
 	} else {
 		debug_printf("unhandled message %s\n", type);
@@ -1499,6 +1519,54 @@
 	xmlnode_free(x);
 }
 
+static void jabber_chat_set_topic(struct gaim_connection *gc, int id, char *topic)
+{
+	GSList *bcs = gc->buddy_chats;
+	struct conversation *b;
+	struct jabber_data *jd = gc->proto_data;
+	xmlnode x, y;
+	struct jabber_chat *jc;
+	char *chatname;
+	char buf[8192];
+
+	while (bcs) {
+		b = bcs->data;
+		if (id == b->id)
+			break;
+		bcs = bcs->next;
+	}
+	if (!bcs)
+		return;
+
+	bcs = jd->existing_chats;
+	while (bcs) {
+		jc = bcs->data;
+		if (jc->b == b)
+			break;
+		bcs = bcs->next;
+	}
+	if (!bcs)
+		return;
+
+	x = xmlnode_new_tag("message");
+	xmlnode_put_attrib(x, "from", jid_full(jc->Jid));
+	chatname = g_strdup_printf("%s@%s", jc->Jid->user, jc->Jid->server);
+	xmlnode_put_attrib(x, "to", chatname);
+	g_free(chatname);
+	xmlnode_put_attrib(x, "type", "groupchat");
+
+	if (topic && strlen(topic)) {
+		y = xmlnode_insert_tag(x, "subject");
+		xmlnode_insert_cdata(y, topic, -1);
+		y = xmlnode_insert_tag(x, "body");
+		g_snprintf(buf, sizeof(buf), "/me has changed the subject to: %s", topic);
+		xmlnode_insert_cdata(y, buf, -1);
+	}
+
+	gjab_send(((struct jabber_data *)gc->proto_data)->jc, x);
+	xmlnode_free(x);
+}
+
 static void jabber_chat_whisper(struct gaim_connection *gc, int id, char *who, char *message)
 {
 	GSList *bcs = gc->buddy_chats;
@@ -1943,6 +2011,7 @@
 	ret->chat_invite = jabber_chat_invite;
 	ret->chat_leave = jabber_chat_leave;
 	ret->chat_whisper = jabber_chat_whisper;
+	ret->chat_set_topic = jabber_chat_set_topic;
 	ret->chat_send = jabber_chat_send;
 	ret->keepalive = NULL;
 	ret->normalize = jabber_normalize;
--- a/src/buddy_chat.c	Wed May 30 07:59:35 2001 +0000
+++ b/src/buddy_chat.c	Wed May 30 18:26:52 2001 +0000
@@ -441,6 +441,13 @@
 
 }
 
+void topic_callback(GtkWidget *widget, struct conversation *b) {
+   	char *buf = gtk_entry_get_text(GTK_ENTRY(widget));;
+
+	serv_chat_set_topic(b->gc, b->id, buf);
+
+	g_free(buf);
+}
 
 static gint insertname(gconstpointer one, gconstpointer two)
 {
@@ -831,7 +838,7 @@
 		gtk_notebook_append_page(GTK_NOTEBOOK(chat_notebook), cont, gtk_label_new(b->name));
 		gtk_widget_show(cont);
 	} else {
-		cont = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+		win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 		b->window = win;
 		gtk_object_set_user_data(GTK_OBJECT(win), b);
 		gtk_window_set_wmclass(GTK_WINDOW(win), "buddy_chat", "Gaim");
@@ -842,6 +849,29 @@
 		g_snprintf(buf, sizeof(buf), "Gaim - %s (chat)", b->name);
 		gtk_window_set_title(GTK_WINDOW(win), buf);
 		gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(close_callback), b);
+
+		cont = gtk_vbox_new(FALSE,5);
+		gtk_container_add(GTK_CONTAINER(win), cont);
+		gtk_widget_show(cont);
+	}
+
+	if (b->gc->prpl->options & OPT_PROTO_CHAT_TOPIC) {
+		GtkWidget *hbox;
+		GtkWidget *label;
+
+		hbox = gtk_hbox_new(FALSE, 0);
+		gtk_box_pack_start(GTK_BOX(cont), hbox, FALSE, FALSE, 5);
+		gtk_widget_show(hbox);
+
+		label = gtk_label_new(_("Topic:"));
+		gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
+		gtk_widget_show(label);
+
+		b->topic_text = gtk_entry_new();
+		gtk_signal_connect(GTK_OBJECT(b->topic_text), "activate",
+				   GTK_SIGNAL_FUNC(topic_callback), b);
+		gtk_box_pack_start(GTK_BOX(hbox), b->topic_text, TRUE, TRUE, 5);
+		gtk_widget_show(b->topic_text);
 	}
 
 	vpaned = gtk_vpaned_new();
@@ -979,6 +1009,14 @@
 	gtk_widget_show(win);
 }
 
+void chat_set_topic(struct conversation *b, char* who, char* topic) {
+
+	debug_printf("event_chat_topic: \"%s\" \"%s\" %s\n", b->name, who, topic);
+
+	gtk_entry_set_text(GTK_ENTRY(b->topic_text), topic);
+
+}
+
 
 
 void handle_click_chat(GtkWidget *widget, GdkEventButton * event, struct chat_room *cr)
--- a/src/gaim.h	Wed May 30 07:59:35 2001 +0000
+++ b/src/gaim.h	Wed May 30 18:26:52 2001 +0000
@@ -376,6 +376,7 @@
 	GtkWidget *whisper;
 	GtkWidget *invite;
 	GtkWidget *close;
+	GtkWidget *topic_text;
 
 	/* something to distinguish */
 	gboolean is_chat;
@@ -590,6 +591,7 @@
 extern void update_im_tabs();
 extern void update_idle_times();
 extern void do_join_chat();
+extern void chat_set_topic(struct conversation*, char*, char*);
 
 /* Functions in html.c */
 extern struct g_url parse_url(char *);
@@ -604,8 +606,8 @@
 extern int escape_text(char *);
 extern char *escape_text2(char *);
 extern int escape_message(char *msg);
-extern char *tobase64(char *);
-extern char *frombase64(char *);
+extern char *tobase64(const char *);
+extern void frombase64(const char *, char **, int *);
 extern gint clean_pid(void *);
 extern char *date();
 extern gint linkify_text(char *);
@@ -664,6 +666,7 @@
 extern void serv_chat_leave(struct gaim_connection *, int);
 extern void serv_chat_whisper(struct gaim_connection *, int, char *, char *);
 extern void serv_chat_send(struct gaim_connection *, int, char *);
+extern void serv_chat_set_topic(struct gaim_connection *, int, char *);
 extern void update_keepalive(struct gaim_connection *, gboolean);
 
 /* output from serv */
--- a/src/prpl.h	Wed May 30 07:59:35 2001 +0000
+++ b/src/prpl.h	Wed May 30 18:26:52 2001 +0000
@@ -126,6 +126,7 @@
 	void (* chat_whisper)	(struct gaim_connection *, int id, char *who, char *message);
 	void (* chat_send)	(struct gaim_connection *, int id, char *message);
 	void (* keepalive)	(struct gaim_connection *);
+	void (* chat_set_topic) (struct gaim_connection *, int id, char *topic);
 
 	char *(* normalize)(const char *);
 };
--- a/src/server.c	Wed May 30 07:59:35 2001 +0000
+++ b/src/server.c	Wed May 30 18:26:52 2001 +0000
@@ -303,6 +303,12 @@
 		(*g->prpl->chat_whisper)(g, id, who, message);
 }
 
+void serv_chat_set_topic(struct gaim_connection *g, int id, char *topic) 
+{
+   	if (g->prpl && g->prpl->chat_set_topic)
+	   	(*g->prpl->chat_set_topic)(g, id, topic);
+}
+
 void serv_chat_send(struct gaim_connection *g, int id, char *message)
 {
 	if (g->prpl && g->prpl->chat_send)
--- a/src/toc.c	Wed May 30 07:59:35 2001 +0000
+++ b/src/toc.c	Wed May 30 18:26:52 2001 +0000
@@ -92,6 +92,13 @@
         int size;
 };
 
+struct buddy_icon {
+	guint32 hash;
+	guint32 len;
+	time_t time;
+	void *data;
+};
+
 struct toc_data {
 	int toc_fd;
 	int seqno;
@@ -381,6 +388,10 @@
 		g_snprintf(snd, sizeof snd, "toc_init_done");
 		sflap_send(gc, snd, -1, TYPE_DATA);
 
+		/*
+		g_snprintf(snd, sizeof snd, "toc_set_caps %s %s %s",
+				FILE_SEND_UID, FILE_GET_UID, B_ICON_UID);
+		*/
 		g_snprintf(snd, sizeof snd, "toc_set_caps %s %s", FILE_SEND_UID, FILE_GET_UID);
 		sflap_send(gc, snd, -1, TYPE_DATA);
 
@@ -616,9 +627,9 @@
 				sscanf(strtok(NULL, ":"), "%d", &unk[i]);
 				if (unk[i] == 10001)
 					break;
-				messages[i] = frombase64(strtok(NULL, ":"));
+				frombase64(strtok(NULL, ":"), &messages[i], NULL);
 			}
-			tmp = frombase64(strtok(NULL, ":"));
+			frombase64(strtok(NULL, ":"), &tmp, NULL);
 
 			subtype = tmp[1];
 			files = tmp[3];
@@ -670,9 +681,9 @@
 				sscanf(strtok(NULL, ":"), "%d", unk + i);
 				if (unk[i] == 10001)
 					break;
-				messages[i] = frombase64(strtok(NULL, ":"));
+				frombase64(strtok(NULL, ":"), &messages[i], NULL);
 			}
-			tmp = frombase64(strtok(NULL, ":"));
+			frombase64(strtok(NULL, ":"), &tmp, NULL);
 
 			ft = g_new0(struct ft_request, 1);
 			ft->cookie = g_strdup(cookie);
@@ -694,7 +705,24 @@
 		} else if (!strcmp(uuid, VOICE_UID)) {
 			/* oh goody. voice over ip. fun stuff. */
 		} else if (!strcmp(uuid, B_ICON_UID)) {
-			/* buddy icon... */
+			/*
+			int unk[4], i;
+			char *messages[4];
+			struct buddy_icon *icon;
+
+			for (i = 0; i < 4; i++) {
+				sscanf(strtok(NULL, ":"), "%d", unk + i);
+				if (unk[i] == 10001)
+					break;
+				frombase64(strtok(NULL, ":"), &messages[i], NULL);
+			}
+			frombase64(strtok(NULL, ":"), (char **)&icon, NULL);
+
+			debug_printf("received icon of length %d\n", icon->len);
+			g_free(icon);
+			for (i--; i >= 0; i--)
+				g_free(messages[i]);
+			*/
 		} else if (!strcmp(uuid, IMAGE_UID)) {
 			/* aka Direct IM */
 		} else {
@@ -1362,7 +1390,8 @@
 	}
 
 	if (ft->hdr.hdrtype != 0x202) {
-		char *buf = frombase64(ft->cookie);
+		char *buf;
+		frombase64(ft->cookie, &buf, NULL);
 
 		read(source, ft, 8);
 		read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8));
@@ -1646,7 +1675,7 @@
 	hdr->magic[0] = 'O'; hdr->magic[1] = 'F'; hdr->magic[2] = 'T'; hdr->magic[3] = '2';
 	hdr->hdrlen = htons(256);
 	hdr->hdrtype = htons(0x1108);
-	buf = frombase64(ft->cookie);
+	frombase64(ft->cookie, &buf, NULL);
 	g_snprintf(hdr->bcookie, 8, "%s", buf);
 	g_free(buf);
 	hdr->totfiles = htons(1); hdr->filesleft = htons(1);
--- a/src/util.c	Wed May 30 07:59:35 2001 +0000
+++ b/src/util.c	Wed May 30 18:26:52 2001 +0000
@@ -590,10 +590,10 @@
 char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
 
 
-char *tobase64(char *text)
+char *tobase64(const char *text)
 {
 	char *out = NULL;
-	char *c;
+	const char *c;
 	unsigned int tmp = 0;
 	int len = 0, n = 0;
 
@@ -645,14 +645,17 @@
 }
 
 
-char *frombase64(char *text)
+void frombase64(const char *text, char **data, int *size)
 {
 	char *out = NULL;
 	char tmp = 0;
-	char *c;
+	const char *c;
 	gint32 tmp2 = 0;
 	int len = 0, n = 0;
 
+	if (!text || !data)
+		return;
+
 	c = text;
 
 	while (*c) {
@@ -699,7 +702,9 @@
 	out = g_realloc(out, len + 1);
 	out[len] = 0;
 
-	return out;
+	*data = out;
+	if (size)
+		*size = len;
 }
 
 void put_out(struct gaim_connection *gc, char *buf, char *(*fun)())