From a3129e67494af13035af98e826d895bc997c14b1 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sat, 29 Nov 2008 18:46:49 +0000 Subject: The Add Buddy dialog should not blindly create a duplicate buddy in a group Fix up a subset of the prpls add_buddy functions to properly handle this situation. * Everything that comes before oscar alphabetically should work properly (except Gadu-Gadu and MSN, which need testing/another set of eyes) --- finch/gntblist.c | 10 +++++++--- libpurple/protocols/irc/irc.c | 2 +- libpurple/protocols/myspace/myspace.c | 12 ++++++++---- libpurple/protocols/myspace/user.c | 19 +++++++++---------- libpurple/protocols/myspace/user.h | 2 +- libpurple/protocols/novell/novell.c | 4 ++++ pidgin/gtkblist.c | 8 ++++++-- pidgin/plugins/gevolution/gevo-util.c | 8 ++++++-- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/finch/gntblist.c b/finch/gntblist.c index 39f852fb77..8e917d472f 100644 --- a/finch/gntblist.c +++ b/finch/gntblist.c @@ -643,10 +643,14 @@ add_buddy_cb(void *data, PurpleRequestFields *allfields) purple_blist_add_group(grp, NULL); } - /* XXX: Ask if there's already the same buddy in the same group (#4553) */ + /* XXX: Ask to merge if there's already a buddy with the same alias in the same group (#4553) */ + + if ((buddy = purple_find_buddy_in_group(account, username, grp)) == NULL) + { + buddy = purple_buddy_new(account, username, alias); + purple_blist_add_buddy(buddy, NULL, grp, NULL); + } - buddy = purple_buddy_new(account, username, alias); - purple_blist_add_buddy(buddy, NULL, grp, NULL); purple_account_add_buddy(account, buddy); } diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c index e0013a3d3f..befaaaf29f 100644 --- a/libpurple/protocols/irc/irc.c +++ b/libpurple/protocols/irc/irc.c @@ -565,7 +565,7 @@ static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup struct irc_conn *irc = (struct irc_conn *)gc->proto_data; struct irc_buddy *ib = g_new0(struct irc_buddy, 1); ib->name = g_strdup(buddy->name); - g_hash_table_insert(irc->buddies, ib->name, ib); + g_hash_table_replace(irc->buddies, ib->name, ib); /* if the timer isn't set, this is during signon, so we don't want to flood * ourself off with ISON's, so we don't, but after that we want to know when diff --git a/libpurple/protocols/myspace/myspace.c b/libpurple/protocols/myspace/myspace.c index 9fee85a8e7..425af34c5c 100644 --- a/libpurple/protocols/myspace/myspace.c +++ b/libpurple/protocols/myspace/myspace.c @@ -1984,7 +1984,7 @@ msim_incoming_status(MsimSession *session, MsimMessage *msg) buddy = purple_buddy_new(session->account, username, NULL); purple_blist_add_buddy(buddy, NULL, NULL, NULL); - user = msim_get_user_from_buddy(buddy); + user = msim_get_user_from_buddy(buddy, TRUE); /* All buddies on list should have a UserID integer associated with them. */ purple_blist_node_set_int(&buddy->node, "UserID", msim_msg_get_integer(msg, "f")); @@ -2082,6 +2082,10 @@ msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) MsimMessage *body; session = (MsimSession *)gc->proto_data; + + if (msim_get_user_from_buddy(buddy, FALSE) != NULL) + return; + purple_debug_info("msim", "msim_add_buddy: want to add %s to %s\n", buddy->name, (group && group->name) ? group->name : "(no group)"); @@ -2750,7 +2754,7 @@ msim_status_text(PurpleBuddy *buddy) g_return_val_if_fail(buddy != NULL, NULL); - user = msim_get_user_from_buddy(buddy); + user = msim_get_user_from_buddy(buddy, TRUE); session = (MsimSession *)buddy->account->gc->proto_data; g_return_val_if_fail(MSIM_SESSION_VALID(session), NULL); @@ -2796,7 +2800,7 @@ msim_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, g_return_if_fail(buddy != NULL); g_return_if_fail(user_info != NULL); - user = msim_get_user_from_buddy(buddy); + user = msim_get_user_from_buddy(buddy, TRUE); if (PURPLE_BUDDY_IS_ONLINE(buddy)) { MsimSession *session; @@ -2879,7 +2883,7 @@ msim_add_contact_from_server_cb(MsimSession *session, MsimMessage *user_lookup_i purple_blist_add_buddy(buddy, NULL, group, NULL /* insertion point */); /* 3. Update buddy information */ - user = msim_get_user_from_buddy(buddy); + user = msim_get_user_from_buddy(buddy, TRUE); /* All buddies on list should have 'uid' integer associated with them. */ purple_blist_node_set_int(&buddy->node, "UserID", uid); diff --git a/libpurple/protocols/myspace/user.c b/libpurple/protocols/myspace/user.c index c5ab898b8b..64ed902e7e 100644 --- a/libpurple/protocols/myspace/user.c +++ b/libpurple/protocols/myspace/user.c @@ -47,26 +47,25 @@ msim_format_now_playing(const gchar *band, const gchar *song) return NULL; } } -/** Get the MsimUser from a PurpleBuddy, creating it if needed. */ + +/** Get the MsimUser from a PurpleBuddy, optionally creating it if needed. */ MsimUser * -msim_get_user_from_buddy(PurpleBuddy *buddy) +msim_get_user_from_buddy(PurpleBuddy *buddy, gboolean create) { MsimUser *user; - if (!buddy) { - return NULL; - } + g_return_val_if_fail(buddy != NULL, NULL); - if (!buddy->proto_data) { + if (create && !buddy->proto_data) { /* No MsimUser for this buddy; make one. */ /* TODO: where is this freed? */ user = g_new0(MsimUser, 1); user->buddy = buddy; buddy->proto_data = (gpointer)user; - } - - user = (MsimUser *)(buddy->proto_data); + } else { + user = (MsimUser *)(buddy->proto_data); + } return user; } @@ -83,7 +82,7 @@ msim_find_user(MsimSession *session, const gchar *username) return NULL; } - user = msim_get_user_from_buddy(buddy); + user = msim_get_user_from_buddy(buddy, TRUE); return user; } diff --git a/libpurple/protocols/myspace/user.h b/libpurple/protocols/myspace/user.h index 633883dc14..4bf0056d09 100644 --- a/libpurple/protocols/myspace/user.h +++ b/libpurple/protocols/myspace/user.h @@ -45,7 +45,7 @@ typedef struct _MsimUser * initiated from a user lookup. */ typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, MsimMessage *userinfo, gpointer data); -MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy); +MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy, gboolean create); MsimUser *msim_find_user(MsimSession *session, const gchar *username); void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full); gboolean msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user); diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c index d137964a85..08db5eff0d 100644 --- a/libpurple/protocols/novell/novell.c +++ b/libpurple/protocols/novell/novell.c @@ -2553,6 +2553,10 @@ novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group) if (!user->clist_synched) return; + /* Don't re-add a buddy that is already on our contact list */ + if (nm_find_user_record(user, buddy->name) == NULL) + return; + contact = nm_create_contact(); nm_contact_set_dn(contact, buddy->name); diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index 05e6099a5b..1f1c29c7c2 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -6495,8 +6495,12 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data) purple_blist_add_group(g, NULL); } - b = purple_buddy_new(data->account, who, whoalias); - purple_blist_add_buddy(b, NULL, g, NULL); + if ((b = purple_find_buddy_in_group(data->account, who, g)) == NULL) + { + b = purple_buddy_new(data->account, who, whoalias); + purple_blist_add_buddy(b, NULL, g, NULL); + } + purple_account_add_buddy(data->account, b); /* Offer to merge people with the same alias. */ diff --git a/pidgin/plugins/gevolution/gevo-util.c b/pidgin/plugins/gevolution/gevo-util.c index c0613ae8f0..3c96fe3c7a 100644 --- a/pidgin/plugins/gevolution/gevo-util.c +++ b/pidgin/plugins/gevolution/gevo-util.c @@ -41,8 +41,12 @@ gevo_add_buddy(PurpleAccount *account, const char *group_name, purple_blist_add_group(group, NULL); } - buddy = purple_buddy_new(account, screenname, alias); - purple_blist_add_buddy(buddy, NULL, group, NULL); + if ((buddy = purple_find_buddy_in_group(account, screenname, group)) == NULL) + { + buddy = purple_buddy_new(account, screenname, alias); + purple_blist_add_buddy(buddy, NULL, group, NULL); + } + purple_account_add_buddy(account, buddy); if (conv != NULL) -- cgit v1.2.1 From f18083dee5b9c6e9d639e0b87b56cb65d0ba7d12 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sun, 21 Dec 2008 19:15:21 +0000 Subject: Oscar: Re-request authorization when adding a buddy that is already on the list. This might want to simply call purple_auth_request instead of popping up the request dialog again. I'm not sure which is better. --- libpurple/protocols/oscar/oscar.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index 8332fa995e..fa3d31343b 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -4814,19 +4814,26 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { return; } - if ((od->ssi.received_data) && !(aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY))) { - purple_debug_info("oscar", - "ssi: adding buddy %s to group %s\n", buddy->name, group->name); - aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); + if (od->ssi.received_data) { + if (!aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY)) { + purple_debug_info("oscar", + "ssi: adding buddy %s to group %s\n", buddy->name, group->name); + aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); - /* Mobile users should always be online */ - if (buddy->name[0] == '+') { - purple_prpl_got_user_status(account, - purple_buddy_get_name(buddy), - OSCAR_STATUS_ID_AVAILABLE, NULL); - purple_prpl_got_user_status(account, - purple_buddy_get_name(buddy), - OSCAR_STATUS_ID_MOBILE, NULL); + /* Mobile users should always be online */ + if (buddy->name[0] == '+') { + purple_prpl_got_user_status(account, + purple_buddy_get_name(buddy), + OSCAR_STATUS_ID_AVAILABLE, NULL); + purple_prpl_got_user_status(account, + purple_buddy_get_name(buddy), + OSCAR_STATUS_ID_MOBILE, NULL); + } + } else if (aim_ssi_waitingforauth(od->ssi.local, + aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(buddy)), + purple_buddy_get_name(buddy))) { + /* Not authorized -- Re-request authorization */ + purple_auth_sendrequest(gc, purple_buddy_get_name(buddy)); } } -- cgit v1.2.1 From e4200fe26d67cd791d2c2a1047aa3284a5428611 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sun, 21 Dec 2008 22:11:46 +0000 Subject: Properly don't re-add buddies in SILC --- libpurple/protocols/silc/buddy.c | 7 ++++++- libpurple/protocols/silc10/buddy.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libpurple/protocols/silc/buddy.c b/libpurple/protocols/silc/buddy.c index 112d796ddd..5bfc1e768c 100644 --- a/libpurple/protocols/silc/buddy.c +++ b/libpurple/protocols/silc/buddy.c @@ -1390,7 +1390,12 @@ silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init) void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { - silcpurple_add_buddy_i(gc, buddy, FALSE); + /* Don't add if the buddy is already on the list. + * + * SILC doesn't have groups, so we also don't need to do anything + * for a move. */ + if (buddy->proto_data == NULL) + silcpurple_add_buddy_i(gc, buddy, FALSE); } void silcpurple_send_buddylist(PurpleConnection *gc) diff --git a/libpurple/protocols/silc10/buddy.c b/libpurple/protocols/silc10/buddy.c index 67e53f630f..54f49d1335 100644 --- a/libpurple/protocols/silc10/buddy.c +++ b/libpurple/protocols/silc10/buddy.c @@ -1390,7 +1390,12 @@ silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init) void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { - silcpurple_add_buddy_i(gc, buddy, FALSE); + /* Don't add if the buddy is already on the list. + * + * SILC doesn't have groups, so we don't need to do anything + * for a move. */ + if (buddy->proto_data == NULL) + silcpurple_add_buddy_i(gc, buddy, FALSE); } void silcpurple_send_buddylist(PurpleConnection *gc) -- cgit v1.2.1 From f04984aadddb03a107896b26bd8d35197abe98c3 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sun, 21 Dec 2008 22:12:23 +0000 Subject: Update the comment for add_buddy in prpl.h to note it may be called to mean 'request authorization' --- libpurple/prpl.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libpurple/prpl.h b/libpurple/prpl.h index 615beb6981..769bc1bd62 100644 --- a/libpurple/prpl.h +++ b/libpurple/prpl.h @@ -294,6 +294,14 @@ struct _PurplePluginProtocolInfo void (*set_idle)(PurpleConnection *, int idletime); void (*change_passwd)(PurpleConnection *, const char *old_pass, const char *new_pass); + /** + * Add a buddy to a group on the server. + * + * This PRPL function may be called in situations in which the buddy is + * already in the specified group. If the protocol supports + * authorization and the user is not already authorized to see the + * status of \a buddy, \a add_buddy should request authorization. + */ void (*add_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group); void (*add_buddies)(PurpleConnection *, GList *buddies, GList *groups); void (*remove_buddy)(PurpleConnection *, PurpleBuddy *buddy, PurpleGroup *group); -- cgit v1.2.1 From bd16974e8bc194ed5a00e547dafbc1f9c6e41ce3 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sun, 21 Dec 2008 22:42:04 +0000 Subject: Fix the novell check --- libpurple/protocols/novell/novell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c index 08db5eff0d..4c87ec1ce2 100644 --- a/libpurple/protocols/novell/novell.c +++ b/libpurple/protocols/novell/novell.c @@ -2554,7 +2554,7 @@ novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group) return; /* Don't re-add a buddy that is already on our contact list */ - if (nm_find_user_record(user, buddy->name) == NULL) + if (nm_find_user_record(user, buddy->name) != NULL) return; contact = nm_create_contact(); -- cgit v1.2.1 From 7ae3c6df5b8e908aae83368d08d7f2c8545bd1ad Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 22 Dec 2008 19:40:05 +0000 Subject: Fix situation in which group was not specified and purple_find_buddy_in_group(account, who, NULL or "") won't find the existing PurpleBuddy in "Buddies" --- pidgin/gtkblist.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index e861c68b74..a0ec4babb6 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -6504,13 +6504,22 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data) whoalias = NULL; g = NULL; - if ((grp != NULL) && (*grp != '\0') && ((g = purple_find_group(grp)) == NULL)) + if ((grp != NULL) && (*grp != '\0')) { - g = purple_group_new(grp); - purple_blist_add_group(g, NULL); + if ((g = purple_find_group(grp)) == NULL) + { + g = purple_group_new(grp); + purple_blist_add_group(g, NULL); + } + + b = purple_find_buddy_in_group(data->account, who, g); + } + else if ((b = purple_find_buddy(data->account, who)) != NULL) + { + g = purple_buddy_get_group(b); } - if ((b = purple_find_buddy_in_group(data->account, who, g)) == NULL) + if (b == NULL) { b = purple_buddy_new(data->account, who, whoalias); purple_blist_add_buddy(b, NULL, g, NULL); -- cgit v1.2.1 From 82650f71e951f9a3a70aa8510fb0e0568fa2b832 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Fri, 2 Jan 2009 19:31:16 +0000 Subject: Fix merge --- libpurple/protocols/myspace/user.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurple/protocols/myspace/user.h b/libpurple/protocols/myspace/user.h index 0f17b28c6d..d1a8b59970 100644 --- a/libpurple/protocols/myspace/user.h +++ b/libpurple/protocols/myspace/user.h @@ -46,7 +46,7 @@ typedef struct _MsimUser * initiated from a user lookup. */ typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, const MsimMessage *userinfo, gpointer data); -MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy); +MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy, gboolean create); void msim_user_free(MsimUser *user); MsimUser *msim_find_user(MsimSession *session, const gchar *username); void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full); -- cgit v1.2.1 From f45126c0fd5f91ce1df71a0c470b6641a947f3dc Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sat, 7 Mar 2009 22:40:30 +0000 Subject: Fixing busted merge --- pidgin/plugins/gevolution/gevo-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidgin/plugins/gevolution/gevo-util.c b/pidgin/plugins/gevolution/gevo-util.c index e097478287..d5cac965da 100644 --- a/pidgin/plugins/gevolution/gevo-util.c +++ b/pidgin/plugins/gevolution/gevo-util.c @@ -41,7 +41,7 @@ gevo_add_buddy(PurpleAccount *account, const char *group_name, purple_blist_add_group(group, NULL); } - if ((buddy = purple_find_buddy_in_group(account, buddy_name, group))) { + if ((buddy = purple_find_buddy_in_group(account, buddy_name, group))) { buddy = purple_buddy_new(account, buddy_name, alias); purple_blist_add_buddy(buddy, NULL, group, NULL); -- cgit v1.2.1 From fe0788b53233a2c98e65e9b271f96a7b9379e989 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Thu, 12 Mar 2009 05:56:04 +0000 Subject: Exposing the GHashTable seems crazy to me. See #8644. --- libpurple/blist.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libpurple/blist.h b/libpurple/blist.h index 460291a886..d770690022 100644 --- a/libpurple/blist.h +++ b/libpurple/blist.h @@ -118,8 +118,8 @@ typedef enum /** * A Buddy list node. This can represent a group, a buddy, or anything else. - * This is a base class for struct buddy and struct group and for anything - * else that wants to put itself in the buddy list. */ + * This is a base class for PurpleBuddy, PurpleContact, PurpleGroup, and for + * anything else that wants to put itself in the buddy list. */ struct _PurpleBlistNode { PurpleBlistNodeType type; /**< The type of node this is */ PurpleBlistNode *prev; /**< The sibling before this buddy. */ @@ -207,7 +207,7 @@ struct _PurpleBlistUiOps PurpleBlistNode *node); /**< This will update a node in the buddy list. */ void (*remove)(PurpleBuddyList *list, PurpleBlistNode *node); /**< This removes a node from the list */ - void (*destroy)(PurpleBuddyList *list); /**< When the list gets destroyed, this gets called to destroy the UI. */ + void (*destroy)(PurpleBuddyList *list); /**< When the list is destroyed, this is called to destroy the UI. */ void (*set_visible)(PurpleBuddyList *list, gboolean show); /**< Hides or unhides the buddy list */ void (*request_add_buddy)(PurpleAccount *account, const char *username, @@ -261,6 +261,11 @@ PurpleBlistNode *purple_blist_get_root(void); /** * Returns the hash table of every buddy in the list. + * You MUST treat this data structure as immutable. The only use should + * be for iterating over the values (PurpleBuddy*) in performance-critical + * code. + * + * @see purple_find_buddy for the recommended alternative. * * @return The hash table of every buddy in the list. * -- cgit v1.2.1 From 0112687f7b0fd7d36d57c748b1557cd04001a792 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Thu, 12 Mar 2009 06:01:56 +0000 Subject: Repluralize these --- libpurple/smiley.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libpurple/smiley.h b/libpurple/smiley.h index c7b0a3b31c..cb951b6cbf 100644 --- a/libpurple/smiley.h +++ b/libpurple/smiley.h @@ -67,7 +67,7 @@ extern "C" { GType purple_smiley_get_type(void); /** - * Create a new custom smiley from a PurpleStoredImage. + * Creates a new custom smiley from a PurpleStoredImage. * * If a custom smiley with the given shortcut already exists, it * will be automaticaly returned. @@ -81,7 +81,7 @@ PurpleSmiley * purple_smiley_new(PurpleStoredImage *img, const char *shortcut); /** - * Create a new custom smiley, reading the image data from a file. + * Creates a new custom smiley, reading the image data from a file. * * If a custom smiley with the given shortcut already exists, it * will be automaticaly returned. @@ -95,7 +95,7 @@ PurpleSmiley * purple_smiley_new_from_file(const char *shortcut, const char *filepath); /** - * Destroy the custom smiley and release the associated resources. + * Destroys the custom smiley and release the associated resources. * * @param smiley The custom smiley. */ -- cgit v1.2.1 From 295b6498e1b9823f8c6c8723b9383000dcf8c1a2 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Thu, 12 Mar 2009 06:19:15 +0000 Subject: More documentation (mostly little changes) --- libpurple/blist.h | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/libpurple/blist.h b/libpurple/blist.h index d770690022..356d80fc77 100644 --- a/libpurple/blist.h +++ b/libpurple/blist.h @@ -280,7 +280,7 @@ GHashTable *purple_blist_get_buddies(void); * * @since 2.6.0 */ -void *purple_blist_get_ui_data(void); +gpointer purple_blist_get_ui_data(void); /** * Sets the UI data for the list. @@ -289,7 +289,7 @@ void *purple_blist_get_ui_data(void); * * @since 2.6.0 */ -void purple_blist_set_ui_data(void *ui_data); +void purple_blist_set_ui_data(gpointer ui_data); /** * Returns the next node of a given node. This function is to be used to iterate @@ -364,7 +364,7 @@ PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node); * @return The UI data. * @since 2.6.0 */ -void *purple_blist_node_get_ui_data(const PurpleBlistNode *node); +gpointer purple_blist_node_get_ui_data(const PurpleBlistNode *node); /** * Sets the UI data of a given node. @@ -374,7 +374,7 @@ void *purple_blist_node_get_ui_data(const PurpleBlistNode *node); * * @since 2.6.0 */ -void purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data); +void purple_blist_node_set_ui_data(PurpleBlistNode *node, gpointer ui_data); /** * Shows the buddy list, creating a new one if necessary. @@ -397,6 +397,8 @@ void purple_blist_set_visible(gboolean show); /** * Updates a buddy's status. * + * This should only be called from within Purple. + * * @param buddy The buddy whose status has changed. * @param old_status The status from which we are changing. */ @@ -496,12 +498,19 @@ PurpleChat *purple_chat_new(PurpleAccount *account, const char *alias, GHashTabl void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node); /** - * Creates a new buddy + * Creates a new buddy. + * + * This function only creates the PurpleBuddy. Use purple_blist_add_buddy + * to add the buddy to the list and purple_account_add_buddy to sync up + * with the server. * * @param account The account this buddy will get added to * @param name The name of the new buddy * @param alias The alias of the new buddy (or NULL if unaliased) * @return A newly allocated buddy + * + * @see purple_account_add_buddy + * @see purple_blist_add_buddy */ PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias); @@ -608,7 +617,7 @@ void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGr * Creates a new group * * You can't have more than one group with the same name. Sorry. If you pass - * this the * name of a group that already exists, it will return that group. + * this the name of a group that already exists, it will return that group. * * @param name The name of the new group * @return A new group struct @@ -703,19 +712,23 @@ void purple_contact_invalidate_priority_buddy(PurpleContact *contact); /** * Removes a buddy from the buddy list and frees the memory allocated to it. - * This doesn't actually try to remove the buddy from the server list, nor does - * it clean up the prpl_data. + * This doesn't actually try to remove the buddy from the server list. * * @param buddy The buddy to be removed + * + * @see purple_account_remove_buddy */ void purple_blist_remove_buddy(PurpleBuddy *buddy); /** * Removes a contact, and any buddies it contains, and frees the memory - * allocated to it. + * allocated to it. This calls purple_blist_remove_buddy and therefore + * doesn't remove the buddies from the server list. * * @param contact The contact to be removed - */ + * + * @see purple_blist_remove_buddy + * */ void purple_blist_remove_contact(PurpleContact *contact); /** @@ -826,7 +839,7 @@ PurpleBuddy *purple_find_buddy_in_group(PurpleAccount *account, const char *name * Finds all PurpleBuddy structs given a name and an account * * @param account The account this buddy belongs to - * @param name The buddy's name (or NULL to return all buddies in the account) + * @param name The buddy's name (or NULL to return all buddies for the account) * * @return A GSList of buddies (which must be freed), or NULL if the buddy doesn't exist */ @@ -921,7 +934,7 @@ gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account); const char *purple_group_get_name(PurpleGroup *group); /** - * Called when an account gets signed on. Tells the UI to update all the + * Called when an account connects. Tells the UI to update all the * buddies. * * @param account The account @@ -930,7 +943,7 @@ void purple_blist_add_account(PurpleAccount *account); /** - * Called when an account gets signed off. Sets the presence of all the buddies to 0 + * Called when an account disconnects. Sets the presence of all the buddies to 0 * and tells the UI to update them. * * @param account The account -- cgit v1.2.1 From 6b2dd8a67b12b89e28534389b32d972d4820f35a Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Thu, 12 Mar 2009 11:02:02 +0000 Subject: fix a crash when changing to away without a status message --- libpurple/protocols/oscar/oscar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index 4b8534e8bd..2511111c65 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -4789,7 +4789,7 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char * status_html = purple_status_get_attr_string(status, "message"); - if (primitive == PURPLE_STATUS_AVAILABLE || primitive == PURPLE_STATUS_INVISIBLE) + if (status_html == NULL || primitive == PURPLE_STATUS_AVAILABLE || primitive == PURPLE_STATUS_INVISIBLE) { /* This is needed for us to un-set any previous away message. */ away = g_strdup(""); -- cgit v1.2.1 From b1eba08dab236c82fc629627dd201b4f1e36e146 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 13 Mar 2009 02:21:27 +0000 Subject: Is there any reason this is an int instead of PurplePrivacyType? I believe this is safe to do without breaking binary or API compatibility, but someone please yell at me if not --- libpurple/account.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libpurple/account.h b/libpurple/account.h index 7c6bfe9282..4d647546a9 100644 --- a/libpurple/account.h +++ b/libpurple/account.h @@ -42,6 +42,7 @@ typedef void (*PurpleAccountUnregistrationCb)(PurpleAccount *account, gboolean s #include "connection.h" #include "log.h" +#include "privacy.h" #include "proxy.h" #include "prpl.h" #include "status.h" @@ -141,7 +142,7 @@ struct _PurpleAccount */ GSList *permit; /**< Permit list. */ GSList *deny; /**< Deny list. */ - int perm_deny; /**< The permit/deny setting. */ + PurplePrivacyType perm_deny; /**< The permit/deny setting. */ GList *status_types; /**< Status types. */ -- cgit v1.2.1 From abe494ce3882c91ff234ca692d0b2694f429ddcb Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 13 Mar 2009 02:51:00 +0000 Subject: Add a note that this function could potentially be faster. --- libpurple/util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libpurple/util.c b/libpurple/util.c index ac7598e317..0befee69a3 100644 --- a/libpurple/util.c +++ b/libpurple/util.c @@ -2850,6 +2850,12 @@ purple_util_get_image_extension(gconstpointer data, size_t len) return "icon"; } +/* + * TODO: Consider using something faster than SHA-1, such as MD5, MD4 + * or CRC32. Are there security implications to that? Would + * probably be a good idea to benchmark some algorithms with + * 3KB-10KB chunks of data (typical buddy icon sizes). + */ char * purple_util_get_image_checksum(gconstpointer image_data, size_t image_len) { -- cgit v1.2.1 From 821d8660244e7ef3dd02ed8b9ad48ca41947dc4b Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Fri, 13 Mar 2009 03:02:01 +0000 Subject: Mark "Khmer" as translatable since we're not in string freeze --- pidgin/gtkdialogs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c index f8aa7aa755..75d5b01f28 100644 --- a/pidgin/gtkdialogs.c +++ b/pidgin/gtkdialogs.c @@ -189,7 +189,7 @@ static const struct translator translators[] = { {N_("Italian"), "it", "Claudio Satriano", "satriano@na.infn.it"}, {N_("Japanese"), "ja", "Takashi Aihana", "aihana@gnome.gr.jp"}, {N_("Georgian"), "ka", N_("Ubuntu Georgian Translators"), "alexander.didebulidze@stusta.mhn.de"}, - {"Khmer", "km", "Khoem Sokhem", "khoemsokhem@khmeros.info"}, + {N_("Khmer"), "km", "Khoem Sokhem", "khoemsokhem@khmeros.info"}, {N_("Kannada"), "kn", N_("Kannada Translation team"), "translation@sampada.info"}, {N_("Korean"), "ko", "Sushizang", "sushizang@empal.com"}, {N_("Kurdish"), "ku", "Erdal Ronahi", "erdal.ronahi@gmail.com"}, -- cgit v1.2.1 From 0bf9892bf774eca45c70eb2311defe62b6f172dd Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Fri, 13 Mar 2009 03:04:07 +0000 Subject: Move 'Minutes before becoming idle' above 'Change status when idle' Minutes before becoming idle has an effect even when we're not doing autoaway, so it should not be disabled then. --- pidgin/gtkprefs.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c index 44f05ea794..9ca650993d 100644 --- a/pidgin/gtkprefs.c +++ b/pidgin/gtkprefs.c @@ -2385,14 +2385,12 @@ away_page(void) /* Auto-away stuff */ vbox = pidgin_make_frame(ret, _("Auto-away")); - button = pidgin_prefs_checkbox(_("Change status when _idle"), - "/purple/away/away_when_idle", vbox); - select = pidgin_prefs_labeled_spin_button(vbox, _("_Minutes before becoming idle:"), "/purple/away/mins_before_away", 1, 24 * 60, sg); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pidgin_toggle_sensitive), select); + + button = pidgin_prefs_checkbox(_("Change status when _idle"), + "/purple/away/away_when_idle", vbox); /* TODO: Show something useful if we don't have any saved statuses. */ menu = pidgin_status_menu(purple_savedstatus_get_idleaway(), G_CALLBACK(set_idle_away)); @@ -2404,7 +2402,6 @@ away_page(void) if (!purple_prefs_get_bool("/purple/away/away_when_idle")) { gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(select), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE); } -- cgit v1.2.1 From 832b349cf2ff00439333abc4b8dfcfbed51f7635 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 13 Mar 2009 04:29:11 +0000 Subject: Add xmlnode_set_attrib_full that enables you to set an attribute with both a prefix and a namespace. Also, change xmlnode_remove_attribute to remove all existing attributes that match the name. Otherwise, it would just take out the first one, and may not do what you want. Change Bonjour and XMPP to use the new function. References #7681. Fixes #8318. --- ChangeLog.API | 10 ++++++ libpurple/protocols/bonjour/parser.c | 11 +++--- libpurple/protocols/jabber/parser.c | 4 ++- libpurple/xmlnode.c | 68 +++++++++++++++--------------------- libpurple/xmlnode.h | 20 +++++++++++ 5 files changed, 66 insertions(+), 47 deletions(-) diff --git a/ChangeLog.API b/ChangeLog.API index ba94d7b728..5af7616641 100644 --- a/ChangeLog.API +++ b/ChangeLog.API @@ -26,6 +26,14 @@ version 2.6.0 (??/??/2009): * purple_request_field_set_ui_data * purple_strequal * xmlnode_from_file + * xmlnode_set_attrib_full + + Changed: + * xmlnode_remove_attrib now removes all attributes with the + same name. Previously, it would remove the first one found, + which was completely non-deterministic. If you want to remove + the attribute with no namespace, then use NULL with + xmlnode_remove_with_namespace. Deprecated: * purple_buddy_get_local_alias @@ -40,6 +48,8 @@ version 2.6.0 (??/??/2009): * purple_status_set_attr_string * purple_presence_add_status * purple_presence_add_list + * xmlnode_set_attrib_with_namespace + * xmlnode_set_attrib_with_prefix pidgin: Added: diff --git a/libpurple/protocols/bonjour/parser.c b/libpurple/protocols/bonjour/parser.c index 44a8e8bd99..04d6f10681 100644 --- a/libpurple/protocols/bonjour/parser.c +++ b/libpurple/protocols/bonjour/parser.c @@ -91,14 +91,12 @@ bonjour_parser_element_start_libxml(void *user_data, xmlnode_set_namespace(node, (const char*) namespace); for(i=0; i < nb_attributes * 5; i+=5) { + const char *name = (const char *)attributes[i]; + const char *prefix = (const char *)attributes[i+1]; + const char *attrib_ns = (const char *)attributes[i+2]; char *txt; int attrib_len = attributes[i+4] - attributes[i+3]; char *attrib = g_malloc(attrib_len + 1); - char *attrib_ns = NULL; - - if (attributes[i+2]) { - attrib_ns = g_strdup((char*)attributes[i+2]); - } memcpy(attrib, attributes[i+3], attrib_len); attrib[attrib_len] = '\0'; @@ -106,9 +104,8 @@ bonjour_parser_element_start_libxml(void *user_data, txt = attrib; attrib = purple_unescape_html(txt); g_free(txt); - xmlnode_set_attrib_with_namespace(node, (const char*) attributes[i], attrib_ns, attrib); + xmlnode_set_attrib_full(node, name, attrib_ns, prefix, attrib); g_free(attrib); - g_free(attrib_ns); } bconv->current = node; diff --git a/libpurple/protocols/jabber/parser.c b/libpurple/protocols/jabber/parser.c index 4e602768ce..35186ad15e 100644 --- a/libpurple/protocols/jabber/parser.c +++ b/libpurple/protocols/jabber/parser.c @@ -86,6 +86,8 @@ jabber_parser_element_start_libxml(void *user_data, } } for(i=0; i < nb_attributes * 5; i+=5) { + const char *name = (const char *)attributes[i]; + const char *prefix = (const char *)attributes[i+1]; const char *attrib_ns = (const char *)attributes[i+2]; char *txt; int attrib_len = attributes[i+4] - attributes[i+3]; @@ -97,7 +99,7 @@ jabber_parser_element_start_libxml(void *user_data, txt = attrib; attrib = purple_unescape_html(txt); g_free(txt); - xmlnode_set_attrib_with_namespace(node, (const char*) attributes[i], attrib_ns, attrib); + xmlnode_set_attrib_full(node, name, attrib_ns, prefix, attrib); g_free(attrib); } diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c index fc2fc37b36..be8a731a62 100644 --- a/libpurple/xmlnode.c +++ b/libpurple/xmlnode.c @@ -27,6 +27,7 @@ * libxode uses memory pools that we simply have no need for, I decided to * write my own stuff. Also, re-writing this lets me be as lightweight * as I want to be. Thank you libxode for giving me a good starting point */ +#define _PURPLE_XMLNODE_C_ #include "debug.h" #include "internal.h" @@ -126,21 +127,28 @@ xmlnode_remove_attrib(xmlnode *node, const char *attr) g_return_if_fail(node != NULL); g_return_if_fail(attr != NULL); - for(attr_node = node->child; attr_node; attr_node = attr_node->next) - { + attr_node = node->child; + while (attr_node) { if(attr_node->type == XMLNODE_TYPE_ATTRIB && purple_strequal(attr_node->name, attr)) { - if(sibling == NULL) { + if (node->lastchild == attr_node) { + node->lastchild = sibling; + } + if (sibling == NULL) { node->child = attr_node->next; + xmlnode_free(attr_node); + attr_node = node->child; } else { sibling->next = attr_node->next; + sibling = attr_node->next; + xmlnode_free(attr_node); + attr_node = sibling; } - if (node->lastchild == attr_node) { - node->lastchild = sibling; - } - xmlnode_free(attr_node); - return; + } + else + { + attr_node = attr_node->next; } sibling = attr_node; } @@ -178,41 +186,24 @@ xmlnode_remove_attrib_with_namespace(xmlnode *node, const char *attr, const char void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value) { - xmlnode *attrib_node; - - g_return_if_fail(node != NULL); - g_return_if_fail(attr != NULL); - g_return_if_fail(value != NULL); - xmlnode_remove_attrib(node, attr); - - attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB); - - attrib_node->data = g_strdup(value); - - xmlnode_insert_child(node, attrib_node); + xmlnode_set_attrib_full(node, attr, NULL, NULL, value); } void xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value) { - xmlnode *attrib_node; - - g_return_if_fail(node != NULL); - g_return_if_fail(attr != NULL); - g_return_if_fail(value != NULL); - - xmlnode_remove_attrib_with_namespace(node, attr, xmlns); - attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB); - - attrib_node->data = g_strdup(value); - attrib_node->xmlns = g_strdup(xmlns); - - xmlnode_insert_child(node, attrib_node); + xmlnode_set_attrib_full(node, attr, xmlns, NULL, value); } void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value) +{ + xmlnode_set_attrib_full(node, attr, NULL, prefix, value); +} + +void +xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value) { xmlnode *attrib_node; @@ -220,9 +211,11 @@ xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *pref g_return_if_fail(attr != NULL); g_return_if_fail(value != NULL); + xmlnode_remove_attrib_with_namespace(node, attr, xmlns); attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB); attrib_node->data = g_strdup(value); + attrib_node->xmlns = g_strdup(xmlns); attrib_node->prefix = g_strdup(prefix); xmlnode_insert_child(node, attrib_node); @@ -585,7 +578,8 @@ xmlnode_parser_element_start_libxml(void *user_data, } for(i=0; i < nb_attributes * 5; i+=5) { - const char *prefix = (const char *)attributes[i + 1]; + const char *name = (const char *)attributes[i]; + const char *prefix = (const char *)attributes[i+1]; char *txt; int attrib_len = attributes[i+4] - attributes[i+3]; char *attrib = g_malloc(attrib_len + 1); @@ -594,11 +588,7 @@ xmlnode_parser_element_start_libxml(void *user_data, txt = attrib; attrib = purple_unescape_html(txt); g_free(txt); - if (prefix && *prefix) { - xmlnode_set_attrib_with_prefix(node, (const char*) attributes[i], prefix, attrib); - } else { - xmlnode_set_attrib(node, (const char*) attributes[i], attrib); - } + xmlnode_set_attrib_full(node, name, NULL, prefix, attrib); g_free(attrib); } diff --git a/libpurple/xmlnode.h b/libpurple/xmlnode.h index bab8192d13..bfc41f2403 100644 --- a/libpurple/xmlnode.h +++ b/libpurple/xmlnode.h @@ -157,6 +157,7 @@ char *xmlnode_get_data_unescaped(xmlnode *node); */ void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_XMLNODE_C_) /** * Sets a prefixed attribute for a node * @@ -164,6 +165,8 @@ void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value); * @param attr The name of the attribute to set * @param prefix The prefix of the attribute to ste * @param value The value of the attribute + * + * @deprecated Use xmlnode_set_attrib_full instead. */ void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value); @@ -174,8 +177,25 @@ void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char * @param attr The name of the attribute to set * @param xmlns The namespace of the attribute to ste * @param value The value of the attribute + * + * @deprecated Use xmlnode_set_attrib_full instead. */ void xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value); +#endif /* PURPLE_DISABLE_DEPRECATED */ + +/** + * Sets a namespaced attribute for a node + * + * @param node The node to set an attribute for. + * @param attr The name of the attribute to set + * @param xmlns The namespace of the attribute to ste + * @param prefix The prefix of the attribute to ste + * @param value The value of the attribute + * + * @since 2.6.0 + */ +void xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, + const char *prefix, const char *value); /** * Gets an attribute from a node. -- cgit v1.2.1 From 157f075b9ce69746c0577bed7b4205667c99a185 Mon Sep 17 00:00:00 2001 From: Marcus Lundblad Date: Sun, 15 Mar 2009 20:19:44 +0000 Subject: Unleak --- libpurple/protocols/jabber/si.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c index d4560a09ec..fe3f490c22 100644 --- a/libpurple/protocols/jabber/si.c +++ b/libpurple/protocols/jabber/si.c @@ -1096,6 +1096,7 @@ jabber_si_xfer_ibb_send_data(JabberIBBSession *sess) "jabber_si_xfer_ibb_send_data: error reading from file\n"); purple_xfer_cancel_local(xfer); } + g_free(data); } static void -- cgit v1.2.1 From fde6567b1218f7d020866d86a63572536ca85393 Mon Sep 17 00:00:00 2001 From: Kevin Stange Date: Mon, 16 Mar 2009 17:07:41 +0000 Subject: A patch from Jorge Villase?or which makes all pounces share a single window. The window is based on the one used by the mail notifications. I made some extra changes on top of the patch to clean things up a little bit, mainly to improve strings. Blame me if something breaks! Thanks to bjlockie for helping with testing. Closes #190. --- ChangeLog | 3 + ChangeLog.API | 1 + pidgin/gtknotify.c | 503 +++++++++++++++++++++++++++++++++++++++++++---------- pidgin/gtknotify.h | 12 ++ pidgin/gtkpounce.c | 40 ++--- 5 files changed, 447 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef538d8b1c..af3fa67814 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,9 @@ version 2.6.0 (??/??/2009): * Pressing the Enter key in the message entry box of the New Status dialog and various other dialogs now causes the cursor to move to the next line. + * Created a unified Buddy Pounce notification window for all pounces + where "Pop up a notification" is selected, which avoids having a + new dialog box every time a pounce is triggered. (Jorge Villaseñor) version 2.5.5 (03/01/2009): libpurple: diff --git a/ChangeLog.API b/ChangeLog.API index 5af7616641..22d0469161 100644 --- a/ChangeLog.API +++ b/ChangeLog.API @@ -62,6 +62,7 @@ version 2.6.0 (??/??/2009): * pidgin_blist_get_theme * pidgin_sound_is_customized * pidgin_utils_init, pidgin_utils_uninit + * pidgin_notify_pounce_add perl: Changed: diff --git a/pidgin/gtknotify.c b/pidgin/gtknotify.c index 288bc83d4a..427f606e8f 100644 --- a/pidgin/gtknotify.c +++ b/pidgin/gtknotify.c @@ -28,6 +28,7 @@ #include +#include "account.h" #include "connection.h" #include "debug.h" #include "prefs.h" @@ -37,6 +38,7 @@ #include "gtkblist.h" #include "gtkimhtml.h" #include "gtknotify.h" +#include "gtkpounce.h" #include "gtkutils.h" typedef struct @@ -54,6 +56,13 @@ typedef struct gboolean purple_has_handle; } PidginNotifyMailData; +typedef struct +{ + PurpleAccount *account; + PurplePounce *pounce; +} PidginNotifyPounceData; + + typedef struct { PurpleAccount *account; @@ -80,21 +89,44 @@ enum COLUMNS_PIDGIN_MAIL }; -typedef struct _PidginMailDialog PidginMailDialog; +enum +{ + PIDGIN_POUNCE_ICON, + PIDGIN_POUNCE_ALIAS, + PIDGIN_POUNCE_EVENT, + PIDGIN_POUNCE_TEXT, + PIDGIN_POUNCE_DATE, + PIDGIN_POUNCE_DATA, + PIDGIN_POUNCE_COLUMNS +}; -struct _PidginMailDialog +typedef struct _PidginNotifyDialog PidginNotifyDialog; +typedef PidginNotifyDialog PidginMailDialog; + +struct _PidginNotifyDialog { GtkWidget *dialog; GtkWidget *treeview; GtkTreeStore *treemodel; GtkLabel *label; GtkWidget *open_button; + GtkWidget *dismiss_button; + GtkWidget *edit_button; int total_count; gboolean in_use; }; -static PidginMailDialog *mail_dialog = NULL; +typedef enum +{ + PIDGIN_NOTIFY_MAIL, + PIDGIN_NOTIFY_POUNCE, + PIDGIN_NOTIFY_TYPES +} PidginNotifyType; + +static PidginNotifyDialog *mail_dialog = NULL; +static PidginNotifyDialog *pounce_dialog = NULL; +static GtkWidget *pidgin_get_notification_dialog(PidginNotifyType type); static void *pidgin_notify_emails(PurpleConnection *gc, size_t count, gboolean detailed, const char **subjects, const char **froms, const char **tos, @@ -108,6 +140,159 @@ message_response_cb(GtkDialog *dialog, gint id, GtkWidget *widget) purple_notify_close(PURPLE_NOTIFY_MESSAGE, widget); } +static void +pounce_response_close(PidginNotifyDialog *dialog) +{ + GtkTreeIter iter; + PidginNotifyPounceData *pounce_data; + + while (gtk_tree_model_get_iter_first( + GTK_TREE_MODEL(pounce_dialog->treemodel), &iter)) { + gtk_tree_model_get(GTK_TREE_MODEL(pounce_dialog->treemodel), &iter, + PIDGIN_POUNCE_DATA, &pounce_data, + -1); + gtk_tree_store_remove(dialog->treemodel, &iter); + + g_free(pounce_data); + } + + gtk_widget_destroy(pounce_dialog->dialog); + g_free(pounce_dialog); + pounce_dialog = NULL; +} + +static void +delete_foreach(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data) +{ + PidginNotifyPounceData *pounce_data; + + gtk_tree_model_get(model, iter, + PIDGIN_POUNCE_DATA, &pounce_data, + -1); + + if (pounce_data != NULL) + g_free(pounce_data); +} + +static void +append_to_list(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data) +{ + GList **list = data; + *list = g_list_prepend(*list, gtk_tree_path_copy(path)); +} +static void +pounce_response_dismiss() +{ + GtkTreeSelection *selection; + GList *list = NULL; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pounce_dialog->treeview)); + gtk_tree_selection_selected_foreach(selection, delete_foreach, pounce_dialog); + gtk_tree_selection_selected_foreach(selection, append_to_list, &list); + + while (list) { + GtkTreeIter iter; + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(pounce_dialog->treemodel), &iter, + list->data)) { + gtk_tree_store_remove(GTK_TREE_STORE(pounce_dialog->treemodel), &iter); + } + gtk_tree_path_free(list->data); + list = g_list_delete_link(list, list); + } +} + +static void +pounce_response_edit_cb(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer data) +{ + PidginNotifyPounceData *pounce_data; + PidginNotifyDialog *dialog = (PidginNotifyDialog*)data; + PurplePounce *pounce; + GList *list; + + list = purple_pounces_get_all(); + + gtk_tree_model_get(GTK_TREE_MODEL(dialog->treemodel), iter, + PIDGIN_POUNCE_DATA, &pounce_data, + -1); + + for (; list != NULL; list = list->next) { + pounce = list->data; + if (pounce == pounce_data->pounce) { + pidgin_pounce_editor_show(pounce_data->account, NULL, pounce_data->pounce); + return; + } + } + + purple_debug_warning("gtknotify", "Pounce was destroyed.\n"); +} + +static void +pounce_response_cb(GtkDialog *dlg, gint id, PidginNotifyDialog *dialog) +{ + GtkTreeSelection *selection = NULL; + + switch (id) { + case GTK_RESPONSE_CLOSE: + case GTK_RESPONSE_DELETE_EVENT: + pounce_response_close(dialog); + break; + case GTK_RESPONSE_NO: + pounce_response_dismiss(); + break; + case GTK_RESPONSE_APPLY: + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); + gtk_tree_selection_selected_foreach(selection, pounce_response_edit_cb, + dialog); + break; + } +} + +static void +pounce_row_selected_cb(GtkTreeView *tv, GtkTreePath *path, + GtkTreeViewColumn *col, gpointer data) +{ + GtkTreeIter iter; + GtkTreeSelection *selection; + gboolean selected; + GList *list; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pounce_dialog->treeview)); + + selected = gtk_tree_selection_get_selected(selection, + NULL, &iter); + + if (selected) { + PurplePounce *pounce; + PidginNotifyPounceData *pounce_data; + + list = purple_pounces_get_all(); + + gtk_tree_model_get(GTK_TREE_MODEL(pounce_dialog->treemodel), &iter, + PIDGIN_POUNCE_DATA, &pounce_data, + -1); + + gtk_widget_set_sensitive(pounce_dialog->edit_button, FALSE); + + for (; list != NULL; list = list->next) { + pounce = list->data; + if (pounce == pounce_data->pounce) { + gtk_widget_set_sensitive(pounce_dialog->edit_button, TRUE); + break; + } + } + + gtk_widget_set_sensitive(pounce_dialog->dismiss_button, TRUE); + } else { + gtk_widget_set_sensitive(pounce_dialog->edit_button, FALSE); + gtk_widget_set_sensitive(pounce_dialog->dismiss_button, FALSE); + } + + +} + static void email_response_cb(GtkDialog *dlg, gint id, PidginMailDialog *dialog) { @@ -342,89 +527,7 @@ mail_window_focus_cb(GtkWidget *widget, GdkEventFocus *focus, gpointer null) static GtkWidget * pidgin_get_mail_dialog(void) { - if (mail_dialog == NULL) { - GtkWidget *dialog = NULL; - GtkWidget *label; - GtkWidget *sw; - GtkCellRenderer *rend; - GtkTreeViewColumn *column; - GtkWidget *button = NULL; - GtkWidget *vbox = NULL; - - dialog = gtk_dialog_new_with_buttons(_("New Mail"), NULL, 0, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - gtk_window_set_role(GTK_WINDOW(dialog), "new_mail_detailed"); - g_signal_connect(G_OBJECT(dialog), "focus-in-event", - G_CALLBACK(mail_window_focus_cb), NULL); - - gtk_dialog_add_button(GTK_DIALOG(dialog), - _("Open All Messages"), GTK_RESPONSE_ACCEPT); - - button = gtk_dialog_add_button(GTK_DIALOG(dialog), - PIDGIN_STOCK_OPEN_MAIL, GTK_RESPONSE_YES); - - /* make "Open All Messages" the default response */ - gtk_dialog_set_default_response(GTK_DIALOG(dialog), - GTK_RESPONSE_ACCEPT); - - /* Setup the dialog */ - gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE); - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE); - gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); - gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER); - - /* Vertical box */ - vbox = GTK_DIALOG(dialog)->vbox; - - /* Golden ratio it up! */ - gtk_widget_set_size_request(dialog, 550, 400); - - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - - mail_dialog = g_new0(PidginMailDialog, 1); - mail_dialog->dialog = dialog; - mail_dialog->open_button = button; - - mail_dialog->treemodel = gtk_tree_store_new(COLUMNS_PIDGIN_MAIL, - GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); - mail_dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(mail_dialog->treemodel)); - g_object_unref(G_OBJECT(mail_dialog->treemodel)); - gtk_tree_view_set_search_column(GTK_TREE_VIEW(mail_dialog->treeview), PIDGIN_MAIL_TEXT); - gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(mail_dialog->treeview), - pidgin_tree_view_search_equal_func, NULL, NULL); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(email_response_cb), mail_dialog); - g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(mail_dialog->treeview))), - "changed", G_CALLBACK(selection_changed_cb), mail_dialog); - g_signal_connect(G_OBJECT(mail_dialog->treeview), "row-activated", G_CALLBACK(email_row_activated_cb), NULL); - - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(mail_dialog->treeview), FALSE); - gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(mail_dialog->treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), mail_dialog->treeview); - - column = gtk_tree_view_column_new(); - gtk_tree_view_column_set_resizable(column, TRUE); - rend = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, "pixbuf", PIDGIN_MAIL_ICON, NULL); - rend = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(column, rend, TRUE); - gtk_tree_view_column_set_attributes(column, rend, "markup", PIDGIN_MAIL_TEXT, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(mail_dialog->treeview), column); - - label = gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(label), _("You have mail!")); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - } - - return mail_dialog->dialog; + return pidgin_get_notification_dialog(PIDGIN_NOTIFY_MAIL); } /* count == 0 means this is a detailed mail notification. @@ -1001,8 +1104,10 @@ pidgin_close_notify(PurpleNotifyType type, void *ui_handle) { PidginNotifyMailData *data = (PidginNotifyMailData *)ui_handle; - g_free(data->url); - g_free(data); + if (data) { + g_free(data->url); + g_free(data); + } } else if (type == PURPLE_NOTIFY_SEARCHRESULTS) { @@ -1234,6 +1339,228 @@ pidgin_notify_uri(const char *uri) return NULL; } +static GtkWidget * +pidgin_get_dialog(PidginNotifyType type, GtkTreeStore *treemodel) +{ + GtkWidget *dialog = NULL; + GtkWidget *label = NULL; + GtkWidget *sw; + GtkCellRenderer *rend; + GtkTreeViewColumn *column; + GtkWidget *button = NULL; + GtkWidget *vbox = NULL; + GtkTreeSelection *sel; + PidginNotifyDialog *spec_dialog = NULL; + + g_return_val_if_fail(type < PIDGIN_NOTIFY_TYPES, NULL); + + dialog = gtk_dialog_new_with_buttons(NULL, NULL, 0, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + /* Setup the dialog */ + gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE); + gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BOX_SPACE); + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), PIDGIN_HIG_BORDER); + + /* Vertical box */ + vbox = GTK_DIALOG(dialog)->vbox; + + /* Golden ratio it up! */ + gtk_widget_set_size_request(dialog, 550, 400); + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + + spec_dialog = g_new0(PidginNotifyDialog, 1); + spec_dialog->dialog = dialog; + spec_dialog->open_button = button; + + spec_dialog->treemodel = treemodel; + spec_dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(spec_dialog->treemodel)); + g_object_unref(G_OBJECT(spec_dialog->treemodel)); + + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(spec_dialog->treeview), TRUE); + gtk_container_add(GTK_CONTAINER(sw), spec_dialog->treeview); + + if (type == PIDGIN_NOTIFY_MAIL) { + gtk_window_set_title(GTK_WINDOW(dialog), _("New Mail")); + gtk_window_set_role(GTK_WINDOW(dialog), "new_mail_detailed"); + g_signal_connect(G_OBJECT(dialog), "focus-in-event", + G_CALLBACK(mail_window_focus_cb), NULL); + + gtk_dialog_add_button(GTK_DIALOG(dialog), + _("Open All Messages"), GTK_RESPONSE_ACCEPT); + + button = gtk_dialog_add_button(GTK_DIALOG(dialog), + PIDGIN_STOCK_OPEN_MAIL, GTK_RESPONSE_YES); + + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(spec_dialog->treeview), FALSE); + + gtk_tree_view_set_search_column(GTK_TREE_VIEW(spec_dialog->treeview), PIDGIN_MAIL_TEXT); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(spec_dialog->treeview), + pidgin_tree_view_search_equal_func, NULL, NULL); + + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(email_response_cb), spec_dialog); + g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(spec_dialog->treeview))), + "changed", G_CALLBACK(selection_changed_cb), spec_dialog); + g_signal_connect(G_OBJECT(spec_dialog->treeview), "row-activated", G_CALLBACK(email_row_activated_cb), NULL); + + column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_resizable(column, TRUE); + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", PIDGIN_MAIL_ICON, NULL); + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, TRUE); + gtk_tree_view_column_set_attributes(column, rend, "markup", PIDGIN_MAIL_TEXT, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(spec_dialog->treeview), column); + + label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label), _("You have mail!")); + + } else if (type == PIDGIN_NOTIFY_POUNCE) { + gtk_window_set_title(GTK_WINDOW(dialog), _("New Pounces")); + + button = gtk_dialog_add_button(GTK_DIALOG(dialog), + _("Dismiss"), GTK_RESPONSE_NO); + gtk_widget_set_sensitive(button, FALSE); + spec_dialog->dismiss_button = button; + + button = gtk_dialog_add_button(GTK_DIALOG(dialog), + PIDGIN_STOCK_EDIT, GTK_RESPONSE_APPLY); + gtk_widget_set_sensitive(button, FALSE); + spec_dialog->edit_button = button; + + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(pounce_response_cb), spec_dialog); + + column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(column, _("Buddy")); + gtk_tree_view_column_set_resizable(column, TRUE); + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", PIDGIN_POUNCE_ICON, NULL); + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_add_attribute(column, rend, "text", PIDGIN_POUNCE_ALIAS); + gtk_tree_view_append_column(GTK_TREE_VIEW(spec_dialog->treeview), column); + + column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(column, _("Event")); + gtk_tree_view_column_set_resizable(column, TRUE); + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_add_attribute(column, rend, "text", PIDGIN_POUNCE_EVENT); + gtk_tree_view_append_column(GTK_TREE_VIEW(spec_dialog->treeview), column); + + column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(column, _("Message")); + gtk_tree_view_column_set_resizable(column, TRUE); + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_add_attribute(column, rend, "text", PIDGIN_POUNCE_TEXT); + gtk_tree_view_append_column(GTK_TREE_VIEW(spec_dialog->treeview), column); + + column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(column, _("Date")); + gtk_tree_view_column_set_resizable(column, TRUE); + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_add_attribute(column, rend, "text", PIDGIN_POUNCE_DATE); + gtk_tree_view_append_column(GTK_TREE_VIEW(spec_dialog->treeview), column); + + label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label), _("You have pounced!")); + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(spec_dialog->treeview)); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); + g_signal_connect(G_OBJECT(sel), "changed", + G_CALLBACK(pounce_row_selected_cb), NULL); + } + + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 2); + + if (type == PIDGIN_NOTIFY_MAIL) + mail_dialog = spec_dialog; + else if (type == PIDGIN_NOTIFY_POUNCE) { + pounce_dialog = spec_dialog; + } + + return spec_dialog->dialog; + +} + +void +pidgin_notify_pounce_add(PurpleAccount *account, PurplePounce *pounce, + const char *alias, const char *event, const char *message, const char *date) +{ + GtkWidget *dialog; + GdkPixbuf *icon; + GtkTreeIter iter; + PidginNotifyPounceData *pounce_data; + + dialog = pidgin_get_notification_dialog(PIDGIN_NOTIFY_POUNCE); + + icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + + pounce_data = g_new(PidginNotifyPounceData, 1); + + pounce_data->account = account; + pounce_data->pounce = pounce; + + gtk_tree_store_append(pounce_dialog->treemodel, &iter, NULL); + + gtk_tree_store_set(pounce_dialog->treemodel, &iter, + PIDGIN_POUNCE_ICON, icon, + PIDGIN_POUNCE_ALIAS, alias, + PIDGIN_POUNCE_EVENT, event, + PIDGIN_POUNCE_TEXT, (message != NULL)? message : _("No message"), + PIDGIN_POUNCE_DATE, date, + PIDGIN_POUNCE_DATA, pounce_data, + -1); + + if (icon) + g_object_unref(icon); + + gtk_widget_show_all(dialog); + + return; +} + +static GtkWidget * +pidgin_get_notification_dialog(PidginNotifyType type) +{ + GtkTreeStore *model = NULL; + + if (type == PIDGIN_NOTIFY_MAIL) { + if (mail_dialog != NULL) + return mail_dialog->dialog; + + model = gtk_tree_store_new(COLUMNS_PIDGIN_MAIL, + GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); + + } else if (type == PIDGIN_NOTIFY_POUNCE) { + + if (pounce_dialog != NULL) + return pounce_dialog->dialog; + + model = gtk_tree_store_new(PIDGIN_POUNCE_COLUMNS, + GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_POINTER); + } + + return pidgin_get_dialog(type, model); +} + static PurpleNotifyUiOps ops = { pidgin_notify_message, diff --git a/pidgin/gtknotify.h b/pidgin/gtknotify.h index d134d9957b..8ecc762a50 100644 --- a/pidgin/gtknotify.h +++ b/pidgin/gtknotify.h @@ -27,6 +27,18 @@ #define _PIDGINNOTIFY_H_ #include "notify.h" +#include "pounce.h" + +/** + * Adds a buddy pounce to the buddy pounce dialog + * + * @param alias The buddy alias + * @param event Event description + * @param message Pounce message + * @param date Pounce date + */ +void pidgin_notify_pounce_add(PurpleAccount *account, PurplePounce *pounce, + const char *alias, const char *event, const char *message, const char *date); /** * Returns the UI operations structure for GTK+ notification functions. diff --git a/pidgin/gtkpounce.c b/pidgin/gtkpounce.c index a8b2096014..e2ee53335c 100644 --- a/pidgin/gtkpounce.c +++ b/pidgin/gtkpounce.c @@ -30,7 +30,6 @@ #include "account.h" #include "conversation.h" #include "debug.h" -#include "notify.h" #include "prpl.h" #include "request.h" #include "server.h" @@ -41,6 +40,7 @@ #include "gtkdialogs.h" #include "gtkimhtml.h" #include "gtkpounce.h" +#include "gtknotify.h" #include "pidginstock.h" #include "gtkutils.h" @@ -1275,7 +1275,6 @@ create_pounces_list(PouncesManager *dialog) /* Handle double-clicking */ g_signal_connect(G_OBJECT(treeview), "button_press_event", G_CALLBACK(pounce_double_click_cb), dialog); - gtk_container_add(GTK_CONTAINER(sw), treeview); gtk_widget_show(treeview); @@ -1458,27 +1457,27 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data) */ tmp = g_strdup_printf( (events & PURPLE_POUNCE_TYPING) ? - _("%s has started typing to you (%s)") : + _("Started typing") : (events & PURPLE_POUNCE_TYPED) ? - _("%s has paused while typing to you (%s)") : + _("Paused while typing") : (events & PURPLE_POUNCE_SIGNON) ? - _("%s has signed on (%s)") : + _("Signed on") : (events & PURPLE_POUNCE_IDLE_RETURN) ? - _("%s has returned from being idle (%s)") : + _("Returned from being idle") : (events & PURPLE_POUNCE_AWAY_RETURN) ? - _("%s has returned from being away (%s)") : + _("Returned from being away") : (events & PURPLE_POUNCE_TYPING_STOPPED) ? - _("%s has stopped typing to you (%s)") : + _("Stopped typing") : (events & PURPLE_POUNCE_SIGNOFF) ? - _("%s has signed off (%s)") : + _("Signed off") : (events & PURPLE_POUNCE_IDLE) ? - _("%s has become idle (%s)") : + _("Became idle") : (events & PURPLE_POUNCE_AWAY) ? - _("%s has gone away. (%s)") : + _("Went away") : (events & PURPLE_POUNCE_MESSAGE_RECEIVED) ? - _("%s has sent you a message. (%s)") : - _("Unknown pounce event. Please report this!"), - alias, purple_account_get_protocol_name(account)); + _("Sent a message") : + _("Unknown.... Please report this!") + ); /* * Ok here is where I change the second argument, title, from @@ -1488,16 +1487,9 @@ pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data) if ((name_shown = purple_account_get_alias(account)) == NULL) name_shown = purple_account_get_username(account); - if (reason == NULL) - { - purple_notify_info(NULL, name_shown, tmp, purple_date_format_full(NULL)); - } - else - { - char *tmp2 = g_strdup_printf("%s\n\n%s", reason, purple_date_format_full(NULL)); - purple_notify_info(NULL, name_shown, tmp, tmp2); - g_free(tmp2); - } + pidgin_notify_pounce_add(account, pounce, alias, tmp, reason, + purple_date_format_full(NULL)); + g_free(tmp); } -- cgit v1.2.1 From cbc69100467dc7040c5c4d9e534269f5a461b1db Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Mon, 16 Mar 2009 22:52:12 +0000 Subject: Just a note --- libpurple/dnssrv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libpurple/dnssrv.c b/libpurple/dnssrv.c index 6fce86cc3d..cce7356793 100644 --- a/libpurple/dnssrv.c +++ b/libpurple/dnssrv.c @@ -175,9 +175,11 @@ resolve(int in, int out) end: size = g_list_length(ret); + /* TODO: Check return value */ write(out, &size, sizeof(int)); while (ret != NULL) { + /* TODO: Check return value */ write(out, ret->data, sizeof(PurpleSrvResponse)); g_free(ret->data); ret = g_list_remove(ret, ret->data); -- cgit v1.2.1 From c4944d43d26641f3dfe8d62842afbd8cfd19bfd6 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Mon, 16 Mar 2009 22:56:57 +0000 Subject: Add a friendly error message if something uses purple_util_fetch_url_request_len() to fetch an https URL when libpurple has not been compiled with ssl --- libpurple/util.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libpurple/util.c b/libpurple/util.c index 0befee69a3..90530589d3 100644 --- a/libpurple/util.c +++ b/libpurple/util.c @@ -4044,6 +4044,13 @@ purple_util_fetch_url_request_len(const char *url, gboolean full, &gfud->website.page, &gfud->website.user, &gfud->website.passwd); if (purple_strcasestr(url, "https://") != NULL) { + if (!purple_ssl_is_supported()) { + purple_util_fetch_url_error(gfud, + _("Unable to connect to %s: Server requires TLS/SSL, but no TLS/SSL support was found."), + gfud->website.address); + return NULL; + } + gfud->is_ssl = TRUE; gfud->ssl_connection = purple_ssl_connect(NULL, gfud->website.address, gfud->website.port, -- cgit v1.2.1 From 028ebbf334e796ddf99c6725607b396e8283c4ec Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Tue, 17 Mar 2009 00:56:37 +0000 Subject: Uh, I think this comment is wrong. Or the code is wrong and does silly things in a lot of places. --- libpurple/blist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurple/blist.h b/libpurple/blist.h index 460291a886..9ccb39b77d 100644 --- a/libpurple/blist.h +++ b/libpurple/blist.h @@ -595,7 +595,7 @@ PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy); * @param contact The optional contact to place the buddy in. * @param group The group to add the new buddy to. * @param node The insertion point. Pass in NULL to add the node as - * the last child in the given group. + * the first child in the given group. */ void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node); -- cgit v1.2.1 From b463b39d03fc1b78513ad68a0766ebdb6034ddb5 Mon Sep 17 00:00:00 2001 From: Marcus Lundblad Date: Wed, 18 Mar 2009 19:30:09 +0000 Subject: Clarified a couple of points in the ChangeLog --- ChangeLog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef538d8b1c..5ddb61f1ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,8 +6,9 @@ version 2.6.0 (??/??/2009): project. With some minor additions and clean ups from Paul Aurich. XMPP: - * Add support for in-band bytestreams (XEP-0047). - * Add support for attention (XEP-0224). + * Add support for in-band bytestreams for file transfers (XEP-0047). + * Add support for sending attentions (equivalent to "buzz" and "nudge") + using the command /buzz (XEP-0224). Pidgin: * Added -f command line option to tell Pidgin to ignore NetworkManager -- cgit v1.2.1 From b7cdd0cfee190a0b601746c7505fb73505c2de5d Mon Sep 17 00:00:00 2001 From: Daniel Atallah Date: Fri, 20 Mar 2009 02:42:38 +0000 Subject: Josef Andrysek noticed that there's a scenario where the PurpleCircBuffer gets corrupted and supplied a patch to fix it. Fixes #8706 --- COPYRIGHT | 1 + libpurple/circbuffer.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/COPYRIGHT b/COPYRIGHT index c38b3f736b..613f8bf8a8 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -8,6 +8,7 @@ Saleem Abdulrasool Dave Ahlswede Manuel Amador Matt Amato +Josef Andrysek Geoffrey Antos Daniel Atallah Paul Aurich diff --git a/libpurple/circbuffer.c b/libpurple/circbuffer.c index 3c6af4301e..619d9c9758 100644 --- a/libpurple/circbuffer.c +++ b/libpurple/circbuffer.c @@ -68,7 +68,8 @@ static void grow_circ_buffer(PurpleCircBuffer *buf, gsize len) { /* If the fill pointer is wrapped to before the remove * pointer, we need to shift the data */ - if (in_offset < out_offset) { + if (in_offset < out_offset + || (in_offset == out_offset && buf->bufused > 0)) { int shift_n = MIN(buf->buflen - start_buflen, in_offset); memcpy(buf->buffer + start_buflen, buf->buffer, -- cgit v1.2.1 From 1ad58c4310989106070dc0ed5a065ac14cccc069 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Fri, 20 Mar 2009 06:01:48 +0000 Subject: Fix Finch warnings when building on 64-bit Fixes #8425. --- finch/gntlog.c | 2 +- finch/gntplugin.c | 4 ++-- finch/gntroomlist.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/finch/gntlog.c b/finch/gntlog.c index 5593f73c87..9f6083a545 100644 --- a/finch/gntlog.c +++ b/finch/gntlog.c @@ -66,7 +66,7 @@ static guint log_viewer_hash(gconstpointer data) g_str_hash(purple_account_get_username(viewer->account)); } - return (guint)viewer; + return g_direct_hash(viewer); } static gboolean log_viewer_equal(gconstpointer y, gconstpointer z) diff --git a/finch/gntplugin.c b/finch/gntplugin.c index 4c1127cbc2..7dd8e58cab 100644 --- a/finch/gntplugin.c +++ b/finch/gntplugin.c @@ -484,10 +484,10 @@ process_pref_frame(PurplePluginPrefFrame *frame) char *value = NULL; switch(type) { case PURPLE_PREF_BOOLEAN: - value = g_strdup_printf("%d", (int)list->next->data); + value = g_strdup_printf("%d", GPOINTER_TO_INT(list->next->data)); break; case PURPLE_PREF_INT: - value = g_strdup_printf("%d", (int)list->next->data); + value = g_strdup_printf("%d", GPOINTER_TO_INT(list->next->data)); break; case PURPLE_PREF_STRING: value = g_strdup(list->next->data); diff --git a/finch/gntroomlist.c b/finch/gntroomlist.c index bbaa3e7dad..89479a4310 100644 --- a/finch/gntroomlist.c +++ b/finch/gntroomlist.c @@ -190,7 +190,7 @@ roomlist_selection_changed(GntWidget *widget, gpointer old, gpointer current, gp label = g_strdup(iter->data ? "True" : "False"); break; case PURPLE_ROOMLIST_FIELD_INT: - label = g_strdup_printf("%d", (int)iter->data); + label = g_strdup_printf("%d", GPOINTER_TO_INT(iter->data)); break; case PURPLE_ROOMLIST_FIELD_STRING: label = g_strdup(iter->data); -- cgit v1.2.1 From 70c4521c02bcf71497e3db71a210fef65b18c80b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 21 Mar 2009 02:20:52 +0000 Subject: Add some missing newlines in debug messages. Fixes #8740. --- libpurple/protocols/msn/notification.c | 4 ++-- libpurple/protocols/msn/oim.c | 4 ++-- libpurple/protocols/msn/state.c | 4 ++-- libpurple/protocols/msn/switchboard.c | 2 +- libpurple/protocols/msn/userlist.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c index d941e5f948..c37eb7a240 100644 --- a/libpurple/protocols/msn/notification.c +++ b/libpurple/protocols/msn/notification.c @@ -1609,7 +1609,7 @@ gcf_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, if ( (root = xmlnode_from_str(cmd->payload, cmd->payload_len)) == NULL) { - purple_debug_error("msn", "Unable to parse GCF payload into a XML tree"); + purple_debug_error("msn", "Unable to parse GCF payload into a XML tree\n"); return; } @@ -1682,7 +1682,7 @@ ubx_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, user = msn_userlist_find_user(session->userlist, passport); if (user == NULL) { char *str = g_strndup(payload, len); - purple_debug_info("msn", "unknown user %s, payload is %s", + purple_debug_info("msn", "unknown user %s, payload is %s\n", passport, str); g_free(str); return; diff --git a/libpurple/protocols/msn/oim.c b/libpurple/protocols/msn/oim.c index 927c9376aa..9caaef8262 100644 --- a/libpurple/protocols/msn/oim.c +++ b/libpurple/protocols/msn/oim.c @@ -174,7 +174,7 @@ msn_oim_request_cb(MsnSoapMessage *request, MsnSoapMessage *response, gchar *faultcode_str = xmlnode_get_data(faultcode); if (faultcode_str && g_str_equal(faultcode_str, "q0:BadContextToken")) { - purple_debug_warning("msn", "OIM Request Error, Updating token now."); + purple_debug_warning("msn", "OIM Request Error, Updating token now.\n"); msn_nexus_update_token(data->oim->session->nexus, data->send ? MSN_AUTH_LIVE_SECURE : MSN_AUTH_MESSENGER_WEB, (GSourceFunc)msn_oim_request_helper, data); @@ -183,7 +183,7 @@ msn_oim_request_cb(MsnSoapMessage *request, MsnSoapMessage *response, } else if (faultcode_str && g_str_equal(faultcode_str, "q0:AuthenticationFailed")) { if (xmlnode_get_child(fault, "detail/RequiredAuthPolicy") != NULL) { - purple_debug_warning("msn", "OIM Request Error, Updating token now."); + purple_debug_warning("msn", "OIM Request Error, Updating token now.\n"); msn_nexus_update_token(data->oim->session->nexus, data->send ? MSN_AUTH_LIVE_SECURE : MSN_AUTH_MESSENGER_WEB, (GSourceFunc)msn_oim_request_helper, data); diff --git a/libpurple/protocols/msn/state.c b/libpurple/protocols/msn/state.c index e172d880bb..5a77a39999 100644 --- a/libpurple/protocols/msn/state.c +++ b/libpurple/protocols/msn/state.c @@ -169,7 +169,7 @@ msn_get_currentmedia(char *xml_str, gsize len) } currentmediaNode = xmlnode_get_child(payloadNode, "CurrentMedia"); if (currentmediaNode == NULL) { - purple_debug_info("msn", "No CurrentMedia Node"); + purple_debug_info("msn", "No CurrentMedia Node\n"); xmlnode_free(payloadNode); return NULL; } @@ -195,7 +195,7 @@ msn_get_psm(char *xml_str, gsize len) } psmNode = xmlnode_get_child(payloadNode, "PSM"); if (psmNode == NULL) { - purple_debug_info("msn", "No PSM status Node"); + purple_debug_info("msn", "No PSM status Node\n"); xmlnode_free(payloadNode); return NULL; } diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c index 0ada2639d1..74fe0a43f3 100644 --- a/libpurple/protocols/msn/switchboard.c +++ b/libpurple/protocols/msn/switchboard.c @@ -590,7 +590,7 @@ release_msg(MsnSwitchBoard *swboard, MsnMessage *msg) payload = msn_message_gen_payload(msg, &payload_len); #ifdef MSN_DEBUG_SB - purple_debug_info("msn", "SB length:{%" G_GSIZE_FORMAT "}", payload_len); + purple_debug_info("msn", "SB length:{%" G_GSIZE_FORMAT "}\n", payload_len); msn_message_show_readable(msg, "SB SEND", FALSE); #endif diff --git a/libpurple/protocols/msn/userlist.c b/libpurple/protocols/msn/userlist.c index a98919d537..ba5cc831c2 100644 --- a/libpurple/protocols/msn/userlist.c +++ b/libpurple/protocols/msn/userlist.c @@ -858,7 +858,7 @@ msn_userlist_add_buddy_to_group(MsnUserList *userlist, const char *who, } if ( (user = msn_userlist_find_user(userlist, who)) == NULL) { - purple_debug_error("msn", "User %s not found!", who); + purple_debug_error("msn", "User %s not found!\n", who); return FALSE; } @@ -887,7 +887,7 @@ msn_userlist_rem_buddy_from_group(MsnUserList *userlist, const char *who, } if ( (user = msn_userlist_find_user(userlist, who)) == NULL) { - purple_debug_error("msn", "User %s not found!", who); + purple_debug_error("msn", "User %s not found!\n", who); return FALSE; } -- cgit v1.2.1 From 0109d45dcdaf7e2cda32cc5e6a27eba1f2b02b20 Mon Sep 17 00:00:00 2001 From: Daniel Atallah Date: Mon, 23 Mar 2009 02:10:44 +0000 Subject: Fix a crash when creating an account with a prpl with no protocol_options. Fixes #8747. --- pidgin/gtkaccount.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c index a5f0a85fe9..1a6c10793e 100644 --- a/pidgin/gtkaccount.c +++ b/pidgin/gtkaccount.c @@ -756,10 +756,6 @@ add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) dialog->protocol_frame = NULL; } - if (dialog->prpl_info == NULL || - dialog->prpl_info->protocol_options == NULL) - return; - while (dialog->protocol_opt_entries != NULL) { ProtocolOptEntry *opt_entry = dialog->protocol_opt_entries->data; g_free(opt_entry->setting); @@ -767,6 +763,10 @@ add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) dialog->protocol_opt_entries = g_list_delete_link(dialog->protocol_opt_entries, dialog->protocol_opt_entries); } + if (dialog->prpl_info == NULL || + dialog->prpl_info->protocol_options == NULL) + return; + account = dialog->account; /* Build the protocol options frame. */ -- cgit v1.2.1 From 220fafc36ba03947fa1fd378d0b516ef35613d58 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 23 Mar 2009 04:27:41 +0000 Subject: Re-hide structs --- libpurple/protocols/oscar/oscar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index 9bbf81ec97..06cd521b75 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -4918,13 +4918,13 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { } if (od->ssi.received_data) { - if (!aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY)) { + if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) { purple_debug_info("oscar", - "ssi: adding buddy %s to group %s\n", buddy->name, group->name); - aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); + "ssi: adding buddy %s to group %s\n", bname, gname); + aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); /* Mobile users should always be online */ - if (buddy->name[0] == '+') { + if (bname[0] == '+') { purple_prpl_got_user_status(account, bname, OSCAR_STATUS_ID_AVAILABLE, NULL); purple_prpl_got_user_status(account, bname, -- cgit v1.2.1 From 71e05a286d6cdcff257e9bac95ab570faf178d46 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 23 Mar 2009 04:31:05 +0000 Subject: Use purple_buddy_get_protocol_data instead of ->proto_data --- libpurple/protocols/silc/buddy.c | 2 +- libpurple/protocols/silc10/buddy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libpurple/protocols/silc/buddy.c b/libpurple/protocols/silc/buddy.c index d6302d0da0..82972a6dc5 100644 --- a/libpurple/protocols/silc/buddy.c +++ b/libpurple/protocols/silc/buddy.c @@ -1401,7 +1401,7 @@ void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup * * SILC doesn't have groups, so we also don't need to do anything * for a move. */ - if (buddy->proto_data == NULL) + if (purple_buddy_get_protocol_data(buddy) == NULL) silcpurple_add_buddy_i(gc, buddy, FALSE); } diff --git a/libpurple/protocols/silc10/buddy.c b/libpurple/protocols/silc10/buddy.c index 54f49d1335..5939ef40a0 100644 --- a/libpurple/protocols/silc10/buddy.c +++ b/libpurple/protocols/silc10/buddy.c @@ -1394,7 +1394,7 @@ void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup * * SILC doesn't have groups, so we don't need to do anything * for a move. */ - if (buddy->proto_data == NULL) + if (purple_buddy_get_protocol_data(buddy) == NULL) silcpurple_add_buddy_i(gc, buddy, FALSE); } -- cgit v1.2.1 From 35bab289ef2f2d01d4d1dfda70325bfb2c23eb89 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 23 Mar 2009 04:41:50 +0000 Subject: Hiding in novell --- libpurple/protocols/novell/novell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c index cd39b0785b..9107fee5de 100644 --- a/libpurple/protocols/novell/novell.c +++ b/libpurple/protocols/novell/novell.c @@ -2547,7 +2547,7 @@ novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group) if (gc == NULL || buddy == NULL || group == NULL) return; - user = (NMUser *) gc->proto_data; + user = (NMUser *) purple_connection_get_protocol_data(gc); if (user == NULL) return; @@ -2558,7 +2558,7 @@ novell_add_buddy(PurpleConnection * gc, PurpleBuddy *buddy, PurpleGroup * group) return; /* Don't re-add a buddy that is already on our contact list */ - if (nm_find_user_record(user, buddy->name) != NULL) + if (nm_find_user_record(user, purple_buddy_get_name(buddy)) != NULL) return; contact = nm_create_contact(); -- cgit v1.2.1 From 291a1845a02ac9fcd410853b12d46b1c0059d1be Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 23 Mar 2009 05:00:14 +0000 Subject: Remove an extra tab --- pidgin/gtkblist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index f510429235..6910052382 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -6713,7 +6713,7 @@ add_buddy_cb(GtkWidget *w, int resp, PidginAddBuddyData *data) } else if ((b = purple_find_buddy(data->account, who)) != NULL) { - g = purple_buddy_get_group(b); + g = purple_buddy_get_group(b); } if (b == NULL) -- cgit v1.2.1 From 65ebfd274c97351b04d8cd868d8ae3c0dd10fce7 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Tue, 24 Mar 2009 00:39:16 +0000 Subject: Changelog the im.pidgin.cpw.darkrain42.buddy-add branch. Also fixed some whitespace in ChangeLog.API. Fixes #479. For good, I hope. --- ChangeLog | 2 ++ ChangeLog.API | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b6a7a181a..991dd74c0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ version 2.6.0 (??/??/2009): General: * Theme support in libpurple thanks to Justin Rodriguez's summer of code project. With some minor additions and clean ups from Paul Aurich. + * It should no longer be possible to end up with duplicates of buddies + in a group on the buddy list. XMPP: * Add support for in-band bytestreams for file transfers (XEP-0047). diff --git a/ChangeLog.API b/ChangeLog.API index 22d0469161..6c49b978b8 100644 --- a/ChangeLog.API +++ b/ChangeLog.API @@ -30,10 +30,10 @@ version 2.6.0 (??/??/2009): Changed: * xmlnode_remove_attrib now removes all attributes with the - same name. Previously, it would remove the first one found, - which was completely non-deterministic. If you want to remove - the attribute with no namespace, then use NULL with - xmlnode_remove_with_namespace. + same name. Previously, it would remove the first one found, + which was completely non-deterministic. If you want to remove + the attribute with no namespace, then use NULL with + xmlnode_remove_with_namespace. Deprecated: * purple_buddy_get_local_alias -- cgit v1.2.1 From 1af08d8d66e9685ce4d763f14027b41ddc2f04c7 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Wed, 25 Mar 2009 06:07:44 +0000 Subject: Fix displaying of status messages in the conversation infopane. Rekkanoryo thinks this is okay (and it doesn't seem to have broken anything else that I've noticed). Fixes #8670. --- pidgin/gtkblist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index 6910052382..8fa8e7c217 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -3898,7 +3898,7 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased presence = purple_buddy_get_presence(b); /* Name is all that is needed */ - if (aliased && biglist) { + if (!aliased || biglist) { /* Status Info */ prpl = purple_find_prpl(purple_account_get_protocol_id(b->account)); @@ -4038,7 +4038,7 @@ pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased } /* Put it all together */ - if (aliased && biglist && (statustext || idletime)) { + if ((!aliased || biglist) && (statustext || idletime)) { /* using breaks the status, so it must be seperated into */ if (name_color) { text = g_strdup_printf("%s\n" -- cgit v1.2.1 From c4bf648e05696a4d3fbbd9b5b353ee7dd0815e19 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Wed, 25 Mar 2009 06:26:16 +0000 Subject: Break the New Account dialog into three tabs. Move proxy options to the new tab. Fixes #8663. committer: John Bailey --- ChangeLog | 2 ++ pidgin/gtkaccount.c | 58 +++++++++++++++++++---------------------------------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 991dd74c0a..1873204882 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,8 @@ version 2.6.0 (??/??/2009): * Created a unified Buddy Pounce notification window for all pounces where "Pop up a notification" is selected, which avoids having a new dialog box every time a pounce is triggered. (Jorge Villaseñor) + * The New Account dialog is now broken into three tabs. Proxy + configuration has been moved from the Advanced tab to the new tab. version 2.5.5 (03/01/2009): libpurple: diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c index 1a6c10793e..b303b2d0b7 100644 --- a/pidgin/gtkaccount.c +++ b/pidgin/gtkaccount.c @@ -106,8 +106,8 @@ typedef struct GtkSizeGroup *sg; GtkWidget *window; + GtkWidget *notebook; GtkWidget *top_vbox; - GtkWidget *bottom_vbox; GtkWidget *ok_button; GtkWidget *register_button; @@ -157,8 +157,7 @@ static void set_account(GtkListStore *store, GtkTreeIter *iter, **************************************************************************/ static void add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent); static void add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent); -static void add_protocol_options(AccountPrefsDialog *dialog, - GtkWidget *parent); +static void add_protocol_options(AccountPrefsDialog *dialog); static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent); static GtkWidget * @@ -237,7 +236,7 @@ set_account_protocol_cb(GtkWidget *item, const char *id, add_login_options(dialog, dialog->top_vbox); add_user_options(dialog, dialog->top_vbox); - add_protocol_options(dialog, dialog->bottom_vbox); + add_protocol_options(dialog); gtk_widget_grab_focus(dialog->protocol_menu); @@ -733,11 +732,11 @@ add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent) } static void -add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) +add_protocol_options(AccountPrefsDialog *dialog) { PurpleAccountOption *option; PurpleAccount *account; - GtkWidget *frame, *vbox, *check, *entry, *combo; + GtkWidget *vbox, *check, *entry, *combo; GList *list, *node; gint i, idx, int_value; GtkListStore *model; @@ -752,7 +751,7 @@ add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) ProtocolOptEntry *opt_entry; if (dialog->protocol_frame != NULL) { - gtk_widget_destroy(dialog->protocol_frame); + gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 1); dialog->protocol_frame = NULL; } @@ -769,19 +768,11 @@ add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) account = dialog->account; - /* Build the protocol options frame. */ - g_snprintf(buf, sizeof(buf), _("%s Options"), dialog->plugin->info->name); - - frame = pidgin_make_frame(parent, buf); - dialog->protocol_frame = - gtk_widget_get_parent(gtk_widget_get_parent(frame)); - - gtk_box_reorder_child(GTK_BOX(parent), dialog->protocol_frame, 0); - gtk_widget_show(dialog->protocol_frame); - /* Main vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_container_add(GTK_CONTAINER(frame), vbox); + dialog->protocol_frame = vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BORDER); + gtk_notebook_insert_page(GTK_NOTEBOOK(dialog->notebook), vbox, + gtk_label_new_with_mnemonic(_("_Advanced")), 1); gtk_widget_show(vbox); for (l = dialog->prpl_info->protocol_options; l != NULL; l = l->next) @@ -1046,22 +1037,15 @@ static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent) { PurpleProxyInfo *proxy_info; - GtkWidget *frame; GtkWidget *vbox; GtkWidget *vbox2; if (dialog->proxy_frame != NULL) gtk_widget_destroy(dialog->proxy_frame); - frame = pidgin_make_frame(parent, _("Proxy Options")); - dialog->proxy_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame)); - - gtk_box_reorder_child(GTK_BOX(parent), dialog->proxy_frame, 1); - gtk_widget_show(dialog->proxy_frame); - /* Main vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_container_add(GTK_CONTAINER(frame), vbox); + dialog->proxy_frame = vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + gtk_container_add(GTK_CONTAINER(parent), vbox); gtk_widget_show(vbox); /* Proxy Type drop-down. */ @@ -1496,15 +1480,15 @@ pidgin_account_dialog_show(PidginAccountDialogType type, dialog->prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(dialog->plugin); dialog->window = win = pidgin_create_dialog((type == PIDGIN_ADD_ACCOUNT_DIALOG) ? _("Add Account") : _("Modify Account"), - PIDGIN_HIG_BORDER, "account", FALSE); + PIDGIN_HIG_BOX_SPACE, "account", FALSE); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(account_win_destroy_cb), dialog); /* Setup the vbox */ - main_vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); + main_vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BOX_SPACE); - notebook = gtk_notebook_new(); + dialog->notebook = notebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(main_vbox), notebook, FALSE, FALSE, 0); gtk_widget_show(GTK_WIDGET(notebook)); @@ -1530,15 +1514,15 @@ pidgin_account_dialog_show(PidginAccountDialogType type, if (!dialog->prpl_info || !dialog->prpl_info->register_user) gtk_widget_hide(button); - /* Setup the page with 'Advanced'. */ - dialog->bottom_vbox = dbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); + /* Setup the page with 'Advanced' (protocol options). */ + add_protocol_options(dialog); + + /* Setup the page with 'Proxy'. */ + dbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_set_border_width(GTK_CONTAINER(dbox), PIDGIN_HIG_BORDER); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dbox, - gtk_label_new_with_mnemonic(_("_Advanced"))); + gtk_label_new_with_mnemonic(_("_Proxy"))); gtk_widget_show(dbox); - - /** Setup the bottom frames. */ - add_protocol_options(dialog, dbox); add_proxy_options(dialog, dbox); /* Cancel button */ -- cgit v1.2.1 From 453161ea148c89ef288b15d185dc501cadfa3d65 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Wed, 25 Mar 2009 06:34:01 +0000 Subject: Fix build of gevolution plugin. Closes #8598. --- pidgin/plugins/gevolution/gevolution.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidgin/plugins/gevolution/gevolution.h b/pidgin/plugins/gevolution/gevolution.h index 7046070277..1b92b2b940 100644 --- a/pidgin/plugins/gevolution/gevolution.h +++ b/pidgin/plugins/gevolution/gevolution.h @@ -75,7 +75,7 @@ typedef struct GtkWidget *win; GtkWidget *accounts_menu; - GtkWidget *screenname; + GtkWidget *username; GtkWidget *firstname; GtkWidget *lastname; GtkWidget *email; -- cgit v1.2.1 From 00cb781d2185c28689e69d97752423d6d85e86d8 Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Wed, 25 Mar 2009 07:11:14 +0000 Subject: hidden is never initialized ==12531== Conditional jump or move depends on uninitialised value(s) ==12531== at 0x44BD3E: pidgin_blist_update_chat (gtkblist.c:6497) ==12531== by 0x44C003: pidgin_blist_update (gtkblist.c:6558) ==12531== by 0x8E30BF7: purple_blist_add_account (blist.c:2438) ==12531== by 0x8E4165B: purple_connection_set_state (connection.c:379) ==12531== by 0xFFC35A6: jabber_stream_set_state (jabber.c:1479) ==12531== by 0xFFB0AAE: auth_old_result_cb (auth.c:574) ==12531== by 0xFFBEFBA: jabber_iq_parse (iq.c:360) ==12531== by 0xFFBFA94: jabber_process_packet (jabber.c:252) ==12531== by 0xFFCC240: jabber_parser_element_end_libxml (parser.c:125) ==12531== by 0xA0D2544: xmlParseChunk (in /usr/lib/libxml2.so.2.6.32) ==12531== by 0xFFCC43C: jabber_parser_process (parser.c:227) ==12531== by 0xFFC0586: jabber_recv_cb (jabber.c:546) --- pidgin/gtkblist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index 6910052382..5670ee60ad 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -6443,7 +6443,7 @@ static void pidgin_blist_update_chat(PurpleBuddyList *list, PurpleBlistNode *nod gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); PidginBlistNode *ui; PurpleConversation *conv; - gboolean hidden; + gboolean hidden = FALSE; GdkColor *bgcolor = NULL; FontColorPair *pair; PidginBlistTheme *theme; -- cgit v1.2.1 From 677b2f921837077018f8b52fdb8e3762282c1211 Mon Sep 17 00:00:00 2001 From: Daniel Atallah Date: Thu, 26 Mar 2009 03:25:57 +0000 Subject: Fix an issue with bonjour buddies that have been dragged into permanent groups not appearing online when the buddy signs on. Fixes #8782 --- libpurple/protocols/bonjour/mdns_win32.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libpurple/protocols/bonjour/mdns_win32.c b/libpurple/protocols/bonjour/mdns_win32.c index 10ee701e9f..fb94484020 100644 --- a/libpurple/protocols/bonjour/mdns_win32.c +++ b/libpurple/protocols/bonjour/mdns_win32.c @@ -169,14 +169,17 @@ _mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_mess gboolean delete_buddy = FALSE; PurpleBuddy *pb = NULL; + if ((pb = purple_find_buddy(args->account, args->res_data->name))) { + if (pb->proto_data != args->bb) { + purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.", + args->res_data->name); + goto cleanup; + } /* Make sure that the BonjourBuddy associated with this request is still around */ - if (g_slist_find(pending_buddies, args->bb) == NULL) + } else if (g_slist_find(pending_buddies, args->bb) == NULL) { + purple_debug_error("bonjour", "host resolution - complete, but buddy no longer pending.\n"); goto cleanup; - - if ((pb = purple_find_buddy(args->account, args->bb->name))) - if (pb->proto_data != args->bb) - purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record. " - "This is going to be ugly!.\n", args->bb->name); + } if (!hosts || !hosts->data) { purple_debug_error("bonjour", "host resolution - callback error.\n"); -- cgit v1.2.1 From a4b529044bed3896ded66b6604ad88cbff8504b0 Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Thu, 26 Mar 2009 03:40:59 +0000 Subject: fixes an invalid read: ==12531== Invalid read of size 1 ==12531== at 0xFD7FB2D: yahoo_packet_read (yahoo_packet.c:205) ==12531== by 0xFD6E18D: yahoo_pending (yahoo.c:3267) ==12531== by 0x474C5C: pidgin_io_invoke (gtkeventloop.c:78) ==12531== by 0x9DF8D5A: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x9DFC52C: (within /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x9DFCA5C: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x60677A6: gtk_main (in /usr/lib/libgtk-x11-2.0.so.0.1400.4) ==12531== by 0x492CFF: main (gtkmain.c:892) ==12531== Address 0xcee0552 is 0 bytes after a block of size 26 alloc'd ==12531== at 0x4C265AE: malloc (vg_replace_malloc.c:207) ==12531== by 0x9E01472: g_malloc (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x9E19056: g_memdup (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0xFD6E1E8: yahoo_pending (yahoo.c:3271) ==12531== by 0x474C5C: pidgin_io_invoke (gtkeventloop.c:78) ==12531== by 0x9DF8D5A: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x9DFC52C: (within /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x9DFCA5C: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.1800.2) ==12531== by 0x60677A6: gtk_main (in /usr/lib/libgtk-x11-2.0.so.0.1400.4) ==12531== by 0x492CFF: main (gtkmain.c:892) --- libpurple/protocols/yahoo/yahoo_packet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libpurple/protocols/yahoo/yahoo_packet.c b/libpurple/protocols/yahoo/yahoo_packet.c index c1226a4c44..86bb3c218b 100644 --- a/libpurple/protocols/yahoo/yahoo_packet.c +++ b/libpurple/protocols/yahoo/yahoo_packet.c @@ -201,6 +201,8 @@ void yahoo_packet_read(struct yahoo_packet *pkt, const guchar *data, int len) } pos += 2; + if (pos + 1 > len) break; + /* Skip over garbage we've noticed in the mail notifications */ if (data[0] == '9' && data[pos] == 0x01) pos++; -- cgit v1.2.1 From c902feed6c9d79d1c8309266d9e425a66c99d10e Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 26 Mar 2009 05:29:18 +0000 Subject: For federated buddies, we should set / to Email, and use an node instead of . Along with that, we shouldn't set any to specify it's a federated buddy either, since the MSN server will complain about it. Fixes #7939. --- libpurple/protocols/msn/contact.c | 48 +++++++++++++++++++-------------------- libpurple/protocols/msn/contact.h | 16 +++---------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c index 1310ce1b74..aee11ab2de 100644 --- a/libpurple/protocols/msn/contact.c +++ b/libpurple/protocols/msn/contact.c @@ -1482,8 +1482,6 @@ msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state, const gchar *passport, const MsnListId list) { gchar *body = NULL, *member = NULL; - const char *type = "PassportMember"; - gchar *federate = NULL; MsnSoapPartnerScenario partner_scenario; MsnUser *user; @@ -1501,23 +1499,28 @@ msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state, msn_callback_state_set_who(state, passport); user = msn_userlist_find_user(session->userlist, passport); - if (user && user->networkid != MSN_NETWORK_PASSPORT) { - type = "EmailMember"; - federate = g_strdup_printf(MSN_MEMBER_FEDERATED_ANNOTATION_XML, - user->networkid); - } if (list == MSN_LIST_PL) { partner_scenario = MSN_PS_CONTACT_API; - member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML, - type, user->membership_id[MSN_LIST_PL], - federate ? federate : ""); + if (user && user->networkid != MSN_NETWORK_PASSPORT) + member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML, + "EmailMember", "Email", + user->membership_id[MSN_LIST_PL]); + else + member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML, + "PassportMember", "Passport", + user->membership_id[MSN_LIST_PL]); } else { /* list == MSN_LIST_AL || list == MSN_LIST_BL */ partner_scenario = MSN_PS_BLOCK_UNBLOCK; - member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, - type, passport, - federate ? federate : ""); + if (user && user->networkid != MSN_NETWORK_PASSPORT) + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + "EmailMember", "Email", + "Email", passport, "Email"); + else + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + "PassportMember", "Passport", + "PassportName", passport, "PassportName"); } body = g_strdup_printf(MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE, @@ -1530,7 +1533,6 @@ msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state, state->cb = msn_del_contact_from_list_read_cb; msn_contact_request(state); - g_free(federate); g_free(member); g_free(body); } @@ -1578,8 +1580,6 @@ msn_add_contact_to_list(MsnSession *session, MsnCallbackState *state, const gchar *passport, const MsnListId list) { gchar *body = NULL, *member = NULL; - const char *type = "PassportMember"; - gchar *federate = NULL; MsnSoapPartnerScenario partner_scenario; MsnUser *user; @@ -1596,15 +1596,16 @@ msn_add_contact_to_list(MsnSession *session, MsnCallbackState *state, msn_callback_state_set_who(state, passport); user = msn_userlist_find_user(session->userlist, passport); - if (user && user->networkid != MSN_NETWORK_PASSPORT) { - type = "EmailMember"; - federate = g_strdup_printf(MSN_MEMBER_FEDERATED_ANNOTATION_XML, - user->networkid); - } partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK; - member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, - type, state->who, federate ? federate : ""); + if (user && user->networkid != MSN_NETWORK_PASSPORT) + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + "EmailMember", "Email", + "Email", state->who, "Email"); + else + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + "PassportMember", "Passport", + "PassportName", state->who, "PassportName"); body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], @@ -1616,7 +1617,6 @@ msn_add_contact_to_list(MsnSession *session, MsnCallbackState *state, state->cb = msn_add_contact_to_list_read_cb; msn_contact_request(state); - g_free(federate); g_free(member); g_free(body); } diff --git a/libpurple/protocols/msn/contact.h b/libpurple/protocols/msn/contact.h index 8c0f612f95..4a05ea555a 100644 --- a/libpurple/protocols/msn/contact.h +++ b/libpurple/protocols/msn/contact.h @@ -397,28 +397,18 @@ #define MSN_MEMBER_PASSPORT_XML \ ""\ - "Passport"\ + "%s"\ "Accepted"\ - "%s"\ - "%s"\ + "<%s>%s"\ "" #define MSN_MEMBER_MEMBERSHIPID_XML \ ""\ - "Passport"\ + "%s"\ "%u"\ "Accepted"\ - "%s"\ "" -#define MSN_MEMBER_FEDERATED_ANNOTATION_XML \ - ""\ - ""\ - "MSN.IM.BuddyType"\ - "%02d:"\ - ""\ - "" - /* first delete contact from allow list */ #define MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE ""\ -- cgit v1.2.1 From f167e7ea38df8bfc30b43e48ee9b78ceae94eb62 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Thu, 26 Mar 2009 07:27:05 +0000 Subject: Cast away a few compile warnings in our "make check" tests, and add libpurple/plugins/one_time_password.c to POTFILES.in so that it can be translatinated. --- libpurple/tests/test_util.c | 8 ++++---- po/POTFILES.in | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libpurple/tests/test_util.c b/libpurple/tests/test_util.c index de56591afb..9269e5e4ec 100644 --- a/libpurple/tests/test_util.c +++ b/libpurple/tests/test_util.c @@ -5,7 +5,7 @@ START_TEST(test_util_base16_encode) { - assert_string_equal_free("68656c6c6f2c20776f726c642100", purple_base16_encode("hello, world!", 14)); + assert_string_equal_free("68656c6c6f2c20776f726c642100", purple_base16_encode((const unsigned char *)"hello, world!", 14)); } END_TEST @@ -14,14 +14,14 @@ START_TEST(test_util_base16_decode) gsize sz = 0; guchar *out = purple_base16_decode("21646c726f77202c6f6c6c656800", &sz); fail_unless(sz == 14, NULL); - fail_unless(strcmp("!dlrow ,olleh", out) == 0, NULL); + fail_unless(strcmp("!dlrow ,olleh", (const char *)out) == 0, NULL); g_free(out); } END_TEST START_TEST(test_util_base64_encode) { - assert_string_equal_free("Zm9ydHktdHdvAA==", purple_base64_encode("forty-two", 10)); + assert_string_equal_free("Zm9ydHktdHdvAA==", purple_base64_encode((const unsigned char *)"forty-two", 10)); } END_TEST @@ -30,7 +30,7 @@ START_TEST(test_util_base64_decode) gsize sz; guchar *out = purple_base64_decode("b3d0LXl0cm9mAA==", &sz); fail_unless(sz == 10, NULL); - fail_unless(strcmp("owt-ytrof", out) == 0, NULL); + fail_unless(strcmp("owt-ytrof", (const char *)out) == 0, NULL); g_free(out); } END_TEST diff --git a/po/POTFILES.in b/po/POTFILES.in index b221f12ced..e406846e3b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,6 +62,7 @@ libpurple/plugins/log_reader.c libpurple/plugins/mono/loader/mono.c libpurple/plugins/newline.c libpurple/plugins/offlinemsg.c +libpurple/plugins/one_time_password.c libpurple/plugins/perl/perl.c libpurple/plugins/psychic.c libpurple/plugins/signals-test.c -- cgit v1.2.1 From 6150d763545dd0506fbf3a126b87818ca2f108a4 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 08:49:10 +0000 Subject: I wrote a little comment --- libpurple/desktopitem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libpurple/desktopitem.c b/libpurple/desktopitem.c index 714a4b14e0..fa6d7340db 100644 --- a/libpurple/desktopitem.c +++ b/libpurple/desktopitem.c @@ -823,7 +823,11 @@ lookup_locale (const PurpleDesktopItem *item, const char *key, const char *local } } -/* fallback to find something suitable for C locale */ +/** + * Fallback to find something suitable for C locale. + * + * @return A newly allocated string which should be g_freed by the caller. + */ static char * try_english_key (PurpleDesktopItem *item, const char *key) { -- cgit v1.2.1 From 164fa285b22be6f865c962506dc590e494833a25 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 08:53:09 +0000 Subject: Remove some unused fields. Thanks to Mayank Jain Nawal's email to the devel list for pointing these out --- libpurple/nat-pmp.c | 2 -- libpurple/ntlm.c | 5 ----- 2 files changed, 7 deletions(-) diff --git a/libpurple/nat-pmp.c b/libpurple/nat-pmp.c index be5bc66222..36e706c2f9 100644 --- a/libpurple/nat-pmp.c +++ b/libpurple/nat-pmp.c @@ -81,8 +81,6 @@ typedef struct { struct _PurplePmpMapResponse { guint8 version; guint8 opcode; - guint16 resultcode; - guint32 epoch; guint16 privateport; guint16 publicport; guint32 lifetime; diff --git a/libpurple/ntlm.c b/libpurple/ntlm.c index b7d3757e44..ebcb0ea827 100644 --- a/libpurple/ntlm.c +++ b/libpurple/ntlm.c @@ -59,14 +59,9 @@ struct type2_message { guint8 protocol[8]; /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/ guint32 type; /* 0x00000002 */ - short msg_len1; /* target name length */ - short msg_len2; /* target name length */ - guint32 msg_off; /* target name offset (always 0x00000048) */ - guint32 flags; /* 0x00008201 */ guint8 nonce[8]; /* nonce */ - guint8 context[8]; }; struct type3_message { -- cgit v1.2.1 From 8a869478eda020a963fa577af3bd9cd8c5f3822d Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 08:54:30 +0000 Subject: Remove a wee bit of stray whitespace --- libpurple/plugins/mono/loader/mono.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libpurple/plugins/mono/loader/mono.c b/libpurple/plugins/mono/loader/mono.c index fe28bdd613..6810ef42a0 100644 --- a/libpurple/plugins/mono/loader/mono.c +++ b/libpurple/plugins/mono/loader/mono.c @@ -39,7 +39,7 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) if (!assm) { return FALSE; - } + } purple_debug(PURPLE_DEBUG_INFO, "mono", "Probing plugin\n"); @@ -50,7 +50,7 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) info = g_new0(PurplePluginInfo, 1); mplug = g_new0(PurpleMonoPlugin, 1); - + mplug->signal_data = NULL; mplug->assm = assm; @@ -87,7 +87,7 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) purple_debug(PURPLE_DEBUG_ERROR, "mono", "did not find the required methods\n"); return FALSE; } - + plugin_info = ml_get_info_prop(mplug->obj); /* now that the methods are filled out we can populate @@ -109,7 +109,7 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) /* this plugin depends on us; duh */ info->dependencies = g_list_append(info->dependencies, MONO_PLUGIN_ID); mplug->plugin = plugin; - + plugin->info = info; info->extra_info = mplug; @@ -238,7 +238,7 @@ static PurplePluginInfo info = static void init_plugin(PurplePlugin *plugin) { ml_init(); - + loader_info.exts = g_list_append(loader_info.exts, "dll"); } -- cgit v1.2.1 From 01355bdb6362819d186adb5604bb9248a4c3b6e5 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:02:22 +0000 Subject: Fix this compile error: debug-glue.c: In function ?purple_debug_glue?: debug-glue.c:12: error: format not a string literal and no format arguments --- libpurple/plugins/mono/loader/debug-glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurple/plugins/mono/loader/debug-glue.c b/libpurple/plugins/mono/loader/debug-glue.c index 01333521f8..fc07ca2289 100644 --- a/libpurple/plugins/mono/loader/debug-glue.c +++ b/libpurple/plugins/mono/loader/debug-glue.c @@ -9,7 +9,7 @@ void purple_debug_glue(int type, MonoString *cat, MonoString *str) ccat = mono_string_to_utf8(cat); cstr = mono_string_to_utf8(str); - purple_debug(type, ccat, cstr); + purple_debug(type, ccat, "%s", cstr); g_free(ccat); g_free(cstr); -- cgit v1.2.1 From e828a578a2ec71a000e95e9a8a524d9e24676dec Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:09:00 +0000 Subject: Free some memory if we exit early due to an error. Thanks to Mayank Jain Nawal's email to the devel list for pointing this out. Oh, and I didn't test these changes at all... I guess I probably should. --- libpurple/plugins/mono/loader/mono.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libpurple/plugins/mono/loader/mono.c b/libpurple/plugins/mono/loader/mono.c index 6810ef42a0..1f378e0901 100644 --- a/libpurple/plugins/mono/loader/mono.c +++ b/libpurple/plugins/mono/loader/mono.c @@ -44,11 +44,11 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) purple_debug(PURPLE_DEBUG_INFO, "mono", "Probing plugin\n"); if (ml_is_api_dll(mono_assembly_get_image(assm))) { - purple_debug(PURPLE_DEBUG_INFO, "mono", "Found our PurpleAPI.dll\n"); + purple_debug_info("mono", "Found our PurpleAPI.dll\n"); + mono_assembly_close(assm); return FALSE; } - info = g_new0(PurplePluginInfo, 1); mplug = g_new0(PurpleMonoPlugin, 1); mplug->signal_data = NULL; @@ -58,12 +58,16 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) mplug->klass = ml_find_plugin_class(mono_assembly_get_image(mplug->assm)); if (!mplug->klass) { purple_debug(PURPLE_DEBUG_ERROR, "mono", "no plugin class in \'%s\'\n", file); + mono_assembly_close(assm); + g_free(mplug); return FALSE; } mplug->obj = mono_object_new(ml_get_domain(), mplug->klass); if (!mplug->obj) { purple_debug(PURPLE_DEBUG_ERROR, "mono", "obj not valid\n"); + mono_assembly_close(assm); + g_free(mplug); return FALSE; } @@ -85,6 +89,8 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) if (!(found_load && found_unload && found_destroy)) { purple_debug(PURPLE_DEBUG_ERROR, "mono", "did not find the required methods\n"); + mono_assembly_close(assm); + g_free(mplug); return FALSE; } @@ -93,6 +99,7 @@ static gboolean probe_mono_plugin(PurplePlugin *plugin) /* now that the methods are filled out we can populate the info struct with all the needed info */ + info = g_new0(PurplePluginInfo, 1); info->id = ml_get_prop_string(plugin_info, "Id"); info->name = ml_get_prop_string(plugin_info, "Name"); info->version = ml_get_prop_string(plugin_info, "Version"); -- cgit v1.2.1 From 5e6cb442459d55edbba556f3005aba239d968376 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:29:22 +0000 Subject: Remove some unused fields. Thanks to Mayank Jain Nawal's email to the devel list for pointing this out. I'm guessing these fields are left over from Jim Seymour's original vcard implementation, which existed before our generic request fields functions. --- libpurple/protocols/jabber/buddy.c | 50 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/libpurple/protocols/jabber/buddy.c b/libpurple/protocols/jabber/buddy.c index 31f20c7e45..6f393ca4b4 100644 --- a/libpurple/protocols/jabber/buddy.c +++ b/libpurple/protocols/jabber/buddy.c @@ -301,36 +301,32 @@ const char *jabber_buddy_get_status_msg(JabberBuddy *jb) struct vcard_template { char *label; /* label text pointer */ - char *text; /* entry text pointer */ - int visible; /* should entry field be "visible?" */ - int editable; /* should entry field be editable? */ char *tag; /* tag text */ char *ptag; /* parent tag "path" text */ - char *url; /* vCard display format if URL */ } const vcard_template_data[] = { - {N_("Full Name"), NULL, TRUE, TRUE, "FN", NULL, NULL}, - {N_("Family Name"), NULL, TRUE, TRUE, "FAMILY", "N", NULL}, - {N_("Given Name"), NULL, TRUE, TRUE, "GIVEN", "N", NULL}, - {N_("Nickname"), NULL, TRUE, TRUE, "NICKNAME", NULL, NULL}, - {N_("URL"), NULL, TRUE, TRUE, "URL", NULL, "%s"}, - {N_("Street Address"), NULL, TRUE, TRUE, "STREET", "ADR", NULL}, - {N_("Extended Address"), NULL, TRUE, TRUE, "EXTADD", "ADR", NULL}, - {N_("Locality"), NULL, TRUE, TRUE, "LOCALITY", "ADR", NULL}, - {N_("Region"), NULL, TRUE, TRUE, "REGION", "ADR", NULL}, - {N_("Postal Code"), NULL, TRUE, TRUE, "PCODE", "ADR", NULL}, - {N_("Country"), NULL, TRUE, TRUE, "CTRY", "ADR", NULL}, - {N_("Telephone"), NULL, TRUE, TRUE, "NUMBER", "TEL", NULL}, - {N_("Email"), NULL, TRUE, TRUE, "USERID", "EMAIL", "%s"}, - {N_("Organization Name"), NULL, TRUE, TRUE, "ORGNAME", "ORG", NULL}, - {N_("Organization Unit"), NULL, TRUE, TRUE, "ORGUNIT", "ORG", NULL}, - {N_("Title"), NULL, TRUE, TRUE, "TITLE", NULL, NULL}, - {N_("Role"), NULL, TRUE, TRUE, "ROLE", NULL, NULL}, - {N_("Birthday"), NULL, TRUE, TRUE, "BDAY", NULL, NULL}, - {N_("Description"), NULL, TRUE, TRUE, "DESC", NULL, NULL}, - {"", NULL, TRUE, TRUE, "N", NULL, NULL}, - {"", NULL, TRUE, TRUE, "ADR", NULL, NULL}, - {"", NULL, TRUE, TRUE, "ORG", NULL, NULL}, - {NULL, NULL, 0, 0, NULL, NULL, NULL} + {N_("Full Name"), "FN", NULL}, + {N_("Family Name"), "FAMILY", "N"}, + {N_("Given Name"), "GIVEN", "N"}, + {N_("Nickname"), "NICKNAME", NULL}, + {N_("URL"), "URL", NULL}, + {N_("Street Address"), "STREET", "ADR"}, + {N_("Extended Address"), "EXTADD", "ADR"}, + {N_("Locality"), "LOCALITY", "ADR"}, + {N_("Region"), "REGION", "ADR"}, + {N_("Postal Code"), "PCODE", "ADR"}, + {N_("Country"), "CTRY", "ADR"}, + {N_("Telephone"), "NUMBER", "TEL"}, + {N_("Email"), "USERID", "EMAIL"}, + {N_("Organization Name"), "ORGNAME", "ORG"}, + {N_("Organization Unit"), "ORGUNIT", "ORG"}, + {N_("Title"), "TITLE", NULL}, + {N_("Role"), "ROLE", NULL}, + {N_("Birthday"), "BDAY", NULL}, + {N_("Description"), "DESC", NULL}, + {"", "N", NULL}, + {"", "ADR", NULL}, + {"", "ORG", NULL}, + {NULL, NULL, NULL} }; /* -- cgit v1.2.1 From 04a5e0238e31374be23f71c0580b92ee28b3af95 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:34:27 +0000 Subject: purple_xfer_new only returns NULL if an assertion fails, so we should do a similar assertion check here instead of if(xfer). The rest of the changes here are just removing indentation --- libpurple/protocols/jabber/si.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c index fe3f490c22..d5e050569f 100644 --- a/libpurple/protocols/jabber/si.c +++ b/libpurple/protocols/jabber/si.c @@ -1662,23 +1662,22 @@ void jabber_si_parse(JabberStream *js, xmlnode *packet) jsx->iq_id = g_strdup(xmlnode_get_attrib(packet, "id")); xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from); - if (xfer) - { - xfer->data = jsx; + g_return_if_fail(xfer != NULL); - purple_xfer_set_filename(xfer, filename); - if(filesize > 0) - purple_xfer_set_size(xfer, filesize); + xfer->data = jsx; - purple_xfer_set_init_fnc(xfer, jabber_si_xfer_init); - purple_xfer_set_request_denied_fnc(xfer, jabber_si_xfer_request_denied); - purple_xfer_set_cancel_recv_fnc(xfer, jabber_si_xfer_cancel_recv); - purple_xfer_set_end_fnc(xfer, jabber_si_xfer_end); + purple_xfer_set_filename(xfer, filename); + if(filesize > 0) + purple_xfer_set_size(xfer, filesize); - js->file_transfers = g_list_append(js->file_transfers, xfer); + purple_xfer_set_init_fnc(xfer, jabber_si_xfer_init); + purple_xfer_set_request_denied_fnc(xfer, jabber_si_xfer_request_denied); + purple_xfer_set_cancel_recv_fnc(xfer, jabber_si_xfer_cancel_recv); + purple_xfer_set_end_fnc(xfer, jabber_si_xfer_end); - purple_xfer_request(xfer); - } + js->file_transfers = g_list_append(js->file_transfers, xfer); + + purple_xfer_request(xfer); } void -- cgit v1.2.1 From de8b56203c81347d8f52f605e5cedff3cea8f937 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:36:38 +0000 Subject: Fix a potential memleak by freeing this regardless of whether hasActions is set --- libpurple/protocols/jabber/xdata.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libpurple/protocols/jabber/xdata.c b/libpurple/protocols/jabber/xdata.c index 1d2571c269..3a1914fc32 100644 --- a/libpurple/protocols/jabber/xdata.c +++ b/libpurple/protocols/jabber/xdata.c @@ -153,11 +153,12 @@ static void jabber_x_data_ok_cb(struct jabber_x_data_data *data, PurpleRequestFi } g_free(data); - if (hasActions) { + if (hasActions) cb(js, result, actionhandle, user_data); - g_free(actionhandle); - } else + else ((jabber_x_data_cb)cb)(js, result, user_data); + + g_free(actionhandle); } static void jabber_x_data_cancel_cb(struct jabber_x_data_data *data, PurpleRequestFields *fields) { -- cgit v1.2.1 From 620da97f46df71a7d482c9e88c21f39bf91eca15 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:41:12 +0000 Subject: You know something about this here data? It ain't ever used. --- libpurple/protocols/novell/nmmessage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libpurple/protocols/novell/nmmessage.c b/libpurple/protocols/novell/nmmessage.c index aa67bfec47..70b00eed22 100644 --- a/libpurple/protocols/novell/nmmessage.c +++ b/libpurple/protocols/novell/nmmessage.c @@ -24,7 +24,6 @@ struct _NMMessage { NMConference *conference; char *text; - gpointer data; guint32 ref_count; }; -- cgit v1.2.1 From 0ff055fd3fafc551a75555bc1665ac3e0624349b Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:42:10 +0000 Subject: Fix a memleak when setting your status on myspace --- libpurple/protocols/myspace/myspace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libpurple/protocols/myspace/myspace.c b/libpurple/protocols/myspace/myspace.c index 622bcf443b..2fdb82a36f 100644 --- a/libpurple/protocols/myspace/myspace.c +++ b/libpurple/protocols/myspace/myspace.c @@ -2540,6 +2540,7 @@ msim_set_status(PurpleAccount *account, PurpleStatus *status) stripped = g_strdup(""); msim_set_status_code(session, status_code, stripped); + g_free(stripped); /* If we should be idle, set that status. Time is irrelevant here. */ if (purple_presence_is_idle(pres) && status_code != MSIM_STATUS_CODE_OFFLINE_OR_HIDDEN) -- cgit v1.2.1 From cd4f0fc57dc028ce7a102050891885bc777fff66 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:44:36 +0000 Subject: Oh no this one is wrong. msim_set_status_code() calls msim_send() which takes ownership of the string --- libpurple/protocols/myspace/myspace.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libpurple/protocols/myspace/myspace.c b/libpurple/protocols/myspace/myspace.c index 2fdb82a36f..622bcf443b 100644 --- a/libpurple/protocols/myspace/myspace.c +++ b/libpurple/protocols/myspace/myspace.c @@ -2540,7 +2540,6 @@ msim_set_status(PurpleAccount *account, PurpleStatus *status) stripped = g_strdup(""); msim_set_status_code(session, status_code, stripped); - g_free(stripped); /* If we should be idle, set that status. Time is irrelevant here. */ if (purple_presence_is_idle(pres) && status_code != MSIM_STATUS_CODE_OFFLINE_OR_HIDDEN) -- cgit v1.2.1 From d0f6b4741504ebd02597f59f2d51fd53cf857b3f Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:48:25 +0000 Subject: Make sure we free itmsurl when showing the info window for a buddy with an itunes music store url --- libpurple/protocols/msn/cmdproc.c | 4 +++- libpurple/protocols/oscar/oscar.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libpurple/protocols/msn/cmdproc.c b/libpurple/protocols/msn/cmdproc.c index e487c77a66..49db28a3b3 100644 --- a/libpurple/protocols/msn/cmdproc.c +++ b/libpurple/protocols/msn/cmdproc.c @@ -117,8 +117,10 @@ msn_cmdproc_send_trans(MsnCmdProc *cmdproc, MsnTransaction *trans) servconn = cmdproc->servconn; - if (!servconn->connected) + if (!servconn->connected) { + /* TODO: Need to free trans */ return; + } msn_history_add(cmdproc->history, trans); diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index 06cd521b75..ee706e12c0 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -870,11 +870,11 @@ static void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUser if (itmsurl) { tmp = g_strdup_printf("%s", itmsurl, message); - g_free(itmsurl); g_free(message); message = tmp; } } + g_free(itmsurl); if (is_away && message) { tmp = purple_str_sub_away_formatters(message, purple_account_get_username(account)); -- cgit v1.2.1 From e0438e67d7e59404acec5c4bd08888d2045e4ec0 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:49:40 +0000 Subject: Remove an unused field --- libpurple/protocols/qq/buddy_list.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libpurple/protocols/qq/buddy_list.c b/libpurple/protocols/qq/buddy_list.c index e826354753..a1712f90a9 100644 --- a/libpurple/protocols/qq/buddy_list.c +++ b/libpurple/protocols/qq/buddy_list.c @@ -47,7 +47,6 @@ #define QQ_GET_ONLINE_BUDDY_03 0x03 /* unknown function */ typedef struct _qq_buddy_online { - qq_buddy_status bs; guint16 unknown1; guint8 ext_flag; guint8 comm_flag; -- cgit v1.2.1 From eb1586ab14ee9a767ecc838bdb4584029897bcab Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 09:55:28 +0000 Subject: Remove an unused protocol plugin --- ChangeLog | 1 + configure.ac | 4 - libpurple/protocols/Makefile.am | 2 +- libpurple/protocols/toc/Makefile.am | 32 - libpurple/protocols/toc/Makefile.mingw | 78 -- libpurple/protocols/toc/PROTOCOL | 499 ------- libpurple/protocols/toc/toc.c | 2340 -------------------------------- 7 files changed, 2 insertions(+), 2954 deletions(-) delete mode 100644 libpurple/protocols/toc/Makefile.am delete mode 100644 libpurple/protocols/toc/Makefile.mingw delete mode 100644 libpurple/protocols/toc/PROTOCOL delete mode 100644 libpurple/protocols/toc/toc.c diff --git a/ChangeLog b/ChangeLog index 1873204882..b11be599fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ version 2.6.0 (??/??/2009): project. With some minor additions and clean ups from Paul Aurich. * It should no longer be possible to end up with duplicates of buddies in a group on the buddy list. + * Removed the unmaintained and unneeded toc protocol plugin. XMPP: * Add support for in-band bytestreams for file transfers (XEP-0047). diff --git a/configure.ac b/configure.ac index 88de36f823..dd46c3ff9e 100644 --- a/configure.ac +++ b/configure.ac @@ -1048,7 +1048,6 @@ for i in $STATIC_PRPLS ; do silc) static_silc=yes ;; silc10) static_silc=yes ;; simple) static_simple=yes ;; - toc) static_toc=yes ;; yahoo) static_yahoo=yes ;; zephyr) static_zephyr=yes ;; *) echo "Invalid static protocol $i!!" ; exit ;; @@ -1066,7 +1065,6 @@ AM_CONDITIONAL(STATIC_QQ, test "x$static_qq" = "xyes") AM_CONDITIONAL(STATIC_SAMETIME, test "x$static_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") AM_CONDITIONAL(STATIC_SILC, test "x$static_silc" = "xyes" -a "x$have_silc" = "xyes") AM_CONDITIONAL(STATIC_SIMPLE, test "x$static_simple" = "xyes") -AM_CONDITIONAL(STATIC_TOC, test "x$static_toc" = "xyes") AM_CONDITIONAL(STATIC_YAHOO, test "x$static_yahoo" = "xyes") AM_CONDITIONAL(STATIC_ZEPHYR, test "x$static_zephyr" = "xyes") AC_SUBST(STATIC_LINK_LIBS) @@ -1112,7 +1110,6 @@ for i in $DYNAMIC_PRPLS ; do silc) dynamic_silc=yes ;; silc10) dynamic_silc=yes ;; simple) dynamic_simple=yes ;; - toc) dynamic_toc=yes ;; yahoo) dynamic_yahoo=yes ;; zephyr) dynamic_zephyr=yes ;; *) echo "Invalid dynamic protocol $i!!" ; exit ;; @@ -2450,7 +2447,6 @@ AC_OUTPUT([Makefile libpurple/protocols/silc/Makefile libpurple/protocols/silc10/Makefile libpurple/protocols/simple/Makefile - libpurple/protocols/toc/Makefile libpurple/protocols/yahoo/Makefile libpurple/protocols/zephyr/Makefile libpurple/tests/Makefile diff --git a/libpurple/protocols/Makefile.am b/libpurple/protocols/Makefile.am index c904076abb..97d1de9357 100644 --- a/libpurple/protocols/Makefile.am +++ b/libpurple/protocols/Makefile.am @@ -1,5 +1,5 @@ EXTRA_DIST = Makefile.mingw -DIST_SUBDIRS = bonjour gg irc jabber msn msnp9 myspace novell null oscar qq sametime silc silc10 toc simple yahoo zephyr +DIST_SUBDIRS = bonjour gg irc jabber msn msnp9 myspace novell null oscar qq sametime silc silc10 simple yahoo zephyr SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS) diff --git a/libpurple/protocols/toc/Makefile.am b/libpurple/protocols/toc/Makefile.am deleted file mode 100644 index db41dfa9ad..0000000000 --- a/libpurple/protocols/toc/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -EXTRA_DIST = \ - PROTOCOL \ - Makefile.mingw - -pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION) - -TOCSOURCES = toc.c - -AM_CFLAGS = $(st) - -libtoc_la_LDFLAGS = -module -avoid-version - -if STATIC_TOC - -st = -DPURPLE_STATIC_PRPL -noinst_LTLIBRARIES = libtoc.la -libtoc_la_SOURCES = $(TOCSOURCES) -libtoc_la_CFLAGS = $(AM_CFLAGS) - -else - -st = -pkg_LTLIBRARIES = libtoc.la -libtoc_la_SOURCES = $(TOCSOURCES) - -endif - -AM_CPPFLAGS = \ - -I$(top_srcdir)/libpurple \ - -I$(top_builddir)/libpurple \ - $(GLIB_CFLAGS) \ - $(DEBUG_CFLAGS) diff --git a/libpurple/protocols/toc/Makefile.mingw b/libpurple/protocols/toc/Makefile.mingw deleted file mode 100644 index 4da3a3dc26..0000000000 --- a/libpurple/protocols/toc/Makefile.mingw +++ /dev/null @@ -1,78 +0,0 @@ -# -# Makefile.mingw -# -# Description: Makefile for win32 (mingw) version of libtoc -# - -PIDGIN_TREE_TOP := ../../.. -include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak - -TARGET = libtoc -TYPE = PLUGIN - -# Static or Plugin... -ifeq ($(TYPE),STATIC) - DEFINES += -DSTATIC - DLL_INSTALL_DIR = $(PURPLE_INSTALL_DIR) -else -ifeq ($(TYPE),PLUGIN) - DLL_INSTALL_DIR = $(PURPLE_INSTALL_PLUGINS_DIR) -endif -endif - -## -## INCLUDE PATHS -## -INCLUDE_PATHS += -I$(TOC_ROOT) \ - -I$(GTK_TOP)/include \ - -I$(GTK_TOP)/include/glib-2.0 \ - -I$(GTK_TOP)/lib/glib-2.0/include \ - -I$(LIBPIDGIN_TREE_TOP) \ - -I$(LIBPIDGIN_TREE_TOP)/win32 \ - -I$(PIDGIN_TREE_TOP) - -LIB_PATHS += -L$(GTK_TOP)/lib \ - -L$(LIBPIDGIN_TREE_TOP) - -## -## SOURCES, OBJECTS -## -C_SRC = toc.c - -OBJECTS = $(C_SRC:%.c=%.o) - -## -## LIBRARIES -## -LIBS = \ - -lglib-2.0 \ - -lws2_32 \ - -lintl \ - -lpurple - -include $(PIDGIN_COMMON_RULES) - -## -## TARGET DEFINITIONS -## - -.PHONY: all install clean - -all: $(TARGET).dll - -install: all $(DLL_INSTALL_DIR) - cp $(TARGET).dll $(DLL_INSTALL_DIR) - -$(OBJECTS): $(PURPLE_CONFIG_H) - -$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS) - $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll - -## -## CLEAN RULES -## -clean: - rm -f $(OBJECTS) - rm -f $(TARGET).dll - -include $(PIDGIN_COMMON_TARGETS) diff --git a/libpurple/protocols/toc/PROTOCOL b/libpurple/protocols/toc/PROTOCOL deleted file mode 100644 index 87672dd55f..0000000000 --- a/libpurple/protocols/toc/PROTOCOL +++ /dev/null @@ -1,499 +0,0 @@ -# Copyright (c) 1998-9 America Online, Inc. All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA. - -# Note from Jim Duchek, former libpurple maintainer -- this may not be -# the latest version of this document, I provide it as a service. -# Download a copy of TiK (http://www.aim.aol.com/tik/) for the latest -# version of this doc. - -# Note from Eric Warmenhoven, random guy -- this appears to be the last -# published version of the protocol, and AOL has stopped hosting the TiK -# program. TiK is still being maintained and is hosted on sourceforge.net; -# this appears to be the same version of the protocol they're using. - -Version: TOC1.0 - -This document describes the protocol between TOC and TOC clients. -The protocol is built on TCP. Framing is done by SFLAP, -described at the bottom of this document. Inside each -SFLAP frame is a TOC command. - -The TOC protocol is ASCII based, and special attention -must be placed argument separation. The separator and -the rules of separation are different for messages inbound -to TOC and outbound to the client. The rules of separation -are described in sections below. - -The TOC server is built mainly to service the TIC and TiK clients. Since -the TIC client is a Java applet, and downloadable, TOC will NOT support -multiple TOC protocol versions at the same time. Therefore, TiK -users will be forced to upgrade if the protocol version changes. -TOC sends down the protocol version it expects the client -to speak and understand. Note, the protocol version is a string. - -Important Notes -=============== -* TOC will drop the connection if a command exceeds the maximum - length, which is currently 2048 bytes. So the client needs to - spend special attention to im, chat, and config message lengths. - There is an 8k length maximum from TOC to the client. - -* No commands should be sent to TOC (besides toc_signon) before - a SIGN_ON is received. If you do send a command before SIGN_ON - the command will be ignored, and in some case the connection - will be dropped. - -* Initial permit/deny items should be sent after receiving SIGN_ON - but before sending toc_init_done, otherwise the user will flash - on peoples buddylist who the user has denied. You will probably - want to send the toc_add_buddies at this time also. - -* After TOC sends the PAUSE message to a client, all messages sent - to TOC will be ignored, and in some cases the connection will - be dropped. Another SIGN_ON message will be sent to the client - when it is online again. The buddy list and permit/deny items must - be sent again, followed by the toc_init_done. In most cases the - SIGN_ON message will be sent between 1-2 seconds after the - PAUSE message. Therefore a client could choose to ignore the - PAUSE message and hope nothing bad happens. - - -Client -> TOC -============== -The commands and the arguments are usually separated by whitespaces. Arguments -with whitespace characters should be enclosed in quotes. Dollar signs, -curly brackets, square brackets, parentheses, quotes, and backslashes -must all be backslashed whether in quotes or not. It is usually -a good idea just to use quotes no matter what. All user names from clients -to TOC should be normalized (spaces removed and lowercased), and therefore -are the one exception to the always use quotes rule. - -When sending commands to the server you will not get a response -back confirming that the command format was correct or not! However -in some cases if the command format was incorrect the connection -will be dropped. - - -RoastingString="Tic/Toc" - -toc_signon - - The password needs to be roasted with the Roasting String if - coming over a FLAP connection, CP connections don't use - roasted passwords. The language specified will be used - when generating web pages, such as the get info pages. - Currently the only supported language is "english". - If the language sent isn't found, the default "english" - language will be used. The version string will be used - for the client identity, and must be less then 50 - characters. - - Passwords are roasted when sent to the host. This is done so they - aren't sent in "clear text" over the wire, although they are still - trivial to decode. Roasting is performed by first xoring each byte - in the password with the equivalent modulo byte in the roasting - string. The result is then converted to ascii hex, and prepended - with "0x". So for example the password "password" roasts to - "0x2408105c23001130" - -toc_init_done - Tells TOC that we are ready to go online. TOC clients should first - send TOC the buddy list and any permit/deny lists. However toc_init_done - must be called within 30 seconds after toc_signon, or the connection - will be dropped. Remember, it can't be called until after the SIGN_ON - message is received. Calling this before or multiple times after a - SIGN_ON will cause the connection to be dropped. - -toc_send_im [auto] - Send a message to a remote user. Remember to quote and encode the - message. If the optional string "auto" is the last argument, then the - auto response flag will be turned on for the im. - -toc_add_buddy [ [ [...]]] - Add buddies to your buddy list. This does not change your - saved config. - -toc_remove_buddy [ [ [...]]] - Remove buddies from your buddy list. This does not change your - saved config. - -toc_set_config - Set the config information for this user. The config information - is line oriented with the first character being the item type, - followed by a space, with the rest of the line being the item - value. Only letters, numbers, and spaces should be used. Remember - you will have to enclose the entire config in quotes. - - Item Types: - g - Buddy Group (All Buddies until the next g or the end of config - are in this group.) - b - A Buddy - p - Person on permit list - d - Person on deny list - m - Permit/Deny Mode. Possible values are - 1 - Permit All - 2 - Deny All - 3 - Permit Some - 4 - Deny Some - -toc_evil - Evil/Warn someone else. The 2nd argument is either the string - "norm" for a normal warning, or "anon" for an anonymous - warning. You can only evil people who have recently sent you - ims. The higher someones evil level, the slower they can - send message. - -toc_add_permit [ [ [...]]] - ADD the following people to your permit mode. If - you are in deny mode it will switch you to permit - mode first. With no arguments and in deny mode - this will switch you to permit none. If already - in permit mode, no arguments does nothing - and your permit list remains the same. - -toc_add_deny [ [ [...]]] - ADD the following people to your deny mode. If - you are in permit mode it will switch you to - deny mode first. With no arguments and in permit - mode, this will switch you to deny none. If - already in deny mode, no arguments does nothing - and your deny list remains unchanged. - -toc_chat_join - Join a chat room in the given exchange. Exchange is - an integer that represents a group of chat rooms. - Different exchanges have different properties. For - example some exchanges might have room replication (ie - a room never fills up, there are just multiple - instances.) and some exchanges might have navigational - information, and some exchanges might have ... Currently - exchange should always be 4, however this may - change in the future. You will either - receive an ERROR if the room couldn't be joined - or a CHAT_JOIN message. The Chat Room Name - is case insensitive and consecutive spaces - are removed. - -toc_chat_send - Send a message in a chat room using the chat room - id from CHAT_JOIN. Since reflection is always on in - TOC, you do not need to add the message to your chat UI, - since you will get a CHAT_IN with the message. - Remember to quote and encode the message. - -toc_chat_whisper - Send a message in a chat room using the chat room - id from CHAT_JOIN. This message is directed at - only one person. (Currently you DO need to add this to - your UI.) Remember to quote and encode the message. - Chat whispering is different from IMs since it is linked - to a chat room, and should usually be displayed in the chat - room UI. - -toc_chat_evil - Evil/Warn someone else inside a chat room. The 3rd argument is either - the string "norm" for a normal warning, or "anon" for an anonymous - warning. Currently chat evil is not turned on in the chat complex. - -toc_chat_invite [ [ [...]]] - Once you are inside a chat room you can invite other people into - that room. Remember to quote and encode the invite message. - -toc_chat_leave - Leave the chat room. - -toc_chat_accept - Accept a CHAT_INVITE message from TOC. The server will send a - CHAT_JOIN in response. - -toc_get_info - Gets a user's info a GOTO_URL or ERROR message will be sent back to the - client. - -toc_set_info - Set the LOCATE user information. This is basic HTML. - Remember to encode the info. - -toc_set_away [] - if the away message is present, then the unavailable - status flag is set for the user. If the away message - is not present, then the unavailable status flag is - unset. The away message is basic HTML, remember to - encode the information. - -toc_get_dir - Gets a user's dir info a GOTO_URL or ERROR message will be sent back to the - client. - -toc_set_dir - Set the DIR user information. This is a colon separated fields as in: - "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email":"allow web searches" - Should return a DIR_STATUS msg. Having anything in the "allow web searches" - field allows people to use web-searches to find your directory info. - Otherwise, they'd have to use the client. - -toc_dir_search - Perform a search of the Oscar Directory, using colon separated fields as in: - "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email" - Returns either a GOTO_URL or ERROR msg. - -toc_set_idle - Set idle information. If is 0 then the user isn't idle at all. - If is greater then 0 then the user has already been idle - for number of seconds. The server will automatically - keep incrementing this number, so do not repeatedly call with new - idle times. - -toc_set_caps [ [ [...]]] - Set my capabilities. All capabilities that we support need to - be sent at the same time. Capabilities are represented by - UUIDs. - -toc_rvous_propose - Not Implemented Yet - -toc_rvous_accept - Accept a rendezvous proposal from the user . - is the cookie from the RVOUS_PROPOSE - message. is the UUID the proposal was - for. contains a list of tlv tags followed by - base64 encoded values. - -toc_rvous_cancel - Cancel a rendezvous proposal from the user . - is the cookie from the RVOUS_PROPOSE - message. is the UUID the proposal was - for. contains a list of tlv tags followed by - base64 encoded values. - -toc_format_nickname - Reformat a user's nickname. An ADMIN_NICK_STATUS or ERROR message will - be sent back to the client. - -toc_change_passwd - Change a user's password. An ADMIN_PASSWD_STATUS or ERROR message will - be sent back to the client. - - -TOC -> Client -============== -All user names from TOC to client are NOT normalized, and are -sent as they should be displayed. String are NOT encoded, instead -we use colons as separators. So that you can have colons inside -of messages, everything after the colon before : should -be considered part of the message (ie don't just "split" on colons, -instead split with a max number of results.) - - -SIGN_ON: - This is sent after a successful toc_signon command is sent to TOC. - If the command was unsuccessful either the FLAP connection will - be dropped or you will receive a ERROR message. - -CONFIG: - A user's config. Config can be empty in which case the host was not able to - retrieve it, or a config didn't exist for the user. See toc_set_config - above for the format. - -NICK: - Tells you your correct nickname (ie how it should be capitalized and - spacing) - -IM_IN::: - Receive an IM from some one. Everything after the third colon is - the incoming message, including other colons. - -UPDATE_BUDDY:::::: - This one command handles arrival/depart/updates. Evil Amount is - a percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User Class) - is a two/three character string. - uc[0]: - ' ' - Ignore - 'A' - On AOL - uc[1] - ' ' - Ignore - 'A' - Oscar Admin - 'U' - Oscar Unconfirmed - 'O' - Oscar Normal - uc[2] - '\0' - Ignore - ' ' - Ignore - 'U' - The user has set their unavailable flag. - - - -ERROR::Var args - * General Errors * - 901 - $1 not currently available - 902 - Warning of $1 not currently available - 903 - A message has been dropped, you are exceeding - the server speed limit - - * Admin Errors * - 911 - Error validating input - 912 - Invalid account - 913 - Error encountered while processing request - 914 - Service unavailable - - * Chat Errors * - 950 - Chat in $1 is unavailable. - - * IM & Info Errors * - 960 - You are sending message too fast to $1 - 961 - You missed an im from $1 because it was too big. - 962 - You missed an im from $1 because it was sent too fast. - - * Dir Errors * - 970 - Failure - 971 - Too many matches - 972 - Need more qualifiers - 973 - Dir service temporarily unavailable - 974 - Email lookup restricted - 975 - Keyword Ignored - 976 - No Keywords - 977 - Language not supported - 978 - Country not supported - 979 - Failure unknown $1 - - * Auth errors * - 980 - Incorrect nickname or password. - 981 - The service is temporarily unavailable. - 982 - Your warning level is currently too high to sign on. - 983 - You have been connecting and - disconnecting too frequently. Wait 10 minutes and try again. - If you continue to try, you will need to wait even longer. - 989 - An unknown signon error has occurred $1 - - -EVILED:: - The user was just eviled. - -CHAT_JOIN:: - We were able to join this chat room. The Chat Room Id is - internal to TOC. - -CHAT_IN:::: - A chat message was sent in a chat room. - -CHAT_UPDATE_BUDDY::::... - This one command handles arrival/departs from a chat room. The - very first message of this type for each chat room contains the - users already in the room. - -CHAT_INVITE:::: - We are being invited to a chat room. - -CHAT_LEFT: - Tells tic connection to chat room has been dropped - -GOTO_URL:: - Goto a URL. Window Name is the suggested internal name of the window - to use. (Java supports this.) - -DIR_STATUS:: - is always 0 for success status. - -ADMIN_NICK_STATUS:: - is always 0 for success status. - -ADMIN_PASSWD_STATUS:: - is always 0 for success status. - - -PAUSE - Tells TIC to pause so we can do migration - -RVOUS_PROPOSE:::::::: - [:tlv tag1:tlv value1[:tlv tag2:tlv value2[:...]]] - Another user has proposed that we rendezvous with them to - perform the service specified by . They want us - to connect to them, we have their rendezvous ip, their - proposer_ip, and their verified_ip. The tlv values are - base64 encoded. - -Typical Signon Process -====================== -Except for the section marked optional this is an sequential -process. Each line MUST occur before the following line. - -* Client connects to TOC -* Client sends "FLAPON\r\n\r\n" -* TOC sends Client FLAP SIGNON -* Client sends TOC FLAP SIGNON -* Client sends TOC "toc_signon" message -* if login fails TOC drops client's connection - else TOC sends client SIGN_ON reply -* if Client doesn't support version it drops the connection - -[BEGIN OPTIONAL] - * TOC sends Client CONFIG - * Client sends TOC permit/deny stuff - * Client sends TOC toc_add_buddy message -[END OPTIONAL] - -* Client sends TOC toc_init_done message - - -SFLAP Documentation -=================== -SFLAP is pretty much a FLAP connection except the DATA frame payload is a null -terminated string when traveling from client to host, it is NOT null -terminated when traveling from host to client. The FLAP Header is binary -data, and is in network byte order. The data portion is at offset 6, after the -header. The sequence number is sequential in each direction. So -packets from the server to client have one sequence number, while -the packets from the client to server have an independent -increasing number. - -FLAP Header (6 bytes) ------------ -Offset Size Type -0 1 ASTERISK (literal ASCII '*') -1 1 Frame Type -2 2 Sequence Number -4 2 Data Length - - -Valid Frame Type Values ------------------------ -1 SIGNON -2 DATA -3 ERROR (Not used by TOC) -4 SIGNOFF (Not used by TOC) -5 KEEP_ALIVE - - -TOC SIGNON FRAME TYPE ---------------------- -Sequence Number contains the initial sequence number used in each direction. -Data Length contains the payload length, with the payload described -below. The payload area is NOT null terminated. - -Host To Client: - 4 byte FLAP version (1) - -Client To Host: - 4 byte FLAP version (1) - 2 byte TLV Tag (1) - 2 byte Normalized User Name Length - N byte Normalized User Name (NOT null terminated) - - -TOC DATA FRAME TYPE -------------------- -Sequence Number contains the next sequence number. -Data Length is the length of the payload, including the null termination -from client to host. - diff --git a/libpurple/protocols/toc/toc.c b/libpurple/protocols/toc/toc.c deleted file mode 100644 index e89a5d7bb0..0000000000 --- a/libpurple/protocols/toc/toc.c +++ /dev/null @@ -1,2340 +0,0 @@ -/* - * purple - * - * Copyright (C) 1998-1999, Mark Spencer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - * - */ -#include "internal.h" - -#include "account.h" -#include "accountopt.h" -#include "conversation.h" -#include "debug.h" -#include "notify.h" -#include "privacy.h" -#include "proxy.h" -#include "prpl.h" -#include "request.h" -#include "util.h" -#include "version.h" - -static PurplePlugin *my_protocol = NULL; - -#define REVISION "penguin" - -#define TYPE_SIGNON 1 -#define TYPE_DATA 2 -#define TYPE_ERROR 3 -#define TYPE_SIGNOFF 4 -#define TYPE_KEEPALIVE 5 - -#define FLAPON "FLAPON\r\n\r\n" -#define ROAST "Tic/Toc" - -#define TOC_HOST "toc.oscar.aol.com" -#define TOC_PORT 9898 -#define AUTH_HOST "login.oscar.aol.com" -#define AUTH_PORT 5190 -#define LANGUAGE "english" - -#define STATE_OFFLINE 0 -#define STATE_FLAPON 1 -#define STATE_SIGNON_REQUEST 2 -#define STATE_ONLINE 3 -#define STATE_PAUSE 4 - -#define VOICE_UID "09461341-4C7F-11D1-8222-444553540000" -#define FILE_SEND_UID "09461343-4C7F-11D1-8222-444553540000" -#define IMAGE_UID "09461345-4C7F-11D1-8222-444553540000" -#define B_ICON_UID "09461346-4C7F-11D1-8222-444553540000" -#define STOCKS_UID "09461347-4C7F-11D1-8222-444553540000" -#define FILE_GET_UID "09461348-4C7F-11D1-8222-444553540000" -#define GAMES_UID "0946134a-4C7F-11D1-8222-444553540000" - -#define UC_UNAVAILABLE 0x01 -#define UC_AOL 0x02 -#define UC_ADMIN 0x04 -#define UC_UNCONFIRMED 0x08 -#define UC_NORMAL 0x10 -#define UC_WIRELESS 0x20 - -struct ft_request { - PurpleConnection *gc; - char *user; - char UID[2048]; - char *cookie; - char *ip; - int port; - char *message; - char *filename; - int files; - int size; -}; - -struct buddy_icon { - guint32 hash; - guint32 len; - time_t time; - void *data; -}; - -struct toc_data { - int toc_fd; - char toc_ip[20]; - int seqno; - int state; -}; - -struct sflap_hdr { - unsigned char ast; - unsigned char type; - unsigned short seqno; - unsigned short len; -}; - -struct signon { - unsigned int ver; - unsigned short tag; - unsigned short namelen; - char username[80]; -}; - -/* constants to identify proto_opts */ -#define USEROPT_AUTH 0 -#define USEROPT_AUTHPORT 1 - -#define TOC_CONNECT_STEPS 3 - -static void toc_login_callback(gpointer, gint, const gchar *); -static void toc_callback(gpointer, gint, PurpleInputCondition); - -/* ok. this function used to take username/password, and return 0 on success. - * now, it takes username/password, and returns NULL on error or a new purple_connection - * on success. */ -static void toc_login(PurpleAccount *account) -{ - PurpleConnection *gc; - struct toc_data *tdt; - char buf[80]; - - gc = purple_account_get_connection(account); - gc->proto_data = tdt = g_new0(struct toc_data, 1); - gc->flags |= PURPLE_CONNECTION_HTML; - gc->flags |= PURPLE_CONNECTION_AUTO_RESP; - - g_snprintf(buf, sizeof buf, _("Looking up %s"), - purple_account_get_string(account, "server", TOC_HOST)); - purple_connection_update_progress(gc, buf, 0, TOC_CONNECT_STEPS); - - purple_debug(PURPLE_DEBUG_INFO, "toc", "Client connects to TOC\n"); - if (purple_proxy_connect(gc, account, - purple_account_get_string(account, "server", TOC_HOST), - purple_account_get_int(account, "port", TOC_PORT), - toc_login_callback, gc) != 0 || !account->gc) { - g_snprintf(buf, sizeof(buf), _("Connect to %s failed"), - purple_account_get_string(account, "server", TOC_HOST)); - purple_connection_error(gc, buf); - return; - } -} - -static void toc_login_callback(gpointer data, gint source, const gchar *error_message) -{ - PurpleConnection *gc = data; - struct toc_data *tdt; - char buf[80]; - struct sockaddr_in name; - socklen_t namelen; - - if (!PURPLE_CONNECTION_IS_VALID(gc)) { - if (source >= 0) - close(source); - return; - } - - tdt = gc->proto_data; - - if (source == -1) { - /* we didn't successfully connect. tdt->toc_fd is valid here */ - purple_connection_error(gc, _("Unable to connect.")); - return; - } - tdt->toc_fd = source; - - /* - * Copy the IP that we're connected to. We need this because "GOTO_URL"'s - * should open on the exact server we're connected to. toc.oscar.aol.com - * doesn't work because that hostname resolves to multiple IP addresses. - */ - if (getpeername(tdt->toc_fd, (struct sockaddr *)&name, &namelen) == 0) - strncpy(tdt->toc_ip, inet_ntoa(name.sin_addr), sizeof(tdt->toc_ip)); - else - strncpy(tdt->toc_ip, purple_account_get_string(gc->account, "server", TOC_HOST), sizeof(tdt->toc_ip)); - - purple_debug(PURPLE_DEBUG_INFO, "toc", - "Client sends \"FLAPON\\r\\n\\r\\n\"\n"); - if (write(tdt->toc_fd, FLAPON, strlen(FLAPON)) < 0) { - purple_connection_error(gc, _("Disconnected.")); - return; - } - tdt->state = STATE_FLAPON; - - /* i know a lot of people like to look at purple to see how TOC works. so i'll comment - * on what this does. it's really simple. when there's data ready to be read from the - * toc_fd file descriptor, toc_callback is called, with gc passed as its data arg. */ - gc->inpa = purple_input_add(tdt->toc_fd, PURPLE_INPUT_READ, toc_callback, gc); - - g_snprintf(buf, sizeof(buf), _("Signon: %s"), purple_account_get_username(gc->account)); - purple_connection_update_progress(gc, buf, 1, TOC_CONNECT_STEPS); -} - -static void toc_close(PurpleConnection *gc) -{ - if (gc->inpa > 0) - purple_input_remove(gc->inpa); - gc->inpa = 0; - close(((struct toc_data *)gc->proto_data)->toc_fd); - g_free(gc->proto_data); -} - -static void toc_build_config(PurpleAccount *account, char *s, int len, gboolean show) -{ - PurpleBlistNode *gnode, *cnode, *bnode; - PurpleGroup *g; - PurpleBuddy *b; - GSList *plist = account->permit; - GSList *dlist = account->deny; - - int pos = 0; - - if (!account->perm_deny) - account->perm_deny = 1; - - pos += g_snprintf(&s[pos], len - pos, "m %d\n", account->perm_deny); - for(gnode = purple_get_blist()->root; gnode && len > pos; gnode = gnode->next) { - g = (PurpleGroup *)gnode; - if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) - continue; - if(purple_group_on_account(g, account)) { - pos += g_snprintf(&s[pos], len - pos, "g %s\n", g->name); - for(cnode = gnode->child; cnode; cnode = cnode->next) { - if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) - continue; - for(bnode = gnode->child; bnode && len > pos; bnode = bnode->next) { - b = (PurpleBuddy *)bnode; - if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - if(b->account == account) { - pos += g_snprintf(&s[pos], len - pos, "b %s%s%s\n", - b->name, - (show && b->alias) ? ":" : "", - (show && b->alias) ? b->alias : ""); - } - } - } - } - } - - while (len > pos && plist) { - pos += g_snprintf(&s[pos], len - pos, "p %s\n", (char *)plist->data); - plist = plist->next; - } - - while (len > pos && dlist) { - pos += g_snprintf(&s[pos], len - pos, "d %s\n", (char *)dlist->data); - dlist = dlist->next; - } -} - -static char * -escape_message(const char *msg) -{ - char *ret; - int i, j; - - if (!msg) - return NULL; - - /* Calculate the length after escaping */ - for (i=0, j=0; msg[i]; i++) - switch (msg[i]) { - case '$': - case '[': - case ']': - case '(': - case ')': - j++; - default: - j++; - } - - /* Allocate a string */ - ret = (char *)g_malloc((j+1) * sizeof(char)); - - /* Copy the string */ - for (i=0, j=0; msg[i]; i++) - switch (msg[i]) { - case '$': - case '[': - case ']': - case '(': - case ')': - ret[j++] = '\\'; - default: - ret[j++] = msg[i]; - } - ret[j] = '\0'; - - return ret; -} - -/* - * Duplicates the input string, replacing each \n with a
, and - * escaping a few other characters. - */ -static char * -escape_text(const char *msg) -{ - char *ret; - int i, j; - - if (!msg) - return NULL; - - /* Calculate the length after escaping */ - for (i=0, j=0; msg[i]; i++) - switch (msg[i]) { - case '\n': - j += 4; - break; - case '{': - case '}': - case '\\': - case '"': - j += 1; - default: - j += 1; - } - - /* Allocate a string */ - ret = (char *)malloc((j+1) * sizeof(char)); - - /* Copy the string */ - for (i=0, j=0; msg[i]; i++) - switch (msg[i]) { - case '\n': - ret[j++] = '<'; - ret[j++] = 'B'; - ret[j++] = 'R'; - ret[j++] = '>'; - break; - case '{': - case '}': - case '\\': - case '"': - ret[j++] = '\\'; - default: - ret[j++] = msg[i]; - } - ret[j] = '\0'; - - return ret; -} - -static int sflap_send(PurpleConnection *gc, const char *buf, int olen, int type) -{ - struct toc_data *tdt = (struct toc_data *)gc->proto_data; - int len; - int slen = 0; - int ret; - struct sflap_hdr hdr; - char *escaped, *obuf; - - if (tdt->state == STATE_PAUSE) - /* TOC has given us the PAUSE message; sending could cause a disconnect - * so we just return here like everything went through fine */ - return 0; - - if (olen < 0) { - escaped = escape_message(buf); - len = strlen(escaped); - } else { - escaped = g_memdup(buf, olen); - len = olen; - } - - /* - * One _last_ 2048 check here! This shouldn't ever - * get hit though, hopefully. If it gets hit on an IM - * It'll lose the last " and the message won't go through, - * but this'll stop a segfault. - */ - if (len > MSG_LEN) { - purple_debug(PURPLE_DEBUG_WARNING, "toc", "message too long, truncating\n"); - escaped[MSG_LEN - 1] = '\0'; - len = MSG_LEN; - } - - if (olen < 0) - purple_debug(PURPLE_DEBUG_INFO, "toc", "C: %s\n", escaped); - - hdr.ast = '*'; - hdr.type = type; - hdr.seqno = htons(tdt->seqno++ & 0xffff); - hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); - - obuf = (char *)malloc((sizeof(hdr)+len+1) * sizeof(char)); - memcpy(obuf, &hdr, sizeof(hdr)); - slen += sizeof(hdr); - - memcpy(&obuf[slen], escaped, len); - slen += len; - - if (type != TYPE_SIGNON) { - obuf[slen] = '\0'; - slen += 1; - } - - ret = write(tdt->toc_fd, obuf, slen); - free(obuf); - g_free(escaped); - - return ret; -} - -static int toc_send_raw(PurpleConnection *gc, const char *buf, int len) -{ - return sflap_send(gc, buf, len, 2); -} - -static int wait_reply(PurpleConnection *gc, char *buffer, size_t buflen) -{ - struct toc_data *tdt = (struct toc_data *)gc->proto_data; - struct sflap_hdr *hdr; - int ret; - - if (read(tdt->toc_fd, buffer, sizeof(struct sflap_hdr)) < 0) { - purple_debug(PURPLE_DEBUG_ERROR, "toc", "Couldn't read flap header\n"); - return -1; - } - - hdr = (struct sflap_hdr *)buffer; - - if (buflen < ntohs(hdr->len)) { - /* fake like there's a read error */ - purple_debug(PURPLE_DEBUG_ERROR, "toc", - "buffer too small (have %" G_GSIZE_FORMAT ", need %d)\n", - buflen, ntohs(hdr->len)); - return -1; - } - - if (ntohs(hdr->len) > 0) { - int count = 0; - ret = 0; - do { - count += ret; - ret = read(tdt->toc_fd, - buffer + sizeof(struct sflap_hdr) + count, ntohs(hdr->len) - count); - } while (count + ret < ntohs(hdr->len) && ret > 0); - buffer[sizeof(struct sflap_hdr) + count + ret] = '\0'; - return ret; - } else - return 0; -} - -static unsigned char *roast_password(const char *pass) -{ - /* Trivial "encryption" */ - static unsigned char rp[256]; - static char *roast = ROAST; - int pos = 2; - int x; - strcpy(rp, "0x"); - for (x = 0; (x < 150) && pass[x]; x++) - pos += sprintf(&rp[pos], "%02x", pass[x] ^ roast[x % strlen(roast)]); - rp[pos] = '\0'; - return rp; -} - -static void toc_got_info(void *data, const char *url_text, size_t len) -{ - if (!url_text) - return; - - purple_notify_formatted(data, NULL, _("Buddy Information"), NULL, - url_text, NULL, NULL); -} - -static char *show_error_message() -{ - int no = atoi(strtok(NULL, ":")); - char *w = strtok(NULL, ":"); - static char buf[256]; - - switch(no) { - case 69: - g_snprintf(buf, sizeof(buf), _("Unable to write file %s."), w); - break; - case 169: - g_snprintf(buf, sizeof(buf), _("Unable to read file %s."), w); - break; - case 269: - g_snprintf(buf, sizeof(buf), _("Message too long, last %s bytes truncated."), w); - break; - case 901: - g_snprintf(buf, sizeof(buf), _("%s not currently logged in."), w); - break; - case 902: - g_snprintf(buf, sizeof(buf), _("Warning of %s not allowed."), w); - break; - case 903: - g_snprintf(buf, sizeof(buf), _("A message has been dropped, you are exceeding the server speed limit.")); - break; - case 950: - g_snprintf(buf, sizeof(buf), _("Chat in %s is not available."), w); - break; - case 960: - g_snprintf(buf, sizeof(buf), _("You are sending messages too fast to %s."), w); - break; - case 961: - g_snprintf(buf, sizeof(buf), _("You missed an IM from %s because it was too big."), w); - break; - case 962: - g_snprintf(buf, sizeof(buf), _("You missed an IM from %s because it was sent too fast."), w); - break; - case 970: - g_snprintf(buf, sizeof(buf), _("Failure.")); - break; - case 971: - g_snprintf(buf, sizeof(buf), _("Too many matches.")); - break; - case 972: - g_snprintf(buf, sizeof(buf), _("Need more qualifiers.")); - break; - case 973: - g_snprintf(buf, sizeof(buf), _("Dir service temporarily unavailable.")); - break; - case 974: - g_snprintf(buf, sizeof(buf), _("Email lookup restricted.")); - break; - case 975: - g_snprintf(buf, sizeof(buf), _("Keyword ignored.")); - break; - case 976: - g_snprintf(buf, sizeof(buf), _("No keywords.")); - break; - case 977: - g_snprintf(buf, sizeof(buf), _("User has no directory information.")); - /* g_snprintf(buf, sizeof(buf), _("Language not supported.")); */ - break; - case 978: - g_snprintf(buf, sizeof(buf), _("Country not supported.")); - break; - case 979: - g_snprintf(buf, sizeof(buf), _("Failure unknown: %s."), w); - break; - case 980: - g_snprintf(buf, sizeof(buf), _("Incorrect username or password.")); - break; - case 981: - g_snprintf(buf, sizeof(buf), _("The service is temporarily unavailable.")); - break; - case 982: - g_snprintf(buf, sizeof(buf), _("Your warning level is currently too high to log in.")); - break; - case 983: - g_snprintf(buf, sizeof(buf), _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); - break; - g_snprintf(buf, sizeof(buf), _("An unknown signon error has occurred: %s."), w); - break; - default: - g_snprintf(buf, sizeof(buf), _("An unknown error, %d, has occurred. Info: %s"), no, w); - } - - return buf; -} - -static void -parse_toc_buddy_list(PurpleAccount *account, char *config) -{ - char *c; - char current[256]; - GList *buddies = NULL; - - if (config == NULL) - return; - - /* skip "CONFIG:" (if it exists) */ - c = strncmp(config + 6 /* sizeof(struct sflap_hdr) */ , "CONFIG:", strlen("CONFIG:")) ? - strtok(config, "\n") : - strtok(config + 6 /* sizeof(struct sflap_hdr) */ + strlen("CONFIG:"), "\n"); - do { - if (c == NULL) - break; - if (*c == 'g') { - char *utf8 = NULL; - utf8 = purple_utf8_try_convert(c + 2); - if (utf8 == NULL) { - g_strlcpy(current, _("Invalid Groupname"), sizeof(current)); - } else { - g_strlcpy(current, utf8, sizeof(current)); - g_free(utf8); - } - if (!purple_find_group(current)) { - PurpleGroup *g = purple_group_new(current); - purple_blist_add_group(g, NULL); - } - } else if (*c == 'b') { /*&& !purple_find_buddy(user, c + 2)) {*/ - char nm[80], sw[388], *a, *utf8 = NULL; - - if ((a = strchr(c + 2, ':')) != NULL) { - *a++ = '\0'; /* nul the : */ - } - - g_strlcpy(nm, c + 2, sizeof(nm)); - if (a) { - utf8 = purple_utf8_try_convert(a); - if (utf8 == NULL) { - purple_debug(PURPLE_DEBUG_ERROR, "toc blist", - "Failed to convert alias for " - "'%s' to UTF-8\n", nm); - } - } - if (utf8 == NULL) { - sw[0] = '\0'; - } else { - /* This can leave a partial sequence at the end, - * but who cares? */ - g_strlcpy(sw, utf8, sizeof(sw)); - g_free(utf8); - } - - if (!purple_find_buddy(account, nm)) { - PurpleBuddy *b = purple_buddy_new(account, nm, sw); - PurpleGroup *g = purple_find_group(current); - purple_blist_add_buddy(b, NULL, g, NULL); - buddies = g_list_append(buddies, b); - } - } else if (*c == 'p') { - purple_privacy_permit_add(account, c + 2, TRUE); - } else if (*c == 'd') { - purple_privacy_deny_add(account, c + 2, TRUE); - } else if (!strncmp("toc", c, 3)) { - sscanf(c + strlen(c) - 1, "%d", &account->perm_deny); - purple_debug(PURPLE_DEBUG_MISC, "toc blist", - "permdeny: %d\n", account->perm_deny); - if (account->perm_deny == 0) - account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL; - } else if (*c == 'm') { - sscanf(c + 2, "%d", &account->perm_deny); - purple_debug(PURPLE_DEBUG_MISC, "toc blist", - "permdeny: %d\n", account->perm_deny); - if (account->perm_deny == 0) - account->perm_deny = PURPLE_PRIVACY_ALLOW_ALL; - } - } while ((c = strtok(NULL, "\n"))); - - if (account->gc) { - if (buddies != NULL) { - purple_account_add_buddies(account, buddies); - g_list_free(buddies); - } - serv_set_permit_deny(account->gc); - } - g_list_free(buddies); -} - -static void toc_callback(gpointer data, gint source, PurpleInputCondition condition) -{ - PurpleConnection *gc = (PurpleConnection *)data; - PurpleAccount *account = purple_connection_get_account(gc); - struct toc_data *tdt = (struct toc_data *)gc->proto_data; - struct sflap_hdr *hdr; - struct signon so; - char buf[8 * 1024], *c; - char snd[BUF_LEN * 2]; - const char *username = purple_account_get_username(account); - char *password; - PurpleBuddy *buddy; - - /* there's data waiting to be read, so read it. */ - if (wait_reply(gc, buf, 8 * 1024) <= 0) { - purple_connection_error(gc, _("Connection Closed")); - return; - } - - if (tdt->state == STATE_FLAPON) { - hdr = (struct sflap_hdr *)buf; - if (hdr->type != TYPE_SIGNON) - purple_debug(PURPLE_DEBUG_ERROR, "toc", "hdr->type != TYPE_SIGNON\n"); - else - purple_debug(PURPLE_DEBUG_INFO, "toc", - "TOC sends Client FLAP SIGNON\n"); - tdt->seqno = ntohs(hdr->seqno); - tdt->state = STATE_SIGNON_REQUEST; - - purple_debug(PURPLE_DEBUG_INFO, "toc", "Client sends TOC FLAP SIGNON\n"); - g_snprintf(so.username, sizeof(so.username), "%s", username); - so.ver = htonl(1); - so.tag = htons(1); - so.namelen = htons(strlen(so.username)); - if (sflap_send(gc, (char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON) < 0) { - purple_connection_error(gc, _("Disconnected.")); - return; - } - - purple_debug(PURPLE_DEBUG_INFO, "toc", - "Client sends TOC \"toc_signon\" message\n"); - /* i hate icq. */ - if (username[0] >= '0' && username[0] <= '9') - password = g_strndup(purple_connection_get_password(gc), 8); - else - password = g_strdup(purple_connection_get_password(gc)); - g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", - AUTH_HOST, AUTH_PORT, purple_normalize(account, username), - roast_password(password), LANGUAGE, REVISION); - g_free(password); - if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { - purple_connection_error(gc, _("Disconnected.")); - return; - } - - purple_connection_update_progress(gc, _("Waiting for reply..."), 2, TOC_CONNECT_STEPS); - return; - } - - if (tdt->state == STATE_SIGNON_REQUEST) { - purple_debug(PURPLE_DEBUG_INFO, "toc", "TOC sends client SIGN_ON reply\n"); - if (g_ascii_strncasecmp(buf + sizeof(struct sflap_hdr), "SIGN_ON", strlen("SIGN_ON"))) { - purple_debug(PURPLE_DEBUG_ERROR, "toc", - "Didn't get SIGN_ON! buf was: %s\n", - buf + sizeof(struct sflap_hdr)); - if (!g_ascii_strncasecmp(buf + sizeof(struct sflap_hdr), "ERROR", 5)) { - strtok(buf + sizeof(struct sflap_hdr), ":"); - purple_connection_error(gc, show_error_message()); - } else - purple_connection_error(gc, _("Authentication failed")); - return; - } - /* we're supposed to check that it's really TOC v1 here but we know it is ;) */ - purple_debug(PURPLE_DEBUG_INFO, "toc", - "TOC version: %s\n", buf + sizeof(struct sflap_hdr) + 8); - - /* we used to check for the CONFIG here, but we'll wait until we've sent our - * version of the config and then the toc_init_done message. we'll come back to - * the callback in a better state if we get CONFIG anyway */ - - tdt->state = STATE_ONLINE; - - purple_connection_set_state(gc, PURPLE_CONNECTED); - - /* - * Add me to my buddy list so that we know the time when - * the server thinks I signed on. - */ - buddy = purple_buddy_new(account, username, NULL); - /* XXX - Pick a group to add to */ - /* purple_blist_add(buddy, NULL, g, NULL); */ - purple_account_add_buddy(gc, buddy); - - /* Client sends TOC toc_init_done message */ - purple_debug(PURPLE_DEBUG_INFO, "toc", - "Client sends TOC toc_init_done message\n"); - 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); - - return; - } - - purple_debug(PURPLE_DEBUG_INFO, "toc", "S: %s\n", - buf + sizeof(struct sflap_hdr)); - - c = strtok(buf + sizeof(struct sflap_hdr), ":"); /* Ditch the first part */ - - if (!g_ascii_strcasecmp(c, "SIGN_ON")) { - /* we should only get here after a PAUSE */ - if (tdt->state != STATE_PAUSE) - purple_debug(PURPLE_DEBUG_ERROR, "toc", - "got SIGN_ON but not PAUSE!\n"); - else { - tdt->state = STATE_ONLINE; - g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", - AUTH_HOST, AUTH_PORT, - purple_normalize(account, purple_account_get_username(account)), - roast_password(purple_connection_get_password(gc)), - LANGUAGE, REVISION); - if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { - purple_connection_error(gc, _("Disconnected.")); - return; - } - g_snprintf(snd, sizeof snd, "toc_init_done"); - sflap_send(gc, snd, -1, TYPE_DATA); - purple_notify_info(gc, NULL, - _("TOC has come back from its pause. You may " - "now send messages again."), NULL); - } - } else if (!g_ascii_strcasecmp(c, "CONFIG")) { - c = strtok(NULL, ":"); - parse_toc_buddy_list(account, c); - } else if (!g_ascii_strcasecmp(c, "NICK")) { - /* ignore NICK so that things get imported/exported properly - c = strtok(NULL, ":"); - g_snprintf(gc->username, sizeof(gc->username), "%s", c); - */ - } else if (!g_ascii_strcasecmp(c, "IM_IN")) { - char *away, *message; - int a = 0; - - c = strtok(NULL, ":"); - away = strtok(NULL, ":"); - - message = away; - while (*message && (*message != ':')) - message++; - message++; - - a = (away && (*away == 'T')) ? PURPLE_MESSAGE_AUTO_RESP : 0; - - serv_got_im(gc, c, message, a, time(NULL)); - } else if (!g_ascii_strcasecmp(c, "UPDATE_BUDDY")) { - char *l, *uc, *tmp; - gboolean logged_in; - int evil, idle, type = 0; - time_t signon, time_idle; - - c = strtok(NULL, ":"); /* name */ - l = strtok(NULL, ":"); /* online */ - sscanf(strtok(NULL, ":"), "%d", &evil); - sscanf(strtok(NULL, ":"), "%ld", &signon); - sscanf(strtok(NULL, ":"), "%d", &idle); - uc = strtok(NULL, ":"); - - logged_in = (l && (*l == 'T')) ? TRUE : FALSE; - - if (uc[0] == 'A') - type |= UC_AOL; - switch (uc[1]) { - case 'A': - type |= UC_ADMIN; - break; - case 'U': - type |= UC_UNCONFIRMED; - break; - case 'O': - type |= UC_NORMAL; - break; - case 'C': - type |= UC_WIRELESS; - break; - default: - break; - } - if (uc[2] == 'U') - type |= UC_UNAVAILABLE; - - if (idle) { - time(&time_idle); - time_idle -= idle * 60; - } else - time_idle = 0; - - /* - * If we have info for ourselves then set our display name, warning - * level and official time of login. - */ - tmp = g_strdup(purple_normalize(account, purple_account_get_username(gc->account))); - if (!strcmp(tmp, purple_normalize(account, c))) { - purple_connection_set_display_name(gc, c); - /* XXX - What should the second parameter be here? */ - /* purple_prpl_got_account_warning_level(account, NULL, evil);*/ - purple_prpl_got_account_login_time(account, signon); - } - g_free(tmp); - - purple_prpl_got_user_status(account, c, (logged_in ? "online" : "offline"), NULL); - purple_prpl_got_user_login_time(account, c, signon); - if (time_idle > 0) - purple_prpl_got_user_idle(account, c, TRUE, time_idle); - else - purple_prpl_got_user_idle(account, c, FALSE, 0); - } else if (!g_ascii_strcasecmp(c, "ERROR")) { - purple_notify_error(gc, NULL, show_error_message(), NULL); - } else if (!g_ascii_strcasecmp(c, "EVILED")) { - int lev; - char *name; - - sscanf(strtok(NULL, ":"), "%d", &lev); - name = strtok(NULL, ":"); - - /* purple_prpl_got_account_warning_level(account, name, lev); */ - } else if (!g_ascii_strcasecmp(c, "CHAT_JOIN")) { - char *name; - int id; - - sscanf(strtok(NULL, ":"), "%d", &id); - name = strtok(NULL, ":"); - - serv_got_joined_chat(gc, id, name); - } else if (!g_ascii_strcasecmp(c, "CHAT_IN")) { - int id; - PurpleMessageFlags flags; - char *m, *who, *whisper; - - sscanf(strtok(NULL, ":"), "%d", &id); - who = strtok(NULL, ":"); - whisper = strtok(NULL, ":"); - m = whisper; - while (*m && (*m != ':')) - m++; - m++; - - flags = (whisper && (*whisper == 'T')) ? PURPLE_MESSAGE_WHISPER : 0; - - serv_got_chat_in(gc, id, who, flags, m, time((time_t)NULL)); - } else if (!g_ascii_strcasecmp(c, "CHAT_UPDATE_BUDDY")) { - int id; - char *in, *buddy; - GSList *bcs = gc->buddy_chats; - PurpleConversation *b = NULL; - PurpleConvChat *chat; - - sscanf(strtok(NULL, ":"), "%d", &id); - in = strtok(NULL, ":"); - - chat = PURPLE_CONV_CHAT(b); - - while (bcs) { - b = (PurpleConversation *)bcs->data; - if (id == purple_conv_chat_get_id(chat)) - break; - bcs = bcs->next; - b = NULL; - } - - if (!b) - return; - - if (in && (*in == 'T')) - while ((buddy = strtok(NULL, ":")) != NULL) - purple_conv_chat_add_user(chat, buddy, NULL, PURPLE_CBFLAGS_NONE, TRUE); - else - while ((buddy = strtok(NULL, ":")) != NULL) - purple_conv_chat_remove_user(chat, buddy, NULL); - } else if (!g_ascii_strcasecmp(c, "CHAT_INVITE")) { - char *name, *who, *message; - int id; - GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); - - name = strtok(NULL, ":"); - sscanf(strtok(NULL, ":"), "%d", &id); - who = strtok(NULL, ":"); - message = strtok(NULL, ":"); - - g_hash_table_replace(components, g_strdup("id"), g_strdup_printf("%d", id)); - - serv_got_chat_invite(gc, name, who, message, components); - } else if (!g_ascii_strcasecmp(c, "CHAT_LEFT")) { - GSList *bcs = gc->buddy_chats; - PurpleConversation *b = NULL; - int id; - - sscanf(strtok(NULL, ":"), "%d", &id); - - while (bcs) { - b = (PurpleConversation *)bcs->data; - if (id == purple_conv_chat_get_id(PURPLE_CONV_CHAT(b))) - break; - b = NULL; - bcs = bcs->next; - } - - if (!b) - return; - - if (b->window) { - char error_buf[BUF_LONG]; - purple_conversation_set_account(b, NULL); - g_snprintf(error_buf, sizeof error_buf, _("You have been disconnected" - " from chat room %s."), b->name); - purple_notify_error(gc, NULL, error_buf, NULL); - } else - serv_got_chat_left(gc, id); - } else if (!g_ascii_strcasecmp(c, "GOTO_URL")) { - char *name, *url, tmp[256]; - - name = strtok(NULL, ":"); - url = strtok(NULL, ":"); - - g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", tdt->toc_ip, - purple_account_get_int(gc->account, "port", TOC_PORT), - url); - purple_url_fetch(tmp, FALSE, NULL, FALSE, toc_got_info, gc); - } else if (!g_ascii_strcasecmp(c, "DIR_STATUS")) { - } else if (!g_ascii_strcasecmp(c, "ADMIN_NICK_STATUS")) { - } else if (!g_ascii_strcasecmp(c, "ADMIN_PASSWD_STATUS")) { - purple_notify_info(gc, NULL, _("Password Change Successful"), NULL); - } else if (!g_ascii_strcasecmp(c, "PAUSE")) { - tdt->state = STATE_PAUSE; - } else if (!g_ascii_strcasecmp(c, "RVOUS_PROPOSE")) { -#if 0 - char *user, *uuid, *cookie; - int seq; - char *rip, *pip, *vip, *trillian = NULL; - int port; - - user = strtok(NULL, ":"); - uuid = strtok(NULL, ":"); - cookie = strtok(NULL, ":"); - sscanf(strtok(NULL, ":"), "%d", &seq); - rip = strtok(NULL, ":"); - pip = strtok(NULL, ":"); - vip = strtok(NULL, ":"); - sscanf(strtok(NULL, ":"), "%d", &port); - - if (!strcmp(uuid, FILE_SEND_UID)) { - /* they want us to get a file */ - int unk[4], i; - char *messages[4], *tmp, *name; - int subtype, files, totalsize = 0; - struct ft_request *ft; - - for (i = 0; i < 4; i++) { - trillian = strtok(NULL, ":"); - sscanf(trillian, "%d", &unk[i]); - if (unk[i] == 10001) - break; - /* Trillian likes to send an empty token as a message, rather than - no message at all. */ - if (*(trillian + strlen(trillian) +1) != ':') - frombase64(strtok(NULL, ":"), &messages[i], NULL); - } - - frombase64(strtok(NULL, ":"), &tmp, NULL); - - subtype = tmp[1]; - files = tmp[3]; - - totalsize |= (tmp[4] << 24) & 0xff000000; - totalsize |= (tmp[5] << 16) & 0x00ff0000; - totalsize |= (tmp[6] << 8) & 0x0000ff00; - totalsize |= (tmp[7] << 0) & 0x000000ff; - - if (!totalsize) { - g_free(tmp); - for (i--; i >= 0; i--) - g_free(messages[i]); - return; - } - - name = tmp + 8; - - ft = g_new0(struct ft_request, 1); - ft->cookie = g_strdup(cookie); - ft->ip = g_strdup(pip); - ft->port = port; - if (i) - ft->message = g_strdup(messages[0]); - else - ft->message = NULL; - ft->filename = g_strdup(name); - ft->user = g_strdup(user); - ft->size = totalsize; - ft->files = files; - g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); - ft->gc = gc; - - g_free(tmp); - for (i--; i >= 0; i--) - g_free(messages[i]); - - purple_debug(PURPLE_DEBUG_MISC, "toc", - "English translation of RVOUS_PROPOSE: %s requests " - "Send File (i.e. send a file to you); %s:%d " - "(verified_ip:port), %d files at total size of " - "%d bytes.\n", user, vip, port, files, totalsize); - accept_file_dialog(ft); - } else if (!strcmp(uuid, FILE_GET_UID)) { - /* they want us to send a file */ - int unk[4], i; - char *messages[4], *tmp; - struct ft_request *ft; - - for (i = 0; i < 4; i++) { - sscanf(strtok(NULL, ":"), "%d", unk + i); - if (unk[i] == 10001) - break; - /* Trillian likes to send an empty token as a message, rather than - no message at all. */ - if (*(trillian + strlen(trillian) +1) != ':') - frombase64(strtok(NULL, ":"), &messages[i], NULL); - } - frombase64(strtok(NULL, ":"), &tmp, NULL); - - ft = g_new0(struct ft_request, 1); - ft->cookie = g_strdup(cookie); - ft->ip = g_strdup(pip); - ft->port = port; - if (i) - ft->message = g_strdup(messages[0]); - else - ft->message = NULL; - ft->user = g_strdup(user); - g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_GET_UID); - ft->gc = gc; - - g_free(tmp); - for (i--; i >= 0; i--) - g_free(messages[i]); - - accept_file_dialog(ft); - } else if (!strcmp(uuid, VOICE_UID)) { - /* oh goody. voice over ip. fun stuff. */ - } else if (!strcmp(uuid, B_ICON_UID)) { - 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); - - purple_debug(PURPLE_DEBUG_MISC, "toc", - "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 { - purple_debug(PURPLE_DEBUG_ERROR, "toc", - "Don't know what to do with RVOUS UUID %s\n", uuid); - /* do we have to do anything here? i think it just times out */ - } -#endif - } else { - purple_debug(PURPLE_DEBUG_ERROR, "toc", - "don't know what to do with %s\n", c); - } -} - -static int toc_send_im(PurpleConnection *gc, const char *name, const char *message, PurpleMessageFlags flags) -{ - char *buf1, *buf2; - -#if 1 - /* This is the old, non-i18n way */ - buf1 = escape_text(message); - if (strlen(buf1) + 52 > MSG_LEN) { - g_free(buf1); - return -E2BIG; - } - buf2 = g_strdup_printf("toc_send_im %s \"%s\"%s", purple_normalize(gc->account, name), buf1, - ((flags & PURPLE_MESSAGE_AUTO_RESP) ? " auto" : "")); - g_free(buf1); -#else - /* This doesn't work yet. See the comments below for details */ - buf1 = purple_strreplace(message, "\"", "\\\""); - - /* - * We still need to determine what encoding should be used and send the - * message in that encoding. This should be done the same as in - * oscar_encoding_check() in oscar.c. There is no encoding flag sent - * along with the message--the TOC to OSCAR proxy server must just - * use a lil' algorithm to determine what the actual encoding is. - * - * After that, you need to convert buf1 to that encoding, and keep track - * of the length of the resulting string. Then you need to make sure - * that length is passed to sflap_send(). - */ - - if (strlen(buf1) + 52 > MSG_LEN) { - g_free(buf1); - return -E2BIG; - } - - buf2 = g_strdup_printf("toc2_send_im_enc %s F U en \"%s\" %s", purple_normalize(gc->account, name), buf1, - ((flags & PURPLE_MESSAGE_AUTO_RESP) ? "auto" : "")); - g_free(buf1); -#endif - - sflap_send(gc, buf2, -1, TYPE_DATA); - g_free(buf2); - - return 1; -} - -static void toc_set_config(PurpleConnection *gc) -{ - char *buf = g_malloc(MSG_LEN), snd[BUF_LEN * 2]; - toc_build_config(gc->account, buf, MSG_LEN - strlen("toc_set_config \\{\\}"), FALSE); - g_snprintf(snd, MSG_LEN, "toc_set_config {%s}", buf); - sflap_send(gc, snd, -1, TYPE_DATA); - g_free(buf); -} - -static void toc_get_info(PurpleConnection *gc, const char *name) -{ - char buf[BUF_LEN * 2]; - g_snprintf(buf, MSG_LEN, "toc_get_info %s", purple_normalize(gc->account, name)); - sflap_send(gc, buf, -1, TYPE_DATA); -} - -/* Should be implemented as an Account Action? */ -static void toc_get_dir(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *buddy; - PurpleConnection *gc; - char buf[BUF_LEN * 2]; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - - g_snprintf(buf, MSG_LEN, "toc_get_dir %s", - purple_normalize(buddy->account, buddy->name)); - sflap_send(gc, buf, -1, TYPE_DATA); -} - -#if 0 -/* Should be implemented as an Account Action */ -static void toc_set_dir(PurpleConnection *g, const char *first, const char *middle, const char *last, - const char *maiden, const char *city, const char *state, const char *country, int web) -{ - char *buf3, buf2[BUF_LEN * 4], buf[BUF_LEN]; - g_snprintf(buf2, sizeof(buf2), "%s:%s:%s:%s:%s:%s:%s:%s", first, - middle, last, maiden, city, state, country, (web == 1) ? "Y" : ""); - buf3 = escape_text(buf2); - g_snprintf(buf, sizeof(buf), "toc_set_dir %s", buf3); - g_free(buf3); - sflap_send(g, buf, -1, TYPE_DATA); -} -#endif - -#if 0 -/* Should be implemented as an Account Action */ -static void toc_dir_search(PurpleConnection *g, const char *first, const char *middle, const char *last, - const char *maiden, const char *city, const char *state, const char *country, const char *email) -{ - char buf[BUF_LONG]; - g_snprintf(buf, sizeof(buf) / 2, "toc_dir_search %s:%s:%s:%s:%s:%s:%s:%s", first, middle, - last, maiden, city, state, country, email); - purple_debug(PURPLE_DEBUG_INFO, "toc", - "Searching for: %s,%s,%s,%s,%s,%s,%s\n", - first, middle, last, maiden, - city, state, country); - sflap_send(g, buf, -1, TYPE_DATA); -} -#endif - -static void toc_set_status(PurpleAccount *account, PurpleStatus *status) -{ -#if 0 /* do we care about TOC any more? */ - char buf[BUF_LEN * 2]; - if (gc->away) { - g_free(gc->away); - gc->away = NULL; - } - if (message) { - char *tmp; - gc->away = g_strdup(message); - tmp = escape_text(message); - g_snprintf(buf, MSG_LEN, "toc_set_away \"%s\"", tmp); - g_free(tmp); - } else - g_snprintf(buf, MSG_LEN, "toc_set_away \"\""); - sflap_send(g, buf, -1, TYPE_DATA); -#endif -} - -static void toc_set_info(PurpleConnection *g, const char *info) -{ - char buf[BUF_LEN * 2], *buf2; - buf2 = escape_text(info); - g_snprintf(buf, sizeof(buf), "toc_set_info \"%s\n\"", buf2); - g_free(buf2); - sflap_send(g, buf, -1, TYPE_DATA); -} - -static void toc_change_passwd(PurpleConnection *g, const char *orig, const char *new) -{ - char buf[BUF_LEN * 2]; - g_snprintf(buf, BUF_LONG, "toc_change_passwd %s %s", orig, new); - sflap_send(g, buf, -1, TYPE_DATA); -} - -static void -toc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) -{ - char buf[BUF_LEN * 2]; - g_snprintf(buf, sizeof(buf), "toc_add_buddy %s", purple_normalize(gc->account, buddy->name)); - sflap_send(gc, buf, -1, TYPE_DATA); - toc_set_config(gc); -} - -static void toc_add_buddies(PurpleConnection *gc, GList *buddies, GList *groups) -{ - char buf[BUF_LEN * 2]; - int n; - GList *cur; - - n = g_snprintf(buf, sizeof(buf), "toc_add_buddy"); - for (cur = buddies; cur != NULL; cur = cur->next) { - PurpleBuddy *buddy = cur->data; - - if (strlen(purple_normalize(gc->account, buddy->name)) + n + 32 > MSG_LEN) { - sflap_send(gc, buf, -1, TYPE_DATA); - n = g_snprintf(buf, sizeof(buf), "toc_add_buddy"); - } - n += g_snprintf(buf + n, sizeof(buf) - n, " %s", purple_normalize(gc->account, buddy->name)); - } - sflap_send(gc, buf, -1, TYPE_DATA); -} - -static void toc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) -{ - char buf[BUF_LEN * 2]; - g_snprintf(buf, sizeof(buf), "toc_remove_buddy %s", purple_normalize(gc->account, buddy->name)); - sflap_send(gc, buf, -1, TYPE_DATA); - toc_set_config(gc); -} - -static void toc_remove_buddies(PurpleConnection *gc, GList *buddies, GList *groups) -{ - char buf[BUF_LEN * 2]; - int n; - GList *cur; - - n = g_snprintf(buf, sizeof(buf), "toc_remove_buddy"); - for (cur = buddies; cur != NULL; cur = cur->next) { - PurpleBuddy *buddy = cur->data; - - if (strlen(purple_normalize(gc->account, buddy->name)) + n + 32 > MSG_LEN) { - sflap_send(gc, buf, -1, TYPE_DATA); - n = g_snprintf(buf, sizeof(buf), "toc_remove_buddy"); - } - n += g_snprintf(buf + n, sizeof(buf) - n, " %s", purple_normalize(gc->account, buddy->name)); - } - sflap_send(gc, buf, -1, TYPE_DATA); - toc_set_config(gc); -} - -static void toc_set_idle(PurpleConnection *g, int time) -{ - char buf[BUF_LEN * 2]; - g_snprintf(buf, sizeof(buf), "toc_set_idle %d", time); - sflap_send(g, buf, -1, TYPE_DATA); -} - -static void toc_warn(PurpleConnection *g, const char *name, int anon) -{ - char send[BUF_LEN * 2]; - g_snprintf(send, 255, "toc_evil %s %s", name, ((anon) ? "anon" : "norm")); - sflap_send(g, send, -1, TYPE_DATA); -} - -static GList *toc_chat_info(PurpleConnection *gc) -{ - GList *m = NULL; - struct proto_chat_entry *pce; - - pce = g_new0(struct proto_chat_entry, 1); - pce->label = _("_Group:"); - pce->identifier = "room"; - m = g_list_append(m, pce); - - pce = g_new0(struct proto_chat_entry, 1); - pce->label = _("_Exchange:"); - pce->identifier = "exchange"; - pce->is_int = TRUE; - pce->min = 4; - pce->max = 20; - m = g_list_append(m, pce); - - return m; -} - -GHashTable *toc_chat_info_defaults(PurpleConnection *gc, const char *chat_name) -{ - GHashTable *defaults; - - defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); - - if (chat_name != NULL) - g_hash_table_insert(defaults, "room", g_strdup(chat_name)); - - return defaults; -} - -static void toc_join_chat(PurpleConnection *g, GHashTable *data) -{ - char buf[BUF_LONG]; - char *name, *exchange; - char *id; - - name = g_hash_table_lookup(data, "room"); - exchange = g_hash_table_lookup(data, "exchange"); - id = g_hash_table_lookup(data, "id"); - - if (id) { - g_snprintf(buf, 255, "toc_chat_accept %d", atoi(id)); - } else { - g_snprintf(buf, sizeof(buf) / 2, "toc_chat_join %d \"%s\"", atoi(exchange), name); - } - - sflap_send(g, buf, -1, TYPE_DATA); -} - -static void toc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name) -{ - char buf[BUF_LONG]; - g_snprintf(buf, sizeof(buf) / 2, "toc_chat_invite %d \"%s\" %s", id, - message ? message : "", purple_normalize(gc->account, name)); - sflap_send(gc, buf, -1, TYPE_DATA); -} - -static void toc_chat_leave(PurpleConnection *g, int id) -{ - GSList *bcs = g->buddy_chats; - PurpleConversation *b = NULL; - char buf[BUF_LEN * 2]; - - while (bcs) { - b = (PurpleConversation *)bcs->data; - if (id == purple_conv_chat_get_id(PURPLE_CONV_CHAT(b))) - break; - b = NULL; - bcs = bcs->next; - } - - if (!b) - return; /* can this happen? */ - - if (purple_conversation_get_account(b) == NULL) { - /* TOC already kicked us out of this room */ - serv_got_chat_left(g, id); - } - else { - g_snprintf(buf, 255, "toc_chat_leave %d", id); - sflap_send(g, buf, -1, TYPE_DATA); - } -} - -static void toc_chat_whisper(PurpleConnection *gc, int id, const char *who, const char *message) -{ - char *buf1, *buf2; - buf1 = escape_text(message); - buf2 = g_strdup_printf("toc_chat_whisper %d %s \"%s\"", id, purple_normalize(gc->account, who), buf1); - g_free(buf1); - sflap_send(gc, buf2, -1, TYPE_DATA); - g_free(buf2); -} - -static int toc_chat_send(PurpleConnection *g, int id, const char *message, PurpleMessageFlags flags) -{ - char *buf1, *buf2; - buf1 = escape_text(message); - if (strlen(buf1) > 2000) { - g_free(buf1); - return -E2BIG; - } - buf2 = g_strdup_printf("toc_chat_send %d \"%s\"", id, buf1); - g_free(buf1); - sflap_send(g, buf2, -1, TYPE_DATA); - g_free(buf2); - return 0; -} - -static void toc_keepalive(PurpleConnection *gc) -{ - sflap_send(gc, "", 0, TYPE_KEEPALIVE); -} - -static const char * -toc_normalize(const PurpleAccount *account, const char *str) -{ - static char buf[BUF_LEN]; - char *tmp1, *tmp2; - int i, j; - - g_return_val_if_fail(str != NULL, NULL); - - strncpy(buf, str, BUF_LEN); - for (i=0, j=0; buf[j]; i++, j++) - { - while (buf[j] == ' ') - j++; - buf[i] = buf[j]; - } - buf[i] = '\0'; - - tmp1 = g_utf8_strdown(buf, -1); - tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_DEFAULT); - g_snprintf(buf, sizeof(buf), "%s", tmp2); - g_free(tmp2); - g_free(tmp1); - - return buf; -} - -static const char *toc_list_icon(PurpleAccount *a, PurpleBuddy *b) -{ - if (!b || (b && b->name && b->name[0] == '+')) { - if (a != NULL && isdigit(*purple_account_get_username(a))) - return "icq"; - else - return "aim"; - } - - if (b && b->name && isdigit(b->name[0])) - return "icq"; - return "aim"; -} - -static const char* toc_list_emblem(PurpleBuddy *b) -{ - if (b->uc & UC_AOL) - return "aol"; - if (b->uc & UC_ADMIN) - return "admin"; - if (b->uc & UC_WIRELESS) - return "mobile"; - return NULL -} - -static GList *toc_blist_node_menu(PurpleBlistNode *node) -{ - GList *m = NULL; - PurpleMenuAction *act; - - if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { - act = purple_menu_action_new(_("Get Dir Info"), - toc_get_dir, NULL, NULL); - m = g_list_append(m, act); - } - - return m; -} - -static void toc_add_permit(PurpleConnection *gc, const char *who) -{ - char buf2[BUF_LEN * 2]; - if (gc->account->perm_deny != 3) - return; - g_snprintf(buf2, sizeof(buf2), "toc_add_permit %s", purple_normalize(gc->account, who)); - sflap_send(gc, buf2, -1, TYPE_DATA); - toc_set_config(gc); -} - -static void toc_add_deny(PurpleConnection *gc, const char *who) -{ - char buf2[BUF_LEN * 2]; - if (gc->account->perm_deny != 4) - return; - g_snprintf(buf2, sizeof(buf2), "toc_add_deny %s", purple_normalize(gc->account, who)); - sflap_send(gc, buf2, -1, TYPE_DATA); - toc_set_config(gc); -} - -static void toc_set_permit_deny(PurpleConnection *gc) -{ - char buf2[BUF_LEN * 2]; - GSList *list; - int at; - - switch (gc->account->perm_deny) { - case 1: - /* permit all, deny none. to get here reliably we need to have been in permit - * mode, and send an empty toc_add_deny message, which will switch us to deny none */ - g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); - sflap_send(gc, buf2, -1, TYPE_DATA); - g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); - sflap_send(gc, buf2, -1, TYPE_DATA); - break; - case 2: - /* deny all, permit none. to get here reliably we need to have been in deny - * mode, and send an empty toc_add_permit message, which will switch us to permit none */ - g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); - sflap_send(gc, buf2, -1, TYPE_DATA); - g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); - sflap_send(gc, buf2, -1, TYPE_DATA); - break; - case 3: - /* permit some. we want to switch to deny mode first, then send the toc_add_permit - * message, which will clear and set our permit list. toc sucks. */ - g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); - sflap_send(gc, buf2, -1, TYPE_DATA); - - at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); - list = gc->account->permit; - while (list) { - at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", purple_normalize(gc->account, list->data)); - if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ - sflap_send(gc, buf2, -1, TYPE_DATA); - at = g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); - } - list = list->next; - } - sflap_send(gc, buf2, -1, TYPE_DATA); - break; - case 4: - /* deny some. we want to switch to permit mode first, then send the toc_add_deny - * message, which will clear and set our deny list. toc sucks. */ - g_snprintf(buf2, sizeof(buf2), "toc_add_permit "); - sflap_send(gc, buf2, -1, TYPE_DATA); - - at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); - list = gc->account->deny; - while (list) { - at += g_snprintf(buf2 + at, sizeof(buf2) - at, "%s ", purple_normalize(gc->account, list->data)); - if (at > MSG_LEN + 32) { /* from out my ass comes greatness */ - sflap_send(gc, buf2, -1, TYPE_DATA); - at = g_snprintf(buf2, sizeof(buf2), "toc_add_deny "); - } - list = list->next; - } - sflap_send(gc, buf2, -1, TYPE_DATA); - break; - default: - break; - } - toc_set_config(gc); -} - -static void toc_rem_permit(PurpleConnection *gc, const char *who) -{ - if (gc->account->perm_deny != 3) - return; - toc_set_permit_deny(gc); -} - -static void toc_rem_deny(PurpleConnection *gc, const char *who) -{ - if (gc->account->perm_deny != 4) - return; - toc_set_permit_deny(gc); -} - -static GList *toc_away_states(PurpleAccount *account) -{ -#if 0 /* do we care about TOC any more? */ - return g_list_append(NULL, PURPLE_AWAY_CUSTOM); -#else - return NULL; -#endif -} - -static void -show_set_info(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - purple_account_request_change_user_info(purple_connection_get_account(gc)); -} - -static void -change_pass(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - purple_account_request_change_password(purple_connection_get_account(gc)); -} - -static GList *toc_actions(PurplePlugin *plugin, gpointer context) -{ - GList *m = NULL; - PurplePluginAction *act; - - act = purple_plugin_action_new(_("Set User Info"), - show_set_info); - m = g_list_append(m, act); - -#if 0 - act = purple_plugin_action_new(_("Set Dir Info"), - show_set_dir); - m = g_list_append(m, act); -#endif - - act = purple_plugin_action_new(_("Change Password"), - change_pass); - m = g_list_append(m, act); - - return m; -} - -#if 0 -/********* - * RVOUS ACTIONS - ********/ - -struct file_header { - char magic[4]; /* 0 */ - short hdrlen; /* 4 */ - short hdrtype; /* 6 */ - char bcookie[8]; /* 8 */ - short encrypt; /* 16 */ - short compress; /* 18 */ - short totfiles; /* 20 */ - short filesleft; /* 22 */ - short totparts; /* 24 */ - short partsleft; /* 26 */ - long totsize; /* 28 */ - long size; /* 32 */ - long modtime; /* 36 */ - long checksum; /* 40 */ - long rfrcsum; /* 44 */ - long rfsize; /* 48 */ - long cretime; /* 52 */ - long rfcsum; /* 56 */ - long nrecvd; /* 60 */ - long recvcsum; /* 64 */ - char idstring[32]; /* 68 */ - char flags; /* 100 */ - char lnameoffset; /* 101 */ - char lsizeoffset; /* 102 */ - char dummy[69]; /* 103 */ - char macfileinfo[16]; /* 172 */ - short nencode; /* 188 */ - short nlanguage; /* 190 */ - char name[64]; /* 192 */ - /* 256 */ -}; - -struct file_transfer { - struct file_header hdr; - - PurpleConnection *gc; - - char *user; - char *cookie; - char *ip; - int port; - long size; - struct stat st; - - GtkWidget *window; - int files; - char *filename; - FILE *file; - int recvsize; - - gint inpa; -}; - -static void debug_header(struct file_transfer *ft) { - struct file_header *f = (struct file_header *)ft; - purple_debug(PURPLE_DEBUG_MISC, "toc", "FT HEADER:\n" - "\t%s %d 0x%04x\n" - "\t%s %d %d\n" - "\t%d %d %d %d %d %d\n" - "\t%d %d %d %d %d %d %d %d\n" - "\t%s\n" - "\t0x%02x, 0x%02x, 0x%02x\n" - "\t%s %s\n" - "\t%d %d\n" - "\t%s\n", - f->magic, ntohs(f->hdrlen), f->hdrtype, - f->bcookie, ntohs(f->encrypt), ntohs(f->compress), - ntohs(f->totfiles), ntohs(f->filesleft), ntohs(f->totparts), - ntohs(f->partsleft), ntohl(f->totsize), ntohl(f->size), - ntohl(f->modtime), ntohl(f->checksum), ntohl(f->rfrcsum), ntohl(f->rfsize), - ntohl(f->cretime), ntohl(f->rfcsum), ntohl(f->nrecvd), - ntohl(f->recvcsum), - f->idstring, - f->flags, f->lnameoffset, f->lsizeoffset, - f->dummy, f->macfileinfo, - ntohs(f->nencode), ntohs(f->nlanguage), - f->name); -} - -static void toc_send_file_callback(gpointer data, gint source, PurpleInputCondition cond) -{ - char buf[BUF_LONG]; - int rt, i; - - struct file_transfer *ft = data; - - if (ft->hdr.hdrtype != 0x202) { - char *buf; - frombase64(ft->cookie, &buf, NULL); - - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - - ft->hdr.hdrtype = 0x202; - memcpy(ft->hdr.bcookie, buf, 8); - g_free(buf); - ft->hdr.encrypt = 0; ft->hdr.compress = 0; - debug_header(ft); - write(source, ft, 256); - - if (ft->files == 1) { - ft->file = g_fopen(ft->filename, "w"); - if (!ft->file) { - buf = g_strdup_printf(_("Could not open %s for writing!"), ft->filename); - purple_notify_error(ft->gc, NULL, buf, g_strerror(errno)); - g_free(buf); - purple_input_remove(ft->inpa); - close(source); - g_free(ft->filename); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - g_free(ft); - } - } else { - buf = g_strdup_printf("%s/%s", ft->filename, ft->hdr.name); - ft->file = g_fopen(buf, "w"); - g_free(buf); - if (!ft->file) { - buf = g_strdup_printf("Could not open %s/%s for writing!", ft->filename, - ft->hdr.name); - purple_notify_error(ft->gc, NULL, buf, g_strerror(errno)); - g_free(buf); - purple_input_remove(ft->inpa); - close(source); - g_free(ft->filename); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - g_free(ft); - } - } - - return; - } - - rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); - if (rt < 0) { - purple_notify_error(ft->gc, NULL, - _("File transfer failed; other side probably " - "canceled."), NULL); - purple_input_remove(ft->inpa); - close(source); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - if (ft->file) - fclose(ft->file); - g_free(ft); - return; - } - ft->recvsize += rt; - for (i = 0; i < rt; i++) - fprintf(ft->file, "%c", buf[i]); - - if (ft->recvsize == ntohl(ft->hdr.size)) { - ft->hdr.hdrtype = htons(0x0204); - ft->hdr.filesleft = htons(ntohs(ft->hdr.filesleft) - 1); - ft->hdr.partsleft = htons(ntohs(ft->hdr.partsleft) - 1); - ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ - ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); - ft->hdr.flags = 0; - write(source, ft, 256); - debug_header(ft); - ft->recvsize = 0; - fclose(ft->file); - if (ft->hdr.filesleft == 0) { - purple_input_remove(ft->inpa); - close(source); - g_free(ft->filename); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - g_free(ft); - } - } -} - -static void toc_send_file_connect(gpointer data, gint src, PurpleInputCondition cond) -{ - struct file_transfer *ft = data; - - if (src == -1) { - purple_notify_error(ft->gc, NULL, - _("Could not connect for transfer."), NULL); - g_free(ft->filename); - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - return; - } - - ft->inpa = purple_input_add(src, PURPLE_INPUT_READ, toc_send_file_callback, ft); -} - -static void toc_send_file(gpointer a, struct file_transfer *old_ft) -{ - struct file_transfer *ft; - const char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); - PurpleAccount *account; - char buf[BUF_LEN * 2]; - - if (purple_gtk_check_if_dir(dirname, GTK_FILE_SELECTION(old_ft->window))) - return; - ft = g_new0(struct file_transfer, 1); - if (old_ft->files == 1) - ft->filename = g_strdup(dirname); - else - ft->filename = g_path_get_dirname(dirname); - ft->cookie = g_strdup(old_ft->cookie); - ft->user = g_strdup(old_ft->user); - ft->ip = g_strdup(old_ft->ip); - ft->files = old_ft->files; - ft->port = old_ft->port; - ft->gc = old_ft->gc; - account = ft->gc->account; - gtk_widget_destroy(old_ft->window); - - g_snprintf(buf, sizeof(buf), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID); - sflap_send(ft->gc, buf, -1, TYPE_DATA); - - if (purple_proxy_connect(ft->gc, account, ft->ip, ft->port, toc_send_file_connect, ft) != 0) { - purple_notify_error(ft->gc, NULL, - _("Could not connect for transfer."), NULL); - g_free(ft->filename); - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - return; - } -} - -static void toc_get_file_callback(gpointer data, gint source, PurpleInputCondition cond) -{ - char buf[BUF_LONG]; - - struct file_transfer *ft = data; - - if (cond & PURPLE_INPUT_WRITE) { - int remain = MIN(ntohl(ft->hdr.totsize) - ft->recvsize, 1024); - int i; - for (i = 0; i < remain; i++) - fscanf(ft->file, "%c", &buf[i]); - write(source, buf, remain); - ft->recvsize += remain; - if (ft->recvsize == ntohl(ft->hdr.totsize)) { - purple_input_remove(ft->inpa); - ft->inpa = purple_input_add(source, PURPLE_INPUT_READ, - toc_get_file_callback, ft); - } - return; - } - - if (ft->hdr.hdrtype == htons(0x1108)) { - struct tm *fortime; - struct stat st; - char *basename; - - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - - g_stat(ft->filename, &st); - fortime = localtime(&st.st_mtime); - basename = g_path_get_basename(ft->filename); - g_snprintf(buf, sizeof(buf), "%2d/%2d/%4d %2d:%2d %8ld %s\r\n", - fortime->tm_mon + 1, fortime->tm_mday, fortime->tm_year + 1900, - fortime->tm_hour + 1, fortime->tm_min + 1, (long)st.st_size, - basename); - write(source, buf, ntohl(ft->hdr.size)); - g_free(basename); - return; - } - - if (ft->hdr.hdrtype == htons(0x1209)) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - return; - } - - if (ft->hdr.hdrtype == htons(0x120b)) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - - if (ft->hdr.hdrtype != htons(0x120c)) { - g_snprintf(buf, sizeof(buf), "%s decided to cancel the transfer", ft->user); - purple_notify_error(ft->gc, NULL, buf, NULL); - purple_input_remove(ft->inpa); - close(source); - g_free(ft->filename); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - if (ft->file) - fclose(ft->file); - g_free(ft); - return; - } - - ft->hdr.hdrtype = 0x0101; - ft->hdr.totfiles = htons(1); ft->hdr.filesleft = htons(1); - ft->hdr.flags = 0x20; - write(source, ft, 256); - return; - } - - if (ft->hdr.hdrtype == 0x0101) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - - purple_input_remove(ft->inpa); - ft->inpa = purple_input_add(source, PURPLE_INPUT_WRITE, - toc_get_file_callback, ft); - return; - } - - if (ft->hdr.hdrtype == 0x0202) { - read(source, ft, 8); - read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); - debug_header(ft); - - purple_input_remove(ft->inpa); - close(source); - g_free(ft->filename); - g_free(ft->user); - g_free(ft->ip); - g_free(ft->cookie); - if (ft->file) - fclose(ft->file); - g_free(ft); - return; - } -} - -static void toc_get_file_connect(gpointer data, gint src, PurpleInputCondition cond) -{ - struct file_transfer *ft = data; - struct file_header *hdr; - char *buf; - char *basename; - - if (src == -1) { - purple_notify_error(ft->gc, NULL, - _("Could not connect for transfer."), NULL); - fclose(ft->file); - g_free(ft->filename); - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - return; - } - - hdr = (struct file_header *)ft; - hdr->magic[0] = 'O'; hdr->magic[1] = 'F'; hdr->magic[2] = 'T'; hdr->magic[3] = '2'; - hdr->hdrlen = htons(256); - hdr->hdrtype = htons(0x1108); - rombase64(ft->cookie, &buf, NULL); - g_snprintf(hdr->bcookie, 8, "%s", buf); - g_free(buf); - hdr->totfiles = htons(1); hdr->filesleft = htons(1); - hdr->totparts = htons(1); hdr->partsleft = htons(1); - hdr->totsize = htonl((long)ft->st.st_size); /* combined size of all files */ - /* size = strlen("mm/dd/yyyy hh:mm sizesize 'name'\r\n") */ - basename = g_path_get_basename(ft->filename); - hdr->size = htonl(28 + strlen(basename)); /* size of listing.txt */ - g_free(basename); - hdr->modtime = htonl(ft->st.st_mtime); - hdr->checksum = htonl(0x89f70000); /* uh... */ - g_snprintf(hdr->idstring, 32, "OFT_Windows ICBMFT V1.1 32"); - hdr->flags = 0x02; - hdr->lnameoffset = 0x1A; - hdr->lsizeoffset = 0x10; - g_snprintf(hdr->name, 64, "listing.txt"); - if (write(src, hdr, 256) < 0) { - purple_notify_error(ft->gc, NULL, - _("Could not write file header. The file will " - "not be transferred."), NULL); - fclose(ft->file); - g_free(ft->filename); - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - return; - } - - ft->inpa = purple_input_add(src, PURPLE_INPUT_READ, toc_get_file_callback, ft); -} - -static void toc_get_file(gpointer a, struct file_transfer *old_ft) -{ - struct file_transfer *ft; - const char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); - PurpleAccount *account; - char *buf, buf2[BUF_LEN * 2]; - - if (purple_gtk_check_if_dir(dirname, GTK_FILE_SELECTION(old_ft->window))) - return; - ft = g_new0(struct file_transfer, 1); - ft->filename = g_strdup(dirname); - ft->file = g_fopen(ft->filename, "r"); - if (!ft->file) { - buf = g_strdup_printf("Unable to open %s for transfer.", ft->filename); - purple_notify_error(ft->gc, NULL, buf, NULL); - g_free(buf); - g_free(ft->filename); - g_free(ft); - return; - } - if (g_stat(dirname, &ft->st)) { - buf = g_strdup_printf("Unable to examine %s.", dirname); - purple_notify_error(ft->gc, NULL, buf, NULL); - g_free(buf); - g_free(ft->filename); - g_free(ft); - return; - } - ft->cookie = g_strdup(old_ft->cookie); - ft->user = g_strdup(old_ft->user); - ft->ip = g_strdup(old_ft->ip); - ft->port = old_ft->port; - ft->gc = old_ft->gc; - account = ft->gc->account; - gtk_widget_destroy(old_ft->window); - - g_snprintf(buf2, sizeof(buf2), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_GET_UID); - sflap_send(ft->gc, buf2, -1, TYPE_DATA); - - if (purple_proxy_connect(ft->gc, account, ft->ip, ft->port, toc_get_file_connect, ft) < 0) { - purple_notify_error(ft->gc, NULL, - _("Could not connect for transfer."), NULL); - fclose(ft->file); - g_free(ft->filename); - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - return; - } -} - -static void cancel_callback(gpointer a, struct file_transfer *ft) { - gtk_widget_destroy(ft->window); - if (a == ft->window) { - g_free(ft->cookie); - g_free(ft->user); - g_free(ft->ip); - g_free(ft); - } -} - -static void toc_reject_ft(struct ft_request *ft) { - g_free(ft->user); - g_free(ft->filename); - g_free(ft->ip); - g_free(ft->cookie); - if (ft->message) - g_free(ft->message); - g_free(ft); -} - - -static void toc_accept_ft(struct ft_request *fr) { - if(g_list_find(purple_connections_get_all(), fr->gc)) { - GtkWidget *window; - char buf[BUF_LEN]; - - struct file_transfer *ft = g_new0(struct file_transfer, 1); - ft->gc = fr->gc; - ft->user = g_strdup(fr->user); - ft->cookie = g_strdup(fr->cookie); - ft->ip = g_strdup(fr->ip); - ft->port = fr->port; - ft->files = fr->files; - - ft->window = window = gtk_file_selection_new(_("Save As...")); - g_snprintf(buf, sizeof(buf), "%s/%s", purple_home_dir(), fr->filename ? fr->filename : ""); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); - g_signal_connect(G_OBJECT(window), "destroy", - G_CALLBACK(cancel_callback), ft); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), - "clicked", G_CALLBACK(cancel_callback), ft); - - if (!strcmp(fr->UID, FILE_SEND_UID)) - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), - "clicked", G_CALLBACK(toc_send_file), ft); - else - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), - "clicked", G_CALLBACK(toc_get_file), ft); - - gtk_widget_show(window); - } - - toc_reject_ft(fr); -} - -static void accept_file_dialog(struct ft_request *ft) { - char buf[BUF_LONG]; - if (!strcmp(ft->UID, FILE_SEND_UID)) { - /* holy crap. who the fuck would transfer gigabytes through AIM?! */ - static char *sizes[4] = { "bytes", "KB", "MB", "GB" }; - float size = ft->size; - int index = 0; - while ((index < 4) && (size > 1024)) { - size /= 1024; - index++; - } - g_snprintf(buf, sizeof(buf), - dngettext(PACKAGE, - "%s requests %s to accept %d file: %s (%.2f %s)%s%s", - "%s requests %s to accept %d files: %s (%.2f %s)%s%s", - ft->files), - ft->user, purple_account_get_username(ft->gc->account), ft->files, - ft->filename, size, sizes[index], (ft->message) ? "\n" : "", - (ft->message) ? ft->message : ""); - } else { - g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user); - } - - purple_request_accept_cancel(ft->gc, NULL, buf, NULL, - PURPLE_DEFAULT_ACTION_NONE, ft, - G_CALLBACK(toc_accept_ft), - G_CALLBACK(toc_reject_ft)); -} -#endif - -static PurplePluginProtocolInfo prpl_info = -{ - 0, - NULL, /* user_splits */ - NULL, /* protocol_options */ - NO_BUDDY_ICONS, /* icon_spec */ - toc_list_icon, /* list_icon */ - toc_list_emblem, /* list_emblems */ - NULL, /* status_text */ - NULL, /* tooltip_text */ - toc_away_states, /* away_states */ - toc_blist_node_menu, /* blist_node_menu */ - toc_chat_info, /* chat_info */ - toc_chat_info_defaults, /* chat_info_defaults */ - toc_login, /* login */ - toc_close, /* close */ - toc_send_im, /* send_im */ - toc_set_info, /* set_info */ - NULL, /* send_typing */ - toc_get_info, /* get_info */ - toc_set_status, /* set_away */ - toc_set_idle, /* set_idle */ - toc_change_passwd, /* change_passwd */ - toc_add_buddy, /* add_buddy */ - toc_add_buddies, /* add_buddies */ - toc_remove_buddy, /* remove_buddy */ - toc_remove_buddies, /* remove_buddies */ - toc_add_permit, /* add_permit */ - toc_add_deny, /* add_deny */ - toc_rem_permit, /* rem_permit */ - toc_rem_deny, /* rem_deny */ - toc_set_permit_deny, /* set_permit_deny */ - toc_join_chat, /* join_chat */ - NULL, /* reject_chat */ - NULL, /* get_chat_name */ - toc_chat_invite, /* chat_invite */ - toc_chat_leave, /* chat_leave */ - toc_chat_whisper, /* chat_whisper */ - toc_chat_send, /* chat_send */ - toc_keepalive, /* keepalive */ - NULL, /* register_user */ - NULL, /* get_cb_info */ - NULL, /* get_cb_away */ - NULL, /* alias_buddy */ - NULL, /* group_buddy */ - NULL, /* rename_group */ - NULL, /* buddy_free */ - NULL, /* convo_closed */ - toc_normalize, /* normalize */ - NULL, /* set_buddy_icon */ - NULL, /* remove_group */ - NULL, /* get_cb_real_name */ - NULL, /* set_chat_topic */ - NULL, /* find_blist_chat */ - NULL, /* roomlist_get_list */ - NULL, /* roomlist_cancel */ - NULL, /* roomlist_expand_category */ - NULL, /* can_receive_file */ - NULL, /* send_file */ - NULL, /* new_xfer */ - NULL, /* offline_message */ - NULL, /* whiteboard_prpl_ops */ - toc_send_raw, /* send_raw */ -}; - -static PurplePluginInfo info = -{ - PURPLE_PLUGIN_MAGIC, - PURPLE_MAJOR_VERSION, - PURPLE_MINOR_VERSION, - PURPLE_PLUGIN_PROTOCOL, /**< type */ - NULL, /**< ui_requirement */ - 0, /**< flags */ - NULL, /**< dependencies */ - PURPLE_PRIORITY_DEFAULT, /**< priority */ - - "prpl-toc", /**< id */ - "TOC", /**< name */ - DISPLAY_VERSION, /**< version */ - /** summary */ - N_("TOC Protocol Plugin"), - /** description */ - N_("TOC Protocol Plugin"), - NULL, /**< author */ - PURPLE_WEBSITE, /**< homepage */ - - NULL, /**< load */ - NULL, /**< unload */ - NULL, /**< destroy */ - - NULL, /**< ui_info */ - &prpl_info, /**< extra_info */ - NULL, - toc_actions -}; - -static void -init_plugin(PurplePlugin *plugin) -{ - PurpleAccountOption *option; - - option = purple_account_option_string_new(_("Server"), "server", TOC_HOST); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, - option); - - option = purple_account_option_int_new(_("Port"), "port", TOC_PORT); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, - option); - - my_protocol = plugin; -} - -PURPLE_INIT_PLUGIN(toc, init_plugin, info); -- cgit v1.2.1 From dca1f028089220c5779d5143275e7b1645ac1692 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 10:15:38 +0000 Subject: These code can't get executed, because we just created a new dialog --- pidgin/gtkutils.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c index 77ff10fa18..3a0b900a21 100644 --- a/pidgin/gtkutils.c +++ b/pidgin/gtkutils.c @@ -2451,11 +2451,6 @@ GtkWidget *pidgin_buddy_icon_chooser_new(GtkWindow *parent, void(*callback)(cons dialog->callback = callback; dialog->data = data; - if (dialog->icon_filesel != NULL) { - gtk_window_present(GTK_WINDOW(dialog->icon_filesel)); - return NULL; - } - current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder"); #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ -- cgit v1.2.1 From 8b50dd7cde935821a449005dceccd752a660dec9 Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 10:16:46 +0000 Subject: Don't leak an fd if we can't open the destination file when untarring --- pidgin/win32/untar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pidgin/win32/untar.c b/pidgin/win32/untar.c index 0ec2e09ccc..7121513485 100644 --- a/pidgin/win32/untar.c +++ b/pidgin/win32/untar.c @@ -212,9 +212,11 @@ static void linkorcopy(src, dst, sym) * make sure the directory path exists. */ fpdst = createpath(dst); - if (!fpdst) + if (!fpdst) { /* error message already given */ + fclose(fpsrc); return; + } #ifdef _POSIX_SOURCE # ifndef _WEAK_POSIX -- cgit v1.2.1 From f6626b504e52bdf5bff2fa0198e360429dda83df Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 10:17:07 +0000 Subject: Remove an unused field --- pidgin/gtkroomlist.c | 1 - 1 file changed, 1 deletion(-) diff --git a/pidgin/gtkroomlist.c b/pidgin/gtkroomlist.c index 5302481e87..82bac84809 100644 --- a/pidgin/gtkroomlist.c +++ b/pidgin/gtkroomlist.c @@ -64,7 +64,6 @@ typedef struct _PidginRoomlist { gint num_rooms, total_rooms; GtkWidget *tipwindow; GdkRectangle tip_rect; - guint timeout; PangoLayout *tip_layout; PangoLayout *tip_name_layout; int tip_height; -- cgit v1.2.1 From 8b1f0282a891592f499cb6786a9d141123093efe Mon Sep 17 00:00:00 2001 From: Mark Doliner Date: Fri, 27 Mar 2009 17:14:12 +0000 Subject: Need to remove toc from POTFILES.in --- po/POTFILES.in | 1 - 1 file changed, 1 deletion(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index e406846e3b..0457332517 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -166,7 +166,6 @@ libpurple/protocols/silc10/silc.c libpurple/protocols/silc10/util.c libpurple/protocols/silc10/wb.c libpurple/protocols/simple/simple.c -libpurple/protocols/toc/toc.c libpurple/protocols/yahoo/yahoo.c libpurple/protocols/yahoo/yahoo_doodle.c libpurple/protocols/yahoo/yahoo_filexfer.c -- cgit v1.2.1 From 553a1703df39213c351d008f106982a8f2711ee3 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 28 Mar 2009 04:30:40 +0000 Subject: disapproval of revision 'd8cf7a583b30714030386f9f3897142b1b2ddcd2' You can't go randomly changing the size of network structures. --- libpurple/nat-pmp.c | 2 ++ libpurple/ntlm.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/libpurple/nat-pmp.c b/libpurple/nat-pmp.c index 36e706c2f9..be5bc66222 100644 --- a/libpurple/nat-pmp.c +++ b/libpurple/nat-pmp.c @@ -81,6 +81,8 @@ typedef struct { struct _PurplePmpMapResponse { guint8 version; guint8 opcode; + guint16 resultcode; + guint32 epoch; guint16 privateport; guint16 publicport; guint32 lifetime; diff --git a/libpurple/ntlm.c b/libpurple/ntlm.c index ebcb0ea827..b7d3757e44 100644 --- a/libpurple/ntlm.c +++ b/libpurple/ntlm.c @@ -59,9 +59,14 @@ struct type2_message { guint8 protocol[8]; /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/ guint32 type; /* 0x00000002 */ + short msg_len1; /* target name length */ + short msg_len2; /* target name length */ + guint32 msg_off; /* target name offset (always 0x00000048) */ + guint32 flags; /* 0x00008201 */ guint8 nonce[8]; /* nonce */ + guint8 context[8]; }; struct type3_message { -- cgit v1.2.1 From c7df61a3f4a481d73775e722042afe5e24810b13 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 28 Mar 2009 05:12:24 +0000 Subject: Make these type-sizes more explicit. Also, the field names for the type2 message were incorrect. Fortunately, we don't use those fields and they ended up the right size anyway. --- libpurple/ntlm.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libpurple/ntlm.c b/libpurple/ntlm.c index b7d3757e44..956cc5bf7b 100644 --- a/libpurple/ntlm.c +++ b/libpurple/ntlm.c @@ -41,12 +41,12 @@ struct type1_message { guint32 type; /* 0x00000001 */ guint32 flags; /* 0x0000b203 */ - short dom_len1; /* domain string length */ - short dom_len2; /* domain string length */ + guint16 dom_len1; /* domain string length */ + guint16 dom_len2; /* domain string length */ guint32 dom_off; /* domain string offset */ - short host_len1; /* host string length */ - short host_len2; /* host string length */ + guint16 host_len1; /* host string length */ + guint16 host_len2; /* host string length */ guint32 host_off; /* host string offset (always 0x00000020) */ #if 0 @@ -59,47 +59,47 @@ struct type2_message { guint8 protocol[8]; /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/ guint32 type; /* 0x00000002 */ - short msg_len1; /* target name length */ - short msg_len2; /* target name length */ - guint32 msg_off; /* target name offset (always 0x00000048) */ + guint32 zero; + guint16 msg_len1; /* target name length */ + guint16 msg_len2; /* target name length */ guint32 flags; /* 0x00008201 */ guint8 nonce[8]; /* nonce */ - guint8 context[8]; + guint8 context[8]; }; struct type3_message { guint8 protocol[8]; /* 'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0'*/ guint32 type; /* 0x00000003 */ - short lm_resp_len1; /* LanManager response length (always 0x18)*/ - short lm_resp_len2; /* LanManager response length (always 0x18)*/ + guint16 lm_resp_len1; /* LanManager response length (always 0x18)*/ + guint16 lm_resp_len2; /* LanManager response length (always 0x18)*/ guint32 lm_resp_off; /* LanManager response offset */ - short nt_resp_len1; /* NT response length (always 0x18) */ - short nt_resp_len2; /* NT response length (always 0x18) */ + guint16 nt_resp_len1; /* NT response length (always 0x18) */ + guint16 nt_resp_len2; /* NT response length (always 0x18) */ guint32 nt_resp_off; /* NT response offset */ - short dom_len1; /* domain string length */ - short dom_len2; /* domain string length */ + guint16 dom_len1; /* domain string length */ + guint16 dom_len2; /* domain string length */ guint32 dom_off; /* domain string offset (always 0x00000040) */ - short user_len1; /* username string length */ - short user_len2; /* username string length */ + guint16 user_len1; /* username string length */ + guint16 user_len2; /* username string length */ guint32 user_off; /* username string offset */ - short host_len1; /* host string length */ - short host_len2; /* host string length */ + guint16 host_len1; /* host string length */ + guint16 host_len2; /* host string length */ guint32 host_off; /* host string offset */ - short sess_len1; - short sess_len2; + guint16 sess_len1; + guint16 sess_len2; guint32 sess_off; /* message length */ guint32 flags; /* 0x00008201 */ /* guint32 flags2; */ /* unknown, used in windows messenger */ - /* guint32 flags3; */ + /* guint32 flags3; */ #if 0 guint8 dom[*]; /* domain string (unicode UTF-16LE) */ -- cgit v1.2.1 From 357ab60d0e9a86e18cd7e2b6222225ed4a62cd2b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 28 Mar 2009 05:34:25 +0000 Subject: I think I'm just going to apply this patch. I don't really see how it could break anything, anyway. Should fix NTLM authentication on big-endian systems. Fixes #4315. --- ChangeLog | 1 + libpurple/ntlm.c | 45 ++++++++++++++++++++++----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index b11be599fc..e67d83ea36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ version 2.6.0 (??/??/2009): * It should no longer be possible to end up with duplicates of buddies in a group on the buddy list. * Removed the unmaintained and unneeded toc protocol plugin. + * Fixed NTLM authentication on big-endian systems. XMPP: * Add support for in-band bytestreams for file transfers (XEP-0047). diff --git a/libpurple/ntlm.c b/libpurple/ntlm.c index 956cc5bf7b..d551d02d2f 100644 --- a/libpurple/ntlm.c +++ b/libpurple/ntlm.c @@ -110,7 +110,6 @@ struct type3_message { #endif }; -/* TODO: Will this work on both little-endian and big-endian machines? */ gchar * purple_ntlm_gen_type1(const gchar *hostname, const gchar *domain) { @@ -132,12 +131,12 @@ purple_ntlm_gen_type1(const gchar *hostname, const gchar *domain) tmsg->protocol[5] = 'S'; tmsg->protocol[6] = 'P'; tmsg->protocol[7] = '\0'; - tmsg->type = 0x00000001; - tmsg->flags = 0x0000b203; - tmsg->dom_len1 = tmsg->dom_len2 = domainlen; - tmsg->dom_off = sizeof(struct type1_message) + hostnamelen; - tmsg->host_len1 = tmsg->host_len2 = hostnamelen; - tmsg->host_off = sizeof(struct type1_message); + tmsg->type = GUINT32_TO_LE(0x00000001); + tmsg->flags = GUINT32_TO_LE(0x0000b203); + tmsg->dom_len1 = tmsg->dom_len2 = GUINT16_TO_LE(domainlen); + tmsg->dom_off = GUINT32_TO_LE(sizeof(struct type1_message) + hostnamelen); + tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen); + tmsg->host_off = GUINT32_TO_LE(sizeof(struct type1_message)); memcpy(msg + tmsg->host_off, hostname, hostnamelen); memcpy(msg + tmsg->dom_off, domain, domainlen); @@ -157,7 +156,7 @@ purple_ntlm_parse_type2(const gchar *type2, guint32 *flags) tmsg = (struct type2_message*)purple_base64_decode(type2, &retlen); memcpy(nonce, tmsg->nonce, 8); if (flags != NULL) - *flags = tmsg->flags; + *flags = GUINT16_FROM_LE(tmsg->flags); g_free(tmsg); return nonce; @@ -268,27 +267,27 @@ purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *ho tmsg->protocol[4] = 'S'; tmsg->protocol[5] = 'S'; tmsg->protocol[6] = 'P'; - tmsg->type = 0x00000003; - tmsg->lm_resp_len1 = tmsg->lm_resp_len2 = 0x18; - tmsg->lm_resp_off = sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen; - tmsg->nt_resp_len1 = tmsg->nt_resp_len2 = 0x18; - tmsg->nt_resp_off = sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18; + tmsg->type = GUINT32_TO_LE(0x00000003); + tmsg->lm_resp_len1 = tmsg->lm_resp_len2 = GUINT16_TO_LE(0x18); + tmsg->lm_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen); + tmsg->nt_resp_len1 = tmsg->nt_resp_len2 = GUINT16_TO_LE(0x18); + tmsg->nt_resp_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18); - tmsg->dom_len1 = tmsg->dom_len2 = domainlen; - tmsg->dom_off = sizeof(struct type3_message); + tmsg->dom_len1 = tmsg->dom_len2 = GUINT16_TO_LE(domainlen); + tmsg->dom_off = GUINT32_TO_LE(sizeof(struct type3_message)); - tmsg->user_len1 = tmsg->user_len2 = usernamelen; - tmsg->user_off = sizeof(struct type3_message) + domainlen; + tmsg->user_len1 = tmsg->user_len2 = GUINT16_TO_LE(usernamelen); + tmsg->user_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen); - tmsg->host_len1 = tmsg->host_len2 = hostnamelen; - tmsg->host_off = sizeof(struct type3_message) + domainlen + usernamelen; + tmsg->host_len1 = tmsg->host_len2 = GUINT16_TO_LE(hostnamelen); + tmsg->host_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen); if(flags) { - tmsg->sess_off = sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18 + 0x18; - tmsg->sess_len1 = tmsg->sess_len2 = 0x0010; + tmsg->sess_off = GUINT32_TO_LE(sizeof(struct type3_message) + domainlen + usernamelen + hostnamelen + 0x18 + 0x18); + tmsg->sess_len1 = tmsg->sess_len2 = GUINT16_TO_LE(0x0010); } - tmsg->flags = 0x00008201; + tmsg->flags = GUINT32_TO_LE(0x00008201); tmp = (char *)tmsg + sizeof(struct type3_message); @@ -361,7 +360,7 @@ purple_ntlm_gen_type3(const gchar *username, const gchar *passw, const gchar *ho /* LCS Stuff */ if (flags) { - tmsg->flags = 0x409082d4; + tmsg->flags = GUINT32_TO_LE(0x409082d4); gensesskey(sesskey, NULL); memcpy(tmp, sesskey, 0x10); } -- cgit v1.2.1 From db642582b7996fddb36edc5961fecc8df346f8c6 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sat, 28 Mar 2009 07:31:29 +0000 Subject: Save a count of how many ADL (per-request) and FQY (per-contact) we send, and then finish login only after they've all completed. Fixes #8588. --- libpurple/protocols/msn/notification.c | 14 ++++++++++++-- libpurple/protocols/msn/session.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c index c37eb7a240..dfdceacd30 100644 --- a/libpurple/protocols/msn/notification.c +++ b/libpurple/protocols/msn/notification.c @@ -630,7 +630,7 @@ update_contact_network(MsnSession *session, const char *passport, MsnNetwork net } else { purple_debug_error("msn", - "Got FQY update for unkwown user %s on network %d.\n", + "Got FQY update for unknown user %s on network %d.\n", passport, network); } } @@ -686,6 +686,9 @@ msn_notification_dump_contact(MsnSession *session) if (++adl_count % 150 == 0) { payload = xmlnode_to_str(adl_node, &payload_len); + /* ADL's are returned all-together */ + session->adl_fqy++; + msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); @@ -697,6 +700,9 @@ msn_notification_dump_contact(MsnSession *session) xmlnode_set_attrib(adl_node, "l", "1"); } } else { + /* FQY's are returned one-at-a-time */ + session->adl_fqy++; + msn_add_contact_xml(session, fqy_node, user->passport, 0, user->networkid); @@ -718,6 +724,9 @@ msn_notification_dump_contact(MsnSession *session) if (adl_count == 0 || adl_count % 150 != 0) { payload = xmlnode_to_str(adl_node, &payload_len); + /* ADL's are returned all-together */ + session->adl_fqy++; + msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); g_free(payload); @@ -804,7 +813,8 @@ adl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) if (!strcmp(cmd->params[1], "OK")) { /* ADL ack */ - msn_session_finish_login(session); + if (--session->adl_fqy == 0) + msn_session_finish_login(session); } else { cmdproc->last_cmd->payload_cb = adl_cmd_parse; cmd->payload_len = atoi(cmd->params[1]); diff --git a/libpurple/protocols/msn/session.h b/libpurple/protocols/msn/session.h index 82c5a508e9..3fb42f1274 100644 --- a/libpurple/protocols/msn/session.h +++ b/libpurple/protocols/msn/session.h @@ -90,6 +90,7 @@ struct _MsnSession gboolean connected; gboolean logged_in; /**< A temporal flag to ignore local buddy list adds. */ + int adl_fqy; /**< A count of ADL/FQY so status is only changed once. */ gboolean destroying; /**< A flag that states if the session is being destroyed. */ gboolean http_method; -- cgit v1.2.1 From 8717775ed5a95c655e021ff79c7a6384694b975a Mon Sep 17 00:00:00 2001 From: Richard Laager Date: Sat, 28 Mar 2009 12:04:03 +0000 Subject: Update the documentation for the account-authorization-requested signal, as noticed by enst.bupt@gmail.com. --- doc/account-signals.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/account-signals.dox b/doc/account-signals.dox index 5d24f2b53d..a3cc766cc9 100644 --- a/doc/account-signals.dox +++ b/doc/account-signals.dox @@ -109,7 +109,7 @@ void (*account_alias_changed)(PurpleAccount *account, const char *old); @signaldef account-authorization-requested @signalproto -void (*account_authorization_requested)(PurpleAccount *account, const char *user); +int (*account_authorization_requested)(PurpleAccount *account, const char *user); @endsignalproto @signaldesc Emitted when a user requests authorization. -- cgit v1.2.1 From 7a197be3c57ad90eb58c54ba7e33ce1768d5d786 Mon Sep 17 00:00:00 2001 From: Jochen Kemnade Date: Sat, 28 Mar 2009 16:00:47 +0000 Subject: some German translation --- po/de.po | 495 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 236 insertions(+), 259 deletions(-) diff --git a/po/de.po b/po/de.po index 993315bf86..11abb7c79a 100644 --- a/po/de.po +++ b/po/de.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-02-25 17:28+0100\n" -"PO-Revision-Date: 2009-02-25 17:28+0100\n" +"POT-Creation-Date: 2009-03-28 16:59+0100\n" +"PO-Revision-Date: 2009-03-28 16:53+0100\n" "Last-Translator: Jochen Kemnade \n" "Language-Team: German \n" "MIME-Version: 1.0\n" @@ -2630,6 +2630,31 @@ msgstr "Sichere Offline-Nachricht als Alarm" msgid "Do not ask. Always save in pounce." msgstr "Nicht nachfragen. Immer als Alarm sichern." +msgid "One Time Password" +msgstr "" + +#. *< type +#. *< ui_requirement +#. *< flags +#. *< dependencies +#. *< priority +#. *< id +msgid "One Time Password Support" +msgstr "" + +#. *< name +#. *< version +#. * summary +msgid "Enforce that passwords are used only once." +msgstr "" + +#. * description +msgid "" +"Allows you to enforce on a per-account basis that passwords not being saved " +"are only used in a single successful connection.\n" +"Note: The account password must not be saved for this to work." +msgstr "" + #. *< type #. *< ui_requirement #. *< flags @@ -4440,16 +4465,24 @@ msgid "Unable to ping user %s" msgstr "Kann den Benutzer %s nicht anpingen" #, c-format -msgid "Unable to buzz, because there is nothing known about user %s." -msgstr "Kann nicht anklopfen, da nichts über den Benutzer %s bekannt ist." +msgid "Unable to buzz, because there is nothing known about %s." +msgstr "Kann nicht anklopfen, da nichts über %s bekannt ist." + +#, c-format +msgid "Unable to buzz, because %s might be offline." +msgstr "Kann nicht anklopfen, da %s vielleicht offline ist." #, c-format -msgid "Unable to buzz, because user %s might be offline." -msgstr "Kann nicht anklopfen, da der Benutzer %s vielleicht offline ist." +msgid "" +"Unable to buzz, because %s does not support it or does not wish to receive " +"buzzes now." +msgstr "" +"Kann nicht anklopfen, da %s dies nicht unterstützt oder im Moment nicht " +"möchte." #, c-format -msgid "Unable to buzz, because the user %s does not support it." -msgstr "Kann nicht anklopfen, da der Benutzer %s dies nicht unterstützt." +msgid "Buzzing %s..." +msgstr "%s anklopfen..." #. Yahoo only supports one attention command: the 'buzz'. #. This is index number YAHOO_BUZZ. @@ -4460,10 +4493,6 @@ msgstr "Anklopfen" msgid "%s has buzzed you!" msgstr "%s hat bei Ihnen angeklopft!" -#, c-format -msgid "Buzzing %s..." -msgstr "%s anklopfen..." - msgid "config: Configure a chat room." msgstr "config: Konfiguriere einen Chatraum." @@ -4618,6 +4647,19 @@ msgstr "Fehler beim Betreten des Chats %s" msgid "Error in chat %s" msgstr "Fehler im Chat %s" +#, fuzzy +msgid "An error occured on the in-band bytestream transfer\n" +msgstr "Beim Öffnen der Datei trat ein Fehler auf." + +msgid "Transfer was closed." +msgstr "Übertragung wurde geschlossen" + +msgid "Failed to open the file" +msgstr "Öffnen der Datei fehlgeschlagen" + +msgid "Failed to open in-band bytestream" +msgstr "" + #, c-format msgid "Unable to send file to %s, user does not support file transfers" msgstr "" @@ -6435,7 +6477,7 @@ msgstr "" "sein oder mit einem Buchstaben beginnen und nur Buchstaben, Ziffern und " "Leerzeichen enthalten oder nur aus Ziffern bestehen." -#. Unregistered screen name +#. Unregistered username #. uid is not exist msgid "Invalid username." msgstr "Ungültiger Benutzername." @@ -6451,7 +6493,7 @@ msgstr "Ihr Benutzerkonto ist momentan gesperrt." msgid "The AOL Instant Messenger service is temporarily unavailable." msgstr "Der AOL-Sofortnachrichtendienst ist zur Zeit nicht erreichbar." -#. screen name connecting too frequently +#. username connecting too frequently #. IP address connecting too frequently msgid "" "You have been connecting and disconnecting too frequently. Wait ten minutes " @@ -6652,7 +6694,7 @@ msgstr[0] "" msgstr[1] "" "Sie haben %hu Nachrichten von %s aus unbekannten Gründen nicht erhalten." -#. Data is assumed to be the destination sn +#. Data is assumed to be the destination bn #, c-format msgid "Unable to send message: %s" msgstr "Kann die Nachricht nicht senden: %s" @@ -7253,6 +7295,36 @@ msgstr "Aktualisieren" msgid "Could not change buddy information." msgstr "Konnte Buddy-Informationen nicht bearbeiten." +msgid "Mobile" +msgstr "Mobil" + +msgid "Note" +msgstr "Bemerkung" + +#. callback +msgid "Buddy Memo" +msgstr "Buddy-Notiz" + +msgid "Change his/her memo as you like" +msgstr "" + +#, fuzzy +msgid "_Modify" +msgstr "Bearbeiten" + +#, fuzzy +msgid "Memo Modify" +msgstr "Bearbeiten" + +msgid "Server says:" +msgstr "Server meldet:" + +msgid "Your request was accepted." +msgstr "Ihre Anfrage wurde akzeptiert." + +msgid "Your request was rejected." +msgstr "Ihre Anfrage wurde abgelehnt." + #, c-format msgid "%u requires verification" msgstr "%u erfordert Autorisierung" @@ -7701,7 +7773,6 @@ msgstr "" "Unbekannte Antwort bei der Anmeldung (0x%02X):\n" "%s" -#. we didn't successfully connect. tdt->toc_fd is valid here msgid "Unable to connect." msgstr "Verbindung nicht möglich." @@ -8613,9 +8684,6 @@ msgstr "Organisation" msgid "Unit" msgstr "Abteilung" -msgid "Note" -msgstr "Bemerkung" - msgid "Join Chat" msgstr "Chat betreten" @@ -9308,189 +9376,14 @@ msgstr "Auth-Benutzer" msgid "Auth Domain" msgstr "Auth-Domain" -#, c-format -msgid "Looking up %s" -msgstr "Suche nach %s" - -#, c-format -msgid "Connect to %s failed" -msgstr "Verbindung mit %s fehlgeschlagen" - -#, c-format -msgid "Signon: %s" -msgstr "Anmeldung: %s" - -#, c-format -msgid "Unable to write file %s." -msgstr "Datei %s konnte nicht geschrieben werden." - -#, c-format -msgid "Unable to read file %s." -msgstr "Datei %s konnte nicht gelesen werden." - -#, c-format -msgid "Message too long, last %s bytes truncated." -msgstr "Nachricht zu lange, letzten %s Bytes abgeschnitten." - -#, c-format -msgid "%s not currently logged in." -msgstr "%s ist zur Zeit nicht online." - -#, c-format -msgid "Warning of %s not allowed." -msgstr "Verwarnung von %s nicht erlaubt." - -msgid "A message has been dropped, you are exceeding the server speed limit." -msgstr "" -"Eine Nachricht ging verloren. Sie überschreiten die Geschwindigkeitsgrenze " -"des Servers." - -#, c-format -msgid "Chat in %s is not available." -msgstr "Chat in %s ist nicht verfügbar." - -#, c-format -msgid "You are sending messages too fast to %s." -msgstr "Sie verschicken die Nachrichten an %s zu schnell." - -#, c-format -msgid "You missed an IM from %s because it was too big." -msgstr "Eine Nachricht von %s hat Sie nicht erreicht, da sie zu groß war." - -#, c-format -msgid "You missed an IM from %s because it was sent too fast." -msgstr "" -"Eine Nachricht von %s hat Sie nicht erreicht, da sie zu schnell gesendet " -"wurde." - -msgid "Failure." -msgstr "Fehler." - -msgid "Too many matches." -msgstr "Zu viele Übereinstimmungen." - -msgid "Need more qualifiers." -msgstr "Benötige mehr Angaben." - -msgid "Dir service temporarily unavailable." -msgstr "Verzeichnis-Dienst ist zur Zeit nicht verfügbar." - -msgid "Email lookup restricted." -msgstr "E-Mail-Suche eingeschränkt." - -msgid "Keyword ignored." -msgstr "Stichwort ignoriert." - -msgid "No keywords." -msgstr "Keine Stichwörter." - -msgid "User has no directory information." -msgstr "Der Benutzer hat kein Profil." - -msgid "Country not supported." -msgstr "Land nicht unterstützt." - -#, c-format -msgid "Failure unknown: %s." -msgstr "Unbekannter Fehler: %s." - -msgid "Incorrect username or password." -msgstr "Ungültiger Benutzername oder Passwort." - -msgid "The service is temporarily unavailable." -msgstr "Der Dienst ist zur Zeit nicht verfügbar." - -msgid "Your warning level is currently too high to log in." -msgstr "Ihre Warnstufe ist zur Zeit zu hoch, um sich anzumelden." - -msgid "" -"You have been connecting and disconnecting too frequently. Wait ten minutes " -"and try again. If you continue to try, you will need to wait even longer." -msgstr "" -"Sie haben Sich zu schnell an- und abgemeldet. Warten Sie 10 Minuten und " -"versuchen Sie es erneut. Wenn Sie es weiter versuchen, werden sie noch " -"länger warten müssen." - -#, c-format -msgid "An unknown signon error has occurred: %s." -msgstr "Unbekannter Anmeldungsfehler: %s." - -#, c-format -msgid "An unknown error, %d, has occurred. Info: %s" -msgstr "Unbekannter Fehler '%d' aufgetreten. Info: %s" - -msgid "Invalid Groupname" -msgstr "Ungültiger Gruppenname" - -msgid "Connection Closed" -msgstr "Verbindung geschlossen" - -msgid "Waiting for reply..." -msgstr "Warte auf Antwort..." - -msgid "TOC has come back from its pause. You may now send messages again." -msgstr "" -"TOC ist von seiner Pause zurückgekehrt. Sie können wieder Nachrichten senden." - -msgid "Password Change Successful" -msgstr "Passwortänderung erfolgreich" - -msgid "_Group:" -msgstr "_Gruppe:" - -msgid "Get Dir Info" -msgstr "Verzeichnisinformation abrufen" - -msgid "Set Dir Info" -msgstr "Verzeichnisinformation abrufen" - -#, c-format -msgid "Could not open %s for writing!" -msgstr "Kann %s nicht zum Schreiben öffnen!" - -msgid "File transfer failed; other side probably canceled." -msgstr "" -"Dateiübertragung gescheitert; die andere Seite hat die Dateiübertragung " -"wahrscheinlich abgebrochen." - -msgid "Could not connect for transfer." -msgstr "Übertragungsverbindung konnte nicht hergestellt werden." - -msgid "Could not write file header. The file will not be transferred." -msgstr "" -"Konnte keinen Datei-Header schreiben. Die Datei wurde nicht übermittelt." - -msgid "Save As..." -msgstr "Speichern unter..." - -#, c-format -msgid "%s requests %s to accept %d file: %s (%.2f %s)%s%s" -msgid_plural "%s requests %s to accept %d files: %s (%.2f %s)%s%s" -msgstr[0] "%s bittet %s %d Datei zu akzeptieren: %s (%.2f %s)%s%s" -msgstr[1] "%s bittet %s %d Dateien zu akzeptieren: %s (%.2f %s)%s%s" - -#, c-format -msgid "%s requests you to send them a file" -msgstr "%s bittet Sie eine Datei zu senden" - -#. *< type -#. *< ui_requirement -#. *< flags -#. *< dependencies -#. *< priority -#. *< id -#. *< name -#. *< version -#. * summary -#. * description -msgid "TOC Protocol Plugin" -msgstr "TOC-Protokoll-Plugin" - #, c-format msgid "%s has sent you a webcam invite, which is not yet supported." msgstr "" "%s hat Ihnen eine Webcam-Einladung gesendet, die noch nicht unterstützt wird." +msgid "Your SMS was not delivered" +msgstr "Ihre SMS wurde nicht ausgeliefert" + msgid "Your Yahoo! message did not get sent." msgstr "Ihre Yahoo!-Nachricht wurde nicht verschickt." @@ -10099,9 +9992,6 @@ msgstr "Nicht stören" msgid "Extended away" msgstr "Abwesend (erweitert)" -msgid "Mobile" -msgstr "Mobil" - msgid "Listening to music" msgstr "Musik hören" @@ -10143,18 +10033,6 @@ msgstr "+++ %s wurde tätig" msgid "%x %X" msgstr "%x %X" -#, c-format -msgid "Error Reading %s" -msgstr "Fehler beim Lesen von %s" - -#, c-format -msgid "" -"An error was encountered reading your %s. They have not been loaded, and " -"the old file has been renamed to %s~." -msgstr "" -"Beim Einlesen Ihrer %s trat ein Fehler auf. Die Liste wurde nicht geladen " -"und die alte Datei wurde in %s~ umbenannt." - msgid "Calculating..." msgstr "Berechne..." @@ -10229,6 +10107,14 @@ msgstr "Fehler beim Schreiben von %s: %s" msgid "Unable to connect to %s: %s" msgstr "Verbindung zu %s nicht möglich: %s" +#, c-format +msgid "" +"Unable to connect to %s: Server requires TLS/SSL, but no TLS/SSL support was " +"found." +msgstr "" +"Verbindung zu %s fehlgeschlagen: Der Server verlangt TLS/SSL, es wurde " +"jedoch kein TLS/SSL-Support gefunden." + #, c-format msgid " - %s" msgstr " - %s" @@ -10259,6 +10145,18 @@ msgstr "Verbindung abgelehnt." msgid "Address already in use." msgstr "Adresse wird bereits benutzt." +#, c-format +msgid "Error Reading %s" +msgstr "Fehler beim Lesen von %s" + +#, c-format +msgid "" +"An error was encountered reading your %s. The file has not been loaded, and " +"the old file has been renamed to %s~." +msgstr "" +"Beim Einlesen Ihrer %s trat ein Fehler auf. Die Datei wurde nicht geladen " +"und die alte Datei wurde in %s~ umbenannt." + msgid "Internet Messenger" msgstr "Internet-Sofortnachrichtendienst" @@ -10301,10 +10199,8 @@ msgstr "Benachrichtigung über neue _Mails" msgid "Use this buddy _icon for this account:" msgstr "Dieses Buddy-_Icon für dieses Konto benutzen:" -#. Build the protocol options frame. -#, c-format -msgid "%s Options" -msgstr "%s Einstellungen" +msgid "_Advanced" +msgstr "E_rweitert" msgid "Use GNOME Proxy Settings" msgstr "Benutze GNOME-Proxy-Einstellungen" @@ -10339,9 +10235,6 @@ msgstr "Wenn Sie genau hinschauen" msgid "you can see the butterflies mating" msgstr "Sie können den Schmetterlingen beim Paaren zusehen" -msgid "Proxy Options" -msgstr "Proxy-Optionen" - msgid "Proxy _type:" msgstr "Proxy-_Typ:" @@ -10369,8 +10262,8 @@ msgstr "_Einfach" msgid "Create _this new account on the server" msgstr "Dieses _neue Konto auf dem Server anlegen" -msgid "_Advanced" -msgstr "_Erweitert" +msgid "_Proxy" +msgstr "Pr_oxy" # Aktiv msgid "Enabled" @@ -10588,6 +10481,9 @@ msgstr "/Werkzeuge/Buddy-_Alarm" msgid "/Tools/_Certificates" msgstr "/Werkzeuge/_Zertifikate" +msgid "/Tools/Custom Smile_ys" +msgstr "/Werkzeuge/Benutzerdefinierte Smile_ys" + msgid "/Tools/Plu_gins" msgstr "/Werkzeuge/Plu_gins" @@ -10597,9 +10493,6 @@ msgstr "/Werkzeuge/_Einstellungen" msgid "/Tools/Pr_ivacy" msgstr "/Werkzeuge/Pri_vatsphäre" -msgid "/Tools/Smile_y" -msgstr "/Werkzeuge/Smile_y" - msgid "/Tools/_File Transfers" msgstr "/Werkzeuge/_Dateiübertragungen" @@ -10717,8 +10610,8 @@ msgstr "Manuell" msgid "By status" msgstr "Nach Status" -msgid "By log size" -msgstr "Nach Größe der Logs" +msgid "By recent log activity" +msgstr "Nach letzter Mitschnitts-Aktivität" #, c-format msgid "%s disconnected" @@ -10734,6 +10627,9 @@ msgstr "Wiederverbinden" msgid "Re-enable" msgstr "Reaktivieren" +msgid "SSL FAQs" +msgstr "SSL-FAQs" + msgid "Welcome back!" msgstr "Willkommen zurück!" @@ -10824,6 +10720,9 @@ msgstr "" msgid "A_lias:" msgstr "A_lias:" +msgid "_Group:" +msgstr "_Gruppe:" + msgid "Auto_join when account becomes online." msgstr "Automatisch _beitreten, wenn das Konto online geht." @@ -11352,6 +11251,9 @@ msgstr "Georgisch" msgid "Ubuntu Georgian Translators" msgstr "Ubuntu-Georgisch-Übersetzer" +msgid "Khmer" +msgstr "Khmer" + msgid "Kannada" msgstr "Kannada" @@ -11825,15 +11727,6 @@ msgstr "" msgid "Enable typing notification" msgstr "Tipp-Benachrichtigung aktivieren" -msgid "_Copy Email Address" -msgstr "Kopiere _E-Mail-Adresse" - -msgid "_Open Link in Browser" -msgstr "Ö_ffne Link im Browser" - -msgid "_Copy Link Location" -msgstr "_Kopiere den Link" - msgid "" "Unrecognized file type\n" "\n" @@ -12086,6 +11979,7 @@ msgid "" "\n" " -c, --config=DIR use DIR for config files\n" " -d, --debug print debugging messages to stdout\n" +" -f, --force-online force online, regardless of network status\n" " -h, --help display this help and exit\n" " -m, --multiple do not ensure single instance\n" " -n, --nologin don't automatically login\n" @@ -12100,6 +11994,7 @@ msgstr "" "\n" " -c, --config=VERZ benutze VERZ als Konfigurationsverzeichnis\n" " -d, --debug gibt Debugging-Meldungen nach stdout aus\n" +" -f, --force-online online erzwingen, ungeachtet des Netzwerk-Status\n" " -h, --help zeigt diese Hilfe und beendet das Programm\n" " -m, --multiple mehrere Instanzen erlauben\n" " -n, --nologin nicht automatisch anmelden\n" @@ -12117,6 +12012,7 @@ msgid "" "\n" " -c, --config=DIR use DIR for config files\n" " -d, --debug print debugging messages to stdout\n" +" -f, --force-online force online, regardless of network status\n" " -h, --help display this help and exit\n" " -m, --multiple do not ensure single instance\n" " -n, --nologin don't automatically login\n" @@ -12130,6 +12026,7 @@ msgstr "" "\n" " -c, --config=VERZ benutze VERZ als Konfigurationsverzeichnis\n" " -d, --debug gibt Debugging-Meldungen nach stdout aus\n" +" -f, --force-online online erzwingen, ungeachtet des Netzwerkstatus\n" " -h, --help zeigt diese Hilfe und beendet das Programm\n" " -m, --multiple mehrere Instanzen erlauben\n" " -n, --nologin nicht automatisch anmelden\n" @@ -12176,12 +12073,6 @@ msgstr "Pidgin" msgid "Exiting because another libpurple client is already running.\n" msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft\n" -msgid "Open All Messages" -msgstr "Alle Nachrichten öffnen" - -msgid "You have mail!" -msgstr "Sie haben Post!" - #, c-format msgid "%s has %d new message." msgid_plural "%s has %d new messages." @@ -12210,6 +12101,24 @@ msgid "" msgstr "" "Das benutzerdefinierte Browserkommando wurde ausgewählt, aber nicht gesetzt." +msgid "Open All Messages" +msgstr "Alle Nachrichten öffnen" + +msgid "You have mail!" +msgstr "Sie haben Post!" + +msgid "New Pounces" +msgstr "Neuer Alarm" + +msgid "Dismiss" +msgstr "Verwerfen" + +msgid "You have pounced!" +msgstr "Sie haben geklopft!" + +msgid "No message" +msgstr "Keine Nachricht" + msgid "The following plugins will be unloaded." msgstr "Die folgenden Plugins werden entladen." @@ -12258,6 +12167,9 @@ msgstr "Plugin-Details" msgid "Select a file" msgstr "Wählen Sie eine Datei" +msgid "Modify Buddy Pounce" +msgstr "Buddy-Alarm bearbeiten" + #. Create the "Pounce on Whom" frame. msgid "Pounce on Whom" msgstr "Bei wem alarmieren" @@ -12328,6 +12240,49 @@ msgstr "_Wiederkehrend" msgid "Pounce Target" msgstr "Alarm-Ziel" +#, fuzzy +msgid "Started typing" +msgstr "zu tippen beginnt" + +#, fuzzy +msgid "Paused while typing" +msgstr "beim Tippen anhält" + +#, fuzzy +msgid "Signed on" +msgstr "sich anmeldet" + +#, fuzzy +msgid "Returned from being idle" +msgstr "%s ist nicht mehr inaktiv (%s)" + +#, fuzzy +msgid "Returned from being away" +msgstr "wieder anwesend ist" + +#, fuzzy +msgid "Stopped typing" +msgstr "Tippen gestoppt" + +#, fuzzy +msgid "Signed off" +msgstr "sich abmeldet" + +#, fuzzy +msgid "Became idle" +msgstr "untätig wird" + +#, fuzzy +msgid "Went away" +msgstr "Bei Abwesenheit" + +#, fuzzy +msgid "Sent a message" +msgstr "Eine Nachricht senden" + +msgid "Unknown.... Please report this!" +msgstr "Unbekannt.... Bitte berichten Sie dieses Problem!" + msgid "Smiley theme failed to unpack." msgstr "Smiley-Thema konnte nicht entpackt werden." @@ -12350,6 +12305,11 @@ msgstr "Tastaturkürzel" msgid "Cl_ose conversations with the Escape key" msgstr "_Schließe Gespräche mit der Escape-Taste" +#. Buddy List Themes +msgid "Buddy List Theme" +msgstr "Buddy-Listen-Thema" + +#. System Tray msgid "System Tray Icon" msgstr "Kontrollleisten-Icon" @@ -12671,12 +12631,12 @@ msgstr "Wenn abwesend und untätig" msgid "Auto-away" msgstr "Automatisch abwesend" -msgid "Change status when _idle" -msgstr "Ändere Status, wenn _inaktiv" - msgid "_Minutes before becoming idle:" msgstr "_Minuten, bevor auf abwesend gesetzt wird:" +msgid "Change status when _idle" +msgstr "Ändere Status, wenn _inaktiv" + msgid "Change _status to:" msgstr "Ändere _Status zu:" @@ -12833,6 +12793,12 @@ msgstr "S_peichern & Übernehmen" msgid "Status for %s" msgstr "Status für %s" +#. +#. * TODO: We should enable/disable the add button based on +#. * whether the user has entered all required data. That +#. * would eliminate the need for this check and provide a +#. * better user experience. +#. msgid "Custom Smiley" msgstr "Benutzerdefinierter Smiley" @@ -12842,15 +12808,15 @@ msgstr "Weitere Daten benötigt" msgid "Please provide a shortcut to associate with the smiley." msgstr "Bitte geben Sie eine Tastenkombination für den Smiley an." -msgid "Duplicate Shortcut" -msgstr "Doppelte Tastenkombination" - +#, c-format msgid "" -"A custom smiley for the selected shortcut already exists. Please specify a " -"different shortcut." +"A custom smiley for '%s' already exists. Please use a different shortcut." msgstr "" -"Für diese Tastenkombination existiert bereits ein benutzerdefinierter " -"Smiley. Bitten wählen Sie eine andere Tastenkombination." +"Für '%s' existiert bereits ein benutzerdefinierter Smiley. Bitten wählen Sie " +"eine andere Tastenkombination." + +msgid "Duplicate Shortcut" +msgstr "Doppelte Tastenkombination" msgid "Please select an image for the smiley." msgstr "Bitte wählen Sie ein Bild für den Smiley." @@ -12861,16 +12827,21 @@ msgstr "Smiley bearbeiten" msgid "Add Smiley" msgstr "Smiley hinzufügen" -msgid "Smiley _Image" -msgstr "Smiley-_Bild" +msgid "_Image:" +msgstr "_Bild:" -#. Smiley shortcut -msgid "Smiley S_hortcut" -msgstr "_Tastenkombination" +#. Shortcut text +#, fuzzy +msgid "S_hortcut text:" +msgstr "Tastenkombination" msgid "Smiley" msgstr "Smiley" +#, fuzzy +msgid "Shortcut Text" +msgstr "Tastenkombination" + msgid "Custom Smiley Manager" msgstr "Verwaltung für benutzerdefinierte Smileys" @@ -12996,6 +12967,15 @@ msgstr "" "Bild '%s' konnte nicht geladen werden: Grund unbekannt, vermutlich eine " "korrupte Bilddatei" +msgid "_Open Link" +msgstr "Ö_ffne Link" + +msgid "_Copy Link Location" +msgstr "_Kopiere den Link" + +msgid "_Copy Email Address" +msgstr "Kopiere _E-Mail-Adresse" + msgid "Save File" msgstr "Datei speichern" @@ -14023,6 +14003,3 @@ msgstr "Sendet und empfängt RAW-XMPP-Blöcke." msgid "This plugin is useful for debbuging XMPP servers or clients." msgstr "" "Dieses Plugin ist nützlich zur Fehlersuche in XMPP-Servern oder -Clients." - -#~ msgid "Unable to retrieve MSN Address Book" -#~ msgstr "Konnte das MSN-Adressbuch nicht abrufen" -- cgit v1.2.1 From f503646a4363a099636b9f78723daf81935c7cd3 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 30 Mar 2009 05:50:34 +0000 Subject: Apply Paul's second patch to fix some memory leaks found in valgrind. References #8786. --- libpurple/protocols/oscar/oscar.c | 1 + pidgin/gtkutils.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index ee706e12c0..ba6769bd19 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -4847,6 +4847,7 @@ oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char * /* TODO: Combine these two calls! */ aim_srv_setextrainfo(od, FALSE, 0, TRUE, status_text, itmsurl); oscar_set_extendedstatus(gc); + g_free(status_text); } } diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c index 3a0b900a21..bc4030882a 100644 --- a/pidgin/gtkutils.c +++ b/pidgin/gtkutils.c @@ -3578,7 +3578,9 @@ register_gnome_url_handlers(void) if (tmp == NULL) return FALSE; + g_free(tmp); tmp = NULL; + if (!g_spawn_command_line_sync("gconftool-2 --all-dirs /desktop/gnome/url-handlers", &tmp, &err, NULL, NULL)) { -- cgit v1.2.1 From a6c6ee297e32976c30d5cb034993b7f605cdb42f Mon Sep 17 00:00:00 2001 From: Ethan Blanton Date: Tue, 31 Mar 2009 01:08:29 +0000 Subject: Handle multiple 319 (channels joined) messages for IRC WHOIS. This additionally fixes a leak when multiple 319 messages were received. Fixes #8827 --- libpurple/protocols/irc/irc.h | 2 +- libpurple/protocols/irc/msgs.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h index 522405c246..09189c64fa 100644 --- a/libpurple/protocols/irc/irc.h +++ b/libpurple/protocols/irc/irc.h @@ -72,7 +72,7 @@ struct irc_conn { char *name; char *server; char *serverinfo; - char *channels; + GString *channels; int ircop; int identified; int idle; diff --git a/libpurple/protocols/irc/msgs.c b/libpurple/protocols/irc/msgs.c index 81e107d0b1..dec148f9e7 100644 --- a/libpurple/protocols/irc/msgs.c +++ b/libpurple/protocols/irc/msgs.c @@ -336,7 +336,11 @@ void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, cha if (args[3]) irc->whois.signon = (time_t)atoi(args[3]); } else if (!strcmp(name, "319")) { - irc->whois.channels = g_strdup(args[2]); + if (irc->whois.channels == NULL) { + irc->whois.channels = g_string_new(args[2]); + } else { + irc->whois.channels = g_string_append(irc->whois.channels, args[2]); + } } else if (!strcmp(name, "320")) { irc->whois.identified = 1; } @@ -391,8 +395,8 @@ void irc_msg_endwhois(struct irc_conn *irc, const char *name, const char *from, g_free(irc->whois.serverinfo); } if (irc->whois.channels) { - purple_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels); - g_free(irc->whois.channels); + purple_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels->str); + g_string_free(irc->whois.channels, TRUE); } if (irc->whois.idle) { gchar *timex = purple_str_seconds_to_string(irc->whois.idle); -- cgit v1.2.1 From eaf11a5ce8bfbc147ae0beeb57d0b863731038d6 Mon Sep 17 00:00:00 2001 From: Ethan Blanton Date: Tue, 31 Mar 2009 01:10:32 +0000 Subject: ChangeLog for 0fef59d3dbe867b8bb11cf3732a3f4056c01a9fc --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index e67d83ea36..bd2049464b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,10 @@ version 2.6.0 (??/??/2009): * Add support for sending attentions (equivalent to "buzz" and "nudge") using the command /buzz (XEP-0224). + IRC: + * Correctly handle WHOIS for users who are joined to a large number of + channels. + Pidgin: * Added -f command line option to tell Pidgin to ignore NetworkManager and assume it has a valid network connection. -- cgit v1.2.1 From df745d5d9293aa20aa60bc7abe10cc9bb88e5840 Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Wed, 1 Apr 2009 03:36:06 +0000 Subject: fixes a race condition, probably Fixes #8594 and maybe others --- libpurple/protocols/msn/soap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libpurple/protocols/msn/soap.c b/libpurple/protocols/msn/soap.c index b986562272..786e2f3a8e 100644 --- a/libpurple/protocols/msn/soap.c +++ b/libpurple/protocols/msn/soap.c @@ -667,6 +667,7 @@ msn_soap_connection_run(gpointer data) conn->handled_len = 0; conn->current_request = req; + purple_input_remove(conn->event_handle); conn->event_handle = purple_input_add(conn->ssl->fd, PURPLE_INPUT_WRITE, msn_soap_write_cb, conn); if (!msn_soap_write_cb_internal(conn, conn->ssl->fd, PURPLE_INPUT_WRITE, TRUE)) { -- cgit v1.2.1 From 3401fb9a15bcf1d6e3c240d7b0f949ad15fa5f9e Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 1 Apr 2009 05:25:36 +0000 Subject: Fix a faulty condition that would result in an attempt to add most of your email-only contacts to your buddy and/or privacy list. This was temporary, but resulted in a lot of extra traffic during login. References #8579. --- libpurple/protocols/msn/contact.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c index aee11ab2de..0e83a10242 100644 --- a/libpurple/protocols/msn/contact.c +++ b/libpurple/protocols/msn/contact.c @@ -697,25 +697,28 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node) /*TODO: need to support the Mobile type*/ continue; } - for (contactEmailNode = xmlnode_get_child(emailsNode, "ContactEmail"); contactEmailNode; - contactEmailNode = xmlnode_get_next_twin(contactEmailNode)) { - if (!(messengerEnabledNode = xmlnode_get_child(contactEmailNode, "isMessengerEnabled"))) - continue; + for (contactEmailNode = xmlnode_get_child(emailsNode, "ContactEmail"); + contactEmailNode; + contactEmailNode = xmlnode_get_next_twin(contactEmailNode)) { + if ((messengerEnabledNode = xmlnode_get_child(contactEmailNode, "isMessengerEnabled"))) { + + msnEnabled = xmlnode_get_data(messengerEnabledNode); - msnEnabled = xmlnode_get_data(messengerEnabledNode); + if (msnEnabled && !strcmp(msnEnabled, "true")) { + if ((emailNode = xmlnode_get_child(contactEmailNode, "email"))) + passport = xmlnode_get_data(emailNode); - if (msnEnabled && !strcmp(msnEnabled, "true")) { - if ((emailNode = xmlnode_get_child(contactEmailNode, "email"))) - passport = xmlnode_get_data(emailNode); + /* Messenger enabled, Get the Passport*/ + purple_debug_info("msn", "AB Yahoo/Federated User %s\n", passport ? passport : "(null)"); + g_free(msnEnabled); + break; + } - /*Messenger enabled, Get the Passport*/ - purple_debug_info("msn", "AB Yahoo/Federated User %s\n", passport ? passport : "(null)"); g_free(msnEnabled); - break; } - - g_free(msnEnabled); } + if (passport == NULL) /* Couldn't find anything */ + continue; } else { xmlnode *messenger_user; /* ignore non-messenger contacts */ -- cgit v1.2.1