changeset 9933:cee849d17167

[gaim-migrate @ 10825] Another patch from Dave West. This makes the file transfer message show up when someone sends you an AIM file transfer. It also attempts to decode the message to UTF-8. The chat invitation messages also benefit from this attempted conversion. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 02 Sep 2004 03:46:53 +0000
parents 3fa121db91d0
children 31fddde685dd
files ChangeLog src/ft.c src/ft.h src/protocols/oscar/aim.h src/protocols/oscar/im.c src/protocols/oscar/oscar.c src/protocols/oscar/tlv.c src/server.c
diffstat 8 files changed, 102 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Sep 02 02:49:00 2004 +0000
+++ b/ChangeLog	Thu Sep 02 03:46:53 2004 +0000
@@ -6,6 +6,10 @@
 	* View Chat log available from the interface (Daniel Atallah)
 	* Ability to receive offline messages in character encodings
 	  other than ASCII (thanks to Nick Sukharev)
+	* File transfer status messages printed to conversation
+	  windows (Dave West)
+	* Display file transfer messages when someone sends you a file
+	  over AIM (Dave West)
 
 	Bug Fixes:
 	* Compile with gtk 2.5.x (Gary Kramlich)
--- a/src/ft.c	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/ft.c	Thu Sep 02 03:46:53 2004 +0000
@@ -50,6 +50,7 @@
 	xfer->account = account;
 	xfer->who     = g_strdup(who);
 	xfer->ui_ops  = gaim_xfers_get_ui_ops();
+	xfer->message = NULL;
 
 	ui_ops = gaim_xfer_get_ui_ops(xfer);
 
@@ -259,9 +260,14 @@
 				      size_buf);
 		g_free(size_buf);
 
+		if (xfer->message != NULL)
+			serv_got_im(gaim_account_get_connection(xfer->account),
+								 xfer->who, xfer->message, 0, time(NULL));
+
 		gaim_request_accept_cancel(xfer, NULL, buf, NULL, 0, xfer,
 					   G_CALLBACK(gaim_xfer_choose_file),
 					   G_CALLBACK(cancel_recv_cb));
+
 		g_free(buf);
 	} else
 		gaim_xfer_choose_file(xfer);
@@ -524,6 +530,19 @@
 }
 
 void
+gaim_xfer_set_message(GaimXfer *xfer, const char *message)
+{
+	g_return_if_fail(xfer != NULL);
+
+	g_free(xfer->message);
+
+	if (message != NULL)
+		xfer->message = g_strdup(message);
+	else
+		xfer->message = NULL;
+}
+
+void
 gaim_xfer_set_filename(GaimXfer *xfer, const char *filename)
 {
 	g_return_if_fail(xfer != NULL);
--- a/src/ft.h	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/ft.h	Thu Sep 02 03:46:53 2004 +0000
@@ -87,6 +87,7 @@
 	char *who;                    /**< The person on the other end of the
 	                                   transfer.                           */
 
+	char *message;                /**< A message sent with the request     */
 	char *filename;               /**< The name sent over the network.     */
 	char *local_filename;         /**< The name on the local hard drive.   */
 	size_t size;                  /**< The size of the file.               */
@@ -336,6 +337,14 @@
  * Sets the filename for the file transfer.
  *
  * @param xfer     The file transfer.
+ * @param message The message.
+ */
+void gaim_xfer_set_message(GaimXfer *xfer, const char *message);
+
+/**
+ * Sets the filename for the file transfer.
+ *
+ * @param xfer     The file transfer.
  * @param filename The filename.
  */
 void gaim_xfer_set_filename(GaimXfer *xfer, const char *filename);
--- a/src/protocols/oscar/aim.h	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/protocols/oscar/aim.h	Thu Sep 02 03:46:53 2004 +0000
@@ -818,6 +818,7 @@
 	fu16_t port;
 	fu16_t errorcode;
 	const char *msg; /* invite message or file description */
+	fu16_t msglen;
 	const char *encoding;
 	const char *language;
 	union {
@@ -1380,6 +1381,7 @@
 
 /* TLV handling functions */
 faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, fu16_t type, const int nth);
+faim_internal int aim_tlv_getlength(aim_tlvlist_t *list, fu16_t type, const int nth);
 faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth);
 faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth);
 faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth);
--- a/src/protocols/oscar/im.c	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/protocols/oscar/im.c	Thu Sep 02 03:46:53 2004 +0000
@@ -1828,8 +1828,10 @@
 	/*
 	 * Invitation message / chat description.
 	 */
-	if (aim_tlv_gettlv(list2, 0x000c, 1))
+	if (aim_tlv_gettlv(list2, 0x000c, 1)) {
 		args.msg = aim_tlv_getstr(list2, 0x000c, 1);
+		args.msglen = aim_tlv_getlength(list2, 0x000c, 1);
+	}
 
 	/*
 	 * Character set.
--- a/src/protocols/oscar/oscar.c	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/protocols/oscar/oscar.c	Thu Sep 02 03:46:53 2004 +0000
@@ -352,6 +352,8 @@
 	gchar *ret = NULL;
 	char *begin, *end;
 
+	g_return_val_if_fail(encoding != NULL, NULL);
+
 	/* Make sure encoding begins with charset= */
 	if (strncmp(encoding, "text/aolrtf; charset=", 21))
 		return NULL;
@@ -3281,29 +3283,47 @@
 
 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
 	GaimConnection *gc;
+	GaimAccount *account;
 	OscarData *od;
-	const char *username;
+	const char *username = NULL;
+	char *message = NULL;
 
 	g_return_val_if_fail(sess != NULL, 0);
 	g_return_val_if_fail(sess->aux_data != NULL, 0);
 
 	gc = sess->aux_data;
+	account = gaim_connection_get_account(gc);
 	od = gc->proto_data;
-	username = gaim_account_get_username(gaim_connection_get_account(gc));
-
-	if (!args)
+	username = gaim_account_get_username(account);
+
+	if (args == NULL)
 		return 0;
 
-	gaim_debug_misc("oscar",
-			   "rendezvous with %s, status is %hu\n",
-			   userinfo->sn, args->status);
+	gaim_debug_misc("oscar", "rendezvous with %s, status is %hu\n",
+					userinfo->sn, args->status);
+
+	if (args->msg != NULL)
+	{
+		if (args->encoding != NULL)
+		{
+			char *encoding = NULL;
+			encoding = oscar_encoding_extract(args->encoding);
+			message = oscar_encoding_to_utf8(encoding, args->msg, args->msglen);
+			g_free(encoding);
+		} else {
+			if (g_utf8_validate(args->msg, args->msglen, NULL))
+				message = g_strdup(args->msg);
+		}
+	}
 
 	if (args->reqclass & AIM_CAPS_CHAT) {
 		char *name;
 		GHashTable *components;
 
-		if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange || !args->msg)
+		if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange) {
+			g_free(message);
 			return 1;
+		}
 		components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
 				g_free);
 		name = extract_name(args->info.chat.roominfo.name);
@@ -3312,7 +3332,7 @@
 		serv_got_chat_invite(gc,
 				     name ? name : args->info.chat.roominfo.name,
 				     userinfo->sn,
-				     args->msg,
+				     message,
 				     components);
 		if (name)
 			g_free(name);
@@ -3333,6 +3353,7 @@
 					gaim_debug_warning("oscar",
 							   "IP for a proxy server was given.  Gaim "
 							   "does not support this yet.\n");
+				g_free(message);
 				return 1;
 			}
 
@@ -3355,6 +3376,7 @@
 			xfer->remote_port = args->port;
 			gaim_xfer_set_filename(xfer, args->info.sendfile.filename);
 			gaim_xfer_set_size(xfer, args->info.sendfile.totsize);
+			gaim_xfer_set_message(xfer, message);
 
 			/* Create the oscar-specific data */
 			oft_info = aim_oft_createinfo(od->sess, args->cookie, userinfo->sn, args->clientip, xfer->remote_port, 0, 0, NULL);
@@ -3371,11 +3393,6 @@
 			gaim_xfer_set_cancel_recv_fnc(xfer, oscar_xfer_cancel_recv);
 			gaim_xfer_set_ack_fnc(xfer, oscar_xfer_ack_recv);
 
-			/*
-			 * XXX - Should do something with args->msg, args->encoding, and args->language
-			 *       probably make it apply to all ch2 messages.
-			 */
-
 			/* Keep track of this transfer for later */
 			od->file_transfers = g_slist_append(od->file_transfers, xfer);
 
@@ -3402,8 +3419,8 @@
 	} else if (args->reqclass & AIM_CAPS_GETFILE) {
 	} else if (args->reqclass & AIM_CAPS_TALK) {
 	} else if (args->reqclass & AIM_CAPS_BUDDYICON) {
-		gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc),
-									  userinfo->sn, args->info.icon.icon,
+		gaim_buddy_icons_set_for_user(account, userinfo->sn,
+									  args->info.icon.icon,
 									  args->info.icon.length);
 	} else if (args->reqclass & AIM_CAPS_DIRECTIM) {
 		/* Consider moving all this into a helper func in the direct im block way up there */
@@ -3415,6 +3432,7 @@
 			/* TODO: do something about this, after figuring out what it means */
 			gaim_debug_info("oscar",
 					   "directim kill blocked (%s)\n", userinfo->sn);
+			g_free(message);
 			return 1;
 		}
 
@@ -3458,6 +3476,8 @@
 				   "Unknown reqclass %hu\n", args->reqclass);
 	}
 
+	g_free(message);
+
 	return 1;
 }
 
--- a/src/protocols/oscar/tlv.c	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/protocols/oscar/tlv.c	Thu Sep 02 03:46:53 2004 +0000
@@ -785,6 +785,32 @@
 }
 
 /**
+ * Get the length of the data of the nth TLV in the given TLV chain.
+ *
+ * @param list Source chain.
+ * @param type Requested TLV type.
+ * @param nth Index of TLV of type to get.
+ * @return The length of the data in this TLV, or -1 if the TLV could not be
+ *         found.  Unless -1 is returned, this value will be 2 bytes.
+ */
+faim_internal int aim_tlv_getlength(aim_tlvlist_t *list, const fu16_t type, const int nth)
+{
+	aim_tlvlist_t *cur;
+	int i;
+
+	for (cur = list, i = 0; cur; cur = cur->next) {
+		if (cur && cur->tlv) {
+			if (cur->tlv->type == type)
+				i++;
+			if (i >= nth)
+				return cur->tlv->length;
+		}
+	}
+
+	return -1;
+}
+
+/**
  * Retrieve the data from the nth TLV in the given TLV chain as a string.
  *
  * @param list Source TLV chain.
--- a/src/server.c	Thu Sep 02 02:49:00 2004 +0000
+++ b/src/server.c	Thu Sep 02 03:46:53 2004 +0000
@@ -1453,13 +1453,13 @@
 	gaim_signal_emit(gaim_conversations_get_handle(),
 					 "chat-invited", account, who, name, message, data);
 
-	if (message)
+	if (message != NULL)
 		g_snprintf(buf2, sizeof(buf2),
-				   _("User '%s' invites %s to buddy chat room: '%s'\n%s"),
+				   _("%s has invited %s to the chat room %s:\n<b>%s</b>"),
 				   who, gaim_account_get_username(account), name, message);
 	else
 		g_snprintf(buf2, sizeof(buf2),
-				   _("User '%s' invites %s to buddy chat room: '%s'\n"),
+				   _("%s has invited %s to the chat room %s\n"),
 				   who, gaim_account_get_username(account), name);
 
 	cid->gc = gc;