Mercurial > pidgin.yaz
changeset 9434:c5cf752acc4a
[gaim-migrate @ 10254]
" Adds slash commands, ensures that server supplied
subscriptions are not ignored, cleans up some cases
where non-utf8 text was passed to display widgets, and
adds a utility function -- zephyr_send_message() -- to
get rid of code duplication.
Added slash commands:
/msg sends an IM to a user.
/inst /instance both set the instance for the current class
/zl and /zlocate will return user location information
(like Get Info) for a user.
/sub will allow a user to join a new chat
/zi sends message to <"message",instance,"*">
/zc sends message to <class,"PERSONAL","*">
/zci sends a message to <class,instance,"*">
/zcir sends a message to <class,instance,recipient or
realm>
/zir sends a message to <"message",instance,recipient
or realm>" --Arun A Tharuvai
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 30 Jun 2004 20:38:41 +0000 |
parents | 775ee46b67a2 |
children | 5635f71aa5db |
files | src/protocols/zephyr/zephyr.c |
diffstat | 1 files changed, 264 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/src/protocols/zephyr/zephyr.c Wed Jun 30 14:25:13 2004 +0000 +++ b/src/protocols/zephyr/zephyr.c Wed Jun 30 20:38:41 2004 +0000 @@ -32,6 +32,7 @@ #include "prpl.h" #include "server.h" #include "util.h" +#include "cmds.h" #include "zephyr/zephyr.h" @@ -79,6 +80,7 @@ char *local_zephyr_normalize(const char *); static const char *zephyr_normalize(const GaimAccount *, const char *); static const char *gaim_zephyr_get_realm(); +static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic); char *zephyr_strip_foreign_realm(const char* user){ /* @@ -219,10 +221,10 @@ } /* - Convert incoming zephyr to utf-8 if necessary using user specified encoding + Converts strings to utf-8 if necessary using user specified encoding */ -static gchar *zephyr_recv_convert(char *string, int len) +static gchar *zephyr_recv_convert(gchar *string, int len) { gchar *utf8; GError *err = NULL; @@ -612,7 +614,7 @@ } else serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0); - free(user); + g_free(user); } } else { char *buf, *buf2, *buf3; @@ -651,29 +653,38 @@ zt1 = new_triple(notice.z_class, notice.z_class_inst, notice.z_recipient); zt2 = find_sub_by_triple(zt1); if (!zt2) { - /* we shouldn't be subscribed to this message. ignore. */ - } else { + /* This is a server supplied subscription */ + subscrips = g_slist_append(subscrips, zt1); + zt2 = find_sub_by_triple(zt1); + } + /*else { */ GList *gltmp; int found = 0; - + gchar *send_inst_utf8; + /* GError *err; */ + if (!zt2->open) { zt2->open = TRUE; serv_got_joined_chat(zgc, zt2->id, zt2->name); - gconv1 = gaim_find_conversation_with_account(zt2->name, zgc->account); - gcc = gaim_conversation_get_chat_data(gconv1); - gaim_conv_chat_set_topic(gcc, sendertmp, notice.z_class_inst); - + zephyr_chat_set_topic(zgc,zt2->id,notice.z_class_inst); } g_free(sendertmp); /* fix memory leak? */ /* If the person is in the default Realm, then strip the Realm from the sender field */ sendertmp = zephyr_strip_foreign_realm(notice.z_sender); send_inst = g_strdup_printf("%s %s",sendertmp,notice.z_class_inst); - serv_got_chat_in(zgc, zt2->id, send_inst, FALSE, buf3, time(NULL)); + send_inst_utf8 = zephyr_recv_convert(send_inst, strlen(send_inst)); + if (!send_inst_utf8) { + fprintf(stderr, "zephyr: send_inst %s became null\n",send_inst); + gaim_debug(GAIM_DEBUG_ERROR, "zephyr","send_inst %s became null\n", send_inst); + send_inst_utf8 = "malformed instance"; + } + serv_got_chat_in(zgc, zt2->id, send_inst_utf8, FALSE, buf3, time(NULL)); + g_free(send_inst); gconv1 = gaim_find_conversation_with_account(zt2->name, zgc->account); gcc = gaim_conversation_get_chat_data(gconv1); - /* gaim_conv_chat_set_topic(gcc,sendertmp,notice.z_class_inst); */ + for (gltmp = gaim_conv_chat_get_users(gcc); gltmp; gltmp = gltmp->next) { if (!g_ascii_strcasecmp(gltmp->data, sendertmp)) found = 1; @@ -690,8 +701,9 @@ } g_free(sendertmp); - g_free(send_inst); - } + g_free(send_inst_utf8); + + /* } */ free_triple(zt1); } g_free(buf3); @@ -759,8 +771,8 @@ chk = local_zephyr_normalize(b->name); /* doesn't matter if this fails or not; we'll just move on to the next one */ ZRequestLocations(chk, &ald, UNACKED, ZAUTH); - free(ald.user); - free(ald.version); + g_free(ald.user); + g_free(ald.version); } } } @@ -800,6 +812,13 @@ static void process_zsubs() { + /* Loads zephyr chats "(subscriptions) from ~/.zephyr.subs, and + registers (subscribes to) them on the server */ + + /* XXX write subscriptions into the buddy list somehow "a Zephyr Chats group?"*/ + /* XXX deal with unsubscriptions */ + /* XXX deal with punts */ + FILE *f; gchar *fname; gchar buff[BUFSIZ]; @@ -931,6 +950,11 @@ static void write_zsubs() { + /* Exports subscription (chat) list back to + * .zephyr.subs + * XXX deal with %host%, %canon%, unsubscriptions, and negative subscriptions (punts?) + */ + GSList *s = subscrips; zephyr_triple *zt; FILE *fd; @@ -1050,94 +1074,89 @@ z_call(ZClosePort()); } +static int zephyr_send_message(char* zclass, char* instance, char* recipient, const char *im, + const char *sig) ; + +const char * zephyr_get_signature() +{ + const char * sig; + sig = ZGetVariable("zwrite-signature"); + if (!sig) { + sig = g_get_real_name(); + } + return sig; +} + static int zephyr_chat_send(GaimConnection * gc, int id, const char *im) { - ZNotice_t notice; zephyr_triple *zt; - char *buf; const char *sig; GaimConversation *gconv1; GaimConvChat *gcc; char *inst; - char *html_buf; - char *html_buf2; + char *recipient; zt = find_sub_by_id(id); if (!zt) /* this should never happen. */ return -EINVAL; - sig = ZGetVariable("zwrite-signature"); - if (!sig) { - sig = g_get_real_name(); - } - - html_buf = html_to_zephyr(im); - html_buf2 = gaim_unescape_html(html_buf); - - buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); + sig = zephyr_get_signature(); gconv1 = gaim_find_conversation_with_account(zt->name, zgc->account); gcc = gaim_conversation_get_chat_data(gconv1); - - /* Woops. Setting instance to "PERSONAL" which is the default - sending instance if no instance is set */ if (!(inst = (char *)gaim_conv_chat_get_topic(gcc))) - inst = "PERSONAL"; + inst = g_strdup("PERSONAL"); - bzero((char *)¬ice, sizeof(notice)); - notice.z_kind = ACKED; - notice.z_port = 0; - notice.z_opcode = ""; - notice.z_class = zt->class; - notice.z_class_inst = inst; if (!g_ascii_strcasecmp(zt->recipient, "*")) - notice.z_recipient = local_zephyr_normalize(""); + recipient = local_zephyr_normalize(""); else - notice.z_recipient = local_zephyr_normalize(zt->recipient); - notice.z_sender = 0; - notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; - notice.z_message_len = strlen(html_buf2) + strlen(sig) + 2; - notice.z_message = buf; - g_free(html_buf); - g_free(html_buf2); + recipient = local_zephyr_normalize(zt->recipient); - ZSendNotice(¬ice, ZAUTH); - g_free(buf); + zephyr_send_message(zt->class,inst,recipient,im,sig); + /* g_free(inst); */ + /* g_free(recipient); */ return 0; } + static int zephyr_send_im(GaimConnection * gc, const char *who, const char *im, GaimConvImFlags flags) { - ZNotice_t notice; - char *buf; const char *sig; - char *html_buf; - char *html_buf2; if (flags & GAIM_CONV_IM_AUTO_RESP) sig = "Automated reply:"; else { - sig = ZGetVariable("zwrite-signature"); - if (!sig) { - sig = g_get_real_name(); - } + sig = zephyr_get_signature(); } + zephyr_send_message("MESSAGE","PERSONAL",local_zephyr_normalize(who),im,sig); + + return 1; +} - html_buf = html_to_zephyr(im); - html_buf2 = gaim_unescape_html(html_buf); +static int zephyr_send_message(char* zclass, char* instance, char* recipient, const char *im, + const char *sig) +{ + char *html_buf; + char *html_buf2; + char *buf; + ZNotice_t notice; - buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); + html_buf = html_to_zephyr(im); + html_buf2 = gaim_unescape_html(html_buf); + + buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); bzero((char *)¬ice, sizeof(notice)); + notice.z_kind = ACKED; notice.z_port = 0; notice.z_opcode = ""; - notice.z_class = "MESSAGE"; - notice.z_class_inst = "PERSONAL"; - notice.z_sender = 0; - notice.z_recipient = local_zephyr_normalize(who); - notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; + notice.z_class = zclass; + notice.z_class_inst = instance; + notice.z_recipient = recipient; + notice.z_sender = 0; + notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; notice.z_message_len = strlen(html_buf2) + strlen(sig) + 2; notice.z_message = buf; g_free(html_buf2); @@ -1145,7 +1164,7 @@ ZSendNotice(¬ice, ZAUTH); g_free(buf); - return 1; + return 1; } static const char *zephyr_normalize(const GaimAccount * account, const char *orig) @@ -1167,7 +1186,6 @@ { /* Basically the inverse of zephyr_strip_foreign_realm - */ static char buf[80]; @@ -1255,8 +1273,6 @@ const char *classname; const char *instname; const char *recip; - GaimConversation *gconv; - GaimConvChat *gcc; classname = g_hash_table_lookup(data, "class"); instname = g_hash_table_lookup(data, "instance"); @@ -1276,21 +1292,19 @@ if (zt2) { free_triple(zt1); if (!zt2->open) { - serv_got_joined_chat(gc, zt2->id, zt2->name); - gconv = gaim_find_conversation_with_account(zt2->name, zgc->account); - gcc = gaim_conversation_get_chat_data(gconv); if (!g_ascii_strcasecmp(instname,"*")) instname = "PERSONAL"; - gaim_conv_chat_set_topic(gcc, gaim_zephyr_get_sender(), instname); + serv_got_joined_chat(gc, zt2->id, zt2->name); + zephyr_chat_set_topic(zgc,zt2->id,instname); zt2->open = TRUE; } return; } - + sub.zsub_class = zt1->class; sub.zsub_classinst = zt1->instance; sub.zsub_recipient = zt1->recipient; - + if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { free_triple(zt1); return; @@ -1299,11 +1313,9 @@ subscrips = g_slist_append(subscrips, zt1); zt1->open = TRUE; serv_got_joined_chat(gc, zt1->id, zt1->name); - gconv = gaim_find_conversation_with_account(zt1->name, zgc->account); - gcc = gaim_conversation_get_chat_data(gconv); if (!g_ascii_strcasecmp(instname,"*")) instname = "PERSONAL"; - gaim_conv_chat_set_topic(gcc, gaim_zephyr_get_sender(), instname); + zephyr_chat_set_topic(zgc,zt1->id,instname); } static void zephyr_chat_leave(GaimConnection * gc, int id) @@ -1323,20 +1335,191 @@ } + + static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic) { zephyr_triple *zt; GaimConversation *gconv; GaimConvChat *gcc; + gchar *topic_utf8; char *sender = (char *)gaim_zephyr_get_sender(); zt = find_sub_by_id(id); gconv = gaim_find_conversation_with_account(zt->name, zgc->account); gcc = gaim_conversation_get_chat_data(gconv); - gaim_conv_chat_set_topic(gcc, sender, topic); + + topic_utf8 = zephyr_recv_convert((gchar *)topic,strlen(topic)); + gaim_conv_chat_set_topic(gcc,sender,topic_utf8); + g_free(topic_utf8); + return; +} + +/* commands */ + +static GaimCmdRet zephyr_gaim_cmd_msg(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + char *recipient; + if (!g_ascii_strcasecmp(args[0],"*")) + recipient = local_zephyr_normalize(""); + else + recipient = local_zephyr_normalize(args[0]); + + if (zephyr_send_message("MESSAGE","PERSONAL",recipient,args[1],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; +} + +static GaimCmdRet zephyr_gaim_cmd_zlocate(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + zephyr_zloc(zgc,args[0]); + return GAIM_CMD_RET_OK; +} + +static GaimCmdRet zephyr_gaim_cmd_instance(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* Currently it sets the instance with leading spaces and + * all. This might not be the best thing to do, though having + * one word isn't ideal either. */ + + GaimConvChat *gc = gaim_conversation_get_chat_data(conv); + int id = gc->id; + const char* instance = args[0]; + zephyr_chat_set_topic(zgc,id,instance); + return GAIM_CMD_RET_OK; +} + +static GaimCmdRet zephyr_gaim_cmd_joinchat_cir(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* Join a new zephyr chat */ + GHashTable *triple = g_hash_table_new(NULL,NULL); + g_hash_table_insert(triple,"class",args[0]); + g_hash_table_insert(triple,"instance",args[1]); + g_hash_table_insert(triple,"recipient",args[2]); + zephyr_join_chat(zgc,triple); + return GAIM_CMD_RET_OK; +} + +static GaimCmdRet zephyr_gaim_cmd_zi(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* args = instance, message */ + if (zephyr_send_message("message",args[0],"",args[1],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; +} + +static GaimCmdRet zephyr_gaim_cmd_zci(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* args = class, instance, message */ + if ( zephyr_send_message(args[0],args[1],"",args[2],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; +} +static GaimCmdRet zephyr_gaim_cmd_zcir(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* args = class, instance, recipient, message */ + if ( zephyr_send_message(args[0],args[1],args[2],args[3],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; } +static GaimCmdRet zephyr_gaim_cmd_zir(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* args = instance, recipient, message */ + if ( zephyr_send_message("message",args[0],args[1],args[2],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; +} + +static GaimCmdRet zephyr_gaim_cmd_zc(GaimConversation *conv, + const char *cmd, char **args, char **error) +{ + /* args = class, message */ + if ( zephyr_send_message(args[0],"PERSONAL","",args[1],zephyr_get_signature())) + return GAIM_CMD_RET_OK; + else + return GAIM_CMD_RET_FAILED; +} + +static void zephyr_register_slash_commands() +{ + + gaim_cmd_register("msg","ws", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_msg, _("msg <nick> <message>: Send a private message to a user")); + + gaim_cmd_register("zlocate","w", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zlocate, _("zlocate <nick>: Locate user")); + + gaim_cmd_register("zl","w", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zlocate, _("zl <nick>: Locate user")); + + gaim_cmd_register("instance","s", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_instance, _("inst <instance>: Set the instance to be used on this class")); + + gaim_cmd_register("inst","s", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_instance, _("instance <instance>: Set the instance to be used on this class")); + + gaim_cmd_register("sub", "www", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_joinchat_cir, + _("sub <class> <instance> <recipient>: Join a new chat")); + + gaim_cmd_register("zi","ws", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zi, _("zi <instance>: Send a message to <message,<i>instance</i>,*>")); + + gaim_cmd_register("zci","wws",GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zci, + _("zci <class> <instance>: Send a message to <<i>class</i>,<i>instance</i>,*>")); + + gaim_cmd_register("zcir","wwws",GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zcir, + _("zcir <class> <instance> <recipient>: Send a message to <<i>class</i>,<i>instance</i>,<i>recipient</i>>")); + + gaim_cmd_register("zir","wws",GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zir, + _("zir <instance> <recipient>: Send a message to <MESSAGE,<i>instance</i>,<i>recipient</i>>")); + + gaim_cmd_register("zc","ws", GAIM_CMD_P_PRPL, + GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, + "prpl-zephyr", + zephyr_gaim_cmd_zc, _("zc <class>: Send a message to <<i>class</i>,PERSONAL,*>")); + +} + + static int zephyr_resubscribe(GaimConnection *gc) { /* Resubscribe to the in-memory list of subscriptions and also @@ -1358,6 +1541,7 @@ return 1; } + static void zephyr_action_resubscribe(GaimPluginAction *action) { @@ -1483,6 +1667,7 @@ prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); my_protocol = plugin; + zephyr_register_slash_commands(); } GAIM_INIT_PLUGIN(zephyr, init_plugin, info);