? bak ? diff.patch ? diff.txt ? silc.c-backup ? silc.c.callcmd.patch ? stu.todo ? tooltip.patch ? util.c-broke ? util.h-outoftheway Index: .cvsignore =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/.cvsignore,v retrieving revision 1.1 diff -u -p -u -p -r1.1 .cvsignore --- .cvsignore 1 May 2004 19:34:44 -0000 1.1 +++ .cvsignore 20 Jun 2004 10:11:54 -0000 @@ -1,6 +1,9 @@ *.lo *.la +*.lib +*.dll .libs .deps Makefile Makefile.in +Makefile.mingw Index: Makefile.am =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/Makefile.am,v retrieving revision 1.3 diff -u -p -u -p -r1.3 Makefile.am --- Makefile.am 25 May 2004 17:52:08 -0000 1.3 +++ Makefile.am 20 Jun 2004 10:11:54 -0000 @@ -1,4 +1,4 @@ -EXTRA_DIST = README TODO +EXTRA_DIST = README TODO Makefile.mingw pkgdir = $(libdir)/gaim Index: Makefile.mingw =================================================================== RCS file: Makefile.mingw diff -N Makefile.mingw --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Makefile.mingw 20 Jun 2004 10:11:54 -0000 @@ -0,0 +1,149 @@ +# +# Makefile.mingw +# +# Description: Makefile for win32 (mingw) version of libsilcgaim +# + +# +# PATHS +# + +INCLUDE_DIR := . +GTK_TOP := ../../../../win32-dev/gtk_2_0 +GAIM_TOP := ../../.. +SILC_ROOT := . +GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir +SILC_TOP := ../../../../win32-dev/silc-toolkit-cvs-20040613 + +## +## VARIABLE DEFINITIONS +## + +TARGET = libsilcgaim + +NEEDED_DLLS = $(SILC_TOP)/lib/silc.dll \ + $(SILC_TOP)/lib/silcclient.dll + +# Compiler Options + +CFLAGS = + +DEFINES = + +# Static or Plugin... +ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) +else +ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins +endif +endif + + +## +## INCLUDE MAKEFILES +## + +include $(GAIM_TOP)/src/win32/global.mak + +## +## INCLUDE PATHS +## + +INCLUDE_PATHS += -I$(SILC_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) \ + -I$(SILC_TOP)/include + + +LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src \ + -L$(SILC_TOP)/lib + + +## +## SOURCES, OBJECTS +## + +C_SRC = silc.c \ + buddy.c \ + chat.c \ + ft.c \ + ops.c \ + pk.c \ + util.c + + +OBJECTS = $(C_SRC:%.c=%.o) + + +## +## LIBRARIES +## + +LIBS = -lgtk-win32-2.0 \ + -lglib-2.0 \ + -lgdk-win32-2.0 \ + -lgmodule-2.0 \ + -lgobject-2.0 \ + -lws2_32 \ + -lintl \ + -lgaim \ + -lsilcclient \ + -lsilc \ + -lwsock32 + + +## +## RULES +## + +# How to make a C file + +%.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + +## +## TARGET DEFINITIONS +## + +.PHONY: all clean + +all: $(TARGET).dll + +install: + cp $(SILC_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + cp $(NEEDED_DLLS) $(GAIM_INSTALL_DIR) + + +## +## BUILD Dependencies +## + +$(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + +## +## BUILD DLL +## + +$(TARGET).dll: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).lib -o $(TARGET).dll + +## +## CLEAN RULES +## + +clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib Index: chat.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/chat.c,v retrieving revision 1.10 diff -u -p -u -p -r1.10 chat.c --- chat.c 15 Jun 2004 21:59:04 -0000 1.10 +++ chat.c 20 Jun 2004 10:11:54 -0000 @@ -1003,6 +1003,9 @@ void silcgaim_chat_join_done(SilcClient /* 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 @@ void silcgaim_chat_invite(GaimConnection /* 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,30 @@ int silcgaim_chat_send(GaimConnection *g 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 +1279,8 @@ int silcgaim_chat_send(GaimConnection *g /* 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 +1297,7 @@ void silcgaim_chat_set_topic(GaimConnect SilcChannelUser chu; gboolean found = FALSE; - if (!topic || !conn) + if (!conn) return; /* See if setting topic on private group. Set it Index: ft.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/ft.c,v retrieving revision 1.2 diff -u -p -u -p -r1.2 ft.c --- ft.c 9 May 2004 04:06:58 -0000 1.2 +++ ft.c 20 Jun 2004 10:11:54 -0000 @@ -365,7 +365,7 @@ void silcgaim_ftp_send_file(GaimConnecti if (!silc_parse_userfqdn(name, &nickname, NULL)) return; -#if 1 +#ifndef _WIN32 silc_debug = TRUE; silc_log_set_debug_string("*client*,*ftp*"); #endif Index: ops.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/ops.c,v retrieving revision 1.6 diff -u -p -u -p -r1.6 ops.c --- ops.c 12 Jun 2004 18:36:05 -0000 1.6 +++ ops.c 20 Jun 2004 10:11:55 -0000 @@ -85,16 +85,16 @@ silc_channel_message(SilcClient client, } if (flags & SILC_MESSAGE_FLAG_ACTION) { - msg = g_strdup_printf("%s %s", - sender->nickname ? - sender->nickname : "", + 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 : "", 0, + msg, time(NULL)); g_free(msg); return; } @@ -157,16 +157,15 @@ silc_private_message(SilcClient client, } if (flags & SILC_MESSAGE_FLAG_ACTION && convo) { - msg = g_strdup_printf("%s %s", - sender->nickname ? - sender->nickname : "", + 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 : "", + msg, 0, time(NULL)); g_free(msg); return; } @@ -241,8 +240,8 @@ silc_notify(SilcClient client, SilcClien 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 @@ silc_notify(SilcClient client, SilcClien /* 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 @@ silc_notify(SilcClient client, SilcClien break; default: + gaim_debug_info("silc", "Unhandled notification: %d\n", type); break; } @@ -1001,6 +1001,59 @@ silc_command_reply(SilcClient client, Si } break; + case SILC_COMMAND_WHOWAS: + { + SilcClientEntry client_entry; + char *buf, *nickname, *realname, *username; + GString *s; + + if (!success) { + gaim_notify_error(gc, _("User Information"), + _("Cannot get user information"), + silc_get_status_message(status)); + break; + } + + client_entry = va_arg(vp, SilcClientEntry); + nickname = va_arg(vp, char *); + username = va_arg(vp, char *); + realname = va_arg(vp, char *); + if (!nickname) + break; + + s = g_string_new(""); + g_string_append_printf(s, "%s:\t\t%s\n", _("Nickname"), nickname); + if (realname) + g_string_append_printf(s, "%s:\t%s\n", _("Realname"), realname); + if (username) + g_string_append_printf(s, "%s:\t\t%s\n", _("Username"), username); + if (client_entry && client_entry->hostname) + g_string_append_printf(s, "%s:\t\t%s\n", _("Hostname"), client_entry->hostname); + if (client_entry && client_entry->server) + g_string_append_printf(s, "%s:\t\t%s\n", _("Server"), client_entry->server); + + + if (client_entry && client_entry->public_key) { + char *fingerprint, *babbleprint; + unsigned char *pk; + SilcUInt32 pk_len; + pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); + fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); + babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); + g_string_append_printf(s, "\n%s:\n%s\n\n", _("Public Key Fingerprint"), fingerprint); + g_string_append_printf(s, "%s:\n%s", _("Public Key Babbleprint"), babbleprint); + silc_free(fingerprint); + silc_free(babbleprint); + silc_free(pk); + } + + buf = g_string_free(s, FALSE); + gaim_notify_info(NULL, _("User Information"), + _("User Information"), buf); + g_free(buf); + } + break; + case SILC_COMMAND_DETACH: if (!success) { gaim_notify_error(gc, _("Detach From Server"), _("Cannot detach"), @@ -1023,8 +1076,17 @@ silc_command_reply(SilcClient client, Si 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 +1094,42 @@ silc_command_reply(SilcClient client, Si } 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) { + gaim_notify_error(gc, _("Nick"), _("Failed to change nickname"), + silc_get_status_message(status)); + 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 +1198,7 @@ silc_command_reply(SilcClient client, Si 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,12 +1214,99 @@ silc_command_reply(SilcClient client, Si 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; + case SILC_COMMAND_STATS: + { + SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops, + my_router_ops, cell_clients, cell_channels, cell_servers, + clients, channels, servers, routers, server_ops, router_ops; + SilcUInt32 buffer_length; + SilcBufferStruct buf; + + unsigned char *server_stats; + char *msg; + + if (!success) { + gaim_notify_error(gc, _("Server Stats"), + _("Cannot get server stats"), + silc_get_status_message(status)); + return; + } + + server_stats = va_arg(vp, unsigned char *); + buffer_length = va_arg(vp, SilcUInt32); + if (!server_stats || !buffer_length) { + gaim_notify_error(gc, _("Server Stats"), + _("No server statisitics available"), NULL); + break; + } + silc_buffer_set(&buf, server_stats, buffer_length); + silc_buffer_unformat(&buf, + SILC_STR_UI_INT(&starttime), + SILC_STR_UI_INT(&uptime), + SILC_STR_UI_INT(&my_clients), + SILC_STR_UI_INT(&my_channels), + SILC_STR_UI_INT(&my_server_ops), + SILC_STR_UI_INT(&my_router_ops), + SILC_STR_UI_INT(&cell_clients), + SILC_STR_UI_INT(&cell_channels), + SILC_STR_UI_INT(&cell_servers), + SILC_STR_UI_INT(&clients), + SILC_STR_UI_INT(&channels), + SILC_STR_UI_INT(&servers), + SILC_STR_UI_INT(&routers), + SILC_STR_UI_INT(&server_ops), + SILC_STR_UI_INT(&router_ops), + SILC_STR_END); + + msg = g_strdup_printf(_("Local server start time: %s\n" + "Local server uptime: %s\n" + "Local server clients: %d\n" + "Local server channels: %d\n" + "Local server operators: %d\n" + "Local router operators: %d\n" + "Local cell clients: %d\n" + "Local cell channels: %d\n" + "Local cell servers: %d\n" + "Total clients: %d\n" + "Total channels: %d\n" + "Total servers: %d\n" + "Total routers: %d\n" + "Total server operators: %d\n" + "Total router operators: %d\n"), + silc_get_time(starttime), + gaim_str_seconds_to_string((int)uptime), + (int)my_clients, (int)my_channels, (int)my_server_ops, (int)my_router_ops, + (int)cell_clients, (int)cell_channels, (int)cell_servers, + (int)clients, (int)channels, (int)servers, (int)routers, + (int)server_ops, (int)router_ops); + + gaim_notify_info(NULL, _("Server Information"), + _("Server Information"), msg); + g_free(msg); + } + break; + + case SILC_COMMAND_PING: + { + if (!success) { + gaim_notify_error(gc, _("Ping"), _("Ping failed"), + silc_get_status_message(status)); + return; + } + + gaim_notify_info(gc, _("Ping"), _("Ping reply received from server"), + NULL); + } + break; + case SILC_COMMAND_KILL: if (!success) { gaim_notify_error(gc, _("Kill User"), @@ -1150,6 +1335,11 @@ silc_command_reply(SilcClient client, Si 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; } Index: silc.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/silc.c,v retrieving revision 1.14 diff -u -p -u -p -r1.14 silc.c --- silc.c 19 Jun 2004 04:57:42 -0000 1.14 +++ silc.c 20 Jun 2004 10:11:55 -0000 @@ -304,7 +304,11 @@ silcgaim_login(GaimAccount *account) } /* 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 @@ silcgaim_close(GaimConnection *gc) /* 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 @@ silcgaim_send_im(GaimConnection *gc, con 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 @@ GList *silcgaim_blist_node_menu(GaimBlis return silcgaim_buddy_menu((GaimBuddy *) node); } else { g_return_val_if_reached(NULL); - } + } } /********************************* Commands **********************************/ @@ -932,12 +942,27 @@ static GaimCmdRet silcgaim_cmd_chat_part 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 || id == 0) + if (gc == NULL) + return GAIM_CMD_RET_FAILED; + + 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) { + *error = g_strdup(_("Failed to leave channel")); + 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); @@ -951,6 +976,8 @@ static GaimCmdRet silcgaim_cmd_chat_topi { GaimConnection *gc; int id = 0; + char *buf, *tmp; + const char *topic; gc = gaim_conversation_get_gc(conv); id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)); @@ -958,6 +985,20 @@ static GaimCmdRet silcgaim_cmd_chat_topi if (gc == NULL || id == 0) return GAIM_CMD_RET_FAILED; + if (!args || !args[0]) { + topic = gaim_conv_chat_get_topic (GAIM_CONV_CHAT(conv)); + if (topic) { + tmp = gaim_escape_html(topic); + buf = g_strdup_printf(_("current topic is: %s"), tmp); + g_free(tmp); + } else + buf = g_strdup(_("No topic is set")); + gaim_conv_chat_write(GAIM_CONV_CHAT(conv), gc->account->username, buf, + GAIM_MESSAGE_SYSTEM|GAIM_MESSAGE_NO_LOG, time(NULL)); + g_free(buf); + + } + silcgaim_chat_set_topic(gc, id, args ? args[0] : NULL); return GAIM_CMD_RET_OK; @@ -1007,23 +1048,6 @@ static GaimCmdRet silcgaim_cmd_whois(Gai return GAIM_CMD_RET_OK; } -static GaimCmdRet silcgaim_cmd_chat_invite(GaimConversation *conv, - const char *cmd, char **args, char **error) -{ - int id; - GaimConnection *gc; - - id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)); - gc = gaim_conversation_get_gc(conv); - - if (gc == NULL) - return GAIM_CMD_RET_FAILED; - - silcgaim_chat_invite(gc, id, NULL, args[0]); - - return GAIM_CMD_RET_OK; -} - static GaimCmdRet silcgaim_cmd_msg(GaimConversation *conv, const char *cmd, char **args, char **error) { @@ -1051,8 +1075,10 @@ static GaimCmdRet silcgaim_cmd_query(Gai GaimConnection *gc; GaimAccount *account; - if (!args || !args[0]) + if (!args || !args[0]) { + *error = g_strdup(_("You must specify the nick")); return GAIM_CMD_RET_FAILED; + } gc = gaim_conversation_get_gc(conv); @@ -1092,9 +1118,7 @@ static GaimCmdRet silcgaim_cmd_motd(Gaim 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")); + *error = g_strdup(_("There is no Message of the Day associated with this connection")); return GAIM_CMD_RET_FAILED; } @@ -1126,7 +1150,37 @@ static GaimCmdRet silcgaim_cmd_detach(Ga 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); + + if (gc == NULL) + return GAIM_CMD_RET_FAILED; + + sg = gc->proto_data; + + if (sg == NULL) + return GAIM_CMD_RET_FAILED; + + 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); + *error = g_strdup_printf(_("Unknown command: %s, (may be a Gaim bug)"), cmd); + return GAIM_CMD_RET_FAILED; + } + g_free(silccmd); + + return GAIM_CMD_RET_OK; +} + +static GaimCmdRet silcgaim_cmd_quit(GaimConversation *conv, const char *cmd, char **args, char **error) { GaimConnection *gc; @@ -1142,8 +1196,32 @@ static GaimCmdRet silcgaim_cmd_umode(Gai if (sg == NULL) return GAIM_CMD_RET_FAILED; - silc_client_command_call(sg->client, sg->conn, NULL, "UMODE", - args[0], NULL); + silc_client_command_call(sg->client, sg->conn, NULL, + "QUIT", (args && args[0]) ? args[0] : "Download Gaim: " GAIM_WEBSITE, NULL); + + return GAIM_CMD_RET_OK; +} + +static GaimCmdRet silcgaim_cmd_call(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + GaimConnection *gc; + SilcGaim sg; + + gc = gaim_conversation_get_gc(conv); + + if (gc == NULL) + return GAIM_CMD_RET_FAILED; + + sg = gc->proto_data; + + if (sg == NULL) + return GAIM_CMD_RET_FAILED; + + if (!silc_client_command_call(sg->client, sg->conn, args[0])) { + *error = g_strdup_printf(_("Unknown command: %s"), args[0]); + return GAIM_CMD_RET_FAILED; + } return GAIM_CMD_RET_OK; } @@ -1154,12 +1232,14 @@ static GaimCmdRet silcgaim_cmd_umode(Gai static void silcgaim_register_commands(void) { - gaim_cmd_register("part", "", GAIM_CMD_P_PRPL, - GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, - "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, - "prpl-silc", silcgaim_cmd_chat_part, _("leave: Leave the chat")); + 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 [channel]: Leave the chat")); + 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 [channel]: Leave the chat")); gaim_cmd_register("topic", "s", GAIM_CMD_P_PRPL, GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", @@ -1177,10 +1257,6 @@ silcgaim_register_commands(void) GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, "prpl-silc", silcgaim_cmd_whois, _("whois <nick>: View nick's information")); - gaim_cmd_register("invite", "w", GAIM_CMD_P_PRPL, - GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcgaim_cmd_chat_invite, - _("invite <nick>: Invite nick to join this channel")); gaim_cmd_register("msg", "ws", GAIM_CMD_P_PRPL, GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, "prpl-silc", silcgaim_cmd_msg, @@ -1194,13 +1270,80 @@ silcgaim_register_commands(void) 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("quit", "s", 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_quit, + _("quit [message]: Disconnect from the server, with an optional message")); + gaim_cmd_register("call", "s", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_call, + _("call <command>: Call any silc client command")); + /* These below just get passed through for the silc client library to deal with */ + gaim_cmd_register("kill", "ws", 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_generic, + _("kill <nick> [-pubkey|<reason>]: Kill nick")); + gaim_cmd_register("nick", "w", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("nick <newnick>: Change your nickname")); + gaim_cmd_register("whowas", "ww", 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_generic, + _("whowas <nick>: View nick's information")); + gaim_cmd_register("cmode", "wws", 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_generic, + _("cmode <channel> +|-<modes> [arguments]: Change channel modes")); + gaim_cmd_register("cumode", "wws", 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_generic, + _("cumode <channel> +|-<modes> <nick>: Change nick's modes on channel")); 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, - _("umode <usermodes>: Set your user options")); + "prpl-silc", silcgaim_cmd_generic, + _("umode <usermodes>: Set your modes in the network")); + gaim_cmd_register("oper", "s", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("oper <nick> [-pubkey]: Get server operator privileges")); + gaim_cmd_register("invite", "ws", 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_generic, + _("invite <channel> [-|+]<nick>: invite nick or add/remove from channel invite list")); + gaim_cmd_register("kick", "wws", 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_generic, + _("kick <channel> <nick> [comment]: Kick client from channel")); + gaim_cmd_register("info", "ww", 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_generic, + _("info [server]: View server administrative details")); + gaim_cmd_register("ban", "ww", 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_generic, + _("ban [<channel> +|-<nick>]: Ban client from channel")); + gaim_cmd_register("getkey", "w", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("getkey <nick|server>: Retrieve client's or server's public key")); + gaim_cmd_register("stats", "", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("stats: View server and network statistics")); + gaim_cmd_register("ping", "", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("ping: Send PING to the connected server")); +#if 0 /* Gaim doesn't handle the reply for these yet */ + gaim_cmd_register("users", "s", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-silc", silcgaim_cmd_generic, + _("users: no help available")); +#endif } static GaimPluginPrefFrame * @@ -1404,6 +1547,11 @@ init_plugin(GaimPlugin *plugin) 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); Index: silcgaim.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/silcgaim.h,v retrieving revision 1.4 diff -u -p -u -p -r1.4 silcgaim.h --- silcgaim.h 15 Jun 2004 04:37:12 -0000 1.4 +++ silcgaim.h 20 Jun 2004 10:11:55 -0000 @@ -127,4 +127,22 @@ void silcgaim_roomlist_cancel(GaimRoomli 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 */ Index: util.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/silc/util.c,v retrieving revision 1.6 diff -u -p -u -p -r1.6 util.c --- util.c 13 Jun 2004 17:26:45 -0000 1.6 +++ util.c 20 Jun 2004 10:11:55 -0000 @@ -80,7 +80,7 @@ gboolean silcgaim_check_silc_dir(GaimCon 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 @@ gboolean silcgaim_check_silc_dir(GaimCon 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 @@ gboolean silcgaim_check_silc_dir(GaimCon } } +#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 @@ gboolean silcgaim_check_silc_dir(GaimCon } } +#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 @@ gboolean silcgaim_check_silc_dir(GaimCon } 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)