changeset 9353:b8138f3959dc

[gaim-migrate @ 10161] Stu Tomlinson's bug fixes for SILC from bug #975859 committer: Tailor Script <tailor@pidgin.im>
author Ethan Blanton <elb@pidgin.im>
date Tue, 22 Jun 2004 21:12:31 +0000
parents cc2baf349805
children a5ec9e73f46d
files src/protocols/silc/.cvsignore src/protocols/silc/Makefile.am src/protocols/silc/chat.c src/protocols/silc/ft.c src/protocols/silc/ops.c src/protocols/silc/silc.c src/protocols/silc/silcgaim.h src/protocols/silc/util.c
diffstat 8 files changed, 189 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/silc/.cvsignore	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/.cvsignore	Tue Jun 22 21:12:31 2004 +0000
@@ -1,6 +1,9 @@
 *.lo
 *.la
+*.lib
+*.dll
 .libs
 .deps
 Makefile
 Makefile.in
+Makefile.mingw
--- a/src/protocols/silc/Makefile.am	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/Makefile.am	Tue Jun 22 21:12:31 2004 +0000
@@ -1,4 +1,4 @@
-EXTRA_DIST = README TODO
+EXTRA_DIST = README TODO Makefile.mingw
 
 pkgdir = $(libdir)/gaim
 
--- a/src/protocols/silc/chat.c	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/chat.c	Tue Jun 22 21:12:31 2004 +0000
@@ -1003,6 +1003,9 @@
 	/* Set topic */
 	if (channel->topic)
 		gaim_conv_chat_set_topic(GAIM_CONV_CHAT(convo), NULL, channel->topic);
+
+	/* Set nick */
+	gaim_conv_chat_set_nick(GAIM_CONV_CHAT(convo), conn->local_entry->nickname);
 }
 
 void silcgaim_chat_join(GaimConnection *gc, GHashTable *data)
@@ -1130,7 +1133,7 @@
 	/* Call INVITE */
 	silc_client_command_call(client, conn, NULL, "INVITE",
 				 chu->channel->channel_name,
-				 name);
+				 name, NULL);
 }
 
 void silcgaim_chat_leave(GaimConnection *gc, int id)
@@ -1213,21 +1216,31 @@
 	SilcChannelPrivateKey key = NULL;
 	SilcUInt32 flags;
 	int ret;
+	const char *msg2;
 	gboolean found = FALSE;
 	gboolean sign = gaim_prefs_get_bool("/plugins/prpl/silc/sign_chat");
 
 	if (!msg || !conn)
 		return 0;
 
-	/* See if command */
-	if (strlen(msg) > 1 && msg[0] == '/') {
+	flags = SILC_MESSAGE_FLAG_UTF8;
+
+	msg2 = msg;
+
+	if (!g_ascii_strncasecmp(msg2, "/me ", 4))
+	{
+		msg2 += 4;
+		if (!msg2)
+			return 0;
+		flags |= SILC_MESSAGE_FLAG_ACTION;
+	} else if (strlen(msg) > 1 && msg[0] == '/') {
 		if (!silc_client_command_call(client, conn, msg + 1))
 			gaim_notify_error(gc, ("Call Command"), _("Cannot call command"),
-					  _("Unknown command"));
+							  _("Unknown command"));
 		return 0;
 	}
 
-	flags = SILC_MESSAGE_FLAG_UTF8;
+
 	if (sign)
 		flags |= SILC_MESSAGE_FLAG_SIGNED;
 
@@ -1267,8 +1280,8 @@
 
 	/* Send channel message */
 	ret = silc_client_send_channel_message(client, conn, channel, key,
-					       flags, (unsigned char *)msg,
-					       strlen(msg), TRUE);
+					       flags, (unsigned char *)msg2,
+					       strlen(msg2), TRUE);
 	if (ret)
 		serv_got_chat_in(gc, id, gaim_connection_get_display_name(gc), 0, msg,
 				 time(NULL));
@@ -1285,7 +1298,7 @@
 	SilcChannelUser chu;
 	gboolean found = FALSE;
 
-	if (!topic || !conn)
+	if (!conn)
 		return;
 
 	/* See if setting topic on private group.  Set it
--- a/src/protocols/silc/ft.c	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/ft.c	Tue Jun 22 21:12:31 2004 +0000
@@ -365,7 +365,7 @@
 	if (!silc_parse_userfqdn(name, &nickname, NULL))
 		return;
 
-#if 1
+#ifndef _WIN32
 	silc_debug = TRUE;
 	silc_log_set_debug_string("*client*,*ftp*");
 #endif
--- a/src/protocols/silc/ops.c	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/ops.c	Tue Jun 22 21:12:31 2004 +0000
@@ -85,16 +85,16 @@
 	}
 
 	if (flags & SILC_MESSAGE_FLAG_ACTION) {
-		msg = g_strdup_printf("<I>%s</I> %s",
-				      sender->nickname ?
-				      sender->nickname : "<unknown>",
+		msg = g_strdup_printf("/me %s",
 				      (const char *)message);
 		if (!msg)
 			return;
 
 		/* Send to Gaim */
-		gaim_conversation_write(convo, NULL, (const char *)msg,
-					GAIM_MESSAGE_SYSTEM, time(NULL));
+		serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo)),
+				 sender->nickname ?
+				 sender->nickname : "<unknown>", 0,
+				 msg, time(NULL));
 		g_free(msg);
 		return;
 	}
@@ -157,16 +157,15 @@
 	}
 
 	if (flags & SILC_MESSAGE_FLAG_ACTION && convo) {
-		msg = g_strdup_printf("<I>%s</I> %s",
-				      sender->nickname ?
-				      sender->nickname : "<unknown>",
+		msg = g_strdup_printf("/me %s",
 				      (const char *)message);
 		if (!msg)
 			return;
 
 		/* Send to Gaim */
-		gaim_conversation_write(convo, NULL, (const char *)msg,
-					GAIM_MESSAGE_SYSTEM, time(NULL));
+		serv_got_im(gc, sender->nickname ?
+			    sender->nickname : "<unknown>",
+			    msg, 0, time(NULL));
 		g_free(msg);
 		return;
 	}
@@ -241,8 +240,8 @@
 			client_entry = va_arg(va, SilcClientEntry);
 
 			components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-			g_hash_table_insert(components, strdup("channel"), name);
-			serv_got_chat_invite(gc, name, client_entry->nickname, NULL, NULL);
+			g_hash_table_insert(components, strdup("channel"), strdup(name));
+			serv_got_chat_invite(gc, name, client_entry->nickname, NULL, components);
 		}
 		break;
 
@@ -471,7 +470,7 @@
 			/* Remove user from channel */
 			g_snprintf(buf, sizeof(buf), ("Kicked by %s (%s)"),
 				   client_entry2->nickname, tmp ? tmp : "");
-			gaim_conv_chat_rename_user(GAIM_CONV_CHAT(convo),
+			gaim_conv_chat_remove_user(GAIM_CONV_CHAT(convo),
 						   client_entry->nickname,
 						   buf);
 		}
@@ -698,6 +697,7 @@
 		break;
 
 	default:
+		gaim_debug_info("silc", "Unhandled notification: %d\n", type);
 		break;
 	}
 
@@ -1023,8 +1023,17 @@
 
 			convo = gaim_find_conversation_with_account(channel->channel_name,
 								    sg->account);
-			if (!convo)
+			if (!convo) {
+				gaim_debug_error("silc", "Got a topic for %s, which doesn't exist\n",
+								 channel->channel_name);
 				break;
+			}
+
+			if (gaim_conversation_get_type(convo) != GAIM_CONV_CHAT) {
+				gaim_debug_error("silc", "Got a topic for %s, which isn't a chat\n",
+								 channel->channel_name);
+				break;
+			}
 
 			/* Set topic */
 			if (channel->topic)
@@ -1032,6 +1041,40 @@
 		}
 		break;
 
+	case SILC_COMMAND_NICK:
+		{
+			/* I don't think we should need to do this because the server should
+			 * be sending a SILC_NOTIFY_TYPE_NICK_CHANGE when we change our own
+			 * nick, but it isn't, so we deal with it here instead. Stu. */
+			SilcClientEntry local_entry;
+			SilcHashTableList htl;
+			SilcChannelUser chu;
+			const char *oldnick;
+
+			if (!success) {
+				return;
+			}
+
+			local_entry = va_arg(vp, SilcClientEntry);
+
+			/* Change nick on all channels */
+			silc_hash_table_list(local_entry->channels, &htl);
+			while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
+				convo = gaim_find_conversation_with_account(chu->channel->channel_name,
+						sg->account);
+				if (!convo || (gaim_conversation_get_type(convo) != GAIM_CONV_CHAT))
+					continue;
+				oldnick = gaim_conv_chat_get_nick(GAIM_CONV_CHAT(convo));
+				if (strcmp(oldnick, local_entry->nickname)) {
+					gaim_conv_chat_rename_user(GAIM_CONV_CHAT(convo),
+							oldnick, local_entry->nickname);
+					gaim_conv_chat_set_nick(GAIM_CONV_CHAT(convo), local_entry->nickname);
+				}
+			}
+			silc_hash_table_list_reset(&htl);
+		}
+		break;
+
 	case SILC_COMMAND_LIST:
 		{
 			char *topic, *name;
@@ -1100,7 +1143,7 @@
 			SilcServerEntry server_entry;
 			char *server_name;
 			char *server_info;
-			char tmp[256];
+			char tmp[256], *msg;
 
 			if (!success) {
 				gaim_notify_error(gc, _("Server Information"),
@@ -1116,8 +1159,10 @@
 			if (server_name && server_info) {
 				g_snprintf(tmp, sizeof(tmp), "Server: %s\n%s",
 					   server_name, server_info);
+				msg = g_markup_escape_text(tmp, strlen(tmp));
 				gaim_notify_info(NULL, _("Server Information"),
-						 _("Server Information"), tmp);
+						 _("Server Information"), msg);
+				g_free(msg);
 			}
 		}
 		break;
@@ -1150,6 +1195,11 @@
 		break;
 
 	default:
+		if (success)
+			gaim_debug_info("silc", "Unhandled command: %d (succeeded)\n", command);
+		else
+			gaim_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command,
+							silc_get_status_message(status));
 		break;
 	}
 
--- a/src/protocols/silc/silc.c	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/silc.c	Tue Jun 22 21:12:31 2004 +0000
@@ -304,7 +304,11 @@
 	}
 
 	/* Schedule SILC using Glib's event loop */
+#ifndef _WIN32
 	sg->scheduler = g_timeout_add(5, (GSourceFunc)silcgaim_scheduler, sg);
+#else
+	sg->scheduler = g_timeout_add(300, (GSourceFunc)silcgaim_scheduler, sg);
+#endif
 }
 
 static int
@@ -336,7 +340,7 @@
 
 	/* Send QUIT */
 	silc_client_command_call(sg->client, sg->conn, NULL,
-				 "QUIT", "Leaving", NULL);
+				 "QUIT", "Download Gaim: " GAIM_WEBSITE, NULL);
 
 	if (sg->conn)
 		silc_client_close_connection(sg->client, sg->conn);
@@ -869,18 +873,24 @@
 	if (!who || !msg)
 		return 0;
 
-	/* See if command */
-	if (strlen(msg) > 1 && msg[0] == '/') {
+	mflags = SILC_MESSAGE_FLAG_UTF8;
+
+	if (!g_ascii_strncasecmp(msg, "/me ", 4)) {
+		msg += 4;
+		if (!msg)
+			return 0;
+		mflags |= SILC_MESSAGE_FLAG_ACTION;
+	} else if (strlen(msg) > 1 && msg[0] == '/') {
 		if (!silc_client_command_call(client, conn, msg + 1))
 			gaim_notify_error(gc, ("Call Command"), _("Cannot call command"),
-					  _("Unknown command"));
+							  _("Unknown command"));
 		return 0;
 	}
 
+
 	if (!silc_parse_userfqdn(who, &nickname, NULL))
 		return 0;
 
-	mflags = SILC_MESSAGE_FLAG_UTF8;
 	if (sign)
 		mflags |= SILC_MESSAGE_FLAG_SIGNED;
 
@@ -923,7 +933,7 @@
 		return silcgaim_buddy_menu((GaimBuddy *) node);
 	} else {
 		g_return_val_if_reached(NULL);
-	}	
+	}
 }
 
 /********************************* Commands **********************************/
@@ -932,12 +942,25 @@
 		const char *cmd, char **args, char **error)
 {
 	GaimConnection *gc;
+	GaimConversation *convo;
 	int id = 0;
 
 	gc = gaim_conversation_get_gc(conv);
-	id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv));
+
+	if (gc == NULL)
+		return GAIM_CMD_RET_FAILED;
 
-	if (gc == NULL || id == 0)
+	if(args && args[0]) {
+		convo = gaim_find_conversation_with_account(args[0], gc->account);
+	} else
+		convo = conv;
+
+	if (gaim_conversation_get_type(convo) != GAIM_CONV_CHAT)
+		return GAIM_CMD_RET_FAILED;
+
+	id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(convo));
+
+	if (id == 0)
 		return GAIM_CMD_RET_FAILED;
 
 	silcgaim_chat_leave(gc, id);
@@ -1092,9 +1115,8 @@
 		return GAIM_CMD_RET_FAILED;
 
 	if (!sg->motd) {
-		gaim_notify_error(
-				gc, _("Message of the Day"), _("No Message of the Day available"),
-				_("There is no Message of the Day associated with this connection"));
+		gaim_notify_error(gc, _("Message of the Day"), _("No Message of the Day available"),
+						  _("There is no Message of the Day associated with this connection"));
 		return GAIM_CMD_RET_FAILED;
 	}
 
@@ -1126,11 +1148,12 @@
 	return GAIM_CMD_RET_OK;
 }
 
-static GaimCmdRet silcgaim_cmd_umode(GaimConversation *conv,
+static GaimCmdRet silcgaim_cmd_generic(GaimConversation *conv,
 		const char *cmd, char **args, char **error)
 {
 	GaimConnection *gc;
 	SilcGaim sg;
+	char *silccmd, *silcargs;
 
 	gc = gaim_conversation_get_gc(conv);
 
@@ -1142,8 +1165,14 @@
 	if (sg == NULL)
 		return GAIM_CMD_RET_FAILED;
 
-	silc_client_command_call(sg->client, sg->conn, NULL, "UMODE",
-			args[0], NULL);
+	silcargs = g_strjoinv(" ", args);
+	silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL);
+	g_free(silcargs);
+	if (!silc_client_command_call(sg->client, sg->conn, silccmd)) {
+		g_free(silccmd);
+		return GAIM_CMD_RET_FAILED;
+	}
+	g_free(silccmd);
 
 	return GAIM_CMD_RET_OK;
 }
@@ -1154,11 +1183,13 @@
 static void
 silcgaim_register_commands(void)
 {
-	gaim_cmd_register("part", "", GAIM_CMD_P_PRPL,
-			GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY,
+	gaim_cmd_register("part", "w", GAIM_CMD_P_PRPL,
+			GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT |
+			GAIM_CMD_FLAG_PRPL_ONLY | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS,
 			"prpl-silc", silcgaim_cmd_chat_part, _("part:  Leave the chat"));
-	gaim_cmd_register("leave", "", GAIM_CMD_P_PRPL,
-			GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY,
+	gaim_cmd_register("leave", "w", GAIM_CMD_P_PRPL,
+			GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT |
+			GAIM_CMD_FLAG_PRPL_ONLY | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS,
 			"prpl-silc", silcgaim_cmd_chat_part, _("leave:  Leave the chat"));
 	gaim_cmd_register("topic", "s", GAIM_CMD_P_PRPL,
 			GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY |
@@ -1194,12 +1225,12 @@
 			GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcgaim_cmd_motd,
 			_("motd:  View the server's Message Of The Day"));
 	gaim_cmd_register("detach", "", GAIM_CMD_P_PRPL,
-			GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY |
-			GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcgaim_cmd_detach,
+			GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY,
+			"prpl-silc", silcgaim_cmd_detach,
 			_("detach:  Detach this session"));
 	gaim_cmd_register("umode", "w", GAIM_CMD_P_PRPL,
 			GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY,
-			"prpl-silc", silcgaim_cmd_umode,
+			"prpl-silc", silcgaim_cmd_generic,
 			_("umode &lt;usermodes&gt;:  Set your user options"));
 }
 
@@ -1404,6 +1435,11 @@
 	gaim_prefs_add_string("/plugins/prpl/silc/vcard", "");
 
 	silcgaim_register_commands();
+
+#ifdef _WIN32
+	silc_net_win32_init();
+#endif
+
 }
 
 GAIM_INIT_PLUGIN(silc, init_plugin, info);
--- a/src/protocols/silc/silcgaim.h	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/silcgaim.h	Tue Jun 22 21:12:31 2004 +0000
@@ -127,4 +127,22 @@
 void silcgaim_chat_chauth_show(SilcGaim sg, SilcChannelEntry channel,
 			       SilcBuffer channel_pubkeys);
 
+#ifdef _WIN32
+typedef int uid_t;
+
+struct passwd {
+	char	*pw_name;	/* user name */
+	char	*pw_passwd;	/* user password */
+	int		pw_uid;		/* user id */
+	int		pw_gid;		/* group id */
+	char	*pw_gecos;	/* real name */
+	char	*pw_dir;	/* home directory */
+	char	*pw_shell;	/* shell program */
+};
+
+struct passwd *getpwuid(int uid);
+int getuid();
+int geteuid();
+#endif
+
 #endif /* SILCGAIM_H */
--- a/src/protocols/silc/util.c	Tue Jun 22 21:04:33 2004 +0000
+++ b/src/protocols/silc/util.c	Tue Jun 22 21:12:31 2004 +0000
@@ -80,7 +80,7 @@
 		return FALSE;
 	}
 
-	g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S, silcgaim_silcdir());
+	g_snprintf(filename, sizeof(filename) - 1, "%s", silcgaim_silcdir());
 	g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys",
 		   silcgaim_silcdir());
 	g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys",
@@ -109,12 +109,14 @@
 			return FALSE;
 		}
 	} else {
+#ifndef _WIN32
 		/* Check the owner of the dir */
 		if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
 			gaim_debug_error("silc", "You don't seem to own '%s' directory\n",
 				filename);
 			return FALSE;
 		}
+#endif
 	}
 
 	/*
@@ -211,11 +213,13 @@
 		}
 	}
 
+#ifndef _WIN32
 	/* Check the owner of the public key */
 	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
 		gaim_debug_error("silc", "You don't seem to own your public key!?\n");
 		return FALSE;
 	}
+#endif
 
 	if ((stat(file_private_key, &st)) == -1) {
 		/* If file doesn't exist */
@@ -234,6 +238,7 @@
 		}
 	}
 
+#ifndef _WIN32
 	/* Check the owner of the private key */
 	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
 		gaim_debug_error("silc", "You don't seem to own your private key!?\n");
@@ -252,10 +257,26 @@
 		}
 		gaim_debug_warning("silc", "Done.\n\n");
 	}
+#endif
 
 	return TRUE;
 }
 
+#ifdef _WIN32
+struct passwd *getpwuid(uid_t uid) {
+	struct passwd *pwd = calloc(1, sizeof(struct passwd));
+	return pwd;
+}
+
+uid_t getuid() {
+	return 0;
+}
+
+uid_t geteuid() {
+	return 0;
+}
+#endif
+
 void silcgaim_show_public_key(SilcGaim sg,
 			      const char *name, SilcPublicKey public_key,
 			      GCallback callback, void *context)