# HG changeset patch # User Daniel Atallah # Date 1314028857 0 # Node ID e44af4d2e01b1153cbcda07134ab09113ebeb2ec # Parent 8c6254c23e32f6e0157060154f9e29c5970c7e3e# Parent 5876584828e866cd37283507921273859c03120d propagate from branch 'im.pidgin.pidgin.2.x.y' (head 218f7cd8f439bacd4fef6897f0389a7cd18ba67d) to branch 'im.pidgin.pidgin' (head a838619f39988fb46c2305600984725495b15ee1) diff -r 8c6254c23e32 -r e44af4d2e01b ChangeLog --- a/ChangeLog Sun Aug 21 23:45:07 2011 +0000 +++ b/ChangeLog Mon Aug 22 16:00:57 2011 +0000 @@ -1,5 +1,19 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 3.0.0 (??/??/????): + AIM and ICQ: + * Make buddy list management code more efficient. (Oliver) (#4816) + * Don't try to format ICQ usernames entered as email addresses. + Gets rid of an "Unable to format username" error at login. (#13883) + + MXit: + * Remove all reference to Hidden Number. + * Fix decoding of font-size changes in the markup of received messages. + * Ignore new invites to join a GroupChat if you're already joined, or + still have a pending invite. + * The buddy's name was not centered vertically in the buddy-list if they + did not have a status-message or mood set. + version 2.10.0 (08/18/2011): Pidgin: * Make the max size of incoming smileys a pref instead of hardcoding it. diff -r 8c6254c23e32 -r e44af4d2e01b ChangeLog.API --- a/ChangeLog.API Sun Aug 21 23:45:07 2011 +0000 +++ b/ChangeLog.API Mon Aug 22 16:00:57 2011 +0000 @@ -1,5 +1,70 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 3.0.0 (??/??/????): + libpurple: + Added: + * purple_notify_searchresult_column_set_visible + * purple_notify_searchresult_column_is_visible + * purple_notify_user_info_prepend_pair_plaintext + * purple_request_field_set_tooltip + * purple_request_field_get_tooltip + + Changed: + * purple_connection_error now takes a PurpleConnectionError + as the second parameter + * purple_notify_user_info_add_pair renamed to + purple_notify_user_info_add_pair_html + * purple_notify_user_info_get_entries returns a GQueue instead of + a GList + * purple_notify_user_info_prepend_pair renamed to + purple_notify_user_info_prepend_pair_html_html + * purple_util_fetch_url_request_len now takes a PurpleAccount as + the first parameter + * PurpleConnectionUiOps.report_disconnect now passes a + PurpleConnectionError as the second parameter + + Removed: + * _GntFileType + * _GntKeyPressMode + * _GntMouseEvent + * _GntParamFlags + * _GntProgressBarOrientation + * _GntTreeColumnFlag + * _GntWidgetFlags + * _PurpleCipherBatchMode + * _PurpleCipherCaps + * _PurpleCmdFlag + * _PurpleCmdPriority + * _PurpleCmdRet + * _PurpleCmdStatus + * _PurplePrefType + * _PurplePrivacyType + * _PurpleSoundEventID + * _XMLNodeType + * GtkIMHtml.clipboard_html_string + * GtkIMHtml.clipboard_text_string + * pidgin_blist_update_account_error_state + * pidgin_check_if_dir + * PIDGIN_DIALOG + * pidgin_dialogs_alias_contact + * pidgin_set_custom_buddy_icon + * pidgin_setup_screenname_autocomplete + * PidginConversation.sg + * purple_connection_error_reason + * purple_core_migrate + * purple_notify_searchresults_column_get_title + * purple_notify_searchresults_get_columns_count + * purple_notify_searchresults_get_rows_count + * purple_notify_searchresults_row_get + * purple_status_type_get_primary_attr + * purple_status_type_set_primary_attr + * purple_strlcat + * purple_strlcpy + * purple_util_fetch_url_request_len_with_account. Use + purple_util_fetch_url_request_len, insetad. + * PurpleConnectionUiOps.report_disconnect_reason + * struct _GtkIMHtmlFontDetail + version 2.10.0: libpurple: Added: diff -r 8c6254c23e32 -r e44af4d2e01b Makefile.am --- a/Makefile.am Sun Aug 21 23:45:07 2011 +0000 +++ b/Makefile.am Mon Aug 22 16:00:57 2011 +0000 @@ -11,8 +11,6 @@ config.h.mingw \ doxy2devhelp.xsl \ fix-casts.sh \ - gaim.pc.in \ - gaim-uninstalled.pc.in \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ diff -r 8c6254c23e32 -r e44af4d2e01b configure.ac --- a/configure.ac Sun Aug 21 23:45:07 2011 +0000 +++ b/configure.ac Mon Aug 22 16:00:57 2011 +0000 @@ -43,11 +43,11 @@ # # Make sure to update finch/libgnt/configure.ac with libgnt version changes. # -m4_define([purple_lt_current], [10]) -m4_define([purple_major_version], [2]) -m4_define([purple_minor_version], [10]) +m4_define([purple_lt_current], [20]) +m4_define([purple_major_version], [3]) +m4_define([purple_minor_version], [0]) m4_define([purple_micro_version], [0]) -m4_define([purple_version_suffix], []) +m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suffix],[purple_version_suffix])) @@ -56,7 +56,7 @@ m4_define([gnt_major_version], [2]) m4_define([gnt_minor_version], [8]) m4_define([gnt_micro_version], [9]) -m4_define([gnt_version_suffix], []) +m4_define([gnt_version_suffix], [devel]) m4_define([gnt_version], [gnt_major_version.gnt_minor_version.gnt_micro_version]) m4_define([gnt_display_version], gnt_version[]m4_ifdef([gnt_version_suffix],[gnt_version_suffix])) @@ -328,6 +328,9 @@ dnl ####################################################################### dnl # Check for GLib 2.16 (required) dnl ####################################################################### +# TODO: gmodule-2.0 is only needed if enable_plugins is 'yes'. It +# might be nice to change this check so that it's not required +# if enable_plugins is 'no'. PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [ AC_MSG_RESULT(no) AC_MSG_ERROR([ @@ -938,25 +941,6 @@ ], [ have_silc="no" ]) - if test "x$have_silc" = "xno"; then - PKG_CHECK_MODULES(SILC, silcclient, [ - have_silc="yes" - silc10includes="yes" - silc10client="yes" - ], [ - have_silc="no" - ]) - dnl If silcclient.pc wasn't found, check for just silc.pc - if test "x$have_silc" = "xno"; then - PKG_CHECK_MODULES(SILC, silc, [ - have_silc="yes" - silc10includes="yes" - silc10client="yes" - ], [ - have_silc="no" - ]) - fi - fi else if test "$ac_silc_includes" != "no"; then SILC_CFLAGS="-I$ac_silc_includes" @@ -974,17 +958,6 @@ if test "x$silcincludes" = "xyes" -a "x$silcclient" = "xyes"; then have_silc="yes" - else - CPPFLAGS_save="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $SILC_CFLAGS" - AC_CHECK_HEADER(silcincludes.h, [silc10includes=yes]) - CPPFLAGS="$CPPFLAGS_save" - - SILC_LIBS="$SILC_LIBS -lsilc -lsilcclient -lpthread $LIBDL" - AC_CHECK_LIB(silcclient, silc_client_init, [silc10client=yes], , $SILC_LIBS) - if test "x$silc10includes" = "xyes" -a "x$silc10client" = "xyes"; then - have_silc="yes" - fi fi fi AC_SUBST(SILC_LIBS) @@ -992,20 +965,6 @@ dnl SILC Toolkit >= 1.0.1 has a new MIME API if test "x$silcclient" = "xyes"; then AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h]) -elif test "x$silc10client" = "xyes"; then - CPPFLAGS_save="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $SILC_CFLAGS" - AC_MSG_CHECKING(for silcmime.h) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include - ]], [[]])], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_SILCMIME_H, 1, [Define if we have silcmime.h]) - ], [ - AC_MSG_RESULT(no) - ]) - CPPFLAGS="$CPPFLAGS_save" fi dnl ####################################################################### @@ -1120,10 +1079,7 @@ STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/bonjour//'` fi if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then - STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc/silc10/'` -fi -if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then - STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc10//'` + STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/silc//'` fi AC_SUBST(STATIC_PRPLS) STATIC_LINK_LIBS= @@ -1147,8 +1103,6 @@ else if test "x$i" = "xsilc"; then STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib${i}purple.la" - elif test "x$i" = "xsilc10"; then - STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/libsilcpurple.la" else STATIC_LINK_LIBS="$STATIC_LINK_LIBS \$(top_builddir)/libpurple/protocols/$i/lib$i.la" fi @@ -1169,7 +1123,6 @@ icq) static_oscar=yes ;; sametime) static_sametime=yes ;; silc) static_silc=yes ;; - silc10) static_silc=yes ;; simple) static_simple=yes ;; yahoo) static_yahoo=yes ;; zephyr) static_zephyr=yes ;; @@ -1205,10 +1158,7 @@ DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/bonjour//'` fi if test "x$silcincludes" != "xyes" -o "x$silcclient" != "xyes"; then - DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc/silc10/'` -fi -if test "x$silc10includes" != "xyes" -o "x$silc10client" != "xyes"; then - DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc10//'` + DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/silc//'` fi AC_SUBST(DYNAMIC_PRPLS) for i in $DYNAMIC_PRPLS ; do @@ -1227,7 +1177,6 @@ icq) dynamic_oscar=yes ;; sametime) dynamic_sametime=yes ;; silc) dynamic_silc=yes ;; - silc10) dynamic_silc=yes ;; simple) dynamic_simple=yes ;; yahoo) dynamic_yahoo=yes ;; zephyr) dynamic_zephyr=yes ;; @@ -2530,10 +2479,8 @@ m4macros/Makefile pidgin.apspec pidgin/Makefile - pidgin/pidgin.pc - pidgin/pidgin-uninstalled.pc - pidgin/pidgin-2.pc - pidgin/pidgin-2-uninstalled.pc + pidgin/pidgin-3.pc + pidgin/pidgin-3-uninstalled.pc pidgin/pixmaps/Makefile pidgin/pixmaps/emotes/default/24/Makefile pidgin/pixmaps/emotes/none/Makefile @@ -2550,10 +2497,8 @@ libpurple/ciphers/Makefile libpurple/example/Makefile libpurple/gconf/Makefile - libpurple/purple.pc - libpurple/purple-uninstalled.pc - libpurple/purple-2.pc - libpurple/purple-2-uninstalled.pc + libpurple/purple-3.pc + libpurple/purple-3-uninstalled.pc libpurple/plugins/Makefile libpurple/plugins/mono/Makefile libpurple/plugins/mono/api/Makefile @@ -2576,7 +2521,6 @@ libpurple/protocols/oscar/Makefile libpurple/protocols/sametime/Makefile libpurple/protocols/silc/Makefile - libpurple/protocols/silc10/Makefile libpurple/protocols/simple/Makefile libpurple/protocols/yahoo/Makefile libpurple/protocols/zephyr/Makefile diff -r 8c6254c23e32 -r e44af4d2e01b finch/finch.c --- a/finch/finch.c Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/finch.c Mon Aug 22 16:00:57 2011 +0000 @@ -351,29 +351,6 @@ /* We don't want debug-messages to show up and corrupt the display */ purple_debug_set_enabled(debug_enabled); - /* If we're using a custom configuration directory, we - * do NOT want to migrate, or weird things will happen. */ - if (opt_config_dir_arg == NULL) - { - if (!purple_core_migrate()) - { - char *old = g_strconcat(purple_home_dir(), - G_DIR_SEPARATOR_S ".gaim", NULL); - char *text = g_strdup_printf(_( - "%s encountered errors migrating your settings " - "from %s to %s. Please investigate and complete the " - "migration by hand. Please report this error at http://developer.pidgin.im"), _("Finch"), - old, purple_user_dir()); - - g_free(old); - - purple_print_utf8_to_console(stderr, text); - g_free(text); - - return 0; - } - } - purple_core_set_ui_ops(gnt_core_get_ui_ops()); purple_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); purple_idle_set_ui_ops(finch_idle_get_ui_ops()); diff -r 8c6254c23e32 -r e44af4d2e01b finch/gntblist.c --- a/finch/gntblist.c Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/gntblist.c Mon Aug 22 16:00:57 2011 +0000 @@ -1268,7 +1268,7 @@ { PurpleNotifyUserInfo *info = purple_notify_user_info_new(); gpointer uihandle; - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); + purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving...")); uihandle = purple_notify_userinfo(conn, name, info, NULL, NULL); purple_notify_user_info_destroy(info); @@ -1783,15 +1783,13 @@ presence = purple_buddy_get_presence(buddy); if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias)) { - char *esc = g_markup_escape_text(alias, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), esc); - g_free(esc); + purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), alias); } tmp = g_strdup_printf("%s (%s)", purple_account_get_username(account), purple_account_get_protocol_name(account)); - purple_notify_user_info_add_pair(user_info, _("Account"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Account"), tmp); g_free(tmp); prpl = purple_find_prpl(purple_account_get_protocol_id(account)); @@ -1806,7 +1804,7 @@ time_t idle = purple_presence_get_idle_time(pre); if (idle > 0) { char *st = purple_str_seconds_to_string(time(NULL) - idle); - purple_notify_user_info_add_pair(user_info, _("Idle"), st); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), st); g_free(st); } } diff -r 8c6254c23e32 -r e44af4d2e01b finch/gntconn.c --- a/finch/gntconn.c Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/gntconn.c Mon Aug 22 16:00:57 2011 +0000 @@ -165,7 +165,6 @@ NULL, /* connected */ NULL, /* disconnected */ NULL, /* notice */ - NULL, NULL, /* network_connected */ NULL, /* network_disconnected */ finch_connection_report_disconnect, diff -r 8c6254c23e32 -r e44af4d2e01b finch/gntnotify.c --- a/finch/gntnotify.c Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/gntnotify.c Mon Aug 22 16:00:57 2011 +0000 @@ -290,7 +290,7 @@ text = g_string_new(""); - for (l = purple_notify_user_info_get_entries(user_info); l != NULL; + for (l = purple_notify_user_info_get_entries(user_info)->head; l != NULL; l = l->next) { PurpleNotifyUserInfoEntry *user_info_entry = l->data; PurpleNotifyUserInfoEntryType type = purple_notify_user_info_entry_get_type(user_info_entry); @@ -430,6 +430,9 @@ { PurpleNotifySearchColumn *column = iter->data; gnt_tree_set_column_title(GNT_TREE(tree), i, column->title); + + if (!purple_notify_searchresult_column_is_visible(column)) + gnt_tree_set_column_visible(GNT_TREE(tree), i, FALSE); i++; } diff -r 8c6254c23e32 -r e44af4d2e01b finch/gntprefs.c --- a/finch/gntprefs.c Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/gntprefs.c Mon Aug 22 16:00:57 2011 +0000 @@ -62,14 +62,6 @@ void finch_prefs_update_old() { - const char *str = NULL; - - purple_prefs_rename("/gaim/gnt", "/finch"); - purple_prefs_rename("/purple/gnt", "/finch"); - - if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) && - strcmp(str, "gaim") == 0) - purple_prefs_set_string("/purple/away/idle_reporting", "purple"); } typedef struct diff -r 8c6254c23e32 -r e44af4d2e01b finch/libgnt/gntfilesel.h --- a/finch/libgnt/gntfilesel.h Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/libgnt/gntfilesel.h Mon Aug 22 16:00:57 2011 +0000 @@ -81,7 +81,7 @@ void (*gnt_reserved4)(void); }; -typedef enum _GntFileType +typedef enum { GNT_FILE_REGULAR, GNT_FILE_DIR diff -r 8c6254c23e32 -r e44af4d2e01b finch/libgnt/gntprogressbar.h --- a/finch/libgnt/gntprogressbar.h Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/libgnt/gntprogressbar.h Mon Aug 22 16:00:57 2011 +0000 @@ -37,7 +37,7 @@ #define GNT_IS_PROGRESS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNT_TYPE_PROGRESS_BAR)) #define GNT_PROGRESS_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarClass)) -typedef enum _GntProgressBarOrientation +typedef enum { GNT_PROGRESS_LEFT_TO_RIGHT, GNT_PROGRESS_RIGHT_TO_LEFT, diff -r 8c6254c23e32 -r e44af4d2e01b finch/libgnt/gnttree.h --- a/finch/libgnt/gnttree.h Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/libgnt/gnttree.h Mon Aug 22 16:00:57 2011 +0000 @@ -47,7 +47,7 @@ typedef struct _GntTreeRow GntTreeRow; typedef struct _GntTreeCol GntTreeCol; -typedef enum _GntTreeColumnFlag { +typedef enum { GNT_TREE_COLUMN_INVISIBLE = 1 << 0, GNT_TREE_COLUMN_FIXED_SIZE = 1 << 1, GNT_TREE_COLUMN_BINARY_DATA = 1 << 2, diff -r 8c6254c23e32 -r e44af4d2e01b finch/libgnt/gntwidget.h --- a/finch/libgnt/gntwidget.h Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/libgnt/gntwidget.h Mon Aug 22 16:00:57 2011 +0000 @@ -49,7 +49,7 @@ typedef struct _GntWidgetPriv GntWidgetPriv; typedef struct _GntWidgetClass GntWidgetClass; -typedef enum _GntWidgetFlags +typedef enum { GNT_WIDGET_DESTROYING = 1 << 0, GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1, @@ -69,7 +69,7 @@ } GntWidgetFlags; /* XXX: This will probably move elsewhere */ -typedef enum _GntMouseEvent +typedef enum { GNT_LEFT_MOUSE_DOWN = 1, GNT_RIGHT_MOUSE_DOWN, @@ -80,7 +80,7 @@ } GntMouseEvent; /* XXX: I'll have to ask grim what he's using this for in guifications. */ -typedef enum _GntParamFlags +typedef enum { GNT_PARAM_SERIALIZABLE = 1 << G_PARAM_USER_SHIFT } GntParamFlags; diff -r 8c6254c23e32 -r e44af4d2e01b finch/libgnt/gntwm.h --- a/finch/libgnt/gntwm.h Sun Aug 21 23:45:07 2011 +0000 +++ b/finch/libgnt/gntwm.h Mon Aug 22 16:00:57 2011 +0000 @@ -41,7 +41,7 @@ #define GNT_IS_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WM)) #define GNT_WM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WM, GntWMClass)) -typedef enum _GntKeyPressMode +typedef enum { GNT_KP_MODE_NORMAL, GNT_KP_MODE_RESIZE, diff -r 8c6254c23e32 -r e44af4d2e01b gaim-uninstalled.pc.in --- a/gaim-uninstalled.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -Name: Pidgin (Gaim compatibility) -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${pc_top_builddir}/${pcfiledir}/libpurple -I${pc_top_builddir}/${pcfiledir}/pidgin -Libs: ${pc_top_builddir}/${pcfiledir}/libpurple/libpurple.la diff -r 8c6254c23e32 -r e44af4d2e01b gaim.pc.in --- a/gaim.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -Name: Pidgin (Gaim compatibility) -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${includedir}/libpurple -Libs: -L${libdir} -lpurple diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/Makefile.am --- a/libpurple/Makefile.am Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/Makefile.am Mon Aug 22 16:00:57 2011 +0000 @@ -9,8 +9,8 @@ purple-send-async \ purple-url-handler \ purple.h.in \ - purple.pc.in \ - purple-uninstalled.pc.in \ + purple-3.pc.in \ + purple-3-uninstalled.pc.in \ version.h.in \ Makefile.mingw \ win32/global.mak \ @@ -30,7 +30,7 @@ endif pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = purple.pc +pkgconfig_DATA = purple-3.pc SUBDIRS = $(GCONF_DIR) plugins protocols ciphers . tests example @@ -117,7 +117,6 @@ desktopitem.h \ eventloop.h \ ft.h \ - gaim-compat.h \ idle.h \ imgstore.h \ log.h \ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/account.c --- a/libpurple/account.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/account.c Mon Aug 22 16:00:57 2011 +0000 @@ -874,7 +874,7 @@ return NULL; } - ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */ + ret = purple_account_new(name, protocol_id); g_free(name); g_free(protocol_id); @@ -924,15 +924,6 @@ { purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len); } - else - { - /* Try to see if the icon got left behind in the old cache. */ - g_free(filename); - filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL); - if (g_file_get_contents(filename, &contents, &len, NULL)) { - purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len); - } - } g_free(filename); g_free(data); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/blist.c --- a/libpurple/blist.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/blist.c Mon Aug 22 16:00:57 2011 +0000 @@ -461,19 +461,16 @@ PurpleAccount *account; PurpleBuddy *buddy; char *name = NULL, *alias = NULL; - const char *acct_name, *proto, *protocol; + const char *acct_name, *proto; xmlnode *x; acct_name = xmlnode_get_attrib(bnode, "account"); - protocol = xmlnode_get_attrib(bnode, "protocol"); - protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */ proto = xmlnode_get_attrib(bnode, "proto"); - proto = _purple_oscar_convert(acct_name, proto); /* XXX: Remove */ - - if (!acct_name || (!proto && !protocol)) + + if (!acct_name || !proto) return; - account = purple_accounts_find(acct_name, proto ? proto : protocol); + account = purple_accounts_find(acct_name, proto); if (!account) return; @@ -532,19 +529,18 @@ { PurpleChat *chat; PurpleAccount *account; - const char *acct_name, *proto, *protocol; + const char *acct_name, *proto; xmlnode *x; char *alias = NULL; GHashTable *components; acct_name = xmlnode_get_attrib(cnode, "account"); - protocol = xmlnode_get_attrib(cnode, "protocol"); proto = xmlnode_get_attrib(cnode, "proto"); - if (!acct_name || (!proto && !protocol)) + if (!acct_name || !proto) return; - account = purple_accounts_find(acct_name, proto ? proto : protocol); + account = purple_accounts_find(acct_name, proto); if (!account) return; @@ -630,17 +626,16 @@ xmlnode *x; PurpleAccount *account; int imode; - const char *acct_name, *proto, *mode, *protocol; + const char *acct_name, *proto, *mode; acct_name = xmlnode_get_attrib(anode, "name"); - protocol = xmlnode_get_attrib(anode, "protocol"); proto = xmlnode_get_attrib(anode, "proto"); mode = xmlnode_get_attrib(anode, "mode"); - if (!acct_name || (!proto && !protocol) || !mode) + if (!acct_name || !proto || !mode) continue; - account = purple_accounts_find(acct_name, proto ? proto : protocol); + account = purple_accounts_find(acct_name, proto); if (!account) continue; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/buddyicon.c --- a/libpurple/buddyicon.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/buddyicon.c Mon Aug 22 16:00:57 2011 +0000 @@ -105,9 +105,6 @@ /** "Should icons be cached to disk?" */ static gboolean icon_caching = TRUE; -/* For ~/.gaim to ~/.purple migration. */ -static char *old_icons_dir = NULL; - static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name); /* @@ -759,7 +756,7 @@ else g_hash_table_remove(pointer_icon_cache, account); - if (purple_account_is_connected(account)) + if (!purple_account_is_disconnected(account)) { PurpleConnection *gc; PurplePluginProtocolInfo *prpl_info; @@ -977,12 +974,6 @@ return purple_buddy_icons_node_set_custom_icon((PurpleBlistNode*)contact, icon_data, icon_len); } -void -_purple_buddy_icon_set_old_icons_dir(const char *dirname) -{ - old_icons_dir = g_strdup(dirname); -} - static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name) { @@ -995,133 +986,6 @@ } } -static void -migrate_buddy_icon(PurpleBlistNode *node, const char *setting_name, - const char *dirname, const char *filename) -{ - char *path; - - if (filename[0] != '/') - { - path = g_build_filename(dirname, filename, NULL); - if (g_file_test(path, G_FILE_TEST_EXISTS)) - { - g_free(path); - return; - } - g_free(path); - - path = g_build_filename(old_icons_dir, filename, NULL); - } - else - path = g_strdup(filename); - - if (g_file_test(path, G_FILE_TEST_EXISTS)) - { - guchar *icon_data; - size_t icon_len; - FILE *file; - char *new_filename; - - if (!read_icon_file(path, &icon_data, &icon_len)) - { - g_free(path); - delete_buddy_icon_settings(node, setting_name); - return; - } - - if (icon_data == NULL || icon_len <= 0) - { - /* This really applies to the icon_len check. - * icon_data should never be NULL if - * read_icon_file() returns TRUE. */ - purple_debug_error("buddyicon", "Empty buddy icon file: %s\n", path); - delete_buddy_icon_settings(node, setting_name); - g_free(path); - return; - } - - g_free(path); - - new_filename = purple_util_get_image_filename(icon_data, icon_len); - if (new_filename == NULL) - { - purple_debug_error("buddyicon", - "New icon filename is NULL. This should never happen! " - "The old filename was: %s\n", path); - delete_buddy_icon_settings(node, setting_name); - g_return_if_reached(); - } - - path = g_build_filename(dirname, new_filename, NULL); - if ((file = g_fopen(path, "wb")) != NULL) - { - if (!fwrite(icon_data, icon_len, 1, file)) - { - purple_debug_error("buddyicon", "Error writing %s: %s\n", - path, g_strerror(errno)); - } - else - purple_debug_info("buddyicon", "Wrote migrated cache file: %s\n", path); - - fclose(file); - } - else - { - purple_debug_error("buddyicon", "Unable to create file %s: %s\n", - path, g_strerror(errno)); - g_free(new_filename); - g_free(path); - - delete_buddy_icon_settings(node, setting_name); - return; - } - g_free(path); - - purple_blist_node_set_string(node, - setting_name, - new_filename); - ref_filename(new_filename); - - g_free(new_filename); - - if (purple_strequal(setting_name, "buddy_icon")) - { - const char *hash; - - hash = purple_blist_node_get_string(node, "avatar_hash"); - if (hash != NULL) - { - purple_blist_node_set_string(node, "icon_checksum", hash); - purple_blist_node_remove_setting(node, "avatar_hash"); - } - else - { - PurpleAccount *account = purple_buddy_get_account((PurpleBuddy *)node); - const char *prpl_id = purple_account_get_protocol_id(account); - - if (g_str_equal(prpl_id, "prpl-yahoo") || g_str_equal(prpl_id, "prpl-yahoojp")) - { - int checksum = purple_blist_node_get_int(node, "icon_checksum"); - if (checksum != 0) - { - char *checksum_str = g_strdup_printf("%i", checksum); - purple_blist_node_remove_setting(node, "icon_checksum"); - purple_blist_node_set_string(node, "icon_checksum", checksum_str); - g_free(checksum_str); - } - } - } - } - } - else - { - purple_debug_error("buddyicon", "Old icon file doesn't exist: %s\n", path); - delete_buddy_icon_settings(node, setting_name); - g_free(path); - } -} - void _purple_buddy_icons_account_loaded_cb() { @@ -1153,22 +1017,6 @@ PurpleBlistNode *node = purple_blist_get_root(); const char *dirname = purple_buddy_icons_get_cache_dir(); - /* Doing this once here saves having to check it inside a loop. */ - if (old_icons_dir != NULL) - { - if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) - { - purple_debug_info("buddyicon", "Creating icon cache directory.\n"); - - if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) - { - purple_debug_error("buddyicon", - "Unable to create directory %s: %s\n", - dirname, g_strerror(errno)); - } - } - } - while (node != NULL) { if (PURPLE_BLIST_NODE_IS_BUDDY(node)) @@ -1178,26 +1026,17 @@ filename = purple_blist_node_get_string(node, "buddy_icon"); if (filename != NULL) { - if (old_icons_dir != NULL) + char *path = g_build_filename(dirname, filename, NULL); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) { - migrate_buddy_icon(node, - "buddy_icon", - dirname, filename); + purple_blist_node_remove_setting(node, + "buddy_icon"); + purple_blist_node_remove_setting(node, + "icon_checksum"); } else - { - char *path = g_build_filename(dirname, filename, NULL); - if (!g_file_test(path, G_FILE_TEST_EXISTS)) - { - purple_blist_node_remove_setting(node, - "buddy_icon"); - purple_blist_node_remove_setting(node, - "icon_checksum"); - } - else - ref_filename(filename); - g_free(path); - } + ref_filename(filename); + g_free(path); } } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || @@ -1209,24 +1048,15 @@ filename = purple_blist_node_get_string(node, "custom_buddy_icon"); if (filename != NULL) { - if (old_icons_dir != NULL) + char *path = g_build_filename(dirname, filename, NULL); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) { - migrate_buddy_icon(node, - "custom_buddy_icon", - dirname, filename); + purple_blist_node_remove_setting(node, + "custom_buddy_icon"); } else - { - char *path = g_build_filename(dirname, filename, NULL); - if (!g_file_test(path, G_FILE_TEST_EXISTS)) - { - purple_blist_node_remove_setting(node, - "custom_buddy_icon"); - } - else - ref_filename(filename); - g_free(path); - } + ref_filename(filename); + g_free(path); } } node = purple_blist_node_next(node, TRUE); @@ -1298,11 +1128,9 @@ g_hash_table_destroy(icon_data_cache); g_hash_table_destroy(icon_file_cache); g_hash_table_destroy(pointer_icon_cache); - g_free(old_icons_dir); g_free(cache_dir); cache_dir = NULL; - old_icons_dir = NULL; } void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int *height) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/certificate.c --- a/libpurple/certificate.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/certificate.c Mon Aug 22 16:00:57 2011 +0000 @@ -1704,7 +1704,7 @@ flags |= PURPLE_CERTIFICATE_CA_UNKNOWN; purple_debug_warning("certificate/x509/tls_cached", - "No Certificate Authorities with either DN found " + "No Certificate Authorities with either DN " "found. I'll prompt the user, I guess.\n"); x509_tls_cached_check_subject_name(vrq, flags); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/cipher.h --- a/libpurple/cipher.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/cipher.h Mon Aug 22 16:00:57 2011 +0000 @@ -41,7 +41,7 @@ /** * Modes for batch encrypters */ -typedef enum _PurpleCipherBatchMode { +typedef enum { PURPLE_CIPHER_BATCH_MODE_ECB, PURPLE_CIPHER_BATCH_MODE_CBC } PurpleCipherBatchMode; @@ -49,7 +49,7 @@ /** * The operation flags for a cipher */ -typedef enum _PurpleCipherCaps { +typedef enum { PURPLE_CIPHER_CAPS_SET_OPT = 1 << 1, /**< Set option flag */ PURPLE_CIPHER_CAPS_GET_OPT = 1 << 2, /**< Get option flag */ PURPLE_CIPHER_CAPS_INIT = 1 << 3, /**< Init flag */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/cmds.h --- a/libpurple/cmds.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/cmds.h Mon Aug 22 16:00:57 2011 +0000 @@ -32,7 +32,7 @@ /*@{*/ /** The possible results of running a command with purple_cmd_do_command(). */ -typedef enum _PurpleCmdStatus { +typedef enum { PURPLE_CMD_STATUS_OK, PURPLE_CMD_STATUS_FAILED, PURPLE_CMD_STATUS_NOT_FOUND, @@ -48,7 +48,7 @@ * #PURPLE_CMD_RET_CONTINUE to cause the core to fall through to other * commands with the same name. */ -typedef enum _PurpleCmdRet { +typedef enum { PURPLE_CMD_RET_OK, /**< Everything's okay; Don't look for another command to call. */ PURPLE_CMD_RET_FAILED, /**< The command failed, but stop looking.*/ PURPLE_CMD_RET_CONTINUE /**< Continue, looking for other commands with the same name to call. */ @@ -68,7 +68,7 @@ */ typedef guint PurpleCmdId; -typedef enum _PurpleCmdPriority { +typedef enum { PURPLE_CMD_P_VERY_LOW = -1000, PURPLE_CMD_P_LOW = 0, PURPLE_CMD_P_DEFAULT = 1000, @@ -85,7 +85,7 @@ * * @see purple_cmd_register */ -typedef enum _PurpleCmdFlag { +typedef enum { /** Command is usable in IMs. */ PURPLE_CMD_FLAG_IM = 0x01, /** Command is usable in multi-user chats. */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/connection.c --- a/libpurple/connection.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/connection.c Mon Aug 22 16:00:57 2011 +0000 @@ -528,22 +528,7 @@ } void -purple_connection_error(PurpleConnection *gc, const char *text) -{ - /* prpls that have not been updated to use disconnection reasons will - * be setting wants_to_die before calling this function, so choose - * PURPLE_CONNECTION_ERROR_OTHER_ERROR (which is fatal) if it's true, - * and PURPLE_CONNECTION_ERROR_NETWORK_ERROR (which isn't) if not. See - * the documentation in connection.h. - */ - PurpleConnectionError reason = gc->wants_to_die - ? PURPLE_CONNECTION_ERROR_OTHER_ERROR - : PURPLE_CONNECTION_ERROR_NETWORK_ERROR; - purple_connection_error_reason (gc, reason, text); -} - -void -purple_connection_error_reason (PurpleConnection *gc, +purple_connection_error (PurpleConnection *gc, PurpleConnectionError reason, const char *description) { @@ -557,13 +542,13 @@ */ if (reason > PURPLE_CONNECTION_ERROR_OTHER_ERROR) { purple_debug_error("connection", - "purple_connection_error_reason: reason %u isn't a " + "purple_connection_error: reason %u isn't a " "valid reason\n", reason); reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR; } if (description == NULL) { - purple_debug_error("connection", "purple_connection_error_reason called with NULL description\n"); + purple_debug_error("connection", "purple_connection_error called with NULL description\n"); description = _("Unknown error"); } @@ -578,13 +563,8 @@ ops = purple_connections_get_ui_ops(); - if (ops != NULL) - { - if (ops->report_disconnect_reason != NULL) - ops->report_disconnect_reason (gc, reason, description); - if (ops->report_disconnect != NULL) - ops->report_disconnect (gc, description); - } + if (ops && ops->report_disconnect) + ops->report_disconnect(gc, reason, description); purple_signal_emit(purple_connections_get_handle(), "connection-error", gc, reason, description); @@ -615,7 +595,7 @@ reason = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR; } - purple_connection_error_reason (gc, reason, + purple_connection_error (gc, reason, purple_ssl_strerror(ssl_error)); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/connection.h --- a/libpurple/connection.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/connection.h Mon Aug 22 16:00:57 2011 +0000 @@ -128,7 +128,7 @@ /** Some other error occurred which fits into none of the other * categories. */ - /* purple_connection_error_reason() in connection.c uses the fact that + /* purple_connection_error() in connection.c uses the fact that * this is the last member of the enum when sanity-checking; if other * reasons are added after it, the check must be updated. */ @@ -194,16 +194,6 @@ void (*notice)(PurpleConnection *gc, const char *text); /** - * Called when an error causes a connection to be disconnected. - * Called before #disconnected. - * @param text a localized error message. - * @see #purple_connection_error - * @deprecated in favour of - * #PurpleConnectionUiOps.report_disconnect_reason. - */ - void (*report_disconnect)(PurpleConnection *gc, const char *text); - - /** * Called when libpurple discovers that the computer's network * connection is active. On Linux, this uses Network Manager if * available; on Windows, it uses Win32's network change notification @@ -219,21 +209,19 @@ /** * Called when an error causes a connection to be disconnected. - * Called before #disconnected. This op is intended to replace - * #report_disconnect. If both are implemented, this will be called - * first; however, there's no real reason to implement both. + * Called before #disconnected. * - * @param reason why the connection ended, if known, or - * #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not. - * @param text a localized message describing the disconnection - * in more detail to the user. - * @see #purple_connection_error_reason + * @param reason why the connection ended, if known, or + * #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not. + * @param text a localized message describing the disconnection + * in more detail to the user. + * @see #purple_connection_error * - * @since 2.3.0 + * @since 2.3.0 */ - void (*report_disconnect_reason)(PurpleConnection *gc, - PurpleConnectionError reason, - const char *text); + void (*report_disconnect)(PurpleConnection *gc, + PurpleConnectionError reason, + const char *text); void (*_purple_reserved1)(void); void (*_purple_reserved2)(void); @@ -264,7 +252,7 @@ /** Wants to Die state. This is set when the user chooses to log out, or * when the protocol is disconnected and should not be automatically * reconnected (incorrect password, etc.). prpls should rely on - * purple_connection_error_reason() to set this for them rather than + * purple_connection_error() to set this for them rather than * setting it themselves. * @see purple_connection_error_is_fatal */ @@ -465,21 +453,6 @@ void purple_connection_notice(PurpleConnection *gc, const char *text); /** - * Closes a connection with an error. - * - * @param gc The connection. - * @param reason The error text, which may not be @c NULL. - * @deprecated in favour of #purple_connection_error_reason. Calling - * @c purple_connection_error(gc, text) is equivalent to calling - * @c purple_connection_error_reason(gc, reason, text) where @c reason is - * #PURPLE_CONNECTION_ERROR_OTHER_ERROR if @c gc->wants_to_die is @c TRUE, and - * #PURPLE_CONNECTION_ERROR_NETWORK_ERROR if not. (This is to keep - * auto-reconnection behaviour the same when using old prpls which don't use - * reasons yet.) - */ -void purple_connection_error(PurpleConnection *gc, const char *reason); - -/** * Closes a connection with an error and a human-readable description of the * error. It also sets @c gc->wants_to_die to the value of * #purple_connection_error_is_fatal(@a reason), mainly for @@ -492,14 +465,14 @@ * @since 2.3.0 */ void -purple_connection_error_reason (PurpleConnection *gc, - PurpleConnectionError reason, - const char *description); +purple_connection_error(PurpleConnection *gc, + PurpleConnectionError reason, + const char *description); /** * Closes a connection due to an SSL error; this is basically a shortcut to * turning the #PurpleSslErrorType into a #PurpleConnectionError and a - * human-readable string and then calling purple_connection_error_reason(). + * human-readable string and then calling purple_connection_error(). * * @since 2.3.0 */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/core.c --- a/libpurple/core.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/core.c Mon Aug 22 16:00:57 2011 +0000 @@ -371,386 +371,6 @@ return is_single_instance; } -static gboolean -move_and_symlink_dir(const char *path, const char *basename, const char *old_base, const char *new_base, const char *relative) -{ - char *new_name = g_build_filename(new_base, basename, NULL); -#ifndef _WIN32 - char *old_name; -#endif - if (g_rename(path, new_name)) - { - purple_debug_error("core", "Error renaming %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - path, new_name, g_strerror(errno)); - g_free(new_name); - return FALSE; - } - g_free(new_name); - -#ifndef _WIN32 - /* NOTE: This new_name is relative. */ - new_name = g_build_filename(relative, basename, NULL); - old_name = g_build_filename(old_base, basename, NULL); - if (symlink(new_name, old_name)) - { - purple_debug_warning("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - old_name, new_name, g_strerror(errno)); - } - g_free(old_name); - g_free(new_name); -#endif - - return TRUE; -} - -gboolean -purple_core_migrate(void) -{ - const char *user_dir = purple_user_dir(); - char *old_user_dir = g_strconcat(purple_home_dir(), - G_DIR_SEPARATOR_S ".gaim", NULL); - char *status_file; - FILE *fp; - GDir *dir; - GError *err; - const char *entry; -#ifndef _WIN32 - char *logs_dir; -#endif - char *old_icons_dir; - - if (!g_file_test(old_user_dir, G_FILE_TEST_EXISTS)) - { - /* ~/.gaim doesn't exist, so there's nothing to migrate. */ - g_free(old_user_dir); - return TRUE; - } - - status_file = g_strconcat(user_dir, G_DIR_SEPARATOR_S "migrating", NULL); - - if (g_file_test(user_dir, G_FILE_TEST_EXISTS)) - { - /* If we're here, we have both ~/.gaim and .purple. */ - - if (!g_file_test(status_file, G_FILE_TEST_EXISTS)) - { - /* There's no "migrating" status file, - * so ~/.purple is all up to date. */ - g_free(status_file); - g_free(old_user_dir); - return TRUE; - } - } - - /* If we're here, it's time to migrate from ~/.gaim to ~/.purple. */ - - /* Ensure the user directory exists */ - if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR)) - { - if (g_mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) - { - purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - user_dir, g_strerror(errno)); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - } - - /* This writes ~/.purple/migrating, which allows us to detect - * incomplete migrations and properly retry. */ - if (!(fp = g_fopen(status_file, "w"))) - { - purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - status_file, g_strerror(errno)); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - fclose(fp); - - /* Open ~/.gaim so we can loop over its contents. */ - err = NULL; - if (!(dir = g_dir_open(old_user_dir, 0, &err))) - { - purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - status_file, - (err ? err->message : "Unknown error")); - if (err) - g_error_free(err); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - /* Loop over the contents of ~/.gaim */ - while ((entry = g_dir_read_name(dir))) - { - char *name = g_build_filename(old_user_dir, entry, NULL); - -#ifndef _WIN32 - /* Deal with symlinks... */ - if (g_file_test(name, G_FILE_TEST_IS_SYMLINK)) - { - /* We're only going to duplicate a logs symlink. */ - if (purple_strequal(entry, "logs")) - { - char *link; - err = NULL; - - if ((link = g_file_read_link(name, &err)) == NULL) - { - char *name_utf8 = g_filename_to_utf8(name, -1, NULL, NULL, NULL); - purple_debug_error("core", "Error reading symlink %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - name_utf8 ? name_utf8 : name, err->message); - g_free(name_utf8); - g_error_free(err); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - logs_dir = g_build_filename(user_dir, "logs", NULL); - - if (purple_strequal(link, "../.purple/logs") || - purple_strequal(link, logs_dir)) - { - /* If the symlink points to the new directory, we're - * likely just trying again after a failed migration, - * so there's no need to fail here. */ - g_free(link); - g_free(logs_dir); - continue; - } - - /* In case we are trying again after a failed migration, we need - * to unlink any existing symlink. If it's a directory, this - * will fail, and so will the symlink below, which is good - * because the user should sort things out. */ - g_unlink(logs_dir); - - /* Relative links will most likely still be - * valid from ~/.purple, though it's not - * guaranteed. Oh well. */ - if (symlink(link, logs_dir)) - { - purple_debug_error("core", "Error symlinking %s to %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - logs_dir, link, g_strerror(errno)); - g_free(link); - g_free(name); - g_free(logs_dir); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - g_free(link); - g_free(logs_dir); - continue; - } - - /* Ignore all other symlinks. */ - continue; - } -#endif - - /* Deal with directories... */ - if (g_file_test(name, G_FILE_TEST_IS_DIR)) - { - if (purple_strequal(entry, "icons")) - { - /* This is a special case for the Album plugin, which - * stores data in the icons folder. We're not copying - * the icons directory over because previous bugs - * meant that it filled up with junk for many users. - * This is a great time to purge it. */ - - GDir *icons_dir; - char *new_icons_dir; - const char *icons_entry; - - err = NULL; - if (!(icons_dir = g_dir_open(name, 0, &err))) - { - purple_debug_error("core", "Error opening directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - name, - (err ? err->message : "Unknown error")); - if (err) - g_error_free(err); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - new_icons_dir = g_build_filename(user_dir, "icons", NULL); - /* Ensure the new icon directory exists */ - if (!g_file_test(new_icons_dir, G_FILE_TEST_IS_DIR)) - { - if (g_mkdir(new_icons_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) - { - purple_debug_error("core", "Error creating directory %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - new_icons_dir, g_strerror(errno)); - g_free(new_icons_dir); - g_dir_close(icons_dir); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - } - - while ((icons_entry = g_dir_read_name(icons_dir))) - { - char *icons_name = g_build_filename(name, icons_entry, NULL); - - if (g_file_test(icons_name, G_FILE_TEST_IS_DIR)) - { - if (!move_and_symlink_dir(icons_name, icons_entry, - name, new_icons_dir, "../../.purple/icons")) - { - g_free(icons_name); - g_free(new_icons_dir); - g_dir_close(icons_dir); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - } - g_free(icons_name); - } - - g_dir_close(icons_dir); - } - else if (purple_strequal(entry, "plugins")) - { - /* Do nothing, because we broke plugin compatibility. - * This means that the plugins directory gets left behind. */ - } - else - { - /* All other directories are moved and symlinked. */ - if (!move_and_symlink_dir(name, entry, old_user_dir, user_dir, "../.purple")) - { - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - } - } - else if (g_file_test(name, G_FILE_TEST_IS_REGULAR)) - { - /* Regular files are copied. */ - - char *new_name; - FILE *new_file; - - if (!(fp = g_fopen(name, "rb"))) - { - purple_debug_error("core", "Error opening file %s for reading: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - name, g_strerror(errno)); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - new_name = g_build_filename(user_dir, entry, NULL); - if (!(new_file = g_fopen(new_name, "wb"))) - { - purple_debug_error("core", "Error opening file %s for writing: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - new_name, g_strerror(errno)); - fclose(fp); - g_free(new_name); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - while (!feof(fp)) - { - unsigned char buf[256]; - size_t size; - - size = fread(buf, 1, sizeof(buf), fp); - if (size != sizeof(buf) && !feof(fp)) - { - purple_debug_error("core", "Error reading %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - name, g_strerror(errno)); - fclose(new_file); - fclose(fp); - g_free(new_name); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - - if (!fwrite(buf, size, 1, new_file) && ferror(new_file) != 0) - { - purple_debug_error("core", "Error writing %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - new_name, g_strerror(errno)); - fclose(new_file); - fclose(fp); - g_free(new_name); - g_free(name); - g_dir_close(dir); - g_free(status_file); - g_free(old_user_dir); - return FALSE; - } - } - - if (fclose(new_file)) - { - purple_debug_error("core", "Error writing: %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - new_name, g_strerror(errno)); - } - if (fclose(fp)) - { - purple_debug_warning("core", "Error closing %s: %s\n", - name, g_strerror(errno)); - } - g_free(new_name); - } - else - purple_debug_warning("core", "Not a regular file or directory: %s\n", name); - - g_free(name); - } - - /* The migration was successful, so delete the status file. */ - if (g_unlink(status_file)) - { - purple_debug_error("core", "Error unlinking file %s: %s. Please report this at " PURPLE_DEVEL_WEBSITE "\n", - status_file, g_strerror(errno)); - g_free(status_file); - return FALSE; - } - - old_icons_dir = g_build_filename(old_user_dir, "icons", NULL); - _purple_buddy_icon_set_old_icons_dir(old_icons_dir); - g_free(old_icons_dir); - - g_free(old_user_dir); - - g_free(status_file); - return TRUE; -} - GHashTable* purple_core_get_ui_info() { PurpleCoreUiOps *ops = purple_core_get_ui_ops(); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/core.h --- a/libpurple/core.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/core.h Mon Aug 22 16:00:57 2011 +0000 @@ -156,17 +156,6 @@ PurpleCoreUiOps *purple_core_get_ui_ops(void); /** - * Migrates from .gaim to .purple. - * - * UIs must not call this if they have been told to use a - * custom user directory. - * - * @return A boolean indicating success or migration failure. On failure, - * the application must display an error to the user and then exit. - */ -gboolean purple_core_migrate(void); - -/** * Ensures that only one instance is running. If libpurple is built with D-Bus * support, this checks if another process owns the libpurple bus name and if * so whether that process is using the same configuration directory as this diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/dnssrv.c --- a/libpurple/dnssrv.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/dnssrv.c Mon Aug 22 16:00:57 2011 +0000 @@ -798,6 +798,12 @@ return NULL; } + /* + * TODO: We should put a cap on the number of forked processes that we + * allow at any given time. If we get too many requests they + * should be put into a queue and handled later. (This is what + * we do for A record lookups.) + */ pid = fork(); if (pid == -1) { purple_debug_error("dnssrv", "Could not create process!\n"); @@ -929,6 +935,12 @@ return NULL; } + /* + * TODO: We should put a cap on the number of forked processes that we + * allow at any given time. If we get too many requests they + * should be put into a queue and handled later. (This is what + * we do for A record lookups.) + */ pid = fork(); if (pid == -1) { purple_debug_error("dnssrv", "Could not create process!\n"); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/dnssrv.h --- a/libpurple/dnssrv.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/dnssrv.h Mon Aug 22 16:00:57 2011 +0000 @@ -32,10 +32,6 @@ typedef struct _PurpleSrvResponse PurpleSrvResponse; typedef struct _PurpleTxtResponse PurpleTxtResponse; -/* For compatibility, should be removed for 3.0.0 - */ -typedef struct _PurpleSrvTxtQueryData PurpleSrvQueryData; - #include enum PurpleDnsType { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/gaim-compat.h --- a/libpurple/gaim-compat.h Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2317 +0,0 @@ -/** - * @file gaim-compat.h Gaim Compat macros - * @ingroup core - */ - -/* pidgin - * - * Pidgin is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * 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 - */ -#ifndef _GAIM_COMPAT_H_ -#define _GAIM_COMPAT_H_ - -#include - -/* from account.h */ -#define GaimAccountUiOps PurpleAccountUiOps -#define GaimAccount PurpleAccount - -#define GaimFilterAccountFunc PurpleFilterAccountFunc -#define GaimAccountRequestAuthorizationCb PurpleAccountRequestAuthorizationCb - -#define gaim_account_new purple_account_new -#define gaim_account_destroy purple_account_destroy -#define gaim_account_connect purple_account_connect -#define gaim_account_register purple_account_register -#define gaim_account_disconnect purple_account_disconnect -#define gaim_account_notify_added purple_account_notify_added -#define gaim_account_request_add purple_account_request_add -#define gaim_account_request_close purple_account_request_close - -#define gaim_account_request_authorization purple_account_request_authorization -#define gaim_account_request_change_password purple_account_request_change_password -#define gaim_account_request_change_user_info purple_account_request_change_user_info - -#define gaim_account_set_username purple_account_set_username -#define gaim_account_set_password purple_account_set_password -#define gaim_account_set_alias purple_account_set_alias -#define gaim_account_set_user_info purple_account_set_user_info -#define gaim_account_set_buddy_icon_path purple_account_set_buddy_icon_path -#define gaim_account_set_protocol_id purple_account_set_protocol_id -#define gaim_account_set_connection purple_account_set_connection -#define gaim_account_set_remember_password purple_account_set_remember_password -#define gaim_account_set_check_mail purple_account_set_check_mail -#define gaim_account_set_enabled purple_account_set_enabled -#define gaim_account_set_proxy_info purple_account_set_proxy_info -#define gaim_account_set_status_types purple_account_set_status_types -#define gaim_account_set_status purple_account_set_status -#define gaim_account_set_status_list purple_account_set_status_list - -#define gaim_account_clear_settings purple_account_clear_settings - -#define gaim_account_set_int purple_account_set_int -#define gaim_account_set_string purple_account_set_string -#define gaim_account_set_bool purple_account_set_bool - -#define gaim_account_set_ui_int purple_account_set_ui_int -#define gaim_account_set_ui_string purple_account_set_ui_string -#define gaim_account_set_ui_bool purple_account_set_ui_bool - -#define gaim_account_is_connected purple_account_is_connected -#define gaim_account_is_connecting purple_account_is_connecting -#define gaim_account_is_disconnected purple_account_is_disconnected - -#define gaim_account_get_username purple_account_get_username -#define gaim_account_get_password purple_account_get_password -#define gaim_account_get_alias purple_account_get_alias -#define gaim_account_get_user_info purple_account_get_user_info -#define gaim_account_get_buddy_icon_path purple_account_get_buddy_icon_path -#define gaim_account_get_protocol_id purple_account_get_protocol_id -#define gaim_account_get_protocol_name purple_account_get_protocol_name -#define gaim_account_get_connection purple_account_get_connection -#define gaim_account_get_remember_password purple_account_get_remember_password -#define gaim_account_get_check_mail purple_account_get_check_mail -#define gaim_account_get_enabled purple_account_get_enabled -#define gaim_account_get_proxy_info purple_account_get_proxy_info -#define gaim_account_get_active_status purple_account_get_active_status -#define gaim_account_get_status purple_account_get_status -#define gaim_account_get_status_type purple_account_get_status_type -#define gaim_account_get_status_type_with_primitive \ - purple_account_get_status_type_with_primitive - -#define gaim_account_get_presence purple_account_get_presence -#define gaim_account_is_status_active purple_account_is_status_active -#define gaim_account_get_status_types purple_account_get_status_types - -#define gaim_account_get_int purple_account_get_int -#define gaim_account_get_string purple_account_get_string -#define gaim_account_get_bool purple_account_get_bool - -#define gaim_account_get_ui_int purple_account_get_ui_int -#define gaim_account_get_ui_string purple_account_get_ui_string -#define gaim_account_get_ui_bool purple_account_get_ui_bool - - -#define gaim_account_get_log purple_account_get_log -#define gaim_account_destroy_log purple_account_destroy_log - -#define gaim_account_add_buddy purple_account_add_buddy -#define gaim_account_add_buddies purple_account_add_buddies -#define gaim_account_remove_buddy purple_account_remove_buddy -#define gaim_account_remove_buddies purple_account_remove_buddies - -#define gaim_account_remove_group purple_account_remove_group - -#define gaim_account_change_password purple_account_change_password - -#define gaim_account_supports_offline_message purple_account_supports_offline_message - -#define gaim_accounts_add purple_accounts_add -#define gaim_accounts_remove purple_accounts_remove -#define gaim_accounts_delete purple_accounts_delete -#define gaim_accounts_reorder purple_accounts_reorder - -#define gaim_accounts_get_all purple_accounts_get_all -#define gaim_accounts_get_all_active purple_accounts_get_all_active - -#define gaim_accounts_find purple_accounts_find - -#define gaim_accounts_restore_current_statuses purple_accounts_restore_current_statuses - -#define gaim_accounts_set_ui_ops purple_accounts_set_ui_ops -#define gaim_accounts_get_ui_ops purple_accounts_get_ui_ops - -#define gaim_accounts_get_handle purple_accounts_get_handle - -#define gaim_accounts_init purple_accounts_init -#define gaim_accounts_uninit purple_accounts_uninit - -/* from accountopt.h */ - -#define GaimAccountOption PurpleAccountOption -#define GaimAccountUserSplit PurpleAccountUserSplit - -#define gaim_account_option_new purple_account_option_new -#define gaim_account_option_bool_new purple_account_option_bool_new -#define gaim_account_option_int_new purple_account_option_int_new -#define gaim_account_option_string_new purple_account_option_string_new -#define gaim_account_option_list_new purple_account_option_list_new - -#define gaim_account_option_destroy purple_account_option_destroy - -#define gaim_account_option_set_default_bool purple_account_option_set_default_bool -#define gaim_account_option_set_default_int purple_account_option_set_default_int -#define gaim_account_option_set_default_string purple_account_option_set_default_string - -#define gaim_account_option_set_masked purple_account_option_set_masked - -#define gaim_account_option_set_list purple_account_option_set_list - -#define gaim_account_option_add_list_item purple_account_option_add_list_item - -#define gaim_account_option_get_type purple_account_option_get_type -#define gaim_account_option_get_text purple_account_option_get_text -#define gaim_account_option_get_setting purple_account_option_get_setting - -#define gaim_account_option_get_default_bool purple_account_option_get_default_bool -#define gaim_account_option_get_default_int purple_account_option_get_default_int -#define gaim_account_option_get_default_string purple_account_option_get_default_string -#define gaim_account_option_get_default_list_value purple_account_option_get_default_list_value - -#define gaim_account_option_get_masked purple_account_option_get_masked -#define gaim_account_option_get_list purple_account_option_get_list - -#define gaim_account_user_split_new purple_account_user_split_new -#define gaim_account_user_split_destroy purple_account_user_split_destroy - -#define gaim_account_user_split_get_text purple_account_user_split_get_text -#define gaim_account_user_split_get_default_value purple_account_user_split_get_default_value -#define gaim_account_user_split_get_separator purple_account_user_split_get_separator - -/* from blist.h */ - -#define GaimBuddyList PurpleBuddyList -#define GaimBlistUiOps PurpleBlistUiOps -#define GaimBlistNode PurpleBlistNode - -#define GaimChat PurpleChat -#define GaimGroup PurpleGroup -#define GaimContact PurpleContact -#define GaimBuddy PurpleBuddy - -#define GAIM_BLIST_GROUP_NODE PURPLE_BLIST_GROUP_NODE -#define GAIM_BLIST_CONTACT_NODE PURPLE_BLIST_CONTACT_NODE -#define GAIM_BLIST_BUDDY_NODE PURPLE_BLIST_BUDDY_NODE -#define GAIM_BLIST_CHAT_NODE PURPLE_BLIST_CHAT_NODE -#define GAIM_BLIST_OTHER_NODE PURPLE_BLIST_OTHER_NODE -#define GaimBlistNodeType PurpleBlistNodeType - -#define GAIM_BLIST_NODE_IS_CHAT PURPLE_BLIST_NODE_IS_CHAT -#define GAIM_BLIST_NODE_IS_BUDDY PURPLE_BLIST_NODE_IS_BUDDY -#define GAIM_BLIST_NODE_IS_CONTACT PURPLE_BLIST_NODE_IS_CONTACT -#define GAIM_BLIST_NODE_IS_GROUP PURPLE_BLIST_NODE_IS_GROUP - -#define GAIM_BUDDY_IS_ONLINE PURPLE_BUDDY_IS_ONLINE - -#define GAIM_BLIST_NODE_FLAG_NO_SAVE PURPLE_BLIST_NODE_FLAG_NO_SAVE -#define GaimBlistNodeFlags PurpleBlistNodeFlags - -#define GAIM_BLIST_NODE_HAS_FLAG PURPLE_BLIST_NODE_HAS_FLAG -#define GAIM_BLIST_NODE_SHOULD_SAVE PURPLE_BLIST_NODE_SHOULD_SAVE - -#define GAIM_BLIST_NODE_NAME PURPLE_BLIST_NODE_NAME - - -#define gaim_blist_new purple_blist_new -#define gaim_set_blist purple_set_blist -#define gaim_get_blist purple_get_blist - -#define gaim_blist_get_root purple_blist_get_root -#define gaim_blist_node_next purple_blist_node_next - -#define gaim_blist_show purple_blist_show - -#define gaim_blist_destroy purple_blist_destroy - -#define gaim_blist_set_visible purple_blist_set_visible - -#define gaim_blist_update_buddy_status purple_blist_update_buddy_status -#define gaim_blist_update_buddy_icon purple_blist_update_buddy_icon - - -#define gaim_blist_alias_contact purple_blist_alias_contact -#define gaim_blist_alias_buddy purple_blist_alias_buddy -#define gaim_blist_server_alias_buddy purple_blist_server_alias_buddy -#define gaim_blist_alias_chat purple_blist_alias_chat - -#define gaim_blist_rename_buddy purple_blist_rename_buddy -#define gaim_blist_rename_group purple_blist_rename_group - -#define gaim_chat_new purple_chat_new -#define gaim_blist_add_chat purple_blist_add_chat - -#define gaim_buddy_new purple_buddy_new -#define gaim_buddy_set_icon purple_buddy_set_icon -#define gaim_buddy_get_account purple_buddy_get_account -#define gaim_buddy_get_name purple_buddy_get_name -#define gaim_buddy_get_icon purple_buddy_get_icon -#define gaim_buddy_get_contact purple_buddy_get_contact -#define gaim_buddy_get_presence purple_buddy_get_presence - -#define gaim_blist_add_buddy purple_blist_add_buddy - -#define gaim_group_new purple_group_new - -#define gaim_blist_add_group purple_blist_add_group - -#define gaim_contact_new purple_contact_new - -#define gaim_blist_add_contact purple_blist_add_contact -#define gaim_blist_merge_contact purple_blist_merge_contact - -#define gaim_contact_get_priority_buddy purple_contact_get_priority_buddy -#define gaim_contact_set_alias purple_contact_set_alias -#define gaim_contact_get_alias purple_contact_get_alias -#define gaim_contact_on_account purple_contact_on_account - -#define gaim_contact_invalidate_priority_buddy purple_contact_invalidate_priority_buddy - -#define gaim_blist_remove_buddy purple_blist_remove_buddy -#define gaim_blist_remove_contact purple_blist_remove_contact -#define gaim_blist_remove_chat purple_blist_remove_chat -#define gaim_blist_remove_group purple_blist_remove_group - -#define gaim_buddy_get_alias_only purple_buddy_get_alias_only -#define gaim_buddy_get_server_alias purple_buddy_get_server_alias -#define gaim_buddy_get_contact_alias purple_buddy_get_contact_alias -#define gaim_buddy_get_local_alias purple_buddy_get_local_alias -#define gaim_buddy_get_alias purple_buddy_get_alias - -#define gaim_chat_get_name purple_chat_get_name - -#define gaim_find_buddy purple_find_buddy -#define gaim_find_buddy_in_group purple_find_buddy_in_group -#define gaim_find_buddies purple_find_buddies - -#define gaim_find_group purple_find_group - -#define gaim_blist_find_chat purple_blist_find_chat - -#define gaim_chat_get_group purple_chat_get_group -#define gaim_buddy_get_group purple_buddy_get_group - -#define gaim_group_get_accounts purple_group_get_accounts -#define gaim_group_on_account purple_group_on_account - -#define gaim_blist_add_account purple_blist_add_account -#define gaim_blist_remove_account purple_blist_remove_account - -#define gaim_blist_get_group_size purple_blist_get_group_size -#define gaim_blist_get_group_online_count purple_blist_get_group_online_count - -#define gaim_blist_load purple_blist_load -#define gaim_blist_schedule_save purple_blist_schedule_save - -#define gaim_blist_request_add_buddy purple_blist_request_add_buddy -#define gaim_blist_request_add_chat purple_blist_request_add_chat -#define gaim_blist_request_add_group purple_blist_request_add_group - -#define gaim_blist_node_set_bool purple_blist_node_set_bool -#define gaim_blist_node_get_bool purple_blist_node_get_bool -#define gaim_blist_node_set_int purple_blist_node_set_int -#define gaim_blist_node_get_int purple_blist_node_get_int -#define gaim_blist_node_set_string purple_blist_node_set_string -#define gaim_blist_node_get_string purple_blist_node_get_string - -#define gaim_blist_node_remove_setting purple_blist_node_remove_setting - -#define gaim_blist_node_set_flags purple_blist_node_set_flags -#define gaim_blist_node_get_flags purple_blist_node_get_flags - -#define gaim_blist_node_get_extended_menu purple_blist_node_get_extended_menu - -#define gaim_blist_set_ui_ops purple_blist_set_ui_ops -#define gaim_blist_get_ui_ops purple_blist_get_ui_ops - -#define gaim_blist_get_handle purple_blist_get_handle - -#define gaim_blist_init purple_blist_init -#define gaim_blist_uninit purple_blist_uninit - - -#define GaimBuddyIcon PurpleBuddyIcon - -#define gaim_buddy_icon_new(account, username, icon_data, icon_len)\ - purple_buddy_icon_new(account, username, g_memdup(icon_data, icon_len), icon_len) -#define gaim_buddy_icon_ref purple_buddy_icon_ref -#define gaim_buddy_icon_unref purple_buddy_icon_unref -#define gaim_buddy_icon_update purple_buddy_icon_update - -#define gaim_buddy_icon_set_data(icon, data, len) \ - purple_buddy_icon_set_data(icon, g_memdup(data, len), len, NULL); - -#define gaim_buddy_icon_get_account purple_buddy_icon_get_account -#define gaim_buddy_icon_get_username purple_buddy_icon_get_username -#define gaim_buddy_icon_get_data purple_buddy_icon_get_data -#define gaim_buddy_icon_get_type purple_buddy_icon_get_extension - -#define gaim_buddy_icons_set_for_user(icon, data, len) \ - purple_buddy_icons_set_for_user(icon, g_memdup(data, len), len, NULL) -#define gaim_buddy_icons_set_caching purple_buddy_icons_set_caching -#define gaim_buddy_icons_is_caching purple_buddy_icons_is_caching -#define gaim_buddy_icons_set_cache_dir purple_buddy_icons_set_cache_dir -#define gaim_buddy_icons_get_cache_dir purple_buddy_icons_get_cache_dir -#define gaim_buddy_icons_get_handle purple_buddy_icons_get_handle - -#define gaim_buddy_icons_init purple_buddy_icons_init -#define gaim_buddy_icons_uninit purple_buddy_icons_uninit - -#define gaim_buddy_icon_get_scale_size purple_buddy_icon_get_scale_size - -/* from cipher.h */ - -#define GAIM_CIPHER PURPLE_CIPHER -#define GAIM_CIPHER_OPS PURPLE_CIPHER_OPS -#define GAIM_CIPHER_CONTEXT PURPLE_CIPHER_CONTEXT - -#define GaimCipher PurpleCipher -#define GaimCipherOps PurpleCipherOps -#define GaimCipherContext PurpleCipherContext - -#define GAIM_CIPHER_CAPS_SET_OPT PURPLE_CIPHER_CAPS_SET_OPT -#define GAIM_CIPHER_CAPS_GET_OPT PURPLE_CIPHER_CAPS_GET_OPT -#define GAIM_CIPHER_CAPS_INIT PURPLE_CIPHER_CAPS_INIT -#define GAIM_CIPHER_CAPS_RESET PURPLE_CIPHER_CAPS_RESET -#define GAIM_CIPHER_CAPS_UNINIT PURPLE_CIPHER_CAPS_UNINIT -#define GAIM_CIPHER_CAPS_SET_IV PURPLE_CIPHER_CAPS_SET_IV -#define GAIM_CIPHER_CAPS_APPEND PURPLE_CIPHER_CAPS_APPEND -#define GAIM_CIPHER_CAPS_DIGEST PURPLE_CIPHER_CAPS_DIGEST -#define GAIM_CIPHER_CAPS_ENCRYPT PURPLE_CIPHER_CAPS_ENCRYPT -#define GAIM_CIPHER_CAPS_DECRYPT PURPLE_CIPHER_CAPS_DECRYPT -#define GAIM_CIPHER_CAPS_SET_SALT PURPLE_CIPHER_CAPS_SET_SALT -#define GAIM_CIPHER_CAPS_GET_SALT_SIZE PURPLE_CIPHER_CAPS_GET_SALT_SIZE -#define GAIM_CIPHER_CAPS_SET_KEY PURPLE_CIPHER_CAPS_SET_KEY -#define GAIM_CIPHER_CAPS_GET_KEY_SIZE PURPLE_CIPHER_CAPS_GET_KEY_SIZE -#define GAIM_CIPHER_CAPS_UNKNOWN PURPLE_CIPHER_CAPS_UNKNOWN - -#define gaim_cipher_get_name purple_cipher_get_name -#define gaim_cipher_get_capabilities purple_cipher_get_capabilities -#define gaim_cipher_digest_region purple_cipher_digest_region - -#define gaim_ciphers_find_cipher purple_ciphers_find_cipher -#define gaim_ciphers_register_cipher purple_ciphers_register_cipher -#define gaim_ciphers_unregister_cipher purple_ciphers_unregister_cipher -#define gaim_ciphers_get_ciphers purple_ciphers_get_ciphers - -#define gaim_ciphers_get_handle purple_ciphers_get_handle -#define gaim_ciphers_init purple_ciphers_init -#define gaim_ciphers_uninit purple_ciphers_uninit - -#define gaim_cipher_context_set_option purple_cipher_context_set_option -#define gaim_cipher_context_get_option purple_cipher_context_get_option - -#define gaim_cipher_context_new purple_cipher_context_new -#define gaim_cipher_context_new_by_name purple_cipher_context_new_by_name -#define gaim_cipher_context_reset purple_cipher_context_reset -#define gaim_cipher_context_destroy purple_cipher_context_destroy -#define gaim_cipher_context_set_iv purple_cipher_context_set_iv -#define gaim_cipher_context_append purple_cipher_context_append -#define gaim_cipher_context_digest purple_cipher_context_digest -#define gaim_cipher_context_digest_to_str purple_cipher_context_digest_to_str -#define gaim_cipher_context_encrypt purple_cipher_context_encrypt -#define gaim_cipher_context_decrypt purple_cipher_context_decrypt -#define gaim_cipher_context_set_salt purple_cipher_context_set_salt -#define gaim_cipher_context_get_salt_size purple_cipher_context_get_salt_size -#define gaim_cipher_context_set_key purple_cipher_context_set_key -#define gaim_cipher_context_get_key_size purple_cipher_context_get_key_size -#define gaim_cipher_context_set_data purple_cipher_context_set_data -#define gaim_cipher_context_get_data purple_cipher_context_get_data - -#define gaim_cipher_http_digest_calculate_session_key \ - purple_cipher_http_digest_calculate_session_key - -#define gaim_cipher_http_digest_calculate_response \ - purple_cipher_http_digest_calculate_response - -/* from circbuffer.h */ - -#define GaimCircBuffer PurpleCircBuffer - -#define gaim_circ_buffer_new purple_circ_buffer_new -#define gaim_circ_buffer_destroy purple_circ_buffer_destroy -#define gaim_circ_buffer_append purple_circ_buffer_append -#define gaim_circ_buffer_get_max_read purple_circ_buffer_get_max_read -#define gaim_circ_buffer_mark_read purple_circ_buffer_mark_read - -/* from cmds.h */ - -#define GaimCmdPriority PurpleCmdPriority -#define GaimCmdFlag PurpleCmdFlag -#define GaimCmdStatus PurpleCmdStatus -#define GaimCmdRet PurpleCmdRet - -#define GAIM_CMD_STATUS_OK PURPLE_CMD_STATUS_OK -#define GAIM_CMD_STATUS_FAILED PURPLE_CMD_STATUS_FAILED -#define GAIM_CMD_STATUS_NOT_FOUND PURPLE_CMD_STATUS_NOT_FOUND -#define GAIM_CMD_STATUS_WRONG_ARGS PURPLE_CMD_STATUS_WRONG_ARGS -#define GAIM_CMD_STATUS_WRONG_PRPL PURPLE_CMD_STATUS_WRONG_PRPL -#define GAIM_CMD_STATUS_WRONG_TYPE PURPLE_CMD_STATUS_WRONG_TYPE - -#define GAIM_CMD_FUNC PURPLE_CMD_FUNC - -#define GAIM_CMD_RET_OK PURPLE_CMD_RET_OK -#define GAIM_CMD_RET_FAILED PURPLE_CMD_RET_FAILED -#define GAIM_CMD_RET_CONTINUE PURPLE_CMD_RET_CONTINUE - -#define GAIM_CMD_P_VERY_LOW PURPLE_CMD_P_VERY_LOW -#define GAIM_CMD_P_LOW PURPLE_CMD_P_LOW -#define GAIM_CMD_P_DEFAULT PURPLE_CMD_P_DEFAULT -#define GAIM_CMD_P_PRPL PURPLE_CMD_P_PRPL -#define GAIM_CMD_P_PLUGIN PURPLE_CMD_P_PLUGIN -#define GAIM_CMD_P_ALIAS PURPLE_CMD_P_ALIAS -#define GAIM_CMD_P_HIGH PURPLE_CMD_P_HIGH -#define GAIM_CMD_P_VERY_HIGH PURPLE_CMD_P_VERY_HIGH - -#define GAIM_CMD_FLAG_IM PURPLE_CMD_FLAG_IM -#define GAIM_CMD_FLAG_CHAT PURPLE_CMD_FLAG_CHAT -#define GAIM_CMD_FLAG_PRPL_ONLY PURPLE_CMD_FLAG_PRPL_ONLY -#define GAIM_CMD_FLAG_ALLOW_WRONG_ARGS PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS - - -#define GaimCmdFunc PurpleCmdFunc - -#define GaimCmdId PurpleCmdId - -#define gaim_cmd_register purple_cmd_register -#define gaim_cmd_unregister purple_cmd_unregister -#define gaim_cmd_do_command purple_cmd_do_command -#define gaim_cmd_list purple_cmd_list -#define gaim_cmd_help purple_cmd_help - -/* from connection.h */ - -#define GaimConnection PurpleConnection - -#define GAIM_CONNECTION_HTML PURPLE_CONNECTION_HTML -#define GAIM_CONNECTION_NO_BGCOLOR PURPLE_CONNECTION_NO_BGCOLOR -#define GAIM_CONNECTION_AUTO_RESP PURPLE_CONNECTION_AUTO_RESP -#define GAIM_CONNECTION_FORMATTING_WBFO PURPLE_CONNECTION_FORMATTING_WBFO -#define GAIM_CONNECTION_NO_NEWLINES PURPLE_CONNECTION_NO_NEWLINES -#define GAIM_CONNECTION_NO_FONTSIZE PURPLE_CONNECTION_NO_FONTSIZE -#define GAIM_CONNECTION_NO_URLDESC PURPLE_CONNECTION_NO_URLDESC -#define GAIM_CONNECTION_NO_IMAGES PURPLE_CONNECTION_NO_IMAGES - -#define GaimConnectionFlags PurpleConnectionFlags - -#define GAIM_DISCONNECTED PURPLE_DISCONNECTED -#define GAIM_CONNECTED PURPLE_CONNECTED -#define GAIM_CONNECTING PURPLE_CONNECTING - -#define GaimConnectionState PurpleConnectionState - -#define GaimConnectionUiOps PurpleConnectionUiOps - -#define gaim_connection_new purple_connection_new -#define gaim_connection_destroy purple_connection_destroy - -#define gaim_connection_set_state purple_connection_set_state -#define gaim_connection_set_account purple_connection_set_account -#define gaim_connection_set_display_name purple_connection_set_display_name -#define gaim_connection_get_state purple_connection_get_state - -#define GAIM_CONNECTION_IS_CONNECTED PURPLE_CONNECTION_IS_CONNECTED - -#define gaim_connection_get_account purple_connection_get_account -#define gaim_connection_get_password purple_connection_get_password -#define gaim_connection_get_display_name purple_connection_get_display_name - -#define gaim_connection_update_progress purple_connection_update_progress - -#define gaim_connection_notice purple_connection_notice -#define gaim_connection_error purple_connection_error - -#define gaim_connections_disconnect_all purple_connections_disconnect_all - -#define gaim_connections_get_all purple_connections_get_all -#define gaim_connections_get_connecting purple_connections_get_connecting - -#define GAIM_CONNECTION_IS_VALID PURPLE_CONNECTION_IS_VALID - -#define gaim_connections_set_ui_ops purple_connections_set_ui_ops -#define gaim_connections_get_ui_ops purple_connections_get_ui_ops - -#define gaim_connections_init purple_connections_init -#define gaim_connections_uninit purple_connections_uninit -#define gaim_connections_get_handle purple_connections_get_handle - - -/* from conversation.h */ - -#define GaimConversationUiOps PurpleConversationUiOps -#define GaimConversation PurpleConversation -#define GaimConvIm PurpleConvIm -#define GaimConvChat PurpleConvChat -#define GaimConvChatBuddy PurpleConvChatBuddy - -#define GAIM_CONV_TYPE_UNKNOWN PURPLE_CONV_TYPE_UNKNOWN -#define GAIM_CONV_TYPE_IM PURPLE_CONV_TYPE_IM -#define GAIM_CONV_TYPE_CHAT PURPLE_CONV_TYPE_CHAT -#define GAIM_CONV_TYPE_MISC PURPLE_CONV_TYPE_MISC -#define GAIM_CONV_TYPE_ANY PURPLE_CONV_TYPE_ANY - -#define GaimConversationType PurpleConversationType - -#define GAIM_CONV_UPDATE_ADD PURPLE_CONV_UPDATE_ADD -#define GAIM_CONV_UPDATE_REMOVE PURPLE_CONV_UPDATE_REMOVE -#define GAIM_CONV_UPDATE_ACCOUNT PURPLE_CONV_UPDATE_ACCOUNT -#define GAIM_CONV_UPDATE_TYPING PURPLE_CONV_UPDATE_TYPING -#define GAIM_CONV_UPDATE_UNSEEN PURPLE_CONV_UPDATE_UNSEEN -#define GAIM_CONV_UPDATE_LOGGING PURPLE_CONV_UPDATE_LOGGING -#define GAIM_CONV_UPDATE_TOPIC PURPLE_CONV_UPDATE_TOPIC -#define GAIM_CONV_ACCOUNT_ONLINE PURPLE_CONV_ACCOUNT_ONLINE -#define GAIM_CONV_ACCOUNT_OFFLINE PURPLE_CONV_ACCOUNT_OFFLINE -#define GAIM_CONV_UPDATE_AWAY PURPLE_CONV_UPDATE_AWAY -#define GAIM_CONV_UPDATE_ICON PURPLE_CONV_UPDATE_ICON -#define GAIM_CONV_UPDATE_TITLE PURPLE_CONV_UPDATE_TITLE -#define GAIM_CONV_UPDATE_CHATLEFT PURPLE_CONV_UPDATE_CHATLEFT -#define GAIM_CONV_UPDATE_FEATURES PURPLE_CONV_UPDATE_FEATURES - -#define GaimConvUpdateType PurpleConvUpdateType - -#define GAIM_NOT_TYPING PURPLE_NOT_TYPING -#define GAIM_TYPING PURPLE_TYPING -#define GAIM_TYPED PURPLE_TYPED - -#define GaimTypingState PurpleTypingState - -#define GAIM_MESSAGE_SEND PURPLE_MESSAGE_SEND -#define GAIM_MESSAGE_RECV PURPLE_MESSAGE_RECV -#define GAIM_MESSAGE_SYSTEM PURPLE_MESSAGE_SYSTEM -#define GAIM_MESSAGE_AUTO_RESP PURPLE_MESSAGE_AUTO_RESP -#define GAIM_MESSAGE_ACTIVE_ONLY PURPLE_MESSAGE_ACTIVE_ONLY -#define GAIM_MESSAGE_NICK PURPLE_MESSAGE_NICK -#define GAIM_MESSAGE_NO_LOG PURPLE_MESSAGE_NO_LOG -#define GAIM_MESSAGE_WHISPER PURPLE_MESSAGE_WHISPER -#define GAIM_MESSAGE_ERROR PURPLE_MESSAGE_ERROR -#define GAIM_MESSAGE_DELAYED PURPLE_MESSAGE_DELAYED -#define GAIM_MESSAGE_RAW PURPLE_MESSAGE_RAW -#define GAIM_MESSAGE_IMAGES PURPLE_MESSAGE_IMAGES - -#define GaimMessageFlags PurpleMessageFlags - -#define GAIM_CBFLAGS_NONE PURPLE_CBFLAGS_NONE -#define GAIM_CBFLAGS_VOICE PURPLE_CBFLAGS_VOICE -#define GAIM_CBFLAGS_HALFOP PURPLE_CBFLAGS_HALFOP -#define GAIM_CBFLAGS_OP PURPLE_CBFLAGS_OP -#define GAIM_CBFLAGS_FOUNDER PURPLE_CBFLAGS_FOUNDER -#define GAIM_CBFLAGS_TYPING PURPLE_CBFLAGS_TYPING - -#define GaimConvChatBuddyFlags PurpleConvChatBuddyFlags - -#define gaim_conversations_set_ui_ops purple_conversations_set_ui_ops - -#define gaim_conversation_new purple_conversation_new -#define gaim_conversation_destroy purple_conversation_destroy -#define gaim_conversation_present purple_conversation_present -#define gaim_conversation_get_type purple_conversation_get_type -#define gaim_conversation_set_ui_ops purple_conversation_set_ui_ops -#define gaim_conversation_get_ui_ops purple_conversation_get_ui_ops -#define gaim_conversation_set_account purple_conversation_set_account -#define gaim_conversation_get_account purple_conversation_get_account -#define gaim_conversation_get_gc purple_conversation_get_gc -#define gaim_conversation_set_title purple_conversation_set_title -#define gaim_conversation_get_title purple_conversation_get_title -#define gaim_conversation_autoset_title purple_conversation_autoset_title -#define gaim_conversation_set_name purple_conversation_set_name -#define gaim_conversation_get_name purple_conversation_get_name -#define gaim_conversation_set_logging purple_conversation_set_logging -#define gaim_conversation_is_logging purple_conversation_is_logging -#define gaim_conversation_close_logs purple_conversation_close_logs -#define gaim_conversation_get_im_data purple_conversation_get_im_data - -#define GAIM_CONV_IM PURPLE_CONV_IM - -#define gaim_conversation_get_chat_data purple_conversation_get_chat_data - -#define GAIM_CONV_CHAT PURPLE_CONV_CHAT - -#define gaim_conversation_set_data purple_conversation_set_data -#define gaim_conversation_get_data purple_conversation_get_data - -#define gaim_get_conversations purple_get_conversations -#define gaim_get_ims purple_get_ims -#define gaim_get_chats purple_get_chats - -#define gaim_find_conversation_with_account \ - purple_find_conversation_with_account - -#define gaim_conversation_write purple_conversation_write -#define gaim_conversation_set_features purple_conversation_set_features -#define gaim_conversation_get_features purple_conversation_get_features -#define gaim_conversation_has_focus purple_conversation_has_focus -#define gaim_conversation_update purple_conversation_update -#define gaim_conversation_foreach purple_conversation_foreach - -#define gaim_conv_im_get_conversation purple_conv_im_get_conversation -#define gaim_conv_im_set_icon purple_conv_im_set_icon -#define gaim_conv_im_get_icon purple_conv_im_get_icon -#define gaim_conv_im_set_typing_state purple_conv_im_set_typing_state -#define gaim_conv_im_get_typing_state purple_conv_im_get_typing_state - -#define gaim_conv_im_start_typing_timeout purple_conv_im_start_typing_timeout -#define gaim_conv_im_stop_typing_timeout purple_conv_im_stop_typing_timeout -#define gaim_conv_im_get_typing_timeout purple_conv_im_get_typing_timeout -#define gaim_conv_im_set_type_again purple_conv_im_set_type_again -#define gaim_conv_im_get_type_again purple_conv_im_get_type_again - -#define gaim_conv_im_start_send_typed_timeout \ - purple_conv_im_start_send_typed_timeout - -#define gaim_conv_im_stop_send_typed_timeout \ - purple_conv_im_stop_send_typed_timeout - -#define gaim_conv_im_get_send_typed_timeout \ - purple_conv_im_get_send_typed_timeout - -#define gaim_conv_present_error purple_conv_present_error -#define gaim_conv_send_confirm purple_conv_send_confirm - -#define gaim_conv_im_update_typing purple_conv_im_update_typing -#define gaim_conv_im_write purple_conv_im_write -#define gaim_conv_im_send purple_conv_im_send -#define gaim_conv_im_send_with_flags purple_conv_im_send_with_flags - -#define gaim_conv_custom_smiley_add purple_conv_custom_smiley_add -#define gaim_conv_custom_smiley_write purple_conv_custom_smiley_write -#define gaim_conv_custom_smiley_close purple_conv_custom_smiley_close - -#define gaim_conv_chat_get_conversation purple_conv_chat_get_conversation -#define gaim_conv_chat_set_users purple_conv_chat_set_users -#define gaim_conv_chat_get_users purple_conv_chat_get_users -#define gaim_conv_chat_ignore purple_conv_chat_ignore -#define gaim_conv_chat_unignore purple_conv_chat_unignore -#define gaim_conv_chat_set_ignored purple_conv_chat_set_ignored -#define gaim_conv_chat_get_ignored purple_conv_chat_get_ignored -#define gaim_conv_chat_get_ignored_user purple_conv_chat_get_ignored_user -#define gaim_conv_chat_is_user_ignored purple_conv_chat_is_user_ignored -#define gaim_conv_chat_set_topic purple_conv_chat_set_topic -#define gaim_conv_chat_get_topic purple_conv_chat_get_topic -#define gaim_conv_chat_set_id purple_conv_chat_set_id -#define gaim_conv_chat_get_id purple_conv_chat_get_id -#define gaim_conv_chat_write purple_conv_chat_write -#define gaim_conv_chat_send purple_conv_chat_send -#define gaim_conv_chat_send_with_flags purple_conv_chat_send_with_flags -#define gaim_conv_chat_add_user purple_conv_chat_add_user -#define gaim_conv_chat_add_users purple_conv_chat_add_users -#define gaim_conv_chat_rename_user purple_conv_chat_rename_user -#define gaim_conv_chat_remove_user purple_conv_chat_remove_user -#define gaim_conv_chat_remove_users purple_conv_chat_remove_users -#define gaim_conv_chat_find_user purple_conv_chat_find_user -#define gaim_conv_chat_user_set_flags purple_conv_chat_user_set_flags -#define gaim_conv_chat_user_get_flags purple_conv_chat_user_get_flags -#define gaim_conv_chat_clear_users purple_conv_chat_clear_users -#define gaim_conv_chat_set_nick purple_conv_chat_set_nick -#define gaim_conv_chat_get_nick purple_conv_chat_get_nick -#define gaim_conv_chat_left purple_conv_chat_left -#define gaim_conv_chat_has_left purple_conv_chat_has_left - -#define gaim_find_chat purple_find_chat - -#define gaim_conv_chat_cb_new purple_conv_chat_cb_new -#define gaim_conv_chat_cb_find purple_conv_chat_cb_find -#define gaim_conv_chat_cb_get_name purple_conv_chat_cb_get_name -#define gaim_conv_chat_cb_destroy purple_conv_chat_cb_destroy - -#define gaim_conversations_get_handle purple_conversations_get_handle -#define gaim_conversations_init purple_conversations_init -#define gaim_conversations_uninit purple_conversations_uninit - -/* from core.h */ - -#define GaimCore PurpleCore - -#define GaimCoreUiOps PurpleCoreUiOps - -#define gaim_core_init purple_core_init -#define gaim_core_quit purple_core_quit - -#define gaim_core_quit_cb purple_core_quit_cb -#define gaim_core_get_version purple_core_get_version -#define gaim_core_get_ui purple_core_get_ui -#define gaim_get_core purple_get_core -#define gaim_core_set_ui_ops purple_core_set_ui_ops -#define gaim_core_get_ui_ops purple_core_get_ui_ops - -/* from debug.h */ - -#define GAIM_DEBUG_ALL PURPLE_DEBUG_ALL -#define GAIM_DEBUG_MISC PURPLE_DEBUG_MISC -#define GAIM_DEBUG_INFO PURPLE_DEBUG_INFO -#define GAIM_DEBUG_WARNING PURPLE_DEBUG_WARNING -#define GAIM_DEBUG_ERROR PURPLE_DEBUG_ERROR -#define GAIM_DEBUG_FATAL PURPLE_DEBUG_FATAL - -#define GaimDebugLevel PurpleDebugLevel - -#define GaimDebugUiOps PurpleDebugUiOps - - -#define gaim_debug purple_debug -#define gaim_debug_misc purple_debug_misc -#define gaim_debug_info purple_debug_info -#define gaim_debug_warning purple_debug_warning -#define gaim_debug_error purple_debug_error -#define gaim_debug_fatal purple_debug_fatal - -#define gaim_debug_set_enabled purple_debug_set_enabled -#define gaim_debug_is_enabled purple_debug_is_enabled - -#define gaim_debug_set_ui_ops purple_debug_set_ui_ops -#define gaim_debug_get_ui_ops purple_debug_get_ui_ops - -#define gaim_debug_init purple_debug_init - -/* from desktopitem.h */ - -#define GAIM_DESKTOP_ITEM_TYPE_NULL PURPLE_DESKTOP_ITEM_TYPE_NULL -#define GAIM_DESKTOP_ITEM_TYPE_OTHER PURPLE_DESKTOP_ITEM_TYPE_OTHER -#define GAIM_DESKTOP_ITEM_TYPE_APPLICATION PURPLE_DESKTOP_ITEM_TYPE_APPLICATION -#define GAIM_DESKTOP_ITEM_TYPE_LINK PURPLE_DESKTOP_ITEM_TYPE_LINK -#define GAIM_DESKTOP_ITEM_TYPE_FSDEVICE PURPLE_DESKTOP_ITEM_TYPE_FSDEVICE -#define GAIM_DESKTOP_ITEM_TYPE_MIME_TYPE PURPLE_DESKTOP_ITEM_TYPE_MIME_TYPE -#define GAIM_DESKTOP_ITEM_TYPE_DIRECTORY PURPLE_DESKTOP_ITEM_TYPE_DIRECTORY -#define GAIM_DESKTOP_ITEM_TYPE_SERVICE PURPLE_DESKTOP_ITEM_TYPE_SERVICE -#define GAIM_DESKTOP_ITEM_TYPE_SERVICE_TYPE PURPLE_DESKTOP_ITEM_TYPE_SERVICE_TYPE - -#define GaimDesktopItemType PurpleDesktopItemType - -#define GaimDesktopItem PurpleDesktopItem - -#define GAIM_TYPE_DESKTOP_ITEM PURPLE_TYPE_DESKTOP_ITEM -#define gaim_desktop_item_get_type purple_desktop_item_get_type - -/* standard */ -/* ugh, i'm just copying these as strings, rather than pidginifying them */ -#define GAIM_DESKTOP_ITEM_ENCODING "Encoding" /* string */ -#define GAIM_DESKTOP_ITEM_VERSION "Version" /* numeric */ -#define GAIM_DESKTOP_ITEM_NAME "Name" /* localestring */ -#define GAIM_DESKTOP_ITEM_GENERIC_NAME "GenericName" /* localestring */ -#define GAIM_DESKTOP_ITEM_TYPE "Type" /* string */ -#define GAIM_DESKTOP_ITEM_FILE_PATTERN "FilePattern" /* regexp(s) */ -#define GAIM_DESKTOP_ITEM_TRY_EXEC "TryExec" /* string */ -#define GAIM_DESKTOP_ITEM_NO_DISPLAY "NoDisplay" /* boolean */ -#define GAIM_DESKTOP_ITEM_COMMENT "Comment" /* localestring */ -#define GAIM_DESKTOP_ITEM_EXEC "Exec" /* string */ -#define GAIM_DESKTOP_ITEM_ACTIONS "Actions" /* strings */ -#define GAIM_DESKTOP_ITEM_ICON "Icon" /* string */ -#define GAIM_DESKTOP_ITEM_MINI_ICON "MiniIcon" /* string */ -#define GAIM_DESKTOP_ITEM_HIDDEN "Hidden" /* boolean */ -#define GAIM_DESKTOP_ITEM_PATH "Path" /* string */ -#define GAIM_DESKTOP_ITEM_TERMINAL "Terminal" /* boolean */ -#define GAIM_DESKTOP_ITEM_TERMINAL_OPTIONS "TerminalOptions" /* string */ -#define GAIM_DESKTOP_ITEM_SWALLOW_TITLE "SwallowTitle" /* string */ -#define GAIM_DESKTOP_ITEM_SWALLOW_EXEC "SwallowExec" /* string */ -#define GAIM_DESKTOP_ITEM_MIME_TYPE "MimeType" /* regexp(s) */ -#define GAIM_DESKTOP_ITEM_PATTERNS "Patterns" /* regexp(s) */ -#define GAIM_DESKTOP_ITEM_DEFAULT_APP "DefaultApp" /* string */ -#define GAIM_DESKTOP_ITEM_DEV "Dev" /* string */ -#define GAIM_DESKTOP_ITEM_FS_TYPE "FSType" /* string */ -#define GAIM_DESKTOP_ITEM_MOUNT_POINT "MountPoint" /* string */ -#define GAIM_DESKTOP_ITEM_READ_ONLY "ReadOnly" /* boolean */ -#define GAIM_DESKTOP_ITEM_UNMOUNT_ICON "UnmountIcon" /* string */ -#define GAIM_DESKTOP_ITEM_SORT_ORDER "SortOrder" /* strings */ -#define GAIM_DESKTOP_ITEM_URL "URL" /* string */ -#define GAIM_DESKTOP_ITEM_DOC_PATH "X-GNOME-DocPath" /* string */ - -#define gaim_desktop_item_new_from_file purple_desktop_item_new_from_file -#define gaim_desktop_item_get_entry_type purple_desktop_item_get_entry_type -#define gaim_desktop_item_get_string purple_desktop_item_get_string -#define gaim_desktop_item_copy purple_desktop_item_copy -#define gaim_desktop_item_unref purple_desktop_item_unref - -/* from dnsquery.h */ - -#define GaimDnsQueryData PurpleDnsQueryData -#define GaimDnsQueryConnectFunction PurpleDnsQueryConnectFunction - -#define gaim_dnsquery_a purple_dnsquery_a -#define gaim_dnsquery_destroy purple_dnsquery_destroy -#define gaim_dnsquery_init purple_dnsquery_init -#define gaim_dnsquery_uninit purple_dnsquery_uninit -#define gaim_dnsquery_set_ui_ops purple_dnsquery_set_ui_ops -#define gaim_dnsquery_get_host purple_dnsquery_get_host -#define gaim_dnsquery_get_port purple_dnsquery_get_port - -/* from dnssrv.h */ - -#define GaimSrvResponse PurpleSrvResponse -#define GaimSrvQueryData PurpleSrvTxtQueryData -#define GaimSrvCallback PurpleSrvCallback - -#define gaim_srv_resolve purple_srv_resolve -#define gaim_srv_cancel purple_srv_cancel - -/* from eventloop.h */ - -#define GAIM_INPUT_READ PURPLE_INPUT_READ -#define GAIM_INPUT_WRITE PURPLE_INPUT_WRITE - -#define GaimInputCondition PurpleInputCondition -#define GaimInputFunction PurpleInputFunction -#define GaimEventLoopUiOps PurpleEventLoopUiOps - -#define gaim_timeout_add purple_timeout_add -#define gaim_timeout_remove purple_timeout_remove -#define gaim_input_add purple_input_add -#define gaim_input_remove purple_input_remove - -#define gaim_eventloop_set_ui_ops purple_eventloop_set_ui_ops -#define gaim_eventloop_get_ui_ops purple_eventloop_get_ui_ops - -/* from ft.h */ - -#define GaimXfer PurpleXfer - -#define GAIM_XFER_UNKNOWN PURPLE_XFER_UNKNOWN -#define GAIM_XFER_SEND PURPLE_XFER_SEND -#define GAIM_XFER_RECEIVE PURPLE_XFER_RECEIVE - -#define GaimXferType PurpleXferType - -#define GAIM_XFER_STATUS_UNKNOWN PURPLE_XFER_STATUS_UNKNOWN -#define GAIM_XFER_STATUS_NOT_STARTED PURPLE_XFER_STATUS_NOT_STARTED -#define GAIM_XFER_STATUS_ACCEPTED PURPLE_XFER_STATUS_ACCEPTED -#define GAIM_XFER_STATUS_STARTED PURPLE_XFER_STATUS_STARTED -#define GAIM_XFER_STATUS_DONE PURPLE_XFER_STATUS_DONE -#define GAIM_XFER_STATUS_CANCEL_LOCAL PURPLE_XFER_STATUS_CANCEL_LOCAL -#define GAIM_XFER_STATUS_CANCEL_REMOTE PURPLE_XFER_STATUS_CANCEL_REMOTE - -#define GaimXferStatusType PurpleXferStatusType - -#define GaimXferUiOps PurpleXferUiOps - -#define gaim_xfer_new purple_xfer_new -#define gaim_xfer_ref purple_xfer_ref -#define gaim_xfer_unref purple_xfer_unref -#define gaim_xfer_request purple_xfer_request -#define gaim_xfer_request_accepted purple_xfer_request_accepted -#define gaim_xfer_request_denied purple_xfer_request_denied -#define gaim_xfer_get_type purple_xfer_get_type -#define gaim_xfer_get_account purple_xfer_get_account -#define gaim_xfer_get_status purple_xfer_get_status -#define gaim_xfer_is_canceled purple_xfer_is_canceled -#define gaim_xfer_is_completed purple_xfer_is_completed -#define gaim_xfer_get_filename purple_xfer_get_filename -#define gaim_xfer_get_local_filename purple_xfer_get_local_filename -#define gaim_xfer_get_bytes_sent purple_xfer_get_bytes_sent -#define gaim_xfer_get_bytes_remaining purple_xfer_get_bytes_remaining -#define gaim_xfer_get_size purple_xfer_get_size -#define gaim_xfer_get_progress purple_xfer_get_progress -#define gaim_xfer_get_local_port purple_xfer_get_local_port -#define gaim_xfer_get_remote_ip purple_xfer_get_remote_ip -#define gaim_xfer_get_remote_port purple_xfer_get_remote_port -#define gaim_xfer_set_completed purple_xfer_set_completed -#define gaim_xfer_set_message purple_xfer_set_message -#define gaim_xfer_set_filename purple_xfer_set_filename -#define gaim_xfer_set_local_filename purple_xfer_set_local_filename -#define gaim_xfer_set_size purple_xfer_set_size -#define gaim_xfer_set_bytes_sent purple_xfer_set_bytes_sent -#define gaim_xfer_get_ui_ops purple_xfer_get_ui_ops -#define gaim_xfer_set_read_fnc purple_xfer_set_read_fnc -#define gaim_xfer_set_write_fnc purple_xfer_set_write_fnc -#define gaim_xfer_set_ack_fnc purple_xfer_set_ack_fnc -#define gaim_xfer_set_request_denied_fnc purple_xfer_set_request_denied_fnc -#define gaim_xfer_set_init_fnc purple_xfer_set_init_fnc -#define gaim_xfer_set_start_fnc purple_xfer_set_start_fnc -#define gaim_xfer_set_end_fnc purple_xfer_set_end_fnc -#define gaim_xfer_set_cancel_send_fnc purple_xfer_set_cancel_send_fnc -#define gaim_xfer_set_cancel_recv_fnc purple_xfer_set_cancel_recv_fnc - -#define gaim_xfer_read purple_xfer_read -#define gaim_xfer_write purple_xfer_write -#define gaim_xfer_start purple_xfer_start -#define gaim_xfer_end purple_xfer_end -#define gaim_xfer_add purple_xfer_add -#define gaim_xfer_cancel_local purple_xfer_cancel_local -#define gaim_xfer_cancel_remote purple_xfer_cancel_remote -#define gaim_xfer_error purple_xfer_error -#define gaim_xfer_update_progress purple_xfer_update_progress -#define gaim_xfer_conversation_write purple_xfer_conversation_write - -#define gaim_xfers_get_handle purple_xfers_get_handle -#define gaim_xfers_init purple_xfers_init -#define gaim_xfers_uninit purple_xfers_uninit -#define gaim_xfers_set_ui_ops purple_xfers_set_ui_ops -#define gaim_xfers_get_ui_ops purple_xfers_get_ui_ops - -/* from gaim-client.h */ - -#define gaim_init purple_init - -/* from idle.h */ - -#define GaimIdleUiOps PurpleIdleUiOps - -#define gaim_idle_touch purple_idle_touch -#define gaim_idle_set purple_idle_set -#define gaim_idle_set_ui_ops purple_idle_set_ui_ops -#define gaim_idle_get_ui_ops purple_idle_get_ui_ops -#define gaim_idle_init purple_idle_init -#define gaim_idle_uninit purple_idle_uninit - -/* from imgstore.h */ - -#define GaimStoredImage PurpleStoredImage - -#define gaim_imgstore_add(data, size, filename) \ - purple_imgstore_add_with_id(g_memdup(data, size), size, filename) -#define gaim_imgstore_get purple_imgstore_find_by_id -#define gaim_imgstore_get_data purple_imgstore_get_data -#define gaim_imgstore_get_size purple_imgstore_get_size -#define gaim_imgstore_get_filename purple_imgstore_get_filename -#define gaim_imgstore_ref purple_imgstore_ref_by_id -#define gaim_imgstore_unref purple_imgstore_unref_by_id - - -/* from log.h */ - -#define GaimLog PurpleLog -#define GaimLogLogger PurpleLogLogger -#define GaimLogCommonLoggerData PurpleLogCommonLoggerData -#define GaimLogSet PurpleLogSet - -#define GAIM_LOG_IM PURPLE_LOG_IM -#define GAIM_LOG_CHAT PURPLE_LOG_CHAT -#define GAIM_LOG_SYSTEM PURPLE_LOG_SYSTEM - -#define GaimLogType PurpleLogType - -#define GAIM_LOG_READ_NO_NEWLINE PURPLE_LOG_READ_NO_NEWLINE - -#define GaimLogReadFlags PurpleLogReadFlags - -#define GaimLogSetCallback PurpleLogSetCallback - -#define gaim_log_new purple_log_new -#define gaim_log_free purple_log_free -#define gaim_log_write purple_log_write -#define gaim_log_read purple_log_read - -#define gaim_log_get_logs purple_log_get_logs -#define gaim_log_get_log_sets purple_log_get_log_sets -#define gaim_log_get_system_logs purple_log_get_system_logs -#define gaim_log_get_size purple_log_get_size -#define gaim_log_get_total_size purple_log_get_total_size -#define gaim_log_get_log_dir purple_log_get_log_dir -#define gaim_log_compare purple_log_compare -#define gaim_log_set_compare purple_log_set_compare -#define gaim_log_set_free purple_log_set_free - -#define gaim_log_common_writer purple_log_common_writer -#define gaim_log_common_lister purple_log_common_lister -#define gaim_log_common_total_sizer purple_log_common_total_sizer -#define gaim_log_common_sizer purple_log_common_sizer - -#define gaim_log_logger_new purple_log_logger_new -#define gaim_log_logger_free purple_log_logger_free -#define gaim_log_logger_add purple_log_logger_add -#define gaim_log_logger_remove purple_log_logger_remove -#define gaim_log_logger_set purple_log_logger_set -#define gaim_log_logger_get purple_log_logger_get - -#define gaim_log_logger_get_options purple_log_logger_get_options - -#define gaim_log_init purple_log_init -#define gaim_log_get_handle purple_log_get_handle -#define gaim_log_uninit purple_log_uninit - -/* from mime.h */ - -#define GaimMimeDocument PurpleMimeDocument -#define GaimMimePart PurpleMimePart - -#define gaim_mime_document_new purple_mime_document_new -#define gaim_mime_document_free purple_mime_document_free -#define gaim_mime_document_parse purple_mime_document_parse -#define gaim_mime_document_parsen purple_mime_document_parsen -#define gaim_mime_document_write purple_mime_document_write -#define gaim_mime_document_get_fields purple_mime_document_get_fields -#define gaim_mime_document_get_field purple_mime_document_get_field -#define gaim_mime_document_set_field purple_mime_document_set_field -#define gaim_mime_document_get_parts purple_mime_document_get_parts - -#define gaim_mime_part_new purple_mime_part_new -#define gaim_mime_part_get_fields purple_mime_part_get_fields -#define gaim_mime_part_get_field purple_mime_part_get_field -#define gaim_mime_part_get_field_decoded purple_mime_part_get_field_decoded -#define gaim_mime_part_set_field purple_mime_part_set_field -#define gaim_mime_part_get_data purple_mime_part_get_data -#define gaim_mime_part_get_data_decoded purple_mime_part_get_data_decoded -#define gaim_mime_part_get_length purple_mime_part_get_length -#define gaim_mime_part_set_data purple_mime_part_set_data - - -/* from network.h */ - -#define GaimNetworkListenData PurpleNetworkListenData - -#define GaimNetworkListenCallback PurpleNetworkListenCallback - -#define gaim_network_ip_atoi purple_network_ip_atoi -#define gaim_network_set_public_ip purple_network_set_public_ip -#define gaim_network_get_public_ip purple_network_get_public_ip -#define gaim_network_get_local_system_ip purple_network_get_local_system_ip -#define gaim_network_get_my_ip purple_network_get_my_ip - -#define gaim_network_listen purple_network_listen -#define gaim_network_listen_range purple_network_listen_range -#define gaim_network_listen_cancel purple_network_listen_cancel -#define gaim_network_get_port_from_fd purple_network_get_port_from_fd - -#define gaim_network_is_available purple_network_is_available - -#define gaim_network_init purple_network_init -#define gaim_network_uninit purple_network_uninit - -/* from notify.h */ - - -#define GaimNotifyUserInfoEntry PurpleNotifyUserInfoEntry -#define GaimNotifyUserInfo PurpleNotifyUserInfo - -#define GaimNotifyCloseCallback PurpleNotifyCloseCallback - -#define GAIM_NOTIFY_MESSAGE PURPLE_NOTIFY_MESSAGE -#define GAIM_NOTIFY_EMAIL PURPLE_NOTIFY_EMAIL -#define GAIM_NOTIFY_EMAILS PURPLE_NOTIFY_EMAILS -#define GAIM_NOTIFY_FORMATTED PURPLE_NOTIFY_FORMATTED -#define GAIM_NOTIFY_SEARCHRESULTS PURPLE_NOTIFY_SEARCHRESULTS -#define GAIM_NOTIFY_USERINFO PURPLE_NOTIFY_USERINFO -#define GAIM_NOTIFY_URI PURPLE_NOTIFY_URI - -#define GaimNotifyType PurpleNotifyType - -#define GAIM_NOTIFY_MSG_ERROR PURPLE_NOTIFY_MSG_ERROR -#define GAIM_NOTIFY_MSG_WARNING PURPLE_NOTIFY_MSG_WARNING -#define GAIM_NOTIFY_MSG_INFO PURPLE_NOTIFY_MSG_INFO - -#define GaimNotifyMsgType PurpleNotifyMsgType - -#define GAIM_NOTIFY_BUTTON_LABELED PURPLE_NOTIFY_BUTTON_LABELED -#define GAIM_NOTIFY_BUTTON_CONTINUE PURPLE_NOTIFY_BUTTON_CONTINUE -#define GAIM_NOTIFY_BUTTON_ADD PURPLE_NOTIFY_BUTTON_ADD -#define GAIM_NOTIFY_BUTTON_INFO PURPLE_NOTIFY_BUTTON_INFO -#define GAIM_NOTIFY_BUTTON_IM PURPLE_NOTIFY_BUTTON_IM -#define GAIM_NOTIFY_BUTTON_JOIN PURPLE_NOTIFY_BUTTON_JOIN -#define GAIM_NOTIFY_BUTTON_INVITE PURPLE_NOTIFY_BUTTON_INVITE - -#define GaimNotifySearchButtonType PurpleNotifySearchButtonType - -#define GaimNotifySearchResults PurpleNotifySearchResults - -#define GAIM_NOTIFY_USER_INFO_ENTRY_PAIR PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR -#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK -#define GAIM_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER - -#define GaimNotifyUserInfoEntryType PurpleNotifyUserInfoEntryType - -#define GaimNotifySearchColumn PurpleNotifySearchColumn -#define GaimNotifySearchResultsCallback PurpleNotifySearchResultsCallback -#define GaimNotifySearchButton PurpleNotifySearchButton - -#define GaimNotifyUiOps PurpleNotifyUiOps - -#define gaim_notify_searchresults purple_notify_searchresults -#define gaim_notify_searchresults_free purple_notify_searchresults_free -#define gaim_notify_searchresults_new_rows purple_notify_searchresults_new_rows -#define gaim_notify_searchresults_button_add purple_notify_searchresults_button_add -#define gaim_notify_searchresults_button_add_labeled purple_notify_searchresults_button_add_labeled -#define gaim_notify_searchresults_new purple_notify_searchresults_new -#define gaim_notify_searchresults_column_new purple_notify_searchresults_column_new -#define gaim_notify_searchresults_column_add purple_notify_searchresults_column_add -#define gaim_notify_searchresults_row_add purple_notify_searchresults_row_add -#define gaim_notify_searchresults_get_rows_count purple_notify_searchresults_get_rows_count -#define gaim_notify_searchresults_get_columns_count purple_notify_searchresults_get_columns_count -#define gaim_notify_searchresults_row_get purple_notify_searchresults_row_get -#define gaim_notify_searchresults_column_get_title purple_notify_searchresults_column_get_title - -#define gaim_notify_message purple_notify_message -#define gaim_notify_email purple_notify_email -#define gaim_notify_emails purple_notify_emails -#define gaim_notify_formatted purple_notify_formatted -#define gaim_notify_userinfo purple_notify_userinfo - -#define gaim_notify_user_info_new purple_notify_user_info_new -#define gaim_notify_user_info_destroy purple_notify_user_info_destroy -#define gaim_notify_user_info_get_entries purple_notify_user_info_get_entries -#define gaim_notify_user_info_get_text_with_newline purple_notify_user_info_get_text_with_newline -#define gaim_notify_user_info_add_pair purple_notify_user_info_add_pair -#define gaim_notify_user_info_prepend_pair purple_notify_user_info_prepend_pair -#define gaim_notify_user_info_remove_entry purple_notify_user_info_remove_entry -#define gaim_notify_user_info_entry_new purple_notify_user_info_entry_new -#define gaim_notify_user_info_add_section_break purple_notify_user_info_add_section_break -#define gaim_notify_user_info_add_section_header purple_notify_user_info_add_section_header -#define gaim_notify_user_info_remove_last_item purple_notify_user_info_remove_last_item -#define gaim_notify_user_info_entry_get_label purple_notify_user_info_entry_get_label -#define gaim_notify_user_info_entry_set_label purple_notify_user_info_entry_set_label -#define gaim_notify_user_info_entry_get_value purple_notify_user_info_entry_get_value -#define gaim_notify_user_info_entry_set_value purple_notify_user_info_entry_set_value -#define gaim_notify_user_info_entry_get_type purple_notify_user_info_entry_get_type -#define gaim_notify_user_info_entry_set_type purple_notify_user_info_entry_set_type - -#define gaim_notify_uri purple_notify_uri -#define gaim_notify_close purple_notify_close -#define gaim_notify_close_with_handle purple_notify_close_with_handle - -#define gaim_notify_info purple_notify_info -#define gaim_notify_warning purple_notify_warning -#define gaim_notify_error purple_notify_error - -#define gaim_notify_set_ui_ops purple_notify_set_ui_ops -#define gaim_notify_get_ui_ops purple_notify_get_ui_ops - -#define gaim_notify_get_handle purple_notify_get_handle - -#define gaim_notify_init purple_notify_init -#define gaim_notify_uninit purple_notify_uninit - -/* from ntlm.h */ - -#define gaim_ntlm_gen_type1 purple_ntlm_gen_type1 -#define gaim_ntlm_parse_type2 purple_ntlm_parse_type2 -#define gaim_ntlm_gen_type3 purple_ntlm_gen_type3 - -/* from plugin.h */ - -#ifdef GAIM_PLUGINS -#ifndef PURPLE_PLUGINS -#define PURPLE_PLUGINS -#endif -#endif - -#define GaimPlugin PurplePlugin -#define GaimPluginInfo PurplePluginInfo -#define GaimPluginUiInfo PurplePluginUiInfo -#define GaimPluginLoaderInfo PurplePluginLoaderInfo -#define GaimPluginAction PurplePluginAction -#define GaimPluginPriority PurplePluginPriority - -#define GAIM_PLUGIN_UNKNOWN PURPLE_PLUGIN_UNKNOWN -#define GAIM_PLUGIN_STANDARD PURPLE_PLUGIN_STANDARD -#define GAIM_PLUGIN_LOADER PURPLE_PLUGIN_LOADER -#define GAIM_PLUGIN_PROTOCOL PURPLE_PLUGIN_PROTOCOL - -#define GaimPluginType PurplePluginType - -#define GAIM_PRIORITY_DEFAULT PURPLE_PRIORITY_DEFAULT -#define GAIM_PRIORITY_HIGHEST PURPLE_PRIORITY_HIGHEST -#define GAIM_PRIORITY_LOWEST PURPLE_PRIORITY_LOWEST - -#define GAIM_PLUGIN_FLAG_INVISIBLE PURPLE_PLUGIN_FLAG_INVISIBLE - -#define GAIM_PLUGIN_MAGIC PURPLE_PLUGIN_MAGIC - -#define GAIM_PLUGIN_LOADER_INFO PURPLE_PLUGIN_LOADER_INFO -#define GAIM_PLUGIN_HAS_PREF_FRAME PURPLE_PLUGIN_HAS_PREF_FRAME -#define GAIM_PLUGIN_UI_INFO PURPLE_PLUGIN_UI_INFO - -#define GAIM_PLUGIN_HAS_ACTIONS PURPLE_PLUGIN_HAS_ACTIONS -#define GAIM_PLUGIN_ACTIONS PURPLE_PLUGIN_ACTIONS - -#define GAIM_INIT_PLUGIN PURPLE_INIT_PLUGIN - -#define gaim_plugin_new purple_plugin_new -#define gaim_plugin_probe purple_plugin_probe -#define gaim_plugin_register purple_plugin_register -#define gaim_plugin_load purple_plugin_load -#define gaim_plugin_unload purple_plugin_unload -#define gaim_plugin_reload purple_plugin_reload -#define gaim_plugin_destroy purple_plugin_destroy -#define gaim_plugin_is_loaded purple_plugin_is_loaded -#define gaim_plugin_is_unloadable purple_plugin_is_unloadable -#define gaim_plugin_get_id purple_plugin_get_id -#define gaim_plugin_get_name purple_plugin_get_name -#define gaim_plugin_get_version purple_plugin_get_version -#define gaim_plugin_get_summary purple_plugin_get_summary -#define gaim_plugin_get_description purple_plugin_get_description -#define gaim_plugin_get_author purple_plugin_get_author -#define gaim_plugin_get_homepage purple_plugin_get_homepage - -#define gaim_plugin_ipc_register purple_plugin_ipc_register -#define gaim_plugin_ipc_unregister purple_plugin_ipc_unregister -#define gaim_plugin_ipc_unregister_all purple_plugin_ipc_unregister_all -#define gaim_plugin_ipc_get_params purple_plugin_ipc_get_params -#define gaim_plugin_ipc_call purple_plugin_ipc_call - -#define gaim_plugins_add_search_path purple_plugins_add_search_path -#define gaim_plugins_unload_all purple_plugins_unload_all -#define gaim_plugins_destroy_all purple_plugins_destroy_all -#define gaim_plugins_save_loaded purple_plugins_save_loaded -#define gaim_plugins_load_saved purple_plugins_load_saved -#define gaim_plugins_probe purple_plugins_probe -#define gaim_plugins_enabled purple_plugins_enabled - -#define gaim_plugins_register_probe_notify_cb purple_plugins_register_probe_notify_cb -#define gaim_plugins_unregister_probe_notify_cb purple_plugins_unregister_probe_notify_cb -#define gaim_plugins_register_load_notify_cb purple_plugins_register_load_notify_cb -#define gaim_plugins_unregister_load_notify_cb purple_plugins_unregister_load_notify_cb -#define gaim_plugins_register_unload_notify_cb purple_plugins_register_unload_notify_cb -#define gaim_plugins_unregister_unload_notify_cb purple_plugins_unregister_unload_notify_cb - -#define gaim_plugins_find_with_name purple_plugins_find_with_name -#define gaim_plugins_find_with_filename purple_plugins_find_with_filename -#define gaim_plugins_find_with_basename purple_plugins_find_with_basename -#define gaim_plugins_find_with_id purple_plugins_find_with_id - -#define gaim_plugins_get_loaded purple_plugins_get_loaded -#define gaim_plugins_get_protocols purple_plugins_get_protocols -#define gaim_plugins_get_all purple_plugins_get_all - -#define gaim_plugins_get_handle purple_plugins_get_handle -#define gaim_plugins_init purple_plugins_init -#define gaim_plugins_uninit purple_plugins_uninit - -#define gaim_plugin_action_new purple_plugin_action_new -#define gaim_plugin_action_free purple_plugin_action_free - -/* pluginpref.h */ - -#define GaimPluginPrefFrame PurplePluginPrefFrame -#define GaimPluginPref PurplePluginPref - -#define GAIM_STRING_FORMAT_TYPE_NONE PURPLE_STRING_FORMAT_TYPE_NONE -#define GAIM_STRING_FORMAT_TYPE_MULTILINE PURPLE_STRING_FORMAT_TYPE_MULTILINE -#define GAIM_STRING_FORMAT_TYPE_HTML PURPLE_STRING_FORMAT_TYPE_HTML - -#define GaimStringFormatType PurpleStringFormatType - -#define GAIM_PLUGIN_PREF_NONE PURPLE_PLUGIN_PREF_NONE -#define GAIM_PLUGIN_PREF_CHOICE PURPLE_PLUGIN_PREF_CHOICE -#define GAIM_PLUGIN_PREF_INFO PURPLE_PLUGIN_PREF_INFO -#define GAIM_PLUGIN_PREF_STRING_FORMAT PURPLE_PLUGIN_PREF_STRING_FORMAT - -#define GaimPluginPrefType PurplePluginPrefType - -#define gaim_plugin_pref_frame_new purple_plugin_pref_frame_new -#define gaim_plugin_pref_frame_destroy purple_plugin_pref_frame_destroy -#define gaim_plugin_pref_frame_add purple_plugin_pref_frame_add -#define gaim_plugin_pref_frame_get_prefs purple_plugin_pref_frame_get_prefs - -#define gaim_plugin_pref_new purple_plugin_pref_new -#define gaim_plugin_pref_new_with_name purple_plugin_pref_new_with_name -#define gaim_plugin_pref_new_with_label purple_plugin_pref_new_with_label -#define gaim_plugin_pref_new_with_name_and_label purple_plugin_pref_new_with_name_and_label -#define gaim_plugin_pref_destroy purple_plugin_pref_destroy -#define gaim_plugin_pref_set_name purple_plugin_pref_set_name -#define gaim_plugin_pref_get_name purple_plugin_pref_get_name -#define gaim_plugin_pref_set_label purple_plugin_pref_set_label -#define gaim_plugin_pref_get_label purple_plugin_pref_get_label -#define gaim_plugin_pref_set_bounds purple_plugin_pref_set_bounds -#define gaim_plugin_pref_get_bounds purple_plugin_pref_get_bounds -#define gaim_plugin_pref_set_type purple_plugin_pref_set_type -#define gaim_plugin_pref_get_type purple_plugin_pref_get_type -#define gaim_plugin_pref_add_choice purple_plugin_pref_add_choice -#define gaim_plugin_pref_get_choices purple_plugin_pref_get_choices -#define gaim_plugin_pref_set_max_length purple_plugin_pref_set_max_length -#define gaim_plugin_pref_get_max_length purple_plugin_pref_get_max_length -#define gaim_plugin_pref_set_masked purple_plugin_pref_set_masked -#define gaim_plugin_pref_get_masked purple_plugin_pref_get_masked -#define gaim_plugin_pref_set_format_type purple_plugin_pref_set_format_type -#define gaim_plugin_pref_get_format_type purple_plugin_pref_get_format_type - -/* from pounce.h */ - -#define GaimPounce PurplePounce - -#define GAIM_POUNCE_NONE PURPLE_POUNCE_NONE -#define GAIM_POUNCE_SIGNON PURPLE_POUNCE_SIGNON -#define GAIM_POUNCE_SIGNOFF PURPLE_POUNCE_SIGNOFF -#define GAIM_POUNCE_AWAY PURPLE_POUNCE_AWAY -#define GAIM_POUNCE_AWAY_RETURN PURPLE_POUNCE_AWAY_RETURN -#define GAIM_POUNCE_IDLE PURPLE_POUNCE_IDLE -#define GAIM_POUNCE_IDLE_RETURN PURPLE_POUNCE_IDLE_RETURN -#define GAIM_POUNCE_TYPING PURPLE_POUNCE_TYPING -#define GAIM_POUNCE_TYPED PURPLE_POUNCE_TYPED -#define GAIM_POUNCE_TYPING_STOPPED PURPLE_POUNCE_TYPING_STOPPED -#define GAIM_POUNCE_MESSAGE_RECEIVED PURPLE_POUNCE_MESSAGE_RECEIVED -#define GaimPounceEvent PurplePounceEvent - -#define GAIM_POUNCE_OPTION_NONE PURPLE_POUNCE_OPTION_NONE -#define GAIM_POUNCE_OPTION_AWAY PURPLE_POUNCE_OPTION_AWAY -#define GaimPounceOption PurplePounceOption - -#define GaimPounceCb PurplePounceCb - -#define gaim_pounce_new purple_pounce_new -#define gaim_pounce_destroy purple_pounce_destroy -#define gaim_pounce_destroy_all_by_account purple_pounce_destroy_all_by_account -#define gaim_pounce_set_events purple_pounce_set_events -#define gaim_pounce_set_options purple_pounce_set_options -#define gaim_pounce_set_pouncer purple_pounce_set_pouncer -#define gaim_pounce_set_pouncee purple_pounce_set_pouncee -#define gaim_pounce_set_save purple_pounce_set_save -#define gaim_pounce_action_register purple_pounce_action_register -#define gaim_pounce_action_set_enabled purple_pounce_action_set_enabled -#define gaim_pounce_action_set_attribute purple_pounce_action_set_attribute -#define gaim_pounce_set_data purple_pounce_set_data -#define gaim_pounce_get_events purple_pounce_get_events -#define gaim_pounce_get_options purple_pounce_get_options -#define gaim_pounce_get_pouncer purple_pounce_get_pouncer -#define gaim_pounce_get_pouncee purple_pounce_get_pouncee -#define gaim_pounce_get_save purple_pounce_get_save -#define gaim_pounce_action_is_enabled purple_pounce_action_is_enabled -#define gaim_pounce_action_get_attribute purple_pounce_action_get_attribute -#define gaim_pounce_get_data purple_pounce_get_data -#define gaim_pounce_execute purple_pounce_execute - -#define gaim_find_pounce purple_find_pounce -#define gaim_pounces_load purple_pounces_load -#define gaim_pounces_register_handler purple_pounces_register_handler -#define gaim_pounces_unregister_handler purple_pounces_unregister_handler -#define gaim_pounces_get_all purple_pounces_get_all -#define gaim_pounces_get_handle purple_pounces_get_handle -#define gaim_pounces_init purple_pounces_init -#define gaim_pounces_uninit purple_pounces_uninit - -/* from prefs.h */ - - -#define GAIM_PREF_NONE PURPLE_PREF_NONE -#define GAIM_PREF_BOOLEAN PURPLE_PREF_BOOLEAN -#define GAIM_PREF_INT PURPLE_PREF_INT -#define GAIM_PREF_STRING PURPLE_PREF_STRING -#define GAIM_PREF_STRING_LIST PURPLE_PREF_STRING_LIST -#define GAIM_PREF_PATH PURPLE_PREF_PATH -#define GAIM_PREF_PATH_LIST PURPLE_PREF_PATH_LIST -#define GaimPrefType PurplePrefType - -#define GaimPrefCallback PurplePrefCallback - -#define gaim_prefs_get_handle purple_prefs_get_handle -#define gaim_prefs_init purple_prefs_init -#define gaim_prefs_uninit purple_prefs_uninit -#define gaim_prefs_add_none purple_prefs_add_none -#define gaim_prefs_add_bool purple_prefs_add_bool -#define gaim_prefs_add_int purple_prefs_add_int -#define gaim_prefs_add_string purple_prefs_add_string -#define gaim_prefs_add_string_list purple_prefs_add_string_list -#define gaim_prefs_add_path purple_prefs_add_path -#define gaim_prefs_add_path_list purple_prefs_add_path_list -#define gaim_prefs_remove purple_prefs_remove -#define gaim_prefs_rename purple_prefs_rename -#define gaim_prefs_rename_boolean_toggle purple_prefs_rename_boolean_toggle -#define gaim_prefs_destroy purple_prefs_destroy -#define gaim_prefs_set_generic purple_prefs_set_generic -#define gaim_prefs_set_bool purple_prefs_set_bool -#define gaim_prefs_set_int purple_prefs_set_int -#define gaim_prefs_set_string purple_prefs_set_string -#define gaim_prefs_set_string_list purple_prefs_set_string_list -#define gaim_prefs_set_path purple_prefs_set_path -#define gaim_prefs_set_path_list purple_prefs_set_path_list -#define gaim_prefs_exists purple_prefs_exists -#define gaim_prefs_get_type purple_prefs_get_type -#define gaim_prefs_get_bool purple_prefs_get_bool -#define gaim_prefs_get_int purple_prefs_get_int -#define gaim_prefs_get_string purple_prefs_get_string -#define gaim_prefs_get_string_list purple_prefs_get_string_list -#define gaim_prefs_get_path purple_prefs_get_path -#define gaim_prefs_get_path_list purple_prefs_get_path_list -#define gaim_prefs_connect_callback purple_prefs_connect_callback -#define gaim_prefs_disconnect_callback purple_prefs_disconnect_callback -#define gaim_prefs_disconnect_by_handle purple_prefs_disconnect_by_handle -#define gaim_prefs_trigger_callback purple_prefs_trigger_callback -#define gaim_prefs_load purple_prefs_load -#define gaim_prefs_update_old purple_prefs_update_old - -/* from privacy.h */ - -#define GAIM_PRIVACY_ALLOW_ALL PURPLE_PRIVACY_ALLOW_ALL -#define GAIM_PRIVACY_DENY_ALL PURPLE_PRIVACY_DENY_ALL -#define GAIM_PRIVACY_ALLOW_USERS PURPLE_PRIVACY_ALLOW_USERS -#define GAIM_PRIVACY_DENY_USERS PURPLE_PRIVACY_DENY_USERS -#define GAIM_PRIVACY_ALLOW_BUDDYLIST PURPLE_PRIVACY_ALLOW_BUDDYLIST -#define GaimPrivacyType PurplePrivacyType - -#define GaimPrivacyUiOps PurplePrivacyUiOps - -#define gaim_privacy_permit_add purple_privacy_permit_add -#define gaim_privacy_permit_remove purple_privacy_permit_remove -#define gaim_privacy_deny_add purple_privacy_deny_add -#define gaim_privacy_deny_remove purple_privacy_deny_remove -#define gaim_privacy_allow purple_privacy_allow -#define gaim_privacy_deny purple_privacy_deny -#define gaim_privacy_check purple_privacy_check -#define gaim_privacy_set_ui_ops purple_privacy_set_ui_ops -#define gaim_privacy_get_ui_ops purple_privacy_get_ui_ops -#define gaim_privacy_init purple_privacy_init - -/* from proxy.h */ - -#define GAIM_PROXY_USE_GLOBAL PURPLE_PROXY_USE_GLOBAL -#define GAIM_PROXY_NONE PURPLE_PROXY_NONE -#define GAIM_PROXY_HTTP PURPLE_PROXY_HTTP -#define GAIM_PROXY_SOCKS4 PURPLE_PROXY_SOCKS4 -#define GAIM_PROXY_SOCKS5 PURPLE_PROXY_SOCKS5 -#define GAIM_PROXY_USE_ENVVAR PURPLE_PROXY_USE_ENVVAR -#define GaimProxyType PurpleProxyType - -#define GaimProxyInfo PurpleProxyInfo - -#define GaimProxyConnectData PurpleProxyConnectData -#define GaimProxyConnectFunction PurpleProxyConnectFunction - -#define gaim_proxy_info_new purple_proxy_info_new -#define gaim_proxy_info_destroy purple_proxy_info_destroy -#define gaim_proxy_info_set_type purple_proxy_info_set_type -#define gaim_proxy_info_set_host purple_proxy_info_set_host -#define gaim_proxy_info_set_port purple_proxy_info_set_port -#define gaim_proxy_info_set_username purple_proxy_info_set_username -#define gaim_proxy_info_set_password purple_proxy_info_set_password -#define gaim_proxy_info_get_type purple_proxy_info_get_type -#define gaim_proxy_info_get_host purple_proxy_info_get_host -#define gaim_proxy_info_get_port purple_proxy_info_get_port -#define gaim_proxy_info_get_username purple_proxy_info_get_username -#define gaim_proxy_info_get_password purple_proxy_info_get_password - -#define gaim_global_proxy_get_info purple_global_proxy_get_info -#define gaim_proxy_get_handle purple_proxy_get_handle -#define gaim_proxy_init purple_proxy_init -#define gaim_proxy_uninit purple_proxy_uninit -#define gaim_proxy_get_setup purple_proxy_get_setup - -#define gaim_proxy_connect purple_proxy_connect -#define gaim_proxy_connect_socks5 purple_proxy_connect_socks5 -#define gaim_proxy_connect_cancel purple_proxy_connect_cancel -#define gaim_proxy_connect_cancel_with_handle purple_proxy_connect_cancel_with_handle - -/* from prpl.h */ - -#define GaimPluginProtocolInfo PurplePluginProtocolInfo - -#define GAIM_ICON_SCALE_DISPLAY PURPLE_ICON_SCALE_DISPLAY -#define GAIM_ICON_SCALE_SEND PURPLE_ICON_SCALE_SEND -#define GaimIconScaleRules PurpleIconScaleRules - -#define GaimBuddyIconSpec PurpleBuddyIconSpec - -#define GaimProtocolOptions PurpleProtocolOptions - -#define GAIM_IS_PROTOCOL_PLUGIN PURPLE_IS_PROTOCOL_PLUGIN - -#define GAIM_PLUGIN_PROTOCOL_INFO PURPLE_PLUGIN_PROTOCOL_INFO - -#define gaim_prpl_got_account_idle purple_prpl_got_account_idle -#define gaim_prpl_got_account_login_time purple_prpl_got_account_login_time -#define gaim_prpl_got_account_status purple_prpl_got_account_status -#define gaim_prpl_got_user_idle purple_prpl_got_user_idle -#define gaim_prpl_got_user_login_time purple_prpl_got_user_login_time -#define gaim_prpl_got_user_status purple_prpl_got_user_status -#define gaim_prpl_change_account_status purple_prpl_change_account_status -#define gaim_prpl_get_statuses purple_prpl_get_statuses - -#define gaim_find_prpl purple_find_prpl - -/* from request.h */ - -#define GAIM_DEFAULT_ACTION_NONE PURPLE_DEFAULT_ACTION_NONE - -#define GAIM_REQUEST_INPUT PURPLE_REQUEST_INPUT -#define GAIM_REQUEST_CHOICE PURPLE_REQUEST_CHOICE -#define GAIM_REQUEST_ACTION PURPLE_REQUEST_ACTION -#define GAIM_REQUEST_FIELDS PURPLE_REQUEST_FIELDS -#define GAIM_REQUEST_FILE PURPLE_REQUEST_FILE -#define GAIM_REQUEST_FOLDER PURPLE_REQUEST_FOLDER -#define GaimRequestType PurpleRequestType - -#define GAIM_REQUEST_FIELD_NONE PURPLE_REQUEST_FIELD_NONE -#define GAIM_REQUEST_FIELD_STRING PURPLE_REQUEST_FIELD_STRING -#define GAIM_REQUEST_FIELD_INTEGER PURPLE_REQUEST_FIELD_INTEGER -#define GAIM_REQUEST_FIELD_BOOLEAN PURPLE_REQUEST_FIELD_BOOLEAN -#define GAIM_REQUEST_FIELD_CHOICE PURPLE_REQUEST_FIELD_CHOICE -#define GAIM_REQUEST_FIELD_LIST PURPLE_REQUEST_FIELD_LIST -#define GAIM_REQUEST_FIELD_LABEL PURPLE_REQUEST_FIELD_LABEL -#define GAIM_REQUEST_FIELD_IMAGE PURPLE_REQUEST_FIELD_IMAGE -#define GAIM_REQUEST_FIELD_ACCOUNT PURPLE_REQUEST_FIELD_ACCOUNT -#define GaimRequestFieldType PurpleRequestFieldType - -#define GaimRequestFields PurpleRequestFields - -#define GaimRequestFieldGroup PurpleRequestFieldGroup - -#define GaimRequestField PurpleRequestField - -#define GaimRequestUiOps PurpleRequestUiOps - -#define GaimRequestInputCb PurpleRequestInputCb -#define GaimRequestActionCb PurpleRequestActionCb -#define GaimRequestChoiceCb PurpleRequestChoiceCb -#define GaimRequestFieldsCb PurpleRequestFieldsCb -#define GaimRequestFileCb PurpleRequestFileCb - -#define gaim_request_fields_new purple_request_fields_new -#define gaim_request_fields_destroy purple_request_fields_destroy -#define gaim_request_fields_add_group purple_request_fields_add_group -#define gaim_request_fields_get_groups purple_request_fields_get_groups -#define gaim_request_fields_exists purple_request_fields_exists -#define gaim_request_fields_get_required purple_request_fields_get_required -#define gaim_request_fields_is_field_required purple_request_fields_is_field_required -#define gaim_request_fields_all_required_filled purple_request_fields_all_required_filled -#define gaim_request_fields_get_field purple_request_fields_get_field -#define gaim_request_fields_get_string purple_request_fields_get_string -#define gaim_request_fields_get_integer purple_request_fields_get_integer -#define gaim_request_fields_get_bool purple_request_fields_get_bool -#define gaim_request_fields_get_choice purple_request_fields_get_choice -#define gaim_request_fields_get_account purple_request_fields_get_account - -#define gaim_request_field_group_new purple_request_field_group_new -#define gaim_request_field_group_destroy purple_request_field_group_destroy -#define gaim_request_field_group_add_field purple_request_field_group_add_field -#define gaim_request_field_group_get_title purple_request_field_group_get_title -#define gaim_request_field_group_get_fields purple_request_field_group_get_fields - -#define gaim_request_field_new purple_request_field_new -#define gaim_request_field_destroy purple_request_field_destroy -#define gaim_request_field_set_label purple_request_field_set_label -#define gaim_request_field_set_visible purple_request_field_set_visible -#define gaim_request_field_set_type_hint purple_request_field_set_type_hint -#define gaim_request_field_set_required purple_request_field_set_required -#define gaim_request_field_get_type purple_request_field_get_type -#define gaim_request_field_get_id purple_request_field_get_id -#define gaim_request_field_get_label purple_request_field_get_label -#define gaim_request_field_is_visible purple_request_field_is_visible -#define gaim_request_field_get_type_hint purple_request_field_get_type_hint -#define gaim_request_field_is_required purple_request_field_is_required - -#define gaim_request_field_string_new purple_request_field_string_new -#define gaim_request_field_string_set_default_value \ - purple_request_field_string_set_default_value -#define gaim_request_field_string_set_value purple_request_field_string_set_value -#define gaim_request_field_string_set_masked purple_request_field_string_set_masked -#define gaim_request_field_string_set_editable purple_request_field_string_set_editable -#define gaim_request_field_string_get_default_value \ - purple_request_field_string_get_default_value -#define gaim_request_field_string_get_value purple_request_field_string_get_value -#define gaim_request_field_string_is_multiline purple_request_field_string_is_multiline -#define gaim_request_field_string_is_masked purple_request_field_string_is_masked -#define gaim_request_field_string_is_editable purple_request_field_string_is_editable - -#define gaim_request_field_int_new purple_request_field_int_new -#define gaim_request_field_int_set_default_value \ - purple_request_field_int_set_default_value -#define gaim_request_field_int_set_value purple_request_field_int_set_value -#define gaim_request_field_int_get_default_value \ - purple_request_field_int_get_default_value -#define gaim_request_field_int_get_value purple_request_field_int_get_value - -#define gaim_request_field_bool_new purple_request_field_bool_new -#define gaim_request_field_bool_set_default_value \ - purple_request_field_book_set_default_value -#define gaim_request_field_bool_set_value purple_request_field_bool_set_value -#define gaim_request_field_bool_get_default_value \ - purple_request_field_bool_get_default_value -#define gaim_request_field_bool_get_value purple_request_field_bool_get_value - -#define gaim_request_field_choice_new purple_request_field_choice_new -#define gaim_request_field_choice_add purple_request_field_choice_add -#define gaim_request_field_choice_set_default_value \ - purple_request_field_choice_set_default_value -#define gaim_request_field_choice_set_value purple_request_field_choice_set_value -#define gaim_request_field_choice_get_default_value \ - purple_request_field_choice_get_default_value -#define gaim_request_field_choice_get_value purple_request_field_choice_get_value -#define gaim_request_field_choice_get_labels purple_request_field_choice_get_labels - -#define gaim_request_field_list_new purple_request_field_list_new -#define gaim_request_field_list_set_multi_select purple_request_field_list_set_multi_select -#define gaim_request_field_list_get_multi_select purple_request_field_list_get_multi_select -#define gaim_request_field_list_get_data purple_request_field_list_get_data -#define gaim_request_field_list_add purple_request_field_list_add -#define gaim_request_field_list_add_selected purple_request_field_list_add_selected -#define gaim_request_field_list_clear_selected purple_request_field_list_clear_selected -#define gaim_request_field_list_set_selected purple_request_field_list_set_selected -#define gaim_request_field_list_is_selected purple_request_field_list_is_selected -#define gaim_request_field_list_get_selected purple_request_field_list_get_selected -#define gaim_request_field_list_get_items purple_request_field_list_get_items - -#define gaim_request_field_label_new purple_request_field_label_new - -#define gaim_request_field_image_new purple_request_field_image_new -#define gaim_request_field_image_set_scale purple_request_field_image_set_scale -#define gaim_request_field_image_get_buffer purple_request_field_image_get_buffer -#define gaim_request_field_image_get_size purple_request_field_image_get_size -#define gaim_request_field_image_get_scale_x purple_request_field_image_get_scale_x -#define gaim_request_field_image_get_scale_y purple_request_field_image_get_scale_y - -#define gaim_request_field_account_new purple_request_field_account_new -#define gaim_request_field_account_set_default_value purple_request_field_account_set_default_value -#define gaim_request_field_account_set_value purple_request_field_account_set_value -#define gaim_request_field_account_set_show_all purple_request_field_account_set_show_all -#define gaim_request_field_account_set_filter purple_request_field_account_set_filter -#define gaim_request_field_account_get_default_value purple_request_field_account_get_default_value -#define gaim_request_field_account_get_value purple_request_field_account_get_value -#define gaim_request_field_account_get_show_all purple_request_field_account_get_show_all -#define gaim_request_field_account_get_filter purple_request_field_account_get_filter - -#define gaim_request_input purple_request_input -#define gaim_request_choice purple_request_choice -#define gaim_request_choice_varg purple_request_choice_varg -#define gaim_request_action purple_request_action -#define gaim_request_action_varg purple_request_action_varg -#define gaim_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, user_data) purple_request_fields(handle, title, primary, secondary, fields, ok_text, ok_cb, cancel_text, cancel_cb, NULL, NULL, NULL, user_data) -#define gaim_request_close purple_request_close -#define gaim_request_close_with_handle purple_request_close_with_handle - -#define gaim_request_yes_no purple_request_yes_no -#define gaim_request_ok_cancel purple_request_ok_cancel -#define gaim_request_accept_cancel purple_request_accept_cancel - -#define gaim_request_file purple_request_file -#define gaim_request_folder purple_request_folder - -#define gaim_request_set_ui_ops purple_request_set_ui_ops -#define gaim_request_get_ui_ops purple_request_get_ui_ops - -/* from roomlist.h */ - -#define GaimRoomlist PurpleRoomlist -#define GaimRoomlistRoom PurpleRoomlistRoom -#define GaimRoomlistField PurpleRoomlistField -#define GaimRoomlistUiOps PurpleRoomlistUiOps - -#define GAIM_ROOMLIST_ROOMTYPE_CATEGORY PURPLE_ROOMLIST_ROOMTYPE_CATEGORY -#define GAIM_ROOMLIST_ROOMTYPE_ROOM PURPLE_ROOMLIST_ROOMTYPE_ROOM -#define GaimRoomlistRoomType PurpleRoomlistRoomType - -#define GAIM_ROOMLIST_FIELD_BOOL PURPLE_ROOMLIST_BOOL -#define GAIM_ROOMLIST_FIELD_INT PURPLE_ROOMLIST_INT -#define GAIM_ROOMLIST_FIELD_STRING PURPLE_ROOMLIST_STRING -#define GaimRoomlistFieldType PurpleRoomlistFieldType - -#define gaim_roomlist_show_with_account purple_roomlist_show_with_account -#define gaim_roomlist_new purple_roomlist_new -#define gaim_roomlist_ref purple_roomlist_ref -#define gaim_roomlist_unref purple_roomlist_unref -#define gaim_roomlist_set_fields purple_roomlist_set_fields -#define gaim_roomlist_set_in_progress purple_roomlist_set_in_progress -#define gaim_roomlist_get_in_progress purple_roomlist_get_in_progress -#define gaim_roomlist_room_add purple_roomlist_room_add - -#define gaim_roomlist_get_list purple_roomlist_get_list -#define gaim_roomlist_cancel_get_list purple_roomlist_cancel_get_list -#define gaim_roomlist_expand_category purple_roomlist_expand_category - -#define gaim_roomlist_room_new purple_roomlist_room_new -#define gaim_roomlist_room_add_field purple_roomlist_room_add_field -#define gaim_roomlist_room_join purple_roomlist_room_join -#define gaim_roomlist_field_new purple_roomlist_field_new - -#define gaim_roomlist_set_ui_ops purple_roomlist_set_ui_ops -#define gaim_roomlist_get_ui_ops purple_roomlist_get_ui_ops - -/* from savedstatuses.h */ - -#define GaimSavedStatus PurpleSavedStatus -#define GaimSavedStatusSub PurpleSavedStatusSub - -#define gaim_savedstatus_new purple_savedstatus_new -#define gaim_savedstatus_set_title purple_savedstatus_set_title -#define gaim_savedstatus_set_type purple_savedstatus_set_type -#define gaim_savedstatus_set_message purple_savedstatus_set_message -#define gaim_savedstatus_set_substatus purple_savedstatus_set_substatus -#define gaim_savedstatus_unset_substatus purple_savedstatus_unset_substatus -#define gaim_savedstatus_delete purple_savedstatus_delete - -#define gaim_savedstatuses_get_all purple_savedstatuses_get_all -#define gaim_savedstatuses_get_popular purple_savedstatuses_get_popular -#define gaim_savedstatus_get_current purple_savedstatus_get_current -#define gaim_savedstatus_get_default purple_savedstatus_get_default -#define gaim_savedstatus_get_idleaway purple_savedstatus_get_idleaway -#define gaim_savedstatus_is_idleaway purple_savedstatus_is_idleaway -#define gaim_savedstatus_set_idleaway purple_savedstatus_set_idleaway -#define gaim_savedstatus_get_startup purple_savedstatus_get_startup -#define gaim_savedstatus_find purple_savedstatus_find -#define gaim_savedstatus_find_by_creation_time purple_savedstatus_find_by_creation_time -#define gaim_savedstatus_find_transient_by_type_and_message \ - purple_savedstatus_find_transient_by_type_and_message - -#define gaim_savedstatus_is_transient purple_savedstatus_is_transient -#define gaim_savedstatus_get_title purple_savedstatus_get_title -#define gaim_savedstatus_get_type purple_savedstatus_get_type -#define gaim_savedstatus_get_message purple_savedstatus_get_message -#define gaim_savedstatus_get_creation_time purple_savedstatus_get_creation_time -#define gaim_savedstatus_has_substatuses purple_savedstatus_has_substatuses -#define gaim_savedstatus_get_substatus purple_savedstatus_get_substatus -#define gaim_savedstatus_substatus_get_type purple_savedstatus_substatus_get_type -#define gaim_savedstatus_substatus_get_message purple_savedstatus_substatus_get_message -#define gaim_savedstatus_activate purple_savedstatus_activate -#define gaim_savedstatus_activate_for_account purple_savedstatus_activate_for_account - -#define gaim_savedstatuses_get_handle purple_savedstatuses_get_handle -#define gaim_savedstatuses_init purple_savedstatuses_init -#define gaim_savedstatuses_uninit purple_savedstatuses_uninit - -/* from signals.h */ - -#define GAIM_CALLBACK PURPLE_CALLBACK - -#define GaimCallback PurpleCallback -#define GaimSignalMarshalFunc PurpleSignalMarshalFunc - -#define GAIM_SIGNAL_PRIORITY_DEFAULT PURPLE_SIGNAL_PRIORITY_DEFAULT -#define GAIM_SIGNAL_PRIORITY_HIGHEST PURPLE_SIGNAL_PRIORITY_HIGHEST -#define GAIM_SIGNAL_PRIORITY_LOWEST PURPLE_SIGNAL_PRIORITY_LOWEST - -#define gaim_signal_register purple_signal_register -#define gaim_signal_unregister purple_signal_unregister - -#define gaim_signals_unregister_by_instance purple_signals_unregister_by_instance - -#define gaim_signal_get_values purple_signal_get_values -#define gaim_signal_connect_priority purple_signal_connect_priority -#define gaim_signal_connect purple_signal_connect -#define gaim_signal_connect_priority_vargs purple_signal_connect_priority_vargs -#define gaim_signal_connect_vargs purple_signal_connect_vargs -#define gaim_signal_disconnect purple_signal_disconnect - -#define gaim_signals_disconnect_by_handle purple_signals_disconnect_by_handle - -#define gaim_signal_emit purple_signal_emit -#define gaim_signal_emit_vargs purple_signal_emit_vargs -#define gaim_signal_emit_return_1 purple_signal_emit_vargs -#define gaim_signal_emit_vargs_return_1 purple_signal_emit_vargs_return_1 - -#define gaim_signals_init purple_signals_init -#define gaim_signals_uninit purple_signals_uninit - -#define gaim_marshal_VOID \ - purple_marshal_VOID -#define gaim_marshal_VOID__INT \ - purple_marshal_VOID__INT -#define gaim_marshal_VOID__INT_INT \ - purple_marshal_VOID_INT_INT -#define gaim_marshal_VOID__POINTER \ - purple_marshal_VOID__POINTER -#define gaim_marshal_VOID__POINTER_UINT \ - purple_marshal_VOID__POINTER_UINT -#define gaim_marshal_VOID__POINTER_INT_INT \ - purple_marshal_VOID__POINTER_INT_INT -#define gaim_marshal_VOID__POINTER_POINTER \ - purple_marshal_VOID__POINTER_POINTER -#define gaim_marshal_VOID__POINTER_POINTER_UINT \ - purple_marshal_VOID__POINTER_POINTER_UINT -#define gaim_marshal_VOID__POINTER_POINTER_UINT_UINT \ - purple_marshal_VOID__POINTER_POINTER_UINT_UINT -#define gaim_marshal_VOID__POINTER_POINTER_POINTER \ - purple_marshal_VOID__POINTER_POINTER_POINTER -#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER \ - purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER -#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER \ - purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER -#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT \ - purple_marshal_VOID__POINTER_POINTER_POINTER_UINT -#define gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT \ - purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT -#define gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT \ - purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT - -#define gaim_marshal_INT__INT \ - purple_marshal_INT__INT -#define gaim_marshal_INT__INT_INT \ - purple_marshal_INT__INT_INT -#define gaim_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER \ - purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER - -#define gaim_marshal_BOOLEAN__POINTER \ - purple_marshal_BOOLEAN__POINTER -#define gaim_marshal_BOOLEAN__POINTER_POINTER \ - purple_marshal_BOOLEAN__POINTER_POINTER -#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER \ - purple_marshal_BOOLEAN__POINTER_POINTER_POINTER -#define gaim_marshal_BOOLEAN__POINTER_POINTER_UINT \ - purple_marshal_BOOLEAN__POINTER_POINTER_UINT -#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT \ - purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT -#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER \ - purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER -#define gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER \ - purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER - -#define gaim_marshal_BOOLEAN__INT_POINTER \ - purple_marshal_BOOLEAN__INT_POINTER - -#define gaim_marshal_POINTER__POINTER_INT \ - purple_marshal_POINTER__POINTER_INT -#define gaim_marshal_POINTER__POINTER_INT64 \ - purple_marshal_POINTER__POINTER_INT64 -#define gaim_marshal_POINTER__POINTER_INT_BOOLEAN \ - purple_marshal_POINTER__POINTER_INT_BOOLEAN -#define gaim_marshal_POINTER__POINTER_INT64_BOOLEAN \ - purple_marshal_POINTER__POINTER_INT64_BOOLEAN -#define gaim_marshal_POINTER__POINTER_POINTER \ - purple_marshal_POINTER__POINTER_POINTER - -/* from sound.h */ - -#define GAIM_SOUND_BUDDY_ARRIVE PURPLE_SOUND_BUDDY_ARRIVE -#define GAIM_SOUND_BUDDY_LEAVE PURPLE_SOUND_BUDDY_LEAVE -#define GAIM_SOUND_RECEIVE PURPLE_SOUND_RECEIVE -#define GAIM_SOUND_FIRST_RECEIVE PURPLE_SOUND_FIRST_RECEIVE -#define GAIM_SOUND_SEND PURPLE_SOUND_SEND -#define GAIM_SOUND_CHAT_JOIN PURPLE_SOUND_CHAT_JOIN -#define GAIM_SOUND_CHAT_LEAVE PURPLE_SOUND_CHAT_LEAVE -#define GAIM_SOUND_CHAT_YOU_SAY PURPLE_SOUND_CHAT_YOU_SAY -#define GAIM_SOUND_CHAT_SAY PURPLE_SOUND_CHAT_SAY -#define GAIM_SOUND_POUNCE_DEFAULT PURPLE_SOUND_POUNCE_DEFAULT -#define GAIM_SOUND_CHAT_NICK PURPLE_SOUND_CHAT_NICK -#define GAIM_NUM_SOUNDS PURPLE_NUM_SOUNDS -#define GaimSoundEventID PurpleSoundEventID - -#define GaimSoundUiOps PurpleSoundUiOps - -#define gaim_sound_play_file purple_sound_play_file -#define gaim_sound_play_event purple_sound_play_event -#define gaim_sound_set_ui_ops purple_sound_set_ui_ops -#define gaim_sound_get_ui_ops purple_sound_get_ui_ops -#define gaim_sound_init purple_sound_init -#define gaim_sound_uninit purple_sound_uninit - -#define gaim_sounds_get_handle purple_sounds_get_handle - -/* from sslconn.h */ - -#define GAIM_SSL_DEFAULT_PORT PURPLE_SSL_DEFAULT_PORT - -#define GAIM_SSL_HANDSHAKE_FAILED PURPLE_SSL_HANDSHAKE_FAILED -#define GAIM_SSL_CONNECT_FAILED PURPLE_SSL_CONNECT_FAILED -#define GaimSslErrorType PurpleSslErrorType - -#define GaimSslConnection PurpleSslConnection - -#define GaimSslInputFunction PurpleSslInputFunction -#define GaimSslErrorFunction PurpleSslErrorFunction - -#define GaimSslOps PurpleSslOps - -#define gaim_ssl_is_supported purple_ssl_is_supported -#define gaim_ssl_connect purple_ssl_connect -#define gaim_ssl_connect_fd purple_ssl_connect_fd -#define gaim_ssl_input_add purple_ssl_input_add -#define gaim_ssl_close purple_ssl_close -#define gaim_ssl_read purple_ssl_read -#define gaim_ssl_write purple_ssl_write - -#define gaim_ssl_set_ops purple_ssl_set_ops -#define gaim_ssl_get_ops purple_ssl_get_ops -#define gaim_ssl_init purple_ssl_init -#define gaim_ssl_uninit purple_ssl_uninit - -/* from status.h */ - -#define GaimStatusType PurpleStatusType -#define GaimStatusAttr PurpleStatusAttr -#define GaimPresence PurplePresence -#define GaimStatus PurpleStatus - -#define GAIM_PRESENCE_CONTEXT_UNSET PURPLE_PRESENCE_CONTEXT_UNSET -#define GAIM_PRESENCE_CONTEXT_ACCOUNT PURPLE_PRESENCE_CONTEXT_ACCOUNT -#define GAIM_PRESENCE_CONTEXT_CONV PURPLE_PRESENCE_CONTEXT_CONV -#define GAIM_PRESENCE_CONTEXT_BUDDY PURPLE_PRESENCE_CONTEXT_BUDDY -#define GaimPresenceContext PurplePresenceContext - -#define GAIM_STATUS_UNSET PURPLE_STATUS_UNSET -#define GAIM_STATUS_OFFLINE PURPLE_STATUS_OFFLINE -#define GAIM_STATUS_AVAILABLE PURPLE_STATUS_AVAILABLE -#define GAIM_STATUS_UNAVAILABLE PURPLE_STATUS_UNAVAILABLE -#define GAIM_STATUS_INVISIBLE PURPLE_STATUS_INVISIBLE -#define GAIM_STATUS_AWAY PURPLE_STATUS_AWAY -#define GAIM_STATUS_EXTENDED_AWAY PURPLE_STATUS_EXTENDED_AWAY -#define GAIM_STATUS_MOBILE PURPLE_STATUS_MOBILE -#define GAIM_STATUS_NUM_PRIMITIVES PURPLE_STATUS_NUM_PRIMITIVES -#define GaimStatusPrimitive PurpleStatusPrimitive - -#define gaim_primitive_get_id_from_type purple_primitive_get_id_from_type -#define gaim_primitive_get_name_from_type purple_primitive_get_name_from_type -#define gaim_primitive_get_type_from_id purple_primitive_get_type_from_id - -#define gaim_status_type_new_full purple_status_type_new_full -#define gaim_status_type_new purple_status_type_new -#define gaim_status_type_new_with_attrs purple_status_type_new_with_attrs -#define gaim_status_type_destroy purple_status_type_destroy -#define gaim_status_type_set_primary_attr purple_status_type_set_primary_attr -#define gaim_status_type_add_attr purple_status_type_add_attr -#define gaim_status_type_add_attrs purple_status_type_add_attrs -#define gaim_status_type_add_attrs_vargs purple_status_type_add_attrs_vargs -#define gaim_status_type_get_primitive purple_status_type_get_primitive -#define gaim_status_type_get_id purple_status_type_get_id -#define gaim_status_type_get_name purple_status_type_get_name -#define gaim_status_type_is_saveable purple_status_type_is_saveable -#define gaim_status_type_is_user_settable purple_status_type_is_user_settable -#define gaim_status_type_is_independent purple_status_type_is_independent -#define gaim_status_type_is_exclusive purple_status_type_is_exclusive -#define gaim_status_type_is_available purple_status_type_is_available -#define gaim_status_type_get_primary_attr purple_status_type_get_primary_attr -#define gaim_status_type_get_attr purple_status_type_get_attr -#define gaim_status_type_get_attrs purple_status_type_get_attrs -#define gaim_status_type_find_with_id purple_status_type_find_with_id - -#define gaim_status_attr_new purple_status_attr_new -#define gaim_status_attr_destroy purple_status_attr_destroy -#define gaim_status_attr_get_id purple_status_attr_get_id -#define gaim_status_attr_get_name purple_status_attr_get_name -#define gaim_status_attr_get_value purple_status_attr_get_value - -#define gaim_status_new purple_status_new -#define gaim_status_destroy purple_status_destroy -#define gaim_status_set_active purple_status_set_active -#define gaim_status_set_active_with_attrs purple_status_set_active_with_attrs -#define gaim_status_set_active_with_attrs_list purple_status_set_active_with_attrs_list -#define gaim_status_set_attr_boolean purple_status_set_attr_boolean -#define gaim_status_set_attr_int purple_status_set_attr_int -#define gaim_status_set_attr_string purple_status_set_attr_string -#define gaim_status_get_type purple_status_get_type -#define gaim_status_get_presence purple_status_get_presence -#define gaim_status_get_id purple_status_get_id -#define gaim_status_get_name purple_status_get_name -#define gaim_status_is_independent purple_status_is_independent -#define gaim_status_is_exclusive purple_status_is_exclusive -#define gaim_status_is_available purple_status_is_available -#define gaim_status_is_active purple_status_is_active -#define gaim_status_is_online purple_status_is_online -#define gaim_status_get_attr_value purple_status_get_attr_value -#define gaim_status_get_attr_boolean purple_status_get_attr_boolean -#define gaim_status_get_attr_int purple_status_get_attr_int -#define gaim_status_get_attr_string purple_status_get_attr_string -#define gaim_status_compare purple_status_compare - -#define gaim_presence_new purple_presence_new -#define gaim_presence_new_for_account purple_presence_new_for_account -#define gaim_presence_new_for_conv purple_presence_new_for_conv -#define gaim_presence_new_for_buddy purple_presence_new_for_buddy -#define gaim_presence_destroy purple_presence_destroy -#define gaim_presence_add_status purple_presence_add_status -#define gaim_presence_add_list purple_presence_add_list -#define gaim_presence_set_status_active purple_presence_set_status_active -#define gaim_presence_switch_status purple_presence_switch_status -#define gaim_presence_set_idle purple_presence_set_idle -#define gaim_presence_set_login_time purple_presence_set_login_time -#define gaim_presence_get_context purple_presence_get_context -#define gaim_presence_get_account purple_presence_get_account -#define gaim_presence_get_conversation purple_presence_get_conversation -#define gaim_presence_get_chat_user purple_presence_get_chat_user -#define gaim_presence_get_statuses purple_presence_get_statuses -#define gaim_presence_get_status purple_presence_get_status -#define gaim_presence_get_active_status purple_presence_get_active_status -#define gaim_presence_is_available purple_presence_is_available -#define gaim_presence_is_online purple_presence_is_online -#define gaim_presence_is_status_active purple_presence_is_status_active -#define gaim_presence_is_status_primitive_active \ - purple_presence_is_status_primitive_active -#define gaim_presence_is_idle purple_presence_is_idle -#define gaim_presence_get_idle_time purple_presence_get_idle_time -#define gaim_presence_get_login_time purple_presence_get_login_time -#define gaim_presence_compare purple_presence_compare - -#define gaim_status_get_handle purple_status_get_handle -#define gaim_status_init purple_status_init -#define gaim_status_uninit purple_status_uninit - -/* from stringref.h */ - -#define GaimStringref PurpleStringref - -#define gaim_stringref_new purple_stringref_new -#define gaim_stringref_new_noref purple_stringref_new_noref -#define gaim_stringref_printf purple_stringref_printf -#define gaim_stringref_ref purple_stringref_ref -#define gaim_stringref_unref purple_stringref_unref -#define gaim_stringref_value purple_stringref_value -#define gaim_stringref_cmp purple_stringref_cmp -#define gaim_stringref_len purple_stringref_len - -/* from stun.h */ - -#define GaimStunNatDiscovery PurpleStunNatDiscovery - -#define GAIM_STUN_STATUS_UNDISCOVERED PURPLE_STUN_STATUS_UNDISCOVERED -#define GAIM_STUN_STATUS_UNKNOWN PURPLE_STUN_STATUS_UNKNOWN -#define GAIM_STUN_STATUS_DISCOVERING PURPLE_STUN_STATUS_DISCOVERING -#define GAIM_STUN_STATUS_DISCOVERED PURPLE_STUN_STATUS_DISCOVERED -#define GaimStunStatus PurpleStunStatus - -#define GAIM_STUN_NAT_TYPE_PUBLIC_IP PURPLE_STUN_NAT_TYPE_PUBLIC_IP -#define GAIM_STUN_NAT_TYPE_UNKNOWN_NAT PURPLE_STUN_NAT_TYPE_UNKNOWN_NAT -#define GAIM_STUN_NAT_TYPE_FULL_CONE PURPLE_STUN_NAT_TYPE_FULL_CONE -#define GAIM_STUN_NAT_TYPE_RESTRICTED_CONE PURPLE_STUN_NAT_TYPE_RESTRICTED_CONE -#define GAIM_STUN_NAT_TYPE_PORT_RESTRICTED_CONE PURPLE_STUN_NAT_TYPE_PORT_RESTRICTED_CONE -#define GAIM_STUN_NAT_TYPE_SYMMETRIC PURPLE_STUN_NAT_TYPE_SYMMETRIC -#define GaimStunNatType PurpleStunNatType - -/* why didn't this have a Gaim prefix before? */ -#define StunCallback PurpleStunCallback - -#define gaim_stun_discover purple_stun_discover -#define gaim_stun_init purple_stun_init - -/* from upnp.h */ - -/* suggested rename: PurpleUPnpMappingHandle */ -#define UPnPMappingAddRemove PurpleUPnPMappingAddRemove - -#define GaimUPnPCallback PurpleUPnPCallback - -#define gaim_upnp_discover purple_upnp_discover -#define gaim_upnp_get_public_ip purple_upnp_get_public_ip -#define gaim_upnp_cancel_port_mapping purple_upnp_cancel_port_mapping -#define gaim_upnp_set_port_mapping purple_upnp_set_port_mapping - -#define gaim_upnp_remove_port_mapping purple_upnp_remove_port_mapping - -/* from util.h */ - -#define GaimUtilFetchUrlData PurpleUtilFetchUrlData -#define GaimMenuAction PurpleMenuAction - -#define GaimInfoFieldFormatCallback PurpleIntoFieldFormatCallback - -#define GaimKeyValuePair PurpleKeyValuePair - -#define gaim_menu_action_new purple_menu_action_new -#define gaim_menu_action_free purple_menu_action_free - -#define gaim_base16_encode purple_base16_encode -#define gaim_base16_decode purple_base16_decode -#define gaim_base64_encode purple_base64_encode -#define gaim_base64_decode purple_base64_decode -#define gaim_quotedp_decode purple_quotedp_decode - -#define gaim_mime_decode_field purple_mime_deco_field - -#define gaim_utf8_strftime purple_utf8_strftime -#define gaim_date_format_short purple_date_format_short -#define gaim_date_format_long purple_date_format_long -#define gaim_date_format_full purple_date_format_full -#define gaim_time_format purple_time_format -#define gaim_time_build purple_time_build - -#define GAIM_NO_TZ_OFF PURPLE_NO_TZ_OFF - -#define gaim_str_to_time purple_str_to_time - -#define gaim_markup_find_tag purple_markup_find_tag -#define gaim_markup_extract_info_field purple_markup_extract_info_field -#define gaim_markup_html_to_xhtml purple_markup_html_to_xhtml -#define gaim_markup_strip_html purple_markup_strip_html -#define gaim_markup_linkify purple_markup_linkify -#define gaim_markup_slice purple_markup_slice -#define gaim_markup_get_tag_name purple_markup_get_tag_name -#define gaim_unescape_html purple_unescape_html - -#define gaim_home_dir purple_home_dir -#define gaim_user_dir purple_user_dir - -#define gaim_util_set_user_dir purple_util_set_user_dir - -#define gaim_build_dir purple_build_dir - -#define gaim_util_write_data_to_file purple_util_write_data_to_file - -#define gaim_util_read_xml_from_file purple_util_read_xml_from_file - -#define gaim_mkstemp purple_mkstemp - -#define gaim_program_is_valid purple_program_is_valid - -#define gaim_running_gnome purple_running_gnome -#define gaim_running_kde purple_running_kde -#define gaim_running_osx purple_running_osx - -#define gaim_fd_get_ip purple_fd_get_ip - -#define gaim_normalize purple_normalize -#define gaim_normalize_nocase purple_normalize_nocase - -#define gaim_strdup_withhtml purple_strdup_withhtml - -#define gaim_str_has_prefix purple_str_has_prefix -#define gaim_str_has_suffix purple_str_has_suffix -#define gaim_str_add_cr purple_str_add_cr -#define gaim_str_strip_char purple_str_strip_char - -#define gaim_util_chrreplace purple_util_chrreplace - -#define gaim_strreplace purple_strreplace - -#define gaim_utf8_ncr_encode purple_utf8_ncr_encode -#define gaim_utf8_ncr_decode purple_utf8_ncr_decode - -#define gaim_strcasereplace purple_strcasereplace -#define gaim_strcasestr purple_strcasestr - -#define gaim_str_size_to_units purple_str_size_to_units -#define gaim_str_seconds_to_string purple_str_seconds_to_string -#define gaim_str_binary_to_ascii purple_str_binary_to_ascii - - -#define gaim_got_protocol_handler_uri purple_got_protocol_handler_uri - -#define gaim_url_parse purple_url_parse - -#define GaimUtilFetchUrlCallback PurpleUtilFetchUrlCallback -#define gaim_util_fetch_url purple_util_fetch_url -#define gaim_util_fetch_url_request purple_util_fetch_url_request -#define gaim_util_fetch_url_cancel purple_util_fetch_url_cancel - -#define gaim_url_decode purple_url_decode -#define gaim_url_encode purple_url_encode - -#define gaim_email_is_valid purple_email_is_valid - -#define gaim_uri_list_extract_uris purple_uri_list_extract_uris -#define gaim_uri_list_extract_filenames purple_uri_list_extract_filenames - -#define gaim_utf8_try_convert purple_utf8_try_convert -#define gaim_utf8_salvage purple_utf8_salvage -#define gaim_utf8_strcasecmp purple_utf8_strcasecmp -#define gaim_utf8_has_word purple_utf8_has_word - -#define gaim_print_utf8_to_console purple_print_utf8_to_console - -#define gaim_message_meify purple_message_meify - -#define gaim_text_strip_mnemonic purple_text_strip_mnemonic - -#define gaim_unescape_filename purple_unescape_filename -#define gaim_escape_filename purple_escape_filename - -/* from value.h */ - -#define GAIM_TYPE_UNKNOWN PURPLE_TYPE_UNKNOWN -#define GAIM_TYPE_SUBTYPE PURPLE_TYPE_SUBTYPE -#define GAIM_TYPE_CHAR PURPLE_TYPE_CHAR -#define GAIM_TYPE_UCHAR PURPLE_TYPE_UCHAR -#define GAIM_TYPE_BOOLEAN PURPLE_TYPE_BOOLEAN -#define GAIM_TYPE_SHORT PURPLE_TYPE_SHORT -#define GAIM_TYPE_USHORT PURPLE_TYPE_USHORT -#define GAIM_TYPE_INT PURPLE_TYPE_INT -#define GAIM_TYPE_UINT PURPLE_TYPE_UINT -#define GAIM_TYPE_LONG PURPLE_TYPE_LONG -#define GAIM_TYPE_ULONG PURPLE_TYPE_ULONG -#define GAIM_TYPE_INT64 PURPLE_TYPE_INT64 -#define GAIM_TYPE_UINT64 PURPLE_TYPE_UINT64 -#define GAIM_TYPE_STRING PURPLE_TYPE_STRING -#define GAIM_TYPE_OBJECT PURPLE_TYPE_OBJECT -#define GAIM_TYPE_POINTER PURPLE_TYPE_POINTER -#define GAIM_TYPE_ENUM PURPLE_TYPE_ENUM -#define GAIM_TYPE_BOXED PURPLE_TYPE_BOXED -#define GaimType PurpleType - - -#define GAIM_SUBTYPE_UNKNOWN PURPLE_SUBTYPE_UNKNOWN -#define GAIM_SUBTYPE_ACCOUNT PURPLE_SUBTYPE_ACCOUNT -#define GAIM_SUBTYPE_BLIST PURPLE_SUBTYPE_BLIST -#define GAIM_SUBTYPE_BLIST_BUDDY PURPLE_SUBTYPE_BLIST_BUDDY -#define GAIM_SUBTYPE_BLIST_GROUP PURPLE_SUBTYPE_BLIST_GROUP -#define GAIM_SUBTYPE_BLIST_CHAT PURPLE_SUBTYPE_BLIST_CHAT -#define GAIM_SUBTYPE_BUDDY_ICON PURPLE_SUBTYPE_BUDDY_ICON -#define GAIM_SUBTYPE_CONNECTION PURPLE_SUBTYPE_CONNECTION -#define GAIM_SUBTYPE_CONVERSATION PURPLE_SUBTYPE_CONVERSATION -#define GAIM_SUBTYPE_PLUGIN PURPLE_SUBTYPE_PLUGIN -#define GAIM_SUBTYPE_BLIST_NODE PURPLE_SUBTYPE_BLIST_NODE -#define GAIM_SUBTYPE_CIPHER PURPLE_SUBTYPE_CIPHER -#define GAIM_SUBTYPE_STATUS PURPLE_SUBTYPE_STATUS -#define GAIM_SUBTYPE_LOG PURPLE_SUBTYPE_LOG -#define GAIM_SUBTYPE_XFER PURPLE_SUBTYPE_XFER -#define GAIM_SUBTYPE_SAVEDSTATUS PURPLE_SUBTYPE_SAVEDSTATUS -#define GAIM_SUBTYPE_XMLNODE PURPLE_SUBTYPE_XMLNODE -#define GAIM_SUBTYPE_USERINFO PURPLE_SUBTYPE_USERINFO -#define GaimSubType PurpleSubType - -#define GaimValue PurpleValue - -#define gaim_value_new purple_value_new -#define gaim_value_new_outgoing purple_value_new_outgoing -#define gaim_value_destroy purple_value_destroy -#define gaim_value_dup purple_value_dup -#define gaim_value_purple_buddy_icon_get_extensionget_type purple_value_get_type -#define gaim_value_get_subtype purple_value_get_subtype -#define gaim_value_get_specific_type purple_value_get_specific_type -#define gaim_value_is_outgoing purple_value_is_outgoing -#define gaim_value_set_char purple_value_set_char -#define gaim_value_set_uchar purple_value_set_uchar -#define gaim_value_set_boolean purple_value_set_boolean -#define gaim_value_set_short purple_value_set_short -#define gaim_value_set_ushort purple_value_set_ushort -#define gaim_value_set_int purple_value_set_int -#define gaim_value_set_uint purple_value_set_uint -#define gaim_value_set_long purple_value_set_long -#define gaim_value_set_ulong purple_value_set_ulong -#define gaim_value_set_int64 purple_value_set_int64 -#define gaim_value_set_uint64 purple_value_set_uint64 -#define gaim_value_set_string purple_value_set_string -#define gaim_value_set_object purple_value_set_object -#define gaim_value_set_pointer purple_value_set_pointer -#define gaim_value_set_enum purple_value_set_enum -#define gaim_value_set_boxed purple_value_set_boxed -#define gaim_value_get_char purple_value_get_char -#define gaim_value_get_uchar purple_value_get_uchar -#define gaim_value_get_boolean purple_value_get_boolean -#define gaim_value_get_short purple_value_get_short -#define gaim_value_get_ushort purple_value_get_ushort -#define gaim_value_get_int purple_value_get_int -#define gaim_value_get_uint purple_value_get_uint -#define gaim_value_get_long purple_value_get_long -#define gaim_value_get_ulong purple_value_get_ulong -#define gaim_value_get_int64 purple_value_get_int64 -#define gaim_value_get_uint64 purple_value_get_uint64 -#define gaim_value_get_string purple_value_get_string -#define gaim_value_get_object purple_value_get_object -#define gaim_value_get_pointer purple_value_get_pointer -#define gaim_value_get_enum purple_value_get_enum -#define gaim_value_get_boxed purple_value_get_boxed - -/* from version.h */ - -#define GAIM_MAJOR_VERSION PURPLE_MAJOR_VERSION -#define GAIM_MINOR_VERSION PURPLE_MINOR_VERSION -#define GAIM_MICRO_VERSION PURPLE_MICRO_VERSION - -#define GAIM_VERSION_CHECK PURPLE_VERSION_CHECK - -/* from whiteboard.h */ - -#define GaimWhiteboardPrplOps PurpleWhiteboardPrplOps -#define GaimWhiteboard PurpleWhiteboard -#define GaimWhiteboardUiOps PurpleWhiteboardUiOps - -#define gaim_whiteboard_set_ui_ops purple_whiteboard_set_ui_ops -#define gaim_whiteboard_set_prpl_ops purple_whiteboard_set_prpl_ops - -#define gaim_whiteboard_create purple_whiteboard_create -#define gaim_whiteboard_destroy purple_whiteboard_destroy -#define gaim_whiteboard_start purple_whiteboard_start -#define gaim_whiteboard_get_session purple_whiteboard_get_session -#define gaim_whiteboard_draw_list_destroy purple_whiteboard_draw_list_destroy -#define gaim_whiteboard_get_dimensions purple_whiteboard_get_dimensions -#define gaim_whiteboard_set_dimensions purple_whiteboard_set_dimensions -#define gaim_whiteboard_draw_point purple_whiteboard_draw_point -#define gaim_whiteboard_send_draw_list purple_whiteboard_send_draw_list -#define gaim_whiteboard_draw_line purple_whiteboard_draw_line -#define gaim_whiteboard_clear purple_whiteboard_clear -#define gaim_whiteboard_send_clear purple_whiteboard_send_clear -#define gaim_whiteboard_send_brush purple_whiteboard_send_brush -#define gaim_whiteboard_get_brush purple_whiteboard_get_brush -#define gaim_whiteboard_set_brush purple_whiteboard_set_brush - -/* for static plugins */ -#define gaim_init_ssl_plugin purple_init_ssl_plugin -#define gaim_init_ssl_openssl_plugin purple_init_ssl_openssl_plugin -#define gaim_init_ssl_gnutls_plugin purple_init_ssl_gnutls_plugin -#define gaim_init_gg_plugin purple_init_gg_plugin -#define gaim_init_jabber_plugin purple_init_jabber_plugin -#define gaim_init_sametime_plugin purple_init_sametime_plugin -#define gaim_init_msn_plugin purple_init_msn_plugin -#define gaim_init_novell_plugin purple_init_novell_plugin -#define gaim_init_qq_plugin purple_init_qq_plugin -#define gaim_init_simple_plugin purple_init_simple_plugin -#define gaim_init_yahoo_plugin purple_init_yahoo_plugin -#define gaim_init_zephyr_plugin purple_init_zephyr_plugin -#define gaim_init_aim_plugin purple_init_aim_plugin -#define gaim_init_icq_plugin purple_init_icq_plugin - -#endif /* _GAIM_COMPAT_H_ */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/internal.h --- a/libpurple/internal.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/internal.h Mon Aug 22 16:00:57 2011 +0000 @@ -151,12 +151,6 @@ #include -/* Safer ways to work with static buffers. When using non-static - * buffers, either use g_strdup_* functions (preferred) or use - * g_strlcpy/g_strlcpy directly. */ -#define purple_strlcpy(dest, src) g_strlcpy(dest, src, sizeof(dest)) -#define purple_strlcat(dest, src) g_strlcat(dest, src, sizeof(dest)) - #define PURPLE_WEBSITE "http://pidgin.im/" #define PURPLE_DEVEL_WEBSITE "http://developer.pidgin.im/" @@ -176,12 +170,6 @@ void _purple_buddy_icons_blist_loaded_cb(void); -/* This is for the purple_core_migrate() code to tell the buddy - * icon subsystem about the old icons directory so it can - * migrate any icons in use. */ -void -_purple_buddy_icon_set_old_icons_dir(const char *dirname); - /** * Creates a connection to the specified account and either connects * or attempts to register a new account. If you are logging in, diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/notify.c --- a/libpurple/notify.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/notify.c Mon Aug 22 16:00:57 2011 +0000 @@ -53,7 +53,7 @@ struct _PurpleNotifyUserInfo { - GList *user_info_entries; + GQueue entries; }; void * @@ -363,42 +363,24 @@ sc = g_new0(PurpleNotifySearchColumn, 1); sc->title = g_strdup(title); + sc->visible = TRUE; return sc; } -guint -purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results) +void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible) { - g_return_val_if_fail(results != NULL, 0); + g_return_if_fail(column != NULL); - return g_list_length(results->columns); -} - -guint -purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results) -{ - g_return_val_if_fail(results != NULL, 0); - - return g_list_length(results->rows); + column->visible = visible; } -char * -purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results, - unsigned int column_id) +gboolean +purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column) { - g_return_val_if_fail(results != NULL, NULL); + g_return_val_if_fail(column != NULL, FALSE); - return ((PurpleNotifySearchColumn *)g_list_nth_data(results->columns, column_id))->title; -} - -GList * -purple_notify_searchresults_row_get(PurpleNotifySearchResults *results, - unsigned int row_id) -{ - g_return_val_if_fail(results != NULL, NULL); - - return g_list_nth_data(results->rows, row_id); + return column->visible; } void * @@ -472,7 +454,7 @@ user_info = g_new0(PurpleNotifyUserInfo, 1); PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo); - user_info->user_info_entries = NULL; + g_queue_init(&user_info->entries); return user_info; } @@ -482,23 +464,23 @@ { GList *l; - for (l = user_info->user_info_entries; l != NULL; l = l->next) { + for (l = user_info->entries.head; l != NULL; l = l->next) { PurpleNotifyUserInfoEntry *user_info_entry = l->data; purple_notify_user_info_entry_destroy(user_info_entry); } - g_list_free(user_info->user_info_entries); + g_queue_clear(&user_info->entries); PURPLE_DBUS_UNREGISTER_POINTER(user_info); g_free(user_info); } -GList * +GQueue * purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info) { g_return_val_if_fail(user_info != NULL, NULL); - return user_info->user_info_entries; + return &user_info->entries; } char * @@ -509,7 +491,7 @@ text = g_string_new(""); - for (l = user_info->user_info_entries; l != NULL; l = l->next) { + for (l = user_info->entries.head; l != NULL; l = l->next) { PurpleNotifyUserInfoEntry *user_info_entry = l->data; /* Add a newline before a section header */ if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER) @@ -593,33 +575,41 @@ } void -purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value) +purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value) { PurpleNotifyUserInfoEntry *entry; entry = purple_notify_user_info_entry_new(label, value); - user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); + g_queue_push_tail(&user_info->entries, entry); } void purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value) { gchar *escaped; - PurpleNotifyUserInfoEntry *entry; escaped = g_markup_escape_text(value, -1); - entry = purple_notify_user_info_entry_new(label, escaped); + purple_notify_user_info_add_pair_html(user_info, label, escaped); g_free(escaped); - user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); } void -purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value) +purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value) { PurpleNotifyUserInfoEntry *entry; entry = purple_notify_user_info_entry_new(label, value); - user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); + g_queue_push_head(&user_info->entries, entry); +} + +void +purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value) +{ + gchar *escaped; + + escaped = g_markup_escape_text(value, -1); + purple_notify_user_info_prepend_pair_html(user_info, label, escaped); + g_free(escaped); } void @@ -628,7 +618,7 @@ g_return_if_fail(user_info != NULL); g_return_if_fail(entry != NULL); - user_info->user_info_entries = g_list_remove(user_info->user_info_entries, entry); + g_queue_remove(&user_info->entries, entry); } void @@ -639,7 +629,7 @@ entry = purple_notify_user_info_entry_new(label, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER; - user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); + g_queue_push_tail(&user_info->entries, entry); } void @@ -650,7 +640,7 @@ entry = purple_notify_user_info_entry_new(label, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER; - user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); + g_queue_push_head(&user_info->entries, entry); } void @@ -661,7 +651,7 @@ entry = purple_notify_user_info_entry_new(NULL, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK; - user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); + g_queue_push_tail(&user_info->entries, entry); } void @@ -672,17 +662,17 @@ entry = purple_notify_user_info_entry_new(NULL, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK; - user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); + g_queue_push_head(&user_info->entries, entry); } void purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info) { - GList *last = g_list_last(user_info->user_info_entries); - if (last) { - purple_notify_user_info_entry_destroy(last->data); - user_info->user_info_entries = g_list_delete_link(user_info->user_info_entries, last); - } + PurpleNotifyUserInfoEntry *entry; + + entry = g_queue_pop_tail(&user_info->entries); + if (entry) + purple_notify_user_info_entry_destroy(entry); } void * diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/notify.h --- a/libpurple/notify.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/notify.h Mon Aug 22 16:00:57 2011 +0000 @@ -111,7 +111,8 @@ */ typedef struct { - char *title; /**< Title of the column. */ + char *title; /**< Title of the column. */ + gboolean visible; /**< Should the column be visible to the user. Defaults to TRUE. */ } PurpleNotifySearchColumn; @@ -266,7 +267,8 @@ PurpleNotifySearchResults *purple_notify_searchresults_new(void); /** - * Returns a newly created search result column object. + * Returns a newly created search result column object. The column defaults + * to being visible. * * @param title Title of the column. NOTE: Title will get g_strdup()ed. * @@ -275,6 +277,23 @@ PurpleNotifySearchColumn *purple_notify_searchresults_column_new(const char *title); /** + * Sets whether or not a search result column is visible. + * + * @param field The search column object. + * @param visible TRUE if visible, or FALSE if not. + */ +void purple_notify_searchresult_column_set_visible(PurpleNotifySearchColumn *column, gboolean visible); + +/** + * Returns whether or not a search result column is visible. + * + * @param field The search column object. + * + * @return TRUE if the search result column is visible. FALSE otherwise. + */ +gboolean purple_notify_searchresult_column_is_visible(const PurpleNotifySearchColumn *column); + +/** * Adds a new column to the search result object. * * @param results The result object to which the column will be added. @@ -292,92 +311,6 @@ void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results, GList *row); -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) -/** - * Returns a number of the rows in the search results object. - * - * @deprecated This function will be removed in Pidgin 3.0.0 unless - * there is sufficient demand to keep it. Using this - * function encourages looping through the results - * inefficiently. Instead of using this function you - * should iterate through the results using a loop - * similar to this: - * for (l = results->rows; l != NULL; l = l->next) - * If you really need to get the number of rows you - * can use g_list_length(results->rows). - * - * @param results The search results object. - * - * @return Number of the result rows. - */ -guint purple_notify_searchresults_get_rows_count(PurpleNotifySearchResults *results); -#endif - -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) -/** - * Returns a number of the columns in the search results object. - * - * @deprecated This function will be removed in Pidgin 3.0.0 unless - * there is sufficient demand to keep it. Using this - * function encourages looping through the columns - * inefficiently. Instead of using this function you - * should iterate through the columns using a loop - * similar to this: - * for (l = results->columns; l != NULL; l = l->next) - * If you really need to get the number of columns you - * can use g_list_length(results->columns). - * - * @param results The search results object. - * - * @return Number of the columns. - */ -guint purple_notify_searchresults_get_columns_count(PurpleNotifySearchResults *results); -#endif - -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) -/** - * Returns a row of the results from the search results object. - * - * @deprecated This function will be removed in Pidgin 3.0.0 unless - * there is sufficient demand to keep it. Using this - * function encourages looping through the results - * inefficiently. Instead of using this function you - * should iterate through the results using a loop - * similar to this: - * for (l = results->rows; l != NULL; l = l->next) - * If you really need to get the data for a particular - * row you can use g_list_nth_data(results->rows, row_id). - * - * @param results The search results object. - * @param row_id Index of the row to be returned. - * - * @return Row of the results. - */ -GList *purple_notify_searchresults_row_get(PurpleNotifySearchResults *results, - unsigned int row_id); -#endif - -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) -/** - * Returns a title of the search results object's column. - * - * @deprecated This function will be removed in Pidgin 3.0.0 unless - * there is sufficient demand to keep it. Using this - * function encourages looping through the columns - * inefficiently. Instead of using this function you - * should iterate through the name of a particular - * column you can use - * g_list_nth_data(results->columns, row_id). - * - * @param results The search results object. - * @param column_id Index of the column. - * - * @return Title of the column. - */ -char *purple_notify_searchresults_column_get_title(PurpleNotifySearchResults *results, - unsigned int column_id); -#endif - /*@}*/ /**************************************************************************/ @@ -506,20 +439,20 @@ * Retrieve the array of PurpleNotifyUserInfoEntry objects from a * PurpleNotifyUserInfo * - * This GList may be manipulated directly with normal GList functions such - * as g_list_insert(). Only PurpleNotifyUserInfoEntry are allowed in the - * list. If a PurpleNotifyUserInfoEntry item is added to the list, it - * should not be g_free()'d by the caller; PurpleNotifyUserInfo will g_free - * it when destroyed. + * This GQueue may be manipulated directly with normal GQueue functions such + * as g_queue_push_tail(). Only PurpleNotifyUserInfoEntry are allowed in the + * queue. If a PurpleNotifyUserInfoEntry item is added to the queue, it + * should not be freed by the caller; PurpleNotifyUserInfo will free it when + * destroyed. * * To remove a PurpleNotifyUserInfoEntry, use - * purple_notify_user_info_remove_entry(). Do not use the GList directly. + * purple_notify_user_info_remove_entry(). Do not use the GQueue directly. * * @param user_info The PurpleNotifyUserInfo * - * @constreturn A GList of PurpleNotifyUserInfoEntry objects + * @constreturn A GQueue of PurpleNotifyUserInfoEntry objects. */ -GList *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info); +GQueue *purple_notify_user_info_get_entries(PurpleNotifyUserInfo *user_info); /** * Create a textual representation of a PurpleNotifyUserInfo, separating @@ -547,34 +480,25 @@ * the UI should treat label as independent and not * include a colon if it would otherwise. */ -/* - * TODO: In 3.0.0 this function should be renamed to - * purple_notify_user_info_add_pair_html(). And optionally - * purple_notify_user_info_add_pair_plaintext() could be renamed to - * purple_notify_user_info_add_pair(). - */ -void purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value); +void purple_notify_user_info_add_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value); /** - * Like purple_notify_user_info_add_pair, but value should be plaintext + * Like purple_notify_user_info_add_pair_html, but value should be plaintext * and will be escaped using g_markup_escape_text(). */ void purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value); /** - * Prepend a label/value pair to a PurpleNotifyUserInfo object - * - * @param user_info The PurpleNotifyUserInfo - * @param label A label, which for example might be displayed by a - * UI with a colon after it ("Status:"). Do not include - * a colon. If NULL, value will be displayed without a - * label. - * @param value The value, which might be displayed by a UI after - * the label. If NULL, label will still be displayed; - * the UI should then treat label as independent and not - * include a colon if it would otherwise. + * Like purple_notify_user_info_add_pair_html, but the pair is inserted + * at the beginning of the list. */ -void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value); +void purple_notify_user_info_prepend_pair_html(PurpleNotifyUserInfo *user_info, const char *label, const char *value); + +/** + * Like purple_notify_user_info_prepend_pair_html, but value should be plaintext + * and will be escaped using g_markup_escape_text(). + */ +void purple_notify_user_info_prepend_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value); #if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) /** @@ -597,9 +521,11 @@ * * If added to a PurpleNotifyUserInfo object, this should not be free()'d, * as PurpleNotifyUserInfo will do so when destroyed. - * purple_notify_user_info_add_pair() and - * purple_notify_user_info_prepend_pair() are convenience methods for - * creating entries and adding them to a PurpleNotifyUserInfo. + * purple_notify_user_info_add_pair_html(), + * purple_notify_user_info_add_pair_plaintext(), + * purple_notify_user_info_prepend_pair_html() and + * purple_notify_user_info_prepend_pair_plaintext() are convenience + * methods for creating entries and adding them to a PurpleNotifyUserInfo. * * @param label A label, which for example might be displayed by a UI * with a colon after it ("Status:"). Do not include a diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/plugins/perl/common/Connection.xs --- a/libpurple/plugins/perl/common/Connection.xs Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/plugins/perl/common/Connection.xs Mon Aug 22 16:00:57 2011 +0000 @@ -36,11 +36,6 @@ const char *text void -purple_connection_error(gc, reason) - Purple::Connection gc - const char *reason - -void purple_connection_destroy(gc) Purple::Connection gc diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/plugins/perl/common/Notify.xs --- a/libpurple/plugins/perl/common/Notify.xs Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/plugins/perl/common/Notify.xs Mon Aug 22 16:00:57 2011 +0000 @@ -135,7 +135,7 @@ PREINIT: GList *l; PPCODE: - l = purple_notify_user_info_get_entries(user_info); + l = purple_notify_user_info_get_entries(user_info)->head; for (; l != NULL; l = l->next) { XPUSHs(sv_2mortal(purple_perl_bless_object(l->data, "Purple::NotifyUserInfoEntry"))); } @@ -145,12 +145,12 @@ Purple::NotifyUserInfo user_info const char *newline -void purple_notify_user_info_add_pair(user_info, label, value) +void purple_notify_user_info_add_pair_html(user_info, label, value) Purple::NotifyUserInfo user_info const char *label const char *value -void purple_notify_user_info_prepend_pair(user_info, label, value) +void purple_notify_user_info_prepend_pair_html(user_info, label, value) Purple::NotifyUserInfo user_info const char *label const char *value diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/plugins/perl/common/Status.xs --- a/libpurple/plugins/perl/common/Status.xs Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/plugins/perl/common/Status.xs Mon Aug 22 16:00:57 2011 +0000 @@ -397,10 +397,6 @@ purple_status_type_get_name(status_type) Purple::StatusType status_type -const char * -purple_status_type_get_primary_attr(status_type) - Purple::StatusType status_type - Purple::StatusPrimitive purple_status_type_get_primitive(status_type) Purple::StatusType status_type @@ -440,8 +436,3 @@ gboolean saveable gboolean user_settable gboolean independent - -void -purple_status_type_set_primary_attr(status_type, attr_id) - Purple::StatusType status_type - const char *attr_id diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/plugins/tcl/tcl_cmds.c --- a/libpurple/plugins/tcl/tcl_cmds.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/plugins/tcl/tcl_cmds.c Mon Aug 22 16:00:57 2011 +0000 @@ -1640,13 +1640,13 @@ int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", - "independent", "name", "primary_attr", + "independent", "name", "primitive", "saveable", "user_settable", NULL }; enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, - CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR, + CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, CMD_STATUS_TYPE_USER_SETTABLE } cmd; PurpleStatusType *status_type; @@ -1751,18 +1751,6 @@ Tcl_NewStringObj(purple_primitive_get_id_from_type (purple_status_type_get_primitive(status_type)), -1)); break; - case CMD_STATUS_TYPE_PRIMARY_ATTR: -#if !(defined PURPLE_DISABLE_DEPRECATED) - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "statustype"); - return TCL_ERROR; - } - if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) - return TCL_ERROR; - Tcl_SetObjResult(interp, - Tcl_NewStringObj(purple_status_type_get_primary_attr(status_type), -1)); -#endif - break; case CMD_STATUS_TYPE_SAVEABLE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "statustype"); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/pounce.c --- a/libpurple/pounce.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/pounce.c Mon Aug 22 16:00:57 2011 +0000 @@ -405,12 +405,8 @@ } if (purple_strequal(element_name, "account")) { - char *tmp; g_free(data->account_name); data->account_name = g_strdup(buffer); - tmp = data->protocol_id; - data->protocol_id = g_strdup(_purple_oscar_convert(buffer, tmp)); - g_free(tmp); } else if (purple_strequal(element_name, "pouncee")) { g_free(data->pouncee); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/prefs.h --- a/libpurple/prefs.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/prefs.h Mon Aug 22 16:00:57 2011 +0000 @@ -32,7 +32,7 @@ /** * Preference data types. */ -typedef enum _PurplePrefType +typedef enum { PURPLE_PREF_NONE, /**< No type. */ PURPLE_PREF_BOOLEAN, /**< Boolean. */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/privacy.h --- a/libpurple/privacy.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/privacy.h Mon Aug 22 16:00:57 2011 +0000 @@ -29,7 +29,7 @@ /** * Privacy data types. */ -typedef enum _PurplePrivacyType +typedef enum { PURPLE_PRIVACY_ALLOW_ALL = 1, PURPLE_PRIVACY_DENY_ALL, diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/Makefile.am --- a/libpurple/protocols/Makefile.am Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/Makefile.am Mon Aug 22 16:00:57 2011 +0000 @@ -1,5 +1,5 @@ EXTRA_DIST = Makefile.mingw -DIST_SUBDIRS = bonjour gg irc jabber msn myspace mxit novell null oscar sametime silc silc10 simple yahoo zephyr +DIST_SUBDIRS = bonjour gg irc jabber msn myspace mxit novell null oscar sametime silc simple yahoo zephyr SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Mon Aug 22 16:00:57 2011 +0000 @@ -94,7 +94,7 @@ #ifdef _WIN32 if (!dns_sd_available()) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to find Apple's \"Bonjour for Windows\" toolkit, see " "http://d.pidgin.im/BonjourWindows for more information.")); @@ -114,7 +114,7 @@ if (bonjour_jabber_start(bd->jabber_data) == -1) { /* Send a message about the connection error */ - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to listen for incoming IM connections")); return; @@ -141,7 +141,7 @@ bd->dns_sd_data->account = account; if (!bonjour_dns_sd_start(bd->dns_sd_data)) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to establish connection with the local mDNS server. Is it running?")); return; @@ -371,9 +371,12 @@ else status_description = purple_status_get_name(status); - purple_notify_user_info_add_pair(user_info, _("Status"), status_description); - if (message != NULL) - purple_notify_user_info_add_pair(user_info, _("Message"), message); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_description); + if (message != NULL) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Message"), message); + } if (bb == NULL) { purple_debug_error("bonjour", "Got tooltip request for a buddy without protocol data.\n"); @@ -382,20 +385,35 @@ /* Only show first/last name if there is a nickname set (to avoid duplication) */ if (bb->nick != NULL && *bb->nick != '\0') { - if (bb->first != NULL && *bb->first != '\0') - purple_notify_user_info_add_pair(user_info, _("First name"), bb->first); - if (bb->last != NULL && *bb->last != '\0') - purple_notify_user_info_add_pair(user_info, _("Last name"), bb->last); + if (bb->first != NULL && *bb->first != '\0') { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("First name"), bb->first); + } + if (bb->last != NULL && *bb->last != '\0') { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Last name"), bb->last); + } } - if (bb->email != NULL && *bb->email != '\0') - purple_notify_user_info_add_pair(user_info, _("Email"), bb->email); + if (bb->email != NULL && *bb->email != '\0') { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Email"), bb->email); + } - if (bb->AIM != NULL && *bb->AIM != '\0') - purple_notify_user_info_add_pair(user_info, _("AIM Account"), bb->AIM); + if (bb->AIM != NULL && *bb->AIM != '\0') { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("AIM Account"), bb->AIM); + } - if (bb->jid != NULL && *bb->jid != '\0') - purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid); + if (bb->jid != NULL && *bb->jid != '\0') { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("XMPP Account"), bb->jid); + } } static void diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/bonjour/mdns_types.h --- a/libpurple/protocols/bonjour/mdns_types.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/bonjour/mdns_types.h Mon Aug 22 16:00:57 2011 +0000 @@ -37,7 +37,7 @@ gchar *msg; } BonjourDnsSd; -typedef enum _PublishType { +typedef enum { PUBLISH_START, PUBLISH_UPDATE } PublishType; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/bonjour/mdns_win32.c --- a/libpurple/protocols/bonjour/mdns_win32.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Mon Aug 22 16:00:57 2011 +0000 @@ -105,7 +105,7 @@ purple_debug_error("bonjour", "Error (%d) handling mDNS response.\n", errorCode); /* This happens when the mDNSResponder goes down, I haven't seen it happen any other time (in my limited testing) */ if (errorCode == kDNSServiceErr_Unknown) { - purple_connection_error_reason(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(srh->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Error communicating with local mDNSResponder.")); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/gg/buddylist.c --- a/libpurple/protocols/gg/buddylist.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/gg/buddylist.c Mon Aug 22 16:00:57 2011 +0000 @@ -90,7 +90,7 @@ gchar **data_tbl; gchar *name, *show, *g; - if (strlen(users_tbl[i]) == 0) + if (!*users_tbl[i]) continue; data_tbl = g_strsplit(users_tbl[i], ";", 8); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/gg/gg.c --- a/libpurple/protocols/gg/gg.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/gg/gg.c Mon Aug 22 16:00:57 2011 +0000 @@ -354,14 +354,14 @@ if (email == NULL || p1 == NULL || p2 == NULL || t == NULL || *email == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("You must fill in all registration fields")); goto exit_err; } if (g_utf8_collate(p1, p2) != 0) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Passwords do not match")); goto exit_err; @@ -371,7 +371,7 @@ token->id, t); h = gg_register3(email, p1, token->id, t, 0); if (h == NULL || !(s = h->data) || !s->success) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to register new account. An unknown error occurred.")); goto exit_err; @@ -1024,7 +1024,7 @@ purple_debug_info("gg", "gg_get_avatar_url_cb: " "requesting avatar for %s\n", uin); - url_data = purple_util_fetch_url_request_len_with_account(account, + url_data = purple_util_fetch_url_request_len(account, bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)", FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data); } @@ -1052,7 +1052,7 @@ avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin); - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( purple_connection_get_account(gc), avatarurl, TRUE, "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1, gg_get_avatar_url_cb, gc); @@ -1194,27 +1194,37 @@ val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS); /* XXX: Use of ggp_str_to_uin() is an ugly hack! */ - purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); g_free(val); who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN); - purple_notify_user_info_add_pair(user_info, _("UIN"), who); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("UIN"), who); val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME); - purple_notify_user_info_add_pair(user_info, _("First Name"), val); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("First Name"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME); - purple_notify_user_info_add_pair(user_info, _("Nickname"), val); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Nickname"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY); - purple_notify_user_info_add_pair(user_info, _("City"), val); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("City"), val); g_free(val); val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR); if (strncmp(val, "0", 1)) { - purple_notify_user_info_add_pair(user_info, _("Birth Year"), val); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Birth Year"), val); } g_free(val); @@ -1225,15 +1235,12 @@ if (NULL != buddy) { PurpleStatus *status; const char *msg; - char *text; status = purple_presence_get_active_status(purple_buddy_get_presence(buddy)); msg = purple_status_get_attr_string(status, "message"); if (msg != NULL) { - text = g_markup_escape_text(msg, -1); - purple_notify_user_info_add_pair(user_info, _("Message"), text); - g_free(text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg); } } @@ -1714,7 +1721,7 @@ if (!(ev = gg_watch_fd(info->session))) { purple_debug_error("gg", "ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n"); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to read from socket")); return; @@ -1880,7 +1887,7 @@ if (!(ev = gg_watch_fd(info->session))) { purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n"); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to read from socket")); return; @@ -1919,7 +1926,7 @@ case GG_EVENT_CONN_FAILED: purple_input_remove(gc->inpa); gc->inpa = 0; - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection failed")); break; @@ -1975,7 +1982,7 @@ static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { PurpleStatus *status; - char *text, *tmp; + char *tmp; const char *msg, *name, *alias; g_return_if_fail(b != NULL); @@ -1985,21 +1992,19 @@ name = purple_status_get_name(status); alias = purple_buddy_get_alias(b); - purple_notify_user_info_add_pair (user_info, _("Alias"), alias); + purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias); if (msg != NULL) { - text = g_markup_escape_text(msg, -1); if (PURPLE_BUDDY_IS_ONLINE(b)) { - tmp = g_strdup_printf("%s: %s", name, text); - purple_notify_user_info_add_pair(user_info, _("Status"), tmp); + tmp = g_strdup_printf("%s: %s", name, msg); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), tmp); g_free(tmp); } else { - purple_notify_user_info_add_pair(user_info, _("Message"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg); } - g_free(text); /* We don't want to duplicate 'Status: Offline'. */ } else if (PURPLE_BUDDY_IS_ONLINE(b)) { - purple_notify_user_info_add_pair(user_info, _("Status"), name); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name); } } @@ -2030,7 +2035,7 @@ NULL); types = g_list_append(types, type); - /* + /* * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because * libpurple can't support Chatty status) and Nie przeszkadzac */ @@ -2157,7 +2162,7 @@ if (addr == NULL) { gchar *tmp = g_strdup_printf(_("Unable to resolve hostname '%s': %s"), address, g_strerror(errno)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, /* should this be a settings error? */ tmp); g_free(tmp); @@ -2172,7 +2177,7 @@ info->session = gg_login(glp); purple_connection_update_progress(gc, _("Connecting"), 0, 2); if (info->session == NULL) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection failed")); g_free(glp); @@ -2582,7 +2587,7 @@ if (gg_ping(info->session) < 0) { purple_debug_info("gg", "Not connected to the server " "or gg_session is not correct\n"); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Not connected to the server")); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/irc/irc.c --- a/libpurple/protocols/irc/irc.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/irc/irc.c Mon Aug 22 16:00:57 2011 +0000 @@ -130,7 +130,7 @@ PurpleConnection *gc = purple_account_get_connection(irc->account); gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -174,7 +174,7 @@ PurpleConnection *gc = purple_account_get_connection(irc->account); gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } else if (ret < buflen) { @@ -359,7 +359,7 @@ gc->flags |= PURPLE_CONNECTION_NO_NEWLINES; if (strpbrk(username, " \t\v\r\n") != NULL) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("IRC nick and server may not contain whitespace")); return; @@ -390,7 +390,7 @@ purple_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT), irc_login_cb_ssl, irc_ssl_connect_failure, gc); } else { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); return; @@ -403,7 +403,7 @@ purple_account_get_int(account, "port", IRC_DEFAULT_PORT), irc_login_cb, gc) == NULL) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; @@ -490,7 +490,7 @@ if (source < 0) { gchar *tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -699,12 +699,12 @@ } else if (len < 0) { gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); return; @@ -730,12 +730,12 @@ } else if (len < 0) { gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); return; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/irc/msgs.c Mon Aug 22 16:00:57 2011 +0000 @@ -352,44 +352,40 @@ tmp = g_strdup_printf("%s%s%s", tmp2, (irc->whois.ircop ? _(" (ircop)") : ""), (irc->whois.identified ? _(" (identified)") : "")); - purple_notify_user_info_add_pair(user_info, _("Nick"), tmp); + purple_notify_user_info_add_pair_html(user_info, _("Nick"), tmp); g_free(tmp2); g_free(tmp); if (irc->whois.away) { - tmp = g_markup_escape_text(irc->whois.away, strlen(irc->whois.away)); + purple_notify_user_info_add_pair_plaintext(user_info, _("Away"), irc->whois.away); g_free(irc->whois.away); - purple_notify_user_info_add_pair(user_info, _("Away"), tmp); - g_free(tmp); } if (irc->whois.userhost) { - tmp = g_markup_escape_text(irc->whois.name, strlen(irc->whois.name)); + purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), irc->whois.userhost); + purple_notify_user_info_add_pair_plaintext(user_info, _("Real name"), irc->whois.name); + g_free(irc->whois.userhost); g_free(irc->whois.name); - purple_notify_user_info_add_pair(user_info, _("Username"), irc->whois.userhost); - purple_notify_user_info_add_pair(user_info, _("Real name"), tmp); - g_free(irc->whois.userhost); - g_free(tmp); } if (irc->whois.server) { tmp = g_strdup_printf("%s (%s)", irc->whois.server, irc->whois.serverinfo); - purple_notify_user_info_add_pair(user_info, _("Server"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Server"), tmp); g_free(tmp); g_free(irc->whois.server); g_free(irc->whois.serverinfo); } if (irc->whois.channels) { - purple_notify_user_info_add_pair(user_info, _("Currently on"), irc->whois.channels->str); + purple_notify_user_info_add_pair_plaintext(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); - purple_notify_user_info_add_pair(user_info, _("Idle for"), timex); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle for"), timex); g_free(timex); - purple_notify_user_info_add_pair(user_info, + purple_notify_user_info_add_pair_plaintext(user_info, _("Online since"), purple_date_format_full(localtime(&irc->whois.signon))); } - if (!strcmp(irc->whois.nick, "Paco-Paco")) { - purple_notify_user_info_add_pair(user_info, + if (!strcmp(irc->whois.nick, "elb")) { + purple_notify_user_info_add_pair_plaintext(user_info, _("Defining adjective:"), _("Glorious")); } @@ -1075,7 +1071,7 @@ _("Your selected nickname was rejected by the server. It probably contains invalid characters.")); } else { - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Your selected account name was rejected by the server. It probably contains invalid characters.")); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/irc/parse.c --- a/libpurple/protocols/irc/parse.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/irc/parse.c Mon Aug 22 16:00:57 2011 +0000 @@ -670,11 +670,11 @@ } else if (!strncmp(input, "ERROR ", 6)) { if (g_utf8_validate(input, -1, NULL)) { char *tmp = g_strdup_printf("%s\n%s", _("Disconnected."), input); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } else - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Disconnected.")); return; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/auth.c --- a/libpurple/protocols/jabber/auth.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/auth.c Mon Aug 22 16:00:57 2011 +0000 @@ -77,7 +77,7 @@ static void disallow_plaintext_auth(PurpleAccount *account) { - purple_connection_error_reason(purple_account_get_connection(account), + purple_connection_error(purple_account_get_connection(account), PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Server requires plaintext authentication over an unencrypted stream")); } @@ -145,7 +145,7 @@ mechs = xmlnode_get_child(packet, "mechanisms"); if(!mechs) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response from server")); return; @@ -186,7 +186,7 @@ if (js->auth_mech == NULL) { /* Found no good mechanisms... */ - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("Server does not use any supported authentication method")); return; @@ -194,7 +194,7 @@ state = js->auth_mech->start(js, mechs, &response, &msg); if (state == JABBER_SASL_STATE_FAIL) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, msg ? msg : _("Unknown Error")); } else if (response) { @@ -231,7 +231,7 @@ purple_account_set_password(account, NULL); } - purple_connection_error_reason(js->gc, reason, msg); + purple_connection_error(js->gc, reason, msg); g_free(msg); } } @@ -247,7 +247,7 @@ if (type == JABBER_IQ_ERROR) { PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; char *msg = jabber_parse_error(js, packet, &reason); - purple_connection_error_reason(js->gc, reason, msg); + purple_connection_error(js->gc, reason, msg); g_free(msg); } else if (type == JABBER_IQ_RESULT) { query = xmlnode_get_child(packet, "query"); @@ -321,7 +321,7 @@ } finish_plaintext_authentication(js); } else { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("Server does not use any supported authentication method")); return; @@ -345,7 +345,7 @@ if (!jabber_stream_is_ssl(js) && g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("You require encryption, but it is not available on this server.")); return; @@ -394,7 +394,7 @@ const char *ns = xmlnode_get_namespace(packet); if (!purple_strequal(ns, NS_XMPP_SASL)) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response from server")); return; @@ -405,7 +405,7 @@ char *msg = NULL; JabberSaslState state = js->auth_mech->handle_challenge(js, packet, &response, &msg); if (state == JABBER_SASL_STATE_FAIL) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, msg ? msg : _("Invalid challenge from server")); } else if (response) { @@ -423,7 +423,7 @@ const char *ns = xmlnode_get_namespace(packet); if (!purple_strequal(ns, NS_XMPP_SASL)) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response from server")); return; @@ -434,12 +434,12 @@ JabberSaslState state = js->auth_mech->handle_success(js, packet, &msg); if (state == JABBER_SASL_STATE_FAIL) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, msg ? msg : _("Invalid response from server")); return; } else if (state == JABBER_SASL_STATE_CONTINUE) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, msg ? msg : _("Server thinks authentication is complete, but client does not")); return; @@ -479,11 +479,11 @@ msg = jabber_parse_error(js, packet, &reason); if (!msg) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response from server")); } else { - purple_connection_error_reason(js->gc, reason, msg); + purple_connection_error(js->gc, reason, msg); g_free(msg); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/auth_cyrus.c --- a/libpurple/protocols/jabber/auth_cyrus.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/auth_cyrus.c Mon Aug 22 16:00:57 2011 +0000 @@ -34,7 +34,7 @@ static void disallow_plaintext_auth(PurpleAccount *account) { - purple_connection_error_reason(purple_account_get_connection(account), + purple_connection_error(purple_account_get_connection(account), PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Server may require plaintext authentication over an unencrypted stream")); } @@ -46,7 +46,7 @@ JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error); if (state == JABBER_SASL_STATE_FAIL) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, error); g_free(error); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/auth_plain.c --- a/libpurple/protocols/jabber/auth_plain.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/auth_plain.c Mon Aug 22 16:00:57 2011 +0000 @@ -75,7 +75,7 @@ static void disallow_plaintext_auth(PurpleAccount *account) { - purple_connection_error_reason(purple_account_get_connection(account), + purple_connection_error(purple_account_get_connection(account), PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Server requires plaintext authentication over an unencrypted stream")); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/bosh.c --- a/libpurple/protocols/jabber/bosh.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/bosh.c Mon Aug 22 16:00:57 2011 +0000 @@ -436,7 +436,7 @@ if (type != NULL && !strcmp(type, "terminate")) { conn->state = BOSH_CONN_OFFLINE; - purple_connection_error_reason(conn->js->gc, + purple_connection_error(conn->js->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("The BOSH connection manager terminated your session.")); return TRUE; @@ -539,7 +539,7 @@ if (sid) { conn->sid = g_strdup(sid); } else { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("No session ID given")); return; @@ -556,7 +556,7 @@ minor = atoi(dot + 1); if (major != 1 || minor < 6) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unsupported version of BOSH protocol")); return; @@ -733,7 +733,7 @@ return; if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) { - purple_connection_error_reason(conn->bosh->js->gc, + purple_connection_error(conn->bosh->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to establish a connection with the server")); } else { @@ -939,7 +939,7 @@ gchar *tmp; tmp = g_strdup_printf(_("Unable to establish a connection with the server: %s"), error); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -965,18 +965,18 @@ ssl_connection_error_cb, conn); if (!conn->psc) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("Unable to establish SSL connection")); } } else { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); } } else if (purple_proxy_connect(conn, account, bosh->host, bosh->port, connection_established_cb, conn) == NULL) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } @@ -1023,7 +1023,7 @@ */ gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(conn->bosh->js->gc, + purple_connection_error(conn->bosh->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); @@ -1079,7 +1079,7 @@ */ gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(conn->bosh->js->gc, + purple_connection_error(conn->bosh->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/buddy.c Mon Aug 22 16:00:57 2011 +0000 @@ -465,10 +465,22 @@ xmlnode *vc_node; const struct tag_attr *tag_attr; - /* if we have't grabbed the remote vcard yet, we can't + /* if we haven't grabbed the remote vcard yet, we can't * assume that what we have here is correct */ - if(!js->vcard_fetched) + if(!js->vcard_fetched) { + PurpleStoredImage *image; + g_free(js->initial_avatar_hash); + image = purple_buddy_icons_find_account_icon(purple_connection_get_account(gc)); + if (image != NULL) { + js->initial_avatar_hash = + jabber_calculate_data_hash(purple_imgstore_get_data(image), + purple_imgstore_get_size(image), "sha1"); + purple_imgstore_unref(image); + } else { + js->initial_avatar_hash = NULL; + } return; + } if (js->vcard_timer) { purple_timeout_remove(js->vcard_timer); @@ -719,11 +731,16 @@ g_strdup_printf("%s%s%s", jbr->client.name, (jbr->client.version ? " " : ""), (jbr->client.version ? jbr->client.version : "")); - purple_notify_user_info_prepend_pair(user_info, _("Client"), tmp); + /* TODO: Check whether it's correct to call prepend_pair_html, + or if we should be using prepend_pair_plaintext */ + purple_notify_user_info_prepend_pair_html(user_info, _("Client"), tmp); g_free(tmp); - if (jbr->client.os) - purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os); + if (jbr->client.os) { + /* TODO: Check whether it's correct to call prepend_pair_html, + or if we should be using prepend_pair_plaintext */ + purple_notify_user_info_prepend_pair_html(user_info, _("Operating System"), jbr->client.os); + } } if (jbr && jbr->tz_off != PURPLE_NO_TZ_OFF) { @@ -739,13 +756,13 @@ jbr->tz_off < 0 ? '-' : '+', abs(jbr->tz_off / (60*60)), abs((jbr->tz_off % (60*60)) / 60)); - purple_notify_user_info_prepend_pair(user_info, _("Local Time"), timestamp); + purple_notify_user_info_prepend_pair_plaintext(user_info, _("Local Time"), timestamp); g_free(timestamp); } if (jbir && jbir->idle_seconds > 0) { char *idle = purple_str_seconds_to_string(jbir->idle_seconds); - purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle); + purple_notify_user_info_prepend_pair_plaintext(user_info, _("Idle"), idle); g_free(idle); } @@ -767,15 +784,15 @@ tmp = g_strdup_printf("%s%s%s", (status_name ? status_name : ""), ((status_name && purdy) ? ": " : ""), (purdy ? purdy : "")); - purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp); + purple_notify_user_info_prepend_pair_html(user_info, _("Status"), tmp); g_snprintf(priority, sizeof(priority), "%d", jbr->priority); - purple_notify_user_info_prepend_pair(user_info, _("Priority"), priority); + purple_notify_user_info_prepend_pair_plaintext(user_info, _("Priority"), priority); g_free(tmp); g_free(purdy); } else { - purple_notify_user_info_prepend_pair(user_info, _("Status"), _("Unknown")); + purple_notify_user_info_prepend_pair_plaintext(user_info, _("Status"), _("Unknown")); } } @@ -794,7 +811,7 @@ resource_name = jabber_get_resource(jbi->jid); /* If we have one or more pairs from the vcard, put a section break above it */ - if (purple_notify_user_info_get_entries(user_info)) + if (g_queue_get_length(purple_notify_user_info_get_entries(user_info))) purple_notify_user_info_prepend_section_break(user_info); /* Add the information about the user's resource(s) */ @@ -815,8 +832,11 @@ add_jbr_info(jbi, jbr->name, jbr); - if (jbr->name) - purple_notify_user_info_prepend_pair(user_info, _("Resource"), jbr->name); + if (jbr->name) { + /* TODO: Check whether it's correct to call prepend_pair_html, + or if we should be using prepend_pair_plaintext */ + purple_notify_user_info_prepend_pair_html(user_info, _("Resource"), jbr->name); + } } } @@ -836,7 +856,7 @@ title = _("Logged Off"); message = g_strdup_printf(_("%s ago"), last); } - purple_notify_user_info_prepend_pair(user_info, title, message); + purple_notify_user_info_prepend_pair_plaintext(user_info, title, message); g_free(last); g_free(message); } @@ -846,7 +866,9 @@ g_strdup_printf("%s%s%s", _("Offline"), jbi->last_message ? ": " : "", jbi->last_message ? jbi->last_message : ""); - purple_notify_user_info_prepend_pair(user_info, _("Status"), status); + /* TODO: Check whether it's correct to call prepend_pair_html, + or if we should be using prepend_pair_plaintext */ + purple_notify_user_info_prepend_pair_html(user_info, _("Status"), status); g_free(status); } } @@ -1124,7 +1146,7 @@ char *mailto; escaped = g_markup_escape_text(userid, -1); mailto = g_strdup_printf("%s", escaped, escaped); - purple_notify_user_info_add_pair(user_info, _("Email"), mailto); + purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto); g_free(mailto); g_free(escaped); @@ -1137,7 +1159,7 @@ escaped = g_markup_escape_text(userid, -1); mailto = g_strdup_printf("%s", escaped, escaped); - purple_notify_user_info_add_pair(user_info, _("Email"), mailto); + purple_notify_user_info_add_pair_html(user_info, _("Email"), mailto); g_free(mailto); g_free(escaped); @@ -1184,7 +1206,7 @@ jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png"))); img_text = g_strdup_printf("", GPOINTER_TO_INT(jbi->vcard_imgids->data)); - purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text); + purple_notify_user_info_add_pair_html(user_info, (photo ? _("Photo") : _("Logo")), img_text); hash = jabber_calculate_data_hash(data, size, "sha1"); purple_buddy_icons_set_for_user(account, bare_jid, data, size, hash); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/jabber.c Mon Aug 22 16:00:57 2011 +0000 @@ -119,7 +119,7 @@ if(js->unregistration) jabber_unregister_account_cb(js); } else { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, ("Error initializing session")); } @@ -153,7 +153,7 @@ js->user = jabber_id_new(full_jid); if (js->user == NULL) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response from server")); g_free(full_jid); @@ -170,7 +170,7 @@ } else { PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; char *msg = jabber_parse_error(js, packet, &reason); - purple_connection_error_reason(js->gc, reason, msg); + purple_connection_error(js->gc, reason, msg); g_free(msg); return; @@ -247,14 +247,14 @@ starttls = xmlnode_get_child(packet, "starttls"); if(xmlnode_get_child(starttls, "required")) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("Server requires TLS/SSL, but no TLS/SSL support was found.")); return TRUE; } if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("You require encryption, but no TLS/SSL support was found.")); return TRUE; @@ -275,7 +275,7 @@ return; } } else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("You require encryption, but it is not available on this server.")); return; @@ -320,7 +320,7 @@ PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; char *msg = jabber_parse_error(js, packet, &reason); - purple_connection_error_reason(js->gc, reason, msg); + purple_connection_error(js->gc, reason, msg); g_free(msg); } @@ -407,7 +407,7 @@ else if (ret <= 0) { gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -443,7 +443,7 @@ if (!account->disconnecting) { gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } @@ -544,7 +544,7 @@ purple_debug_error("jabber", "sasl_encode error %d: %s\n", rc, sasl_errdetail(js->sasl)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error); g_free(error); @@ -617,7 +617,7 @@ static gboolean jabber_keepalive_timeout(PurpleConnection *gc) { JabberStream *js = gc->proto_data; - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Ping timed out")); js->keepalive_timeout = 0; return FALSE; @@ -670,7 +670,7 @@ else tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } @@ -702,7 +702,7 @@ purple_debug_error("jabber", "sasl_decode_error %d: %s\n", rc, sasl_errdetail(js->sasl)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error); } else if (olen > 0) { @@ -728,7 +728,7 @@ else tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } @@ -789,7 +789,7 @@ if (!found) { purple_debug_warning("jabber", "Unable to find alternative XMPP connection " "methods after failing to connect directly.\n"); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; @@ -874,7 +874,7 @@ if (purple_proxy_connect(js->gc, purple_connection_get_account(js->gc), host, port, jabber_login_callback, js->gc) == NULL) { if (fatal_failure) { - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } @@ -940,7 +940,7 @@ js->user = jabber_id_new(user); if (!js->user) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Invalid XMPP ID")); g_free(user); @@ -949,7 +949,7 @@ } if (!js->user->node || *(js->user->node) == '\0') { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Invalid XMPP ID. Username portion must be set.")); g_free(user); @@ -958,7 +958,7 @@ } if (!js->user->domain || *(js->user->domain) == '\0') { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Invalid XMPP ID. Domain must be set.")); g_free(user); @@ -978,7 +978,7 @@ g_free(user); if (!js->user_jb) { /* This basically *can't* fail, but for good measure... */ - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Invalid XMPP ID")); /* Destroying the connection will free the JabberStream */ @@ -1037,7 +1037,7 @@ if (js->bosh) jabber_bosh_connection_connect(js->bosh); else { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Malformed BOSH URL")); } @@ -1054,12 +1054,12 @@ purple_account_get_int(account, "port", 5223), jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); if (!js->gsc) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("Unable to establish SSL connection")); } } else { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); } @@ -2225,7 +2225,7 @@ label = g_strdup_printf("%s%s", _("Status"), (res ? res : "")); value = g_strdup_printf("%s%s%s", state, (text ? ": " : ""), (text ? text : "")); - purple_notify_user_info_add_pair(user_info, label, value); + purple_notify_user_info_add_pair_html(user_info, label, value); g_free(label); g_free(value); g_free(text); @@ -2238,7 +2238,7 @@ gchar *idle_str = purple_str_seconds_to_string(time(NULL) - jbr->idle); label = g_strdup_printf("%s%s", _("Idle"), (res ? res : "")); - purple_notify_user_info_add_pair(user_info, label, idle_str); + purple_notify_user_info_add_pair_plaintext(user_info, label, idle_str); g_free(idle_str); g_free(label); } @@ -2310,10 +2310,10 @@ char *moodplustext = g_strdup_printf("%s (%s)", description ? _(description) : mood, moodtext); - purple_notify_user_info_add_pair(user_info, _("Mood"), moodplustext); + purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodplustext); g_free(moodplustext); } else - purple_notify_user_info_add_pair(user_info, _("Mood"), + purple_notify_user_info_add_pair_html(user_info, _("Mood"), description ? _(description) : mood); } if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) { @@ -2323,7 +2323,7 @@ const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM); char *playing = purple_util_format_song_info(title, artist, album, NULL); if (playing) { - purple_notify_user_info_add_pair(user_info, _("Now Listening"), playing); + purple_notify_user_info_add_pair_html(user_info, _("Now Listening"), playing); g_free(playing); } } @@ -2344,12 +2344,12 @@ sub = _("None"); } - purple_notify_user_info_add_pair(user_info, _("Subscription"), sub); + purple_notify_user_info_add_pair_html(user_info, _("Subscription"), sub); } if(!PURPLE_BUDDY_IS_ONLINE(b) && jb->error_msg) { - purple_notify_user_info_add_pair(user_info, _("Error"), jb->error_msg); + purple_notify_user_info_add_pair_html(user_info, _("Error"), jb->error_msg); } } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/jabber/parser.c --- a/libpurple/protocols/jabber/parser.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/jabber/parser.c Mon Aug 22 16:00:57 2011 +0000 @@ -52,7 +52,7 @@ */ purple_debug_error("jabber", "Expecting stream header, got %s with " "xmlns %s\n", element_name, namespace); - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("XMPP stream header missing")); return; @@ -73,7 +73,7 @@ if (js->protocol_version.major > 1) { /* TODO: Send error */ - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("XMPP Version Mismatch")); g_free(attrib); @@ -98,7 +98,7 @@ /* This was underspecified in rfc3920 as only being a SHOULD, so * we cannot rely on it. See #12331 and Oracle's server. */ - purple_connection_error_reason(js->gc, + purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("XMPP stream missing ID")); #else @@ -300,7 +300,7 @@ break; case XML_ERR_FATAL: purple_debug_error("jabber", "xmlParseChunk returned fatal %i\n", ret); - purple_connection_error_reason (js->gc, + purple_connection_error (js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("XML Parse error")); break; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/msn/msn.c Mon Aug 22 16:00:57 2011 +0000 @@ -1078,7 +1078,7 @@ if (psm != NULL && *psm) { purple_notify_user_info_add_pair_plaintext(user_info, tmp2, psm); } else { - purple_notify_user_info_add_pair(user_info, _("Status"), tmp2); + purple_notify_user_info_add_pair_html(user_info, _("Status"), tmp2); } g_free(tmp2); @@ -1091,17 +1091,19 @@ } } else { if (purple_presence_is_idle(presence)) { - purple_notify_user_info_add_pair(user_info, _("Status"), - _("Idle")); + purple_notify_user_info_add_pair_plaintext(user_info, + _("Status"), _("Idle")); } else { - purple_notify_user_info_add_pair(user_info, _("Status"), - purple_status_get_name(status)); + purple_notify_user_info_add_pair_plaintext(user_info, + _("Status"), purple_status_get_name(status)); } } } if (currentmedia) { - purple_notify_user_info_add_pair(user_info, mediatype, currentmedia); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, mediatype, currentmedia); g_free(currentmedia); } } @@ -1119,23 +1121,32 @@ { const char *phone; - purple_notify_user_info_add_pair(user_info, _("Has you"), + purple_notify_user_info_add_pair_plaintext(user_info, _("Has you"), ((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No"))); - purple_notify_user_info_add_pair(user_info, _("Blocked"), + purple_notify_user_info_add_pair_plaintext(user_info, _("Blocked"), ((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No"))); phone = msn_user_get_home_phone(user); - if (phone != NULL) - purple_notify_user_info_add_pair(user_info, _("Home Phone Number"), phone); + if (phone != NULL) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Home Phone Number"), phone); + } phone = msn_user_get_work_phone(user); - if (phone != NULL) - purple_notify_user_info_add_pair(user_info, _("Work Phone Number"), phone); + if (phone != NULL) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Work Phone Number"), phone); + } phone = msn_user_get_mobile_phone(user); - if (phone != NULL) - purple_notify_user_info_add_pair(user_info, _("Mobile Phone Number"), phone); + if (phone != NULL) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Mobile Phone Number"), phone); + } } } @@ -1333,7 +1344,7 @@ if (!purple_ssl_is_supported()) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support is needed for MSN. Please install a supported " "SSL library.")); @@ -1374,7 +1385,7 @@ } if (!msn_session_connect(session, host, port, http_method)) - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } @@ -2262,7 +2273,7 @@ { char *nicktext = g_markup_escape_text(alias, -1); tmp = g_strdup_printf("%s", nicktext); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp); + purple_notify_user_info_add_pair_html(user_info, _("Nickname"), tmp); g_free(tmp); g_free(nicktext); } @@ -2361,7 +2372,7 @@ if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) { - purple_notify_user_info_add_pair(user_info, + purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL); purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL); @@ -2680,7 +2691,7 @@ if (user_url != NULL) { tmp = g_strdup_printf("%s", user_url, user_url); - purple_notify_user_info_add_pair(user_info, _("Homepage"), tmp); + purple_notify_user_info_add_pair_html(user_info, _("Homepage"), tmp); g_free(tmp); g_free(user_url); @@ -2703,9 +2714,9 @@ char *p = strstr(url_buffer, "
gc), info_data->name); - purple_notify_user_info_add_pair(user_info, + purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL); - purple_notify_user_info_add_pair(user_info, NULL, + purple_notify_user_info_add_pair_plaintext(user_info, NULL, ((p && b) ? _("The user has not created a public profile.") : (p ? _("MSN reported not being able to find the user's profile. " "This either means that the user does not exist, " @@ -2720,7 +2731,7 @@ purple_notify_user_info_add_section_break(user_info); tmp = g_strdup_printf("%s", PROFILE_URL, info_data->name, _("View web profile")); - purple_notify_user_info_add_pair(user_info, NULL, tmp); + purple_notify_user_info_add_pair_html(user_info, NULL, tmp); g_free(tmp); #if PHOTO_SUPPORT @@ -2801,7 +2812,7 @@ purple_debug_info("msn", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len); id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL); g_snprintf(buf, sizeof(buf), "
", id); - purple_notify_user_info_prepend_pair(user_info, NULL, buf); + purple_notify_user_info_prepend_pair_html(user_info, NULL, buf); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/msn/session.c --- a/libpurple/protocols/msn/session.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/msn/session.c Mon Aug 22 16:00:57 2011 +0000 @@ -420,7 +420,7 @@ msn_session_disconnect(session); - purple_connection_error_reason(gc, reason, msg); + purple_connection_error(gc, reason, msg); g_free(msg); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/actions.c --- a/libpurple/protocols/mxit/actions.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/actions.c Mon Aug 22 16:00:57 2011 +0000 @@ -84,13 +84,6 @@ g_string_append( attributes, attrib ); acount++; - /* force hidden if disabled */ - if ( profile->hidden == FALSE ) { - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROFILE_TYPE_BOOL, "1" ); - g_string_append( attributes, attrib ); - acount++; - } - /* update birthday */ g_strlcpy( profile->birthday, bday, sizeof( profile->birthday ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROFILE_TYPE_UTF8, profile->birthday ); @@ -165,7 +158,7 @@ /* update where am i */ name = purple_request_fields_get_string( fields, "whereami" ); - if ( !name) + if ( !name ) profile->whereami[0] = '\0'; else g_strlcpy( profile->whereami, name, sizeof( profile->whereami ) ); @@ -375,8 +368,8 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_change_pin_action\n" ); fields = purple_request_fields_new(); - group = purple_request_field_group_new(NULL); - purple_request_fields_add_group(fields, group); + group = purple_request_field_group_new( NULL ); + purple_request_fields_add_group( fields, group ); /* pin */ field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE ); @@ -479,10 +472,10 @@ _( "Search for a MXit contact" ), _( "Type search information" ), NULL, FALSE, FALSE, NULL, - _("_Search"), G_CALLBACK( mxit_user_search_cb ), - _("_Cancel"), NULL, + _( "_Search" ), G_CALLBACK( mxit_user_search_cb ), + _( "_Cancel" ), NULL, purple_connection_get_account( gc ), NULL, NULL, - gc); + gc ); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/cipher.c --- a/libpurple/protocols/mxit/cipher.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/cipher.c Mon Aug 22 16:00:57 2011 +0000 @@ -1,7 +1,7 @@ /* * MXit Protocol libPurple Plugin * - * -- user password encryption -- + * -- encryption -- * * Pieter Loubser * @@ -31,30 +31,69 @@ #include "aes.h" -/* password encryption */ +/* encryption */ #define INITIAL_KEY "6170383452343567" #define SECRET_HEADER "" +#define ENCRYPT_HEADER "" + + +/*------------------------------------------------------------------------ + * Add ISO10126 Padding to the data. + * + * @param data The data to pad. + */ +static void padding_add( GString* data ) +{ + unsigned int blocks = ( data->len / 16 ) + 1; + unsigned int padding = ( blocks * 16 ) - data->len; + + g_string_set_size( data, blocks * 16 ); + data->str[data->len - 1] = padding; +} /*------------------------------------------------------------------------ - * Pad the secret data using ISO10126 Padding. + * Remove ISO10126 Padding from the data. * - * @param secret The data to pad (caller must ensure buffer has enough space for padding) - * @return The total number of 128-bit blocks used + * @param data The data from which to remove padding. */ -static int pad_secret_data( char* secret ) +static void padding_remove( GString* data ) { - int blocks = 0; - int passlen; - int padding; + unsigned int padding; + + if ( data->len == 0 ) + return; + + padding = data->str[data->len - 1]; + g_string_truncate( data, data->len - padding ); +} + - passlen = strlen( secret ); - blocks = ( passlen / 16 ) + 1; - padding = ( blocks * 16 ) - passlen; - secret[passlen] = 0x50; - secret[(blocks * 16) - 1] = padding; +/*------------------------------------------------------------------------ + * Generate the Transport-Layer crypto key. + * (Note: this function is not-thread safe) + * + * @param session The MXit Session object + * @return The transport-layer crypto key. + */ +static char* transport_layer_key( struct MXitSession* session ) +{ + static char key[16 + 1]; + int passlen = strlen( session->acc->password ); - return blocks; + /* initialize with initial key */ + g_strlcpy( key, INITIAL_KEY, sizeof( key ) ); + + /* client key (8 bytes) */ + memcpy( key, session->clientkey, strlen( session->clientkey ) ); + + /* add last 8 characters of the PIN (no padding if less characters) */ + if ( passlen <= 8 ) + memcpy( key + 8, session->acc->password, passlen ); + else + memcpy( key + 8, session->acc->password + ( passlen - 8 ), 8 ); + + return key; } @@ -67,42 +106,131 @@ */ char* mxit_encrypt_password( struct MXitSession* session ) { - char key[64]; + char key[16 + 1]; char exkey[512]; - char pass[64]; + GString* pass = NULL; char encrypted[64]; char* base64; - int blocks; - int size; int i; purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" ); memset( encrypted, 0x00, sizeof( encrypted ) ); - memset( exkey, 0x00, sizeof( exkey ) ); - memset( pass, 0x58, sizeof( pass ) ); - pass[sizeof( pass ) - 1] = '\0'; - /* build the custom AES encryption key */ + /* build the AES encryption key */ g_strlcpy( key, INITIAL_KEY, sizeof( key ) ); memcpy( key, session->clientkey, strlen( session->clientkey ) ); ExpandKey( (unsigned char*) key, (unsigned char*) exkey ); - /* build the custom data to be encrypted */ - g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) ); - strcat( pass, session->acc->password ); + /* build the secret data to be encrypted: SECRET_HEADER + password */ + pass = g_string_new( SECRET_HEADER ); + g_string_append( pass, session->acc->password ); + padding_add( pass ); /* add ISO10126 padding */ - /* pad the secret data */ - blocks = pad_secret_data( pass ); - size = blocks * 16; - - /* now encrypt the password. we encrypt each block separately (ECB mode) */ - for ( i = 0; i < size; i += 16 ) - Encrypt( (unsigned char*) pass + i, (unsigned char*) exkey, (unsigned char*) encrypted + i ); + /* now encrypt the secret. we encrypt each block separately (ECB mode) */ + for ( i = 0; i < pass->len; i += 16 ) + Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) encrypted + i ); /* now base64 encode the encrypted password */ - base64 = purple_base64_encode( (unsigned char*) encrypted, size ); + base64 = purple_base64_encode( (unsigned char*) encrypted, pass->len ); + + g_string_free( pass, TRUE ); return base64; } + +/*------------------------------------------------------------------------ + * Decrypt a message using transport-layer encryption. + * + * @param session The MXit session object + * @param message The encrypted message data (is base64-encoded). + * @return The decrypted message. Must be g_free'd when no longer needed. + */ +char* mxit_decrypt_message( struct MXitSession* session, char* message ) +{ + guchar* raw_message; + gsize raw_len; + char exkey[512]; + GString* decoded = NULL; + int i; + + /* remove optional header: */ + if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 ) + message += strlen( ENCRYPT_HEADER ); + + /* base64 decode the message */ + raw_message = purple_base64_decode( message, &raw_len ); + + /* build the AES key */ + ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey ); + + /* AES decrypt each block */ + decoded = g_string_sized_new( raw_len ); + for ( i = 0; i < raw_len; i += 16 ) { + char block[16]; + + Decrypt( (unsigned char*) raw_message + i, (unsigned char*) exkey, (unsigned char*) block ); + g_string_append_len( decoded, block, 16 ); + } + g_free( raw_message ); + + /* check that the decrypted message starts with header: */ + if ( strncmp( decoded->str, SECRET_HEADER, strlen( SECRET_HEADER ) != 0 ) ) { + g_string_free( decoded, TRUE ); + return NULL; /* message could not be decrypted */ + } + + /* remove ISO10126 padding */ + padding_remove( decoded ); + + /* remove encryption header */ + g_string_erase( decoded, 0, strlen( SECRET_HEADER ) ); + + return g_string_free( decoded, FALSE ); +} + + +/*------------------------------------------------------------------------ + * Encrypt a message using transport-layer encryption. + * + * @param session The MXit session object + * @param message The message data. + * @return The encrypted message. Must be g_free'd when no longer needed. + */ +char* mxit_encrypt_message( struct MXitSession* session, char* message ) +{ + GString* raw_message = NULL; + char exkey[512]; + GString* encoded = NULL; + gchar* base64; + int i; + + purple_debug_info( MXIT_PLUGIN_ID, "encrypt message: '%s'\n", message ); + + /* append encryption header to message data */ + raw_message = g_string_new( SECRET_HEADER ); + g_string_append( raw_message, message ); + padding_add( raw_message ); /* add ISO10126 padding */ + + /* build the AES key */ + ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey ); + + /* AES encrypt each block */ + encoded = g_string_sized_new( raw_message->len ); + for ( i = 0; i < raw_message->len; i += 16 ) { + char block[16]; + + Encrypt( (unsigned char*) raw_message->str + i, (unsigned char*) exkey, (unsigned char*) block ); + g_string_append_len( encoded, block, 16 ); + } + g_string_free( raw_message, TRUE ); + + /* base64 encode the encrypted message */ + base64 = purple_base64_encode( (unsigned char *) encoded->str, encoded->len ); + g_string_free( encoded, TRUE ); + + purple_debug_info( MXIT_PLUGIN_ID, "encrypted message: '%s'\n", base64 ); + + return base64; +} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/cipher.h --- a/libpurple/protocols/mxit/cipher.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/cipher.h Mon Aug 22 16:00:57 2011 +0000 @@ -1,7 +1,7 @@ /* * MXit Protocol libPurple Plugin * - * -- user password encryption -- + * -- encryption -- * * Pieter Loubser * @@ -32,5 +32,7 @@ char* mxit_encrypt_password( struct MXitSession* session ); +char* mxit_decrypt_message( struct MXitSession* session, char* message ); +char* mxit_encrypt_message( struct MXitSession* session, char* message ); #endif /* _MXIT_CIPHER_H_ */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/formcmds.c --- a/libpurple/protocols/mxit/formcmds.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/formcmds.c Mon Aug 22 16:00:57 2011 +0000 @@ -253,8 +253,8 @@ /*------------------------------------------------------------------------ * Process a Reply MXit command. - * [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|id=12345:] - * [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|id=12345:] + * [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:] + * [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:] * * @param mx The received message data object * @param hash The MXit command map @@ -265,22 +265,26 @@ char* selmsg; char* nm; - selmsg = g_hash_table_lookup(hash, "selmsg"); /* find the selection message */ - replymsg = g_hash_table_lookup(hash, "replymsg"); /* find the reply message */ + selmsg = g_hash_table_lookup(hash, "selmsg"); /* selection message */ + replymsg = g_hash_table_lookup(hash, "replymsg"); /* reply message */ nm = g_hash_table_lookup(hash, "nm"); /* name parameter */ - if ((selmsg) && (replymsg) && (nm)) { + + if ((selmsg == NULL) || (replymsg == NULL)) + return; /* these parameters are required */ + + if (nm) { /* indicates response must be a structured response */ gchar* seltext = g_markup_escape_text(purple_url_decode(selmsg), -1); - gchar* replycmd = g_strdup_printf("::type=reply|nm=%s|res=%s|err=0:", nm, replymsg); + gchar* replycmd = g_strdup_printf("type=reply|nm=%s|res=%s|err=0", nm, replymsg); - mxit_add_html_link( mx, replycmd, seltext ); + mxit_add_html_link( mx, replycmd, TRUE, seltext ); g_free(seltext); g_free(replycmd); } - else if ((selmsg) && (replymsg)) { + else { gchar* seltext = g_markup_escape_text(purple_url_decode(selmsg), -1); - mxit_add_html_link( mx, purple_url_decode(replymsg), seltext ); + mxit_add_html_link( mx, purple_url_decode(replymsg), FALSE, seltext ); g_free(seltext); } @@ -317,6 +321,7 @@ /*------------------------------------------------------------------------ * Process an inline image MXit command. + * [::op=img|dat=ASDF23408asdflkj2309flkjsadf%3d%3d|algn=1|w=120|h=12|t=100|replymsg=text:] * * @param mx The received message data object * @param hash The MXit command map @@ -372,7 +377,7 @@ reply = g_hash_table_lookup(hash, "replymsg"); if (reply) { g_string_append_printf(msg, "\n"); - mxit_add_html_link(mx, reply, _( "click here" )); + mxit_add_html_link(mx, reply, FALSE, _( "click here" )); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/http.c --- a/libpurple/protocols/mxit/http.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/http.c Mon Aug 22 16:00:57 2011 +0000 @@ -273,7 +273,7 @@ /* source is the file descriptor of the new connection */ if ( source < 0 ) { purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_http_connect failed: %s\n", error_message ); - purple_connection_error( req->session->con, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) ); + purple_connection_error( req->session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit HTTP server. Please check your server settings." ) ); return; } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/login.c --- a/libpurple/protocols/mxit/login.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/login.c Mon Aug 22 16:00:57 2011 +0000 @@ -165,7 +165,7 @@ /* source is the file descriptor of the new connection */ if ( source < 0 ) { purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_connect failed: %s\n", error_message ); - purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) ); return; } @@ -202,7 +202,7 @@ /* socket connection */ data = purple_proxy_connect( session->con, session->acc, session->server, session->port, mxit_cb_connect, session ); if ( !data ) { - purple_connection_error( session->con, _( "Unable to connect to the MXit server. Please check your server settings." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Unable to connect to the MXit server. Please check your server settings." ) ); return; } } @@ -391,7 +391,7 @@ if ( !url_text ) { /* no reply from the WAP site */ - purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) ); return; } @@ -400,7 +400,7 @@ if ( !parts ) { /* wapserver error */ - purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) ); return; } @@ -410,26 +410,26 @@ /* valid reply! */ break; case '1' : - purple_connection_error( session->con, _( "Wrong security code entered. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Wrong security code entered. Please try again later." ) ); return; case '2' : - purple_connection_error( session->con, _( "Your session has expired. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Your session has expired. Please try again later." ) ); return; case '5' : - purple_connection_error( session->con, _( "Invalid country selected. Please try again." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid country selected. Please try again." ) ); return; case '6' : - purple_connection_error( session->con, _( "The MXit ID you entered is not registered. Please register first." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is not registered. Please register first." ) ); return; case '7' : - purple_connection_error( session->con, _( "The MXit ID you entered is already registered. Please choose another." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "The MXit ID you entered is already registered. Please choose another." ) ); /* this user's account already exists, so we need to change the registration login flag to be login */ purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); return; case '3' : case '4' : default : - purple_connection_error( session->con, _( "Internal error. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Internal error. Please try again later." ) ); return; } @@ -611,7 +611,7 @@ if ( !url_text ) { /* no reply from the WAP site */ - purple_connection_error( session->con, _( "Error contacting the MXit WAP site. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Error contacting the MXit WAP site. Please try again later." ) ); return; } @@ -620,7 +620,7 @@ if ( ( !parts ) || ( parts[0][0] != '0' ) ) { /* server could not find the user */ - purple_connection_error( session->con, _( "MXit is currently unable to process the request. Please try again later." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "MXit is currently unable to process the request. Please try again later." ) ); return; } @@ -743,7 +743,7 @@ * if we don't have any info saved from a previous login, we need to get it from the MXit WAP site. * we do cache it, so this step is only done on the very first login for each account. */ - if ( ( session->distcode == NULL ) || ( strlen( session->distcode ) == 0 ) ) { + if ( ( session->distcode == NULL ) || ( !*session->distcode ) ) { /* this must be the very first login, so we need to retrieve the user information */ get_clientinfo( session ); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/markup.c --- a/libpurple/protocols/mxit/markup.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/markup.c Mon Aug 22 16:00:57 2011 +0000 @@ -124,10 +124,11 @@ * Adds a link to a message * * @param mx The Markup message object - * @param linkname This is the what will be returned when the link gets clicked - * @param displayname This is the name for the link which will be displayed in the UI + * @param replydata This is the what will be returned when the link gets clicked + * @param isStructured Indicates that the reply is a structured reply + * @param displaytext This is the text for the link which will be displayed in the UI */ -void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname ) +void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext ) { #ifdef MXIT_LINK_CLICK char retstr[256]; @@ -135,15 +136,24 @@ char link[256]; int len; - len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%s", MXIT_LINK_KEY, purple_account_get_username( mx->session->acc ), - purple_account_get_protocol_id( mx->session->acc ), mx->from, linkname ); + /* + * The link content is encoded as follows: + * MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA + */ + len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%i|%s", + MXIT_LINK_KEY, + purple_account_get_username( mx->session->acc ), + purple_account_get_protocol_id( mx->session->acc ), + mx->from, + isStructured ? 1 : 0, + replydata ); retstr64 = purple_base64_encode( (const unsigned char*) retstr, len ); g_snprintf( link, sizeof( link ), "%s%s", MXIT_LINK_PREFIX, retstr64 ); g_free( retstr64 ); - g_string_append_printf( mx->msg, "%s", link, displayname ); + g_string_append_printf( mx->msg, "%s", link, displaytext ); #else - g_string_append_printf( mx->msg, "%s", linkname ); + g_string_append_printf( mx->msg, "%s", replydata ); #endif } @@ -735,6 +745,7 @@ gboolean tag_bold = FALSE; gboolean tag_under = FALSE; gboolean tag_italic = FALSE; + int font_size = 0; #ifdef MXIT_DEBUG_MARKUP purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (original): '%s'\n", message ); @@ -823,7 +834,7 @@ if ( ch ) { /* end found */ *ch = '\0'; - mxit_add_html_link( mx, &message[i + 1], &message[i + 1] ); + mxit_add_html_link( mx, &message[i + 1], FALSE, &message[i + 1] ); *ch = '$'; i += ( ch - &message[i + 1] ) + 1; } @@ -862,59 +873,54 @@ } break; case '.' : - if ( !( msgflags & CP_MSG_EMOTICON ) ) { - g_string_append_c( mx->msg, message[i] ); - break; - } - else if ( i + 1 >= len ) { + if ( i + 1 >= len ) { /* message too short */ g_string_append_c( mx->msg, '.' ); break; } - switch ( message[i+1] ) { - case '+' : - /* increment text size */ - g_string_append( mx->msg, "" ); - i++; - break; - case '-' : - /* decrement text size */ - g_string_append( mx->msg, "" ); - i++; - break; - case '{' : - /* custom emoticon */ - if ( i + 2 >= len ) { - /* message too short */ - g_string_append_c( mx->msg, '.' ); - break; - } + if ( ( msgflags & CP_MSG_EMOTICON ) && ( message[i+1] == '{' ) ) { + /* custom emoticon */ + if ( i + 2 >= len ) { + /* message too short */ + g_string_append_c( mx->msg, '.' ); + break; + } + + parse_emoticon_str( &message[i+2], tmpstr1 ); + if ( tmpstr1[0] != '\0' ) { + mx->got_img = TRUE; + + if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) { + /* emoticon found in the cache, so we do not have to request it from the WAPsite */ + } + else { + /* request emoticon from the WAPsite */ + mx->img_count++; + emoticon_request( mx, tmpstr1 ); + } - parse_emoticon_str( &message[i+2], tmpstr1 ); - if ( tmpstr1[0] != '\0' ) { - mx->got_img = TRUE; + g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 ); + i += strlen( tmpstr1 ) + 2; + } + else + g_string_append_c( mx->msg, '.' ); + } + else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '+' ) ) { + /* increment text size */ + font_size++; + g_string_append_printf( mx->msg, "", font_size ); + i++; + } + else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '-' ) ) { + /* decrement text size */ + font_size--; + g_string_append_printf( mx->msg, "", font_size ); + i++; + } + else + g_string_append_c( mx->msg, '.' ); - if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) { - /* emoticon found in the cache, so we do not have to request it from the WAPsite */ - } - else { - /* request emoticon from the WAPsite */ - mx->img_count++; - emoticon_request( mx, tmpstr1 ); - } - - g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 ); - i += strlen( tmpstr1 ) + 2; - } - else - g_string_append_c( mx->msg, '.' ); - - break; - default : - g_string_append_c( mx->msg, '.' ); - break; - } break; case '\\' : if ( i + 1 >= len ) { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/markup.h --- a/libpurple/protocols/mxit/markup.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/markup.h Mon Aug 22 16:00:57 2011 +0000 @@ -31,7 +31,7 @@ void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgtype, int msgflags ); char* mxit_convert_markup_tx( const char* message, int* msgtype ); -void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname ); +void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext ); void mxit_show_message( struct RXMsgData* mx ); void mxit_free_emoticon_cache( struct MXitSession* session ); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/multimx.c --- a/libpurple/protocols/mxit/multimx.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/multimx.c Mon Aug 22 16:00:57 2011 +0000 @@ -277,7 +277,11 @@ GHashTable *components; struct multimx* multimx = NULL; - purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' by '%s'\n", contact->alias, creator); + purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' (roomid='%s') by '%s'\n", contact->alias, contact->username, creator); + + /* Check if the room already exists (ie, already joined or invite pending) */ + if (find_room_by_username(session, contact->username) != NULL) + return; /* Create a new room */ multimx = room_create(session, contact->username, contact->alias, STATE_INVITED); @@ -307,7 +311,7 @@ multimx = find_room_by_username(session, contact->username); if (multimx == NULL) { multimx = room_create(session, contact->username, contact->alias, TRUE); - } + } else if (multimx->state == STATE_INVITED) { /* After successfully accepting an invitation */ multimx->state = STATE_JOINED; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/mxit.c --- a/libpurple/protocols/mxit/mxit.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/mxit.c Mon Aug 22 16:00:57 2011 +0000 @@ -75,10 +75,10 @@ link = (gchar*) purple_base64_decode( link64 + strlen( MXIT_LINK_PREFIX ), &len ); purple_debug_info( MXIT_PLUGIN_ID, "Clicked Link: '%s'\n", link ); - parts = g_strsplit( link, "|", 5 ); + parts = g_strsplit( link, "|", 6 ); /* check if this is a valid mxit link */ - if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) ) { + if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) || ( !parts[5] ) ) { /* this is not for us */ goto skip; } @@ -96,10 +96,10 @@ goto skip; /* determine if it's a command-response to send */ - is_command = g_str_has_prefix( parts[4], "::type=reply|" ); + is_command = ( atoi( parts[4] ) == 1 ); /* send click message back to MXit */ - mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command ); + mxit_send_message( con->proto_data, parts[3], parts[5], FALSE, is_command ); g_free( link ); link = NULL; @@ -129,7 +129,7 @@ /*------------------------------------------------------------------------ * Register MXit to receive URI click notifications from the UI */ -void mxit_register_uri_handler(void) +void mxit_register_uri_handler( void ) { not_link_ref_count++; if ( not_link_ref_count == 1 ) { @@ -198,7 +198,7 @@ if ( !buddy ) return; - contact = purple_buddy_get_protocol_data(buddy); + contact = purple_buddy_get_protocol_data( buddy ); if ( !contact ) return; @@ -214,7 +214,7 @@ case MXIT_TYPE_INFO : tmp = g_strdup_printf("%s\n", _( "Loading menu..." )); serv_got_im( session->con, who, tmp, PURPLE_MESSAGE_NOTIFY, time( NULL ) ); - g_free(tmp); + g_free( tmp ); mxit_send_message( session, who, " ", FALSE, FALSE ); default : break; @@ -268,7 +268,7 @@ */ static const char* mxit_list_emblem( PurpleBuddy* buddy ) { - struct contact* contact = purple_buddy_get_protocol_data(buddy); + struct contact* contact = purple_buddy_get_protocol_data( buddy ); if ( !contact ) return NULL; @@ -309,19 +309,18 @@ */ char* mxit_status_text( PurpleBuddy* buddy ) { - struct contact* contact = purple_buddy_get_protocol_data(buddy); + char* text = NULL; + struct contact* contact = purple_buddy_get_protocol_data( buddy ); if ( !contact ) return NULL; - if ( contact->statusMsg ) { - /* status message */ - return g_strdup( contact-> statusMsg ); - } - else { - /* mood */ - return g_strdup( mxit_convert_mood_to_name( contact->mood ) ); - } + if ( contact->statusMsg ) /* status message */ + text = g_strdup( contact-> statusMsg ); + else if ( contact->mood != MXIT_MOOD_NONE ) /* mood */ + text = g_strdup( mxit_convert_mood_to_name( contact->mood ) ); + + return text; } @@ -334,34 +333,36 @@ */ static void mxit_tooltip( PurpleBuddy* buddy, PurpleNotifyUserInfo* info, gboolean full ) { - struct contact* contact = purple_buddy_get_protocol_data(buddy); + struct contact* contact = purple_buddy_get_protocol_data( buddy ); if ( !contact ) return; /* status (reference: "libpurple/notify.h") */ if ( contact->presence != MXIT_PRESENCE_OFFLINE ) - purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) ); /* status message */ - if ( contact->statusMsg ) - purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg ); + if ( contact->statusMsg ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg ); + } /* mood */ if ( contact->mood != MXIT_MOOD_NONE ) - purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) ); /* subscription type */ if ( contact->subtype != 0 ) - purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) ); /* rejection message */ - if ( ( contact->subtype == MXIT_SUBTYPE_REJECTED ) && ( contact->msg != NULL ) ) - purple_notify_user_info_add_pair( info, _( "Rejection Message" ), contact->msg ); - - /* hidden number */ - if ( contact->flags & MXIT_CFLAG_HIDDEN ) - purple_notify_user_info_add_pair( info, _( "Hidden Number" ), _( "Yes" ) ); + if ( ( contact->subtype == MXIT_SUBTYPE_REJECTED ) && ( contact->msg != NULL ) ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Rejection Message" ), contact->msg ); + } } @@ -429,7 +430,7 @@ char* statusmsg2; /* Handle mood changes */ - if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) { + if ( purple_status_type_get_primitive(purple_status_get_type( status ) ) == PURPLE_STATUS_MOOD ) { const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME ); int mood; @@ -492,7 +493,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_free_buddy\n" ); - contact = purple_buddy_get_protocol_data(buddy); + contact = purple_buddy_get_protocol_data( buddy ); if ( contact ) { if ( contact->statusMsg ) g_free( contact->statusMsg ); @@ -503,7 +504,7 @@ g_free( contact ); } - purple_buddy_set_protocol_data(buddy, NULL); + purple_buddy_set_protocol_data( buddy, NULL ); } @@ -612,12 +613,11 @@ */ static void mxit_reinvite( PurpleBlistNode *node, gpointer ignored ) { - PurpleBuddy* buddy; - struct contact* contact; + PurpleBuddy* buddy = (PurpleBuddy *) node; PurpleConnection* gc; struct MXitSession* session; + struct contact* contact; - buddy = (PurpleBuddy *)node; gc = purple_account_get_connection( purple_buddy_get_account( buddy ) ); session = gc->proto_data; @@ -653,12 +653,24 @@ if ( ( contact->subtype == MXIT_SUBTYPE_DELETED ) || ( contact->subtype == MXIT_SUBTYPE_REJECTED ) || ( contact->subtype == MXIT_SUBTYPE_NONE ) ) { /* contact is in Deleted, Rejected or None state */ act = purple_menu_action_new( _( "Re-Invite" ), PURPLE_CALLBACK( mxit_reinvite ), NULL, NULL ); - m = g_list_append(m, act); + m = g_list_append( m, act ); } return m; } + +/*------------------------------------------------------------------------ + * Return Chat-room default settings. + * + * @return Chat defaults list + */ +static GHashTable *mxit_chat_info_defaults( PurpleConnection *gc, const char *chat_name ) +{ + return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, g_free ); +} + + /*========================================================================================================================*/ static PurplePluginProtocolInfo proto_info = { @@ -680,7 +692,7 @@ mxit_status_types, /* status types [roster.c] */ mxit_blist_menu, /* blist_node_menu */ mxit_chat_info, /* chat_info [multimx.c] */ - NULL, /* chat_info_defaults */ + mxit_chat_info_defaults,/* chat_info_defaults */ mxit_login, /* login [login.c] */ mxit_close, /* close */ mxit_send_im, /* send_im */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/mxit.h --- a/libpurple/protocols/mxit/mxit.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/mxit.h Mon Aug 22 16:00:57 2011 +0000 @@ -191,7 +191,7 @@ void mxit_enable_signals( struct MXitSession* session ); #ifdef MXIT_LINK_CLICK -void mxit_register_uri_handler(void); +void mxit_register_uri_handler( void ); #endif diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/profile.c --- a/libpurple/protocols/mxit/profile.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/profile.c Mon Aug 22 16:00:57 2011 +0000 @@ -115,16 +115,16 @@ struct tm now, bdate; int age; - if ( ( !date ) || ( strlen( date ) == 0 ) ) + if ( ( !date ) || ( !*date ) ) return 0; /* current time */ - t = time(NULL); + t = time( NULL ); localtime_r( &t, &now ); /* decode hdate */ memset( &bdate, 0, sizeof( struct tm ) ); - purple_str_to_time(date, FALSE, &bdate, NULL, NULL); + purple_str_to_time( date, FALSE, &bdate, NULL, NULL ); /* calculate difference */ age = now.tm_year - bdate.tm_year; @@ -170,54 +170,70 @@ buddy = purple_find_buddy( session->acc, username ); if ( buddy ) { - purple_notify_user_info_add_pair( info, _( "Alias" ), purple_buddy_get_alias( buddy ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Alias" ), purple_buddy_get_alias( buddy ) ); purple_notify_user_info_add_section_break( info ); - contact = purple_buddy_get_protocol_data(buddy); + contact = purple_buddy_get_protocol_data( buddy ); } - purple_notify_user_info_add_pair( info, _( "Display Name" ), profile->nickname ); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Display Name" ), profile->nickname ); tmp = g_strdup_printf("%s (%i)", profile->birthday, calculateAge( profile->birthday ) ); - purple_notify_user_info_add_pair( info, _( "Birthday" ), tmp ); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Birthday" ), tmp ); g_free( tmp ); - purple_notify_user_info_add_pair( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) ); /* optional information */ - purple_notify_user_info_add_pair( info, _( "First Name" ), profile->firstname ); - purple_notify_user_info_add_pair( info, _( "Last Name" ), profile->lastname ); - purple_notify_user_info_add_pair( info, _( "Country" ), profile->regcountry ); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "First Name" ), profile->firstname ); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Last Name" ), profile->lastname ); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Country" ), profile->regcountry ); - if ( strlen( profile->aboutme ) > 0 ) - purple_notify_user_info_add_pair( info, _( "About Me" ), profile->aboutme ); - if ( strlen( profile->whereami ) > 0 ) - purple_notify_user_info_add_pair( info, _( "Where I Live" ), profile->whereami ); + if ( *profile->aboutme ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "About Me" ), profile->aboutme ); + } + if ( *profile->whereami ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Where I Live" ), profile->whereami ); + } purple_notify_user_info_add_section_break( info ); if ( contact ) { /* presence */ - purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) ); /* last online */ if ( contact->presence == MXIT_PRESENCE_OFFLINE ) - purple_notify_user_info_add_pair( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) ); /* mood */ if ( contact->mood != MXIT_MOOD_NONE ) - purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) ); else - purple_notify_user_info_add_pair( info, _( "Mood" ), _( "None" ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Mood" ), _( "None" ) ); /* status message */ - if ( contact->statusMsg ) - purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg ); + if ( contact->statusMsg ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg ); + } /* subscription type */ - purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) ); - - /* hidden number */ - purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) ); + purple_notify_user_info_add_pair_plaintext( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) ); } else { /* this is an invite */ @@ -225,18 +241,25 @@ if ( contact ) { /* invite found */ - if ( contact->msg ) - purple_notify_user_info_add_pair( info, _( "Invite Message" ), contact->msg ); + if ( contact->msg ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Invite Message" ), contact->msg ); + } if ( contact->imgid ) { /* this invite has a avatar */ char* img_text; img_text = g_strdup_printf( "", contact->imgid ); - purple_notify_user_info_add_pair( info, _( "Photo" ), img_text ); + purple_notify_user_info_add_pair_html( info, _( "Photo" ), img_text ); + g_free(img_text); } - if ( contact->statusMsg ) - purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg ); + if ( contact->statusMsg ) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html( info, _( "Status Message" ), contact->statusMsg ); + } } } @@ -284,6 +307,7 @@ /* define columns */ column = purple_notify_searchresults_column_new( _( "UserId" ) ); + purple_notify_searchresult_column_set_visible( column, FALSE ); purple_notify_searchresults_column_add( results, column ); column = purple_notify_searchresults_column_new( _( "Display Name" ) ); purple_notify_searchresults_column_add( results, column ); @@ -298,7 +322,7 @@ column = purple_notify_searchresults_column_new( _( "Where I live" ) ); purple_notify_searchresults_column_add( results, column ); - while (entries != NULL) { + while ( entries != NULL ) { struct MXitProfile* profile = ( struct MXitProfile *) entries->data; GList* row; gchar* tmp = purple_base64_encode( (unsigned char *) profile->userid, strlen( profile->userid ) ); @@ -328,5 +352,5 @@ purple_notify_searchresults( session->con, NULL, text, NULL, results, NULL, NULL ); - g_free( text); + g_free( text ); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/profile.h --- a/libpurple/protocols/mxit/profile.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/profile.h Mon Aug 22 16:00:57 2011 +0000 @@ -50,7 +50,6 @@ int flags; /* user's profile flags */ gint64 lastonline; /* user's last-online timestamp */ - gboolean hidden; /* set if the user's mxitid should remain hidden */ }; struct MXitSession; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/protocol.c Mon Aug 22 16:00:57 2011 +0000 @@ -86,7 +86,7 @@ void mxit_strip_domain( char* username ) { if ( g_str_has_suffix( username, "@m" ) ) - username[ strlen(username) - 2 ] = '\0'; + username[ strlen( username ) - 2 ] = '\0'; } @@ -408,7 +408,7 @@ res = mxit_write_sock_packet( session->fd, data, datalen ); if ( res < 0 ) { /* we must have lost the connection, so terminate it so that we can reconnect */ - purple_connection_error( session->con, _( "We have lost the connection to MXit. Please reconnect." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "We have lost the connection to MXit. Please reconnect." ) ); } } else { @@ -530,7 +530,7 @@ if ( session->last_tx <= mxit_now_milli() - ( MXIT_ACK_TIMEOUT * 1000 ) ) { /* ack timeout! so we close the connection here */ purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack ); - purple_connection_error( session->con, _( "Timeout while waiting for a response from the MXit server." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Timeout while waiting for a response from the MXit server." ) ); } return; } @@ -704,9 +704,9 @@ locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); /* Voice and Video supported */ - if (mxit_audio_enabled() && mxit_video_enabled()) - features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); - else if (mxit_audio_enabled()) + if ( mxit_audio_enabled() && mxit_video_enabled() ) + features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO ); + else if ( mxit_audio_enabled() ) features |= MXIT_CF_VOICE; /* generate client version string (eg, P-2.7.10-Y-PURPLE) */ @@ -748,9 +748,9 @@ locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); /* Voice and Video supported */ - if (mxit_audio_enabled() && mxit_video_enabled()) - features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); - else if (mxit_audio_enabled()) + if ( mxit_audio_enabled() && mxit_video_enabled() ) + features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO ); + else if ( mxit_audio_enabled() ) features |= MXIT_CF_VOICE; /* generate client version string (eg, P-2.7.10-Y-PURPLE) */ @@ -835,7 +835,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET ); @@ -868,7 +868,7 @@ /* add attributes */ for ( i = 1; i < nr_attrib * 3; i+=3 ) - datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */ + datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */ CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] ); /* queue packet for transmission */ @@ -900,7 +900,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -929,7 +929,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -1175,7 +1175,7 @@ /* add usernames */ for ( i = 0; i < nr_usernames; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE ); @@ -1204,7 +1204,7 @@ /* add usernames */ for ( i = 0; i < nr_usernames; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); + datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE ); @@ -1448,7 +1448,7 @@ PurpleStatus* status; int presence; const char* statusmsg; - const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME, + const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL, CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS }; @@ -1516,6 +1516,7 @@ { struct RXMsgData* mx = NULL; char* message = NULL; + char* sender = NULL; int msglen = 0; int msgflags = 0; int msgtype = 0; @@ -1529,10 +1530,11 @@ msglen = strlen( message ); /* strip off dummy domain */ - mxit_strip_domain( records[0]->fields[0]->data ); + sender = records[0]->fields[0]->data; + mxit_strip_domain( sender ); #ifdef DEBUG_PROTOCOL - purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", records[0]->fields[0]->data ); + purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", sender ); #endif /* decode message flags (if any) */ @@ -1540,33 +1542,42 @@ msgflags = atoi( records[0]->fields[4]->data ); msgtype = atoi( records[0]->fields[2]->data ); - if ( msgflags & CP_MSG_ENCRYPTED ) { - /* this is an encrypted message. we do not currently support those so ignore it */ + if ( msgflags & CP_MSG_PWD_ENCRYPTED ) { + /* this is a password encrypted message. we do not currently support those so ignore it */ PurpleBuddy* buddy; const char* name; char msg[128]; - buddy = purple_find_buddy( session->acc, records[0]->fields[0]->data ); + buddy = purple_find_buddy( session->acc, sender ); if ( buddy ) name = purple_buddy_get_alias( buddy ); else - name = records[0]->fields[0]->data; + name = sender; g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name ); mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg ); return; } + else if ( msgflags & CP_MSG_TL_ENCRYPTED ) { + /* this is a transport-layer encrypted message. */ + message = mxit_decrypt_message( session, message ); + if ( !message ) { + /* could not be decrypted */ + serv_got_im( session->con, sender, _( "An encrypted message was received which could not be decrypted." ), PURPLE_MESSAGE_ERROR, time( NULL ) ); + return; + } + } if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) { /* delivery notification is requested */ if ( records[0]->fcount >= 4 ) - mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED ); + mxit_send_msgevent( session, sender, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED ); } /* create and initialise new markup struct */ mx = g_new0( struct RXMsgData, 1 ); mx->msg = g_string_sized_new( msglen ); mx->session = session; - mx->from = g_strdup( records[0]->fields[0]->data ); + mx->from = g_strdup( sender ); mx->timestamp = atoi( records[0]->fields[1]->data ); mx->got_img = FALSE; mx->chatid = -1; @@ -1597,6 +1608,10 @@ * so the image received callback function will eventually display * the message. */ } + + /* cleanup */ + if ( msgflags & CP_MSG_TL_ENCRYPTED ) + g_free( message ); } @@ -1633,7 +1648,7 @@ if ( rec->fcount >= 5 ) { /* there is a personal invite message attached */ - if ( ( rec->fields[4]->data ) && ( strlen( rec->fields[4]->data ) > 0 ) ) + if ( ( rec->fields[4]->data ) && ( *rec->fields[4]->data ) ) contact->msg = strdup( rec->fields[4]->data ); } @@ -1810,10 +1825,6 @@ /* gender */ profile->male = ( fvalue[0] == '1' ); } - else if ( strcmp( CP_PROFILE_HIDENUMBER, fname ) == 0 ) { - /* hide number */ - profile->hidden = ( fvalue[0] == '1' ); - } else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) { /* nickname */ g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) ); @@ -1879,7 +1890,7 @@ contact = get_mxit_invite_contact( session, mxitId ); if ( contact ) { /* this is an invite, so update its profile info */ - if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) { + if ( ( statusMsg ) && ( *statusMsg ) ) { /* update the status message */ if ( contact->statusMsg ) g_free( contact->statusMsg ); @@ -1890,7 +1901,7 @@ if ( contact->profile ) g_free( contact->profile ); contact->profile = profile; - if ( ( avatarId ) && ( strlen( avatarId ) > 0 ) ) { + if ( ( avatarId ) && ( *avatarId ) ) { /* avatar must be requested for this invite before we can display it */ mxit_get_avatar( session, mxitId, avatarId ); if ( contact->avatarId ) @@ -1908,7 +1919,7 @@ if ( avatarId ) mxit_update_buddy_avatar( session, mxitId, avatarId ); - if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) { + if ( ( statusMsg ) && ( *statusMsg ) ) { /* update the status message */ PurpleBuddy* buddy = NULL; @@ -2192,7 +2203,7 @@ session->port = atoi( host[2] ); } else { - purple_connection_error( session->con, _( "Cannot perform redirect using the specified protocol" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Cannot perform redirect using the specified protocol" ) ); goto redirect_fail; } @@ -2270,7 +2281,7 @@ case CP_CMD_PRESENCE : /* presence update */ - mxit_parse_cmd_presence(session, &packet->records[2], packet->rcount - 3 ); + mxit_parse_cmd_presence( session, &packet->records[2], packet->rcount - 3 ); break; case CP_CMD_RX_MSG : @@ -2361,7 +2372,7 @@ if ( packet->errcode == MXIT_ERRCODE_LOGGEDOUT ) { /* we are not currently logged in, so we need to reconnect */ - purple_connection_error( session->con, _( errdesc ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( errdesc ) ); } /* packet command */ @@ -2375,12 +2386,12 @@ } else { snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode ); - purple_connection_error( session->con, errmsg ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg ); return -1; } case CP_CMD_LOGOUT : snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode ); - purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) ); return -1; case CP_CMD_CONTACT : mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Contact Error" ), _( errdesc ) ); @@ -2643,7 +2654,7 @@ if ( packet.rcount < 2 ) { /* bad packet */ - purple_connection_error( session->con, _( "Invalid packet received from MXit." ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid packet received from MXit." ) ); free_rx_packet( &packet ); continue; } @@ -2708,12 +2719,12 @@ len = read( session->fd, &ch, 1 ); if ( len < 0 ) { /* connection error */ - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x01)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x01)" ) ); return; } else if ( len == 0 ) { /* connection closed */ - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x02)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x02)" ) ); return; } else { @@ -2723,7 +2734,7 @@ session->rx_lbuf[session->rx_i] = '\0'; session->rx_res = atoi( &session->rx_lbuf[3] ); if ( session->rx_res > CP_MAX_PACKET ) { - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x03)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x03)" ) ); } session->rx_state = RX_STATE_DATA; session->rx_i = 0; @@ -2734,7 +2745,7 @@ session->rx_i++; if ( session->rx_i >= sizeof( session->rx_lbuf ) ) { /* malformed packet length record (too long) */ - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x04)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x04)" ) ); return; } } @@ -2745,12 +2756,12 @@ len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res ); if ( len < 0 ) { /* connection error */ - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x05)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x05)" ) ); return; } else if ( len == 0 ) { /* connection closed */ - purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x06)" ) ); + purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x06)" ) ); return; } else { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/protocol.h --- a/libpurple/protocols/mxit/protocol.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/protocol.h Mon Aug 22 16:00:57 2011 +0000 @@ -155,7 +155,10 @@ /* message flags */ #define CP_MSG_NOTIFY_DELIVERY 0x0002 /* request delivery notification */ #define CP_MSG_NOTIFY_READ 0x0004 /* request read notification */ -#define CP_MSG_ENCRYPTED 0x0010 /* message is encrypted */ +#define CP_MSG_PWD_ENCRYPTED 0x0010 /* message is password encrypted */ +#define CP_MSG_TL_ENCRYPTED 0x0020 /* message is transport encrypted */ +#define CP_MSG_RPLY_PWD_ENCRYPT 0x0040 /* reply should be password encrypted */ +#define CP_MSG_RPLY_TL_ENCRYPT 0x0080 /* reply should be transport encrypted */ #define CP_MSG_MARKUP 0x0200 /* message may contain markup */ #define CP_MSG_EMOTICON 0x0400 /* message may contain custom emoticons */ @@ -179,7 +182,7 @@ /* extended profile attribute fields */ #define CP_PROFILE_BIRTHDATE "birthdate" /* Birthdate (String - ISO 8601 format) */ #define CP_PROFILE_GENDER "gender" /* Gender (Boolean - 0=female, 1=male) */ -#define CP_PROFILE_HIDENUMBER "hidenumber" /* Hide Number (Boolean - 0=false, 1=true) */ +// #define CP_PROFILE_HIDENUMBER "hidenumber" /* Hide Number (Boolean - 0=false, 1=true) (DEPRECATED) */ #define CP_PROFILE_FULLNAME "fullname" /* Fullname (UTF8 String) */ #define CP_PROFILE_STATUS "statusmsg" /* Status Message (UTF8 String) */ #define CP_PROFILE_PREVSTATUS "prevstatusmsgs" /* Previous Status Messages (UTF8 String) */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/roster.c --- a/libpurple/protocols/mxit/roster.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/roster.c Mon Aug 22 16:00:57 2011 +0000 @@ -82,9 +82,9 @@ } /* add Mood option */ - type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE, + type = purple_status_type_new_with_attrs( PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE, PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new( PURPLE_TYPE_STRING ), - NULL); + NULL ); statuslist = g_list_append( statuslist, type ); return statuslist; @@ -135,21 +135,21 @@ /* moods (reference: libpurple/status.h) */ static PurpleMood mxit_moods[] = { - {"angry", N_("Angry"), NULL}, - {"excited", N_("Excited"), NULL}, - {"grumpy", N_("Grumpy"), NULL}, - {"happy", N_("Happy"), NULL}, - {"in_love", N_("In love"), NULL}, - {"invincible", N_("Invincible"), NULL}, - {"sad", N_("Sad"), NULL}, - {"hot", N_("Hot"), NULL}, - {"sick", N_("Sick"), NULL}, - {"sleepy", N_("Sleepy"), NULL}, - {"bored", N_("Bored"), NULL}, - {"cold", N_("Cold"), NULL}, - {"confused", N_("Confused"), NULL}, - {"hungry", N_("Hungry"), NULL}, - {"stressed", N_("Stressed"), NULL}, + { "angry", N_( "Angry" ), NULL }, + { "excited", N_( "Excited" ), NULL }, + { "grumpy", N_( "Grumpy" ), NULL }, + { "happy", N_( "Happy" ), NULL }, + { "in_love", N_( "In love" ), NULL }, + { "invincible", N_( "Invincible" ), NULL }, + { "sad", N_( "Sad" ), NULL }, + { "hot", N_( "Hot" ), NULL }, + { "sick", N_( "Sick" ), NULL }, + { "sleepy", N_( "Sleepy" ), NULL }, + { "bored", N_( "Bored" ), NULL }, + { "cold", N_( "Cold" ), NULL }, + { "confused", N_( "Confused" ), NULL }, + { "hungry", N_( "Hungry" ), NULL }, + { "stressed", N_( "Stressed" ), NULL }, /* Mark the last record. */ { NULL, NULL, NULL } }; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/roster.h --- a/libpurple/protocols/mxit/roster.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/roster.h Mon Aug 22 16:00:57 2011 +0000 @@ -74,7 +74,7 @@ /* MXit contact flags */ -#define MXIT_CFLAG_HIDDEN 0x02 +//#define MXIT_CFLAG_HIDDEN 0x02 /* (DEPRECATED) */ #define MXIT_CFLAG_GATEWAY 0x04 #define MXIT_CFLAG_FOCUS_SEND_BLANK 0x20000 @@ -96,7 +96,7 @@ /* client protocol constants */ #define MXIT_CP_MAX_JID_LEN 64 #define MXIT_CP_MAX_GROUP_LEN 32 -#define MXIT_CP_MAX_ALIAS_LEN 48 +#define MXIT_CP_MAX_ALIAS_LEN 100 #define MXIT_DEFAULT_GROUP "MXit" @@ -106,8 +106,8 @@ */ struct contact { char username[MXIT_CP_MAX_JID_LEN+1]; /* unique contact name (with domain) */ - char alias[MXIT_CP_MAX_GROUP_LEN+1]; /* contact alias (what will be seen) */ - char groupname[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact group name */ + char alias[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact alias (what will be seen) */ + char groupname[MXIT_CP_MAX_GROUP_LEN+1]; /* contact group name */ short type; /* contact type */ short mood; /* contact current mood */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/mxit/voicevideo.c --- a/libpurple/protocols/mxit/voicevideo.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/mxit/voicevideo.c Mon Aug 22 16:00:57 2011 +0000 @@ -71,7 +71,7 @@ purple_debug_info(MXIT_PLUGIN_ID, "mxit_media_caps: buddy '%s'\n", who); /* We need to have a voice/video server */ - if (strlen(session->voip_server) == 0) + if (!*session->voip_server) return PURPLE_MEDIA_CAPS_NONE; /* find the buddy information for this contact (reference: "libpurple/blist.h") */ @@ -95,7 +95,7 @@ /* and only when they're online */ if (contact->presence == MXIT_PRESENCE_OFFLINE) - return MXIT_PRESENCE_OFFLINE; + return PURPLE_MEDIA_CAPS_NONE; /* they support voice-only */ if (contact->capabilities & MXIT_PFLAG_VOICE) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/myspace/myspace.c Mon Aug 22 16:00:57 2011 +0000 @@ -698,7 +698,7 @@ if (nc_len != MSIM_AUTH_CHALLENGE_LENGTH) { purple_debug_info("msim", "bad nc length: %" G_GSIZE_MODIFIER "x != 0x%x\n", nc_len, MSIM_AUTH_CHALLENGE_LENGTH); - purple_connection_error_reason (session->gc, + purple_connection_error (session->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unexpected challenge length from server")); return FALSE; @@ -835,7 +835,7 @@ purple_debug_info("msim", "msim_check_alive: %zu > interval of %d, presumed dead\n", delta, MSIM_KEEPALIVE_INTERVAL); - purple_connection_error_reason(session->gc, + purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Lost connection with server")); @@ -1866,7 +1866,7 @@ purple_account_set_password(session->account, NULL); break; } - purple_connection_error_reason(session->gc, reason, full_errmsg); + purple_connection_error(session->gc, reason, full_errmsg); } else { purple_notify_error(session->account, _("MySpaceIM Error"), full_errmsg, NULL); } @@ -2027,7 +2027,7 @@ /* libpurple/eventloop.h only defines these two */ if (cond != PURPLE_INPUT_READ && cond != PURPLE_INPUT_WRITE) { purple_debug_info("msim_input_cb", "unknown condition=%d\n", cond); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid input condition")); return; @@ -2069,12 +2069,12 @@ tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (n == 0) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); return; @@ -2092,7 +2092,7 @@ purple_debug_info("msim", "msim_input_cb: strlen=%d, but read %d bytes" "--null byte encountered?\n", strlen(session->rxbuf + session->rxoff), n); - /*purple_connection_error_reason (gc, + /*purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Invalid message - null byte on input"); */ return; @@ -2117,7 +2117,7 @@ msg = msim_parse(session->rxbuf); if (!msg) { purple_debug_info("msim", "msim_input_cb: couldn't parse rxbuf\n"); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to parse message")); break; @@ -2162,7 +2162,7 @@ if (source < 0) { gchar *tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -2219,7 +2219,7 @@ if (!purple_proxy_connect(gc, acct, host, port, msim_connect_cb, gc)) { /* TODO: try other ports if in auto mode, then save * working port and try that first next time. */ - purple_connection_error_reason (gc, + purple_connection_error (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/myspace/user.c Mon Aug 22 16:00:57 2011 +0000 @@ -117,27 +117,33 @@ /* Useful to identify the account the tooltip refers to. * Other prpls show this. */ if (user->username) { - purple_notify_user_info_add_pair(user_info, _("User"), user->username); + purple_notify_user_info_add_pair_plaintext(user_info, _("User"), user->username); } /* a/s/l...the vitals */ if (user->age) { char age[16]; g_snprintf(age, sizeof(age), "%d", user->age); - purple_notify_user_info_add_pair(user_info, _("Age"), age); + purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age); } if (user->gender && *user->gender) { - purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), user->gender); } if (user->location && *user->location) { - purple_notify_user_info_add_pair(user_info, _("Location"), user->location); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_plaintext(user_info, _("Location"), user->location); } /* Other information */ if (user->headline && *user->headline) { - purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_plaintext(user_info, _("Headline"), user->headline); } if (user->buddy != NULL) { @@ -153,7 +159,9 @@ str = msim_format_now_playing(artist, title); if (str && *str) { - purple_notify_user_info_add_pair(user_info, _("Song"), str); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_plaintext(user_info, _("Song"), str); } g_free(str); } @@ -163,7 +171,7 @@ if (user->total_friends) { char friends[16]; g_snprintf(friends, sizeof(friends), "%d", user->total_friends); - purple_notify_user_info_add_pair(user_info, _("Total Friends"), friends); + purple_notify_user_info_add_pair_plaintext(user_info, _("Total Friends"), friends); } if (full) { @@ -180,8 +188,11 @@ } else if (cv) { client = g_strdup_printf("Build %d", cv); } - if (client && *client) - purple_notify_user_info_add_pair(user_info, _("Client Version"), client); + if (client && *client) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_plaintext(user_info, _("Client Version"), client); + } g_free(client); } @@ -195,7 +206,7 @@ else profile = g_strdup_printf("%s", user->id, _("View web profile")); - purple_notify_user_info_add_pair(user_info, NULL, profile); + purple_notify_user_info_add_pair_html(user_info, NULL, profile); g_free(profile); } } @@ -636,7 +647,7 @@ if (!body) { purple_debug_info("msim_username_is_set_cb", "No body"); /* Error: No body! */ - purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); } username = msim_msg_get_string(body, "UserName"); code = msim_msg_get_integer(body,"Code"); @@ -678,13 +689,13 @@ NULL)) { /* Error! */ /* Can't set... Disconnect */ - purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); } } else { /* Error! */ purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination"); - purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); } } @@ -782,7 +793,7 @@ if (!body) { purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username); - purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("An error occurred while trying to set the username. " "Please try again, or visit http://editprofile.myspace.com/index.cfm?" "fuseaction=profile.username to set your username.")); @@ -867,7 +878,7 @@ purple_debug_info("msim", "Don't set username"); /* Protocol won't log in now without a username set.. Disconnect */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set")); } /** diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/novell/novell.c --- a/libpurple/protocols/novell/novell.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/novell/novell.c Mon Aug 22 16:00:57 2011 +0000 @@ -140,7 +140,7 @@ reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; } - purple_connection_error_reason(gc, reason, err); + purple_connection_error(gc, reason, err); g_free(err); } } @@ -1126,7 +1126,7 @@ if (_is_disconnect_error(err)) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Error communicating with server. Closing connection.")); return TRUE; @@ -1515,20 +1515,27 @@ tag = _("User ID"); value = nm_user_record_get_userid(user_record); if (value) { - purple_notify_user_info_add_pair(user_info, tag, value); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, tag, value); } -/* tag = _("DN"); +#if 0 + tag = _("DN"); value = nm_user_record_get_dn(user_record); if (value) { - purple_notify_user_info_add_pair(user_info, tag, value); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, tag, value); } -*/ +#endif /* if 0 */ tag = _("Full name"); value = nm_user_record_get_full_name(user_record); if (value) { - purple_notify_user_info_add_pair(user_info, tag, value); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, tag, value); } count = nm_user_record_get_property_count(user_record); @@ -1538,7 +1545,9 @@ tag = _map_property_tag(nm_property_get_tag(property)); value = nm_property_get_value(property); if (tag && value) { - purple_notify_user_info_add_pair(user_info, tag, value); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, tag, value); } nm_release_property(property); } @@ -1702,7 +1711,7 @@ if (_is_disconnect_error(rc)) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Error communicating with server. Closing connection.")); } else { @@ -1743,7 +1752,7 @@ conn->connected = TRUE; purple_ssl_input_add(gsc, novell_ssl_recv_cb, gc); } else { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } @@ -2028,7 +2037,7 @@ { if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _("You have signed on from another location")); } @@ -2184,7 +2193,7 @@ */ /* ...but for now just error out with a nice message. */ - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Unable to connect to server. Please enter the " "address of the server to which you wish to connect.")); @@ -2213,7 +2222,7 @@ user->conn->addr, user->conn->port, novell_ssl_connected_cb, novell_ssl_connect_error, gc); if (user->conn->ssl_conn->data == NULL) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); } @@ -2860,10 +2869,13 @@ break; } - purple_notify_user_info_add_pair(user_info, _("Status"), status_str); - - if (text) - purple_notify_user_info_add_pair(user_info, _("Message"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_str); + + if (text) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Message"), text); + } } } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/null/nullprpl.c --- a/libpurple/protocols/null/nullprpl.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/null/nullprpl.c Mon Aug 22 16:00:57 2011 +0000 @@ -234,7 +234,7 @@ const char *message = purple_status_get_attr_string(status, "message"); char *text; - if (message && strlen(message) > 0) + if (message && *message) text = g_strdup_printf("%s: %s", name, message); else text = g_strdup(name); @@ -258,6 +258,8 @@ PurplePresence *presence = purple_buddy_get_presence(buddy); PurpleStatus *status = purple_presence_get_active_status(presence); char *msg = nullprpl_status_text(buddy); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ purple_notify_user_info_add_pair(info, purple_status_get_name(status), msg); g_free(msg); @@ -265,12 +267,14 @@ if (full) { const char *user_info = purple_account_get_user_info(gc->account); if (user_info) + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ purple_notify_user_info_add_pair(info, _("User info"), user_info); } } else { /* they're not logged in */ - purple_notify_user_info_add_pair(info, _("User info"), _("not logged in")); + purple_notify_user_info_add_pair_plaintext(info, _("User info"), _("not logged in")); } purple_debug_info("nullprpl", "showing %s tooltip for %s\n", @@ -510,6 +514,8 @@ body = purple_account_get_user_info(acct); else body = _("No user info."); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ purple_notify_user_info_add_pair(info, "Info", body); /* show a buddy's user info in a nice dialog box */ @@ -775,10 +781,10 @@ to_username = args[0]; message = args[1]; - if (!to_username || strlen(to_username) == 0) { + if (!to_username || !*to_username) { *error = g_strdup(_("Whisper is missing recipient.")); return PURPLE_CMD_RET_FAILED; - } else if (!message || strlen(message) == 0) { + } else if (!message || !*message) { *error = g_strdup(_("Whisper is missing message.")); return PURPLE_CMD_RET_FAILED; } @@ -927,7 +933,7 @@ purple_conv_chat_set_topic(to, username, topic); - if (topic && strlen(topic) > 0) + if (topic && *topic) msg = g_strdup_printf(_("%s sets topic to: %s"), username, topic); else msg = g_strdup_printf(_("%s clears topic"), username); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/authorization.c --- a/libpurple/protocols/oscar/authorization.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/authorization.c Mon Aug 22 16:00:57 2011 +0000 @@ -49,7 +49,7 @@ purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n", bname, gname); aim_ssi_sendauthrequest(od, bname, msg ? msg : _("Please authorize me so I can add you to my buddy list.")); - if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) + if (!aim_ssi_itemlist_finditem(&od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) { aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/clientlogin.c --- a/libpurple/protocols/oscar/clientlogin.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/clientlogin.c Mon Aug 22 16:00:57 2011 +0000 @@ -182,7 +182,7 @@ /* Note to translators: %s in this string is a URL */ msg = generate_error_message(response_node, get_start_oscar_session_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); return FALSE; @@ -204,7 +204,7 @@ "missing statusCode: %s\n", response); msg = generate_error_message(response_node, get_start_oscar_session_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); @@ -232,7 +232,7 @@ "was %s: %s\n", tmp, response); if ((code == 401 && status_detail != 1014) || code == 607) - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("You have been connecting and disconnecting too " "frequently. Wait ten minutes and try again. If " @@ -242,7 +242,7 @@ char *msg; msg = generate_error_message(response_node, get_start_oscar_session_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); g_free(msg); } @@ -261,7 +261,7 @@ "something: %s\n", response); msg = generate_error_message(response_node, get_start_oscar_session_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); @@ -277,7 +277,7 @@ purple_debug_warning("oscar", "We haven't received a tlsCertName to use. We will not do SSL to BOS.\n"); } else { purple_debug_error("oscar", "startOSCARSession was missing tlsCertName: %s\n", response); - purple_connection_error_reason( + purple_connection_error( gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("You required encryption in your account settings, but one of the servers doesn't support it.")); @@ -299,7 +299,7 @@ "something: %s\n", response); msg = generate_error_message(response_node, get_start_oscar_session_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); g_free(*host); @@ -337,7 +337,7 @@ tmp = g_strdup_printf(_("Error requesting %s: %s"), get_start_oscar_session_url(od), error_message ? error_message : _("The server returned an empty response")); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -384,7 +384,7 @@ g_free(signature); /* Make the request */ - od->url_data = purple_util_fetch_url_request_len_with_account(account, + od->url_data = purple_util_fetch_url_request_len(account, url, TRUE, NULL, FALSE, NULL, FALSE, -1, start_oscar_session_cb, od); g_free(url); @@ -395,7 +395,7 @@ * and extracts the useful information. * * @param gc The PurpleConnection. If the response data does - * not indicate then purple_connection_error_reason() + * not indicate then purple_connection_error() * will be called to close this connection. * @param response The response data from the clientLogin request. * @param response_len The length of the above response, or -1 if @@ -431,7 +431,7 @@ "response as XML: %s\n", response); msg = generate_error_message(response_node, get_client_login_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); return FALSE; @@ -455,7 +455,7 @@ "missing statusCode: %s\n", response); msg = generate_error_message(response_node, get_client_login_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); @@ -482,23 +482,23 @@ PurpleAccount *account = purple_connection_get_account(gc); if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password")); } else if (status_code == 330 && status_detail_code == 3015) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Server requested that you fill out a CAPTCHA in order to " "sign in, but this client does not currently support CAPTCHAs.")); } else if (status_code == 401 && status_detail_code == 3019) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("AOL does not allow your screen name to authenticate here")); } else { char *msg; msg = generate_error_message(response_node, get_client_login_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); g_free(msg); } @@ -517,7 +517,7 @@ "something: %s\n", response); msg = generate_error_message(response_node, get_client_login_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); @@ -535,7 +535,7 @@ "something: %s\n", response); msg = generate_error_message(response_node, get_client_login_url(od)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); g_free(*token); @@ -572,7 +572,7 @@ tmp = g_strdup_printf(_("Error requesting %s: %s"), get_client_login_url(od), error_message ? error_message : _("The server returned an empty response")); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -646,7 +646,7 @@ g_string_free(body, TRUE); /* Send the POST request */ - od->url_data = purple_util_fetch_url_request_len_with_account( + od->url_data = purple_util_fetch_url_request_len( purple_connection_get_account(gc), get_client_login_url(od), TRUE, NULL, FALSE, request->str, FALSE, -1, client_login_cb, od); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/family_feedbag.c --- a/libpurple/protocols/oscar/family_feedbag.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Mon Aug 22 16:00:57 2011 +0000 @@ -21,9 +21,9 @@ /* * Family 0x0013 - Server-Side/Stored Information. * - * Relatively new facility that allows certain types of information, such as - * a user's buddy list, permit/deny list, and permit/deny preferences, to be - * stored on the server, so that they can be accessed from any client. + * Deals with storing certain types of information, such as a user's buddy + * list, permit/deny list, and permit/deny preferences, on the server, so + * that they can be accessed from any client. * * We keep 2 copies of SSI data: * 1) An exact copy of what is stored on the AIM servers. @@ -40,14 +40,41 @@ * * This is entirely too complicated. * You don't know the half of it. - * */ #include "oscar.h" +#include "oscarcommon.h" #include "debug.h" static int aim_ssi_addmoddel(OscarData *od); +static void aim_ssi_item_free(struct aim_ssi_item *item) +{ + g_free(item->name); + aim_tlvlist_free(item->data); + g_free(item); +} + +static void aim_ssi_item_set_name(struct aim_ssi_itemlist *list, struct aim_ssi_item *item, const char *name) +{ + gchar key[3000]; + + if (item->name) { + /* Remove old name from hash table */ + snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name)); + g_hash_table_remove(list->idx_all_named_items, key); + } + + g_free(item->name); + item->name = g_strdup(name); + + if (name) { + /* Add new name to hash table */ + snprintf(key, sizeof(key), "%hx%s", item->type, oscar_normalize(NULL, item->name)); + g_hash_table_insert(list->idx_all_named_items, g_strdup(key), item); + } +} + /** * List types based on http://dev.aol.com/aim/oscar/#FEEDBAG (archive.org) * and http://iserverd.khstu.ru/oscar/ssi_item.html @@ -113,7 +140,7 @@ * @return Return a pointer to the modified item. */ static void -aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name) +aim_ssi_itemlist_rebuildgroup(struct aim_ssi_itemlist *list, const char *name) { int newlen; struct aim_ssi_item *cur, *group; @@ -125,11 +152,11 @@ /* Find the length for the new additional data */ newlen = 0; if (group->gid == 0x0000) { - for (cur=list; cur; cur=cur->next) + for (cur=list->data; cur; cur=cur->next) if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) newlen += 2; } else { - for (cur=list; cur; cur=cur->next) + for (cur=list->data; cur; cur=cur->next) if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) newlen += 2; } @@ -138,14 +165,14 @@ if (newlen > 0) { guint8 *newdata; - newdata = (guint8 *)g_malloc((newlen)*sizeof(guint8)); + newdata = g_new(guint8, newlen); newlen = 0; if (group->gid == 0x0000) { - for (cur=list; cur; cur=cur->next) + for (cur=list->data; cur; cur=cur->next) if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) newlen += aimutil_put16(newdata+newlen, cur->gid); } else { - for (cur=list; cur; cur=cur->next) + for (cur=list->data; cur; cur=cur->next) if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) newlen += aimutil_put16(newdata+newlen, cur->bid); } @@ -167,15 +194,12 @@ * @param data The additional data for the new item. * @return A pointer to the newly created item. */ -static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data) +static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_itemlist *list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data) { gboolean exists; struct aim_ssi_item *cur, *new; - new = g_new(struct aim_ssi_item, 1); - - /* Set the name */ - new->name = g_strdup(name); + new = g_new0(struct aim_ssi_item, 1); /* Set the group ID# and buddy ID# */ new->gid = gid; @@ -185,7 +209,7 @@ do { new->gid += 0x0001; exists = FALSE; - for (cur = *list; cur != NULL; cur = cur->next) + for (cur = list->data; cur != NULL; cur = cur->next) if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) { exists = TRUE; break; @@ -202,7 +226,7 @@ do { new->bid += 0x0001; exists = FALSE; - for (cur = *list; cur != NULL; cur = cur->next) + for (cur = list->data; cur != NULL; cur = cur->next) if (cur->bid == new->bid || cur->gid == new->bid) { exists = TRUE; break; @@ -214,7 +238,7 @@ do { new->bid += 0x0001; exists = FALSE; - for (cur = *list; cur != NULL; cur = cur->next) + for (cur = list->data; cur != NULL; cur = cur->next) if (cur->bid == new->bid && cur->gid == new->gid) { exists = TRUE; break; @@ -226,23 +250,29 @@ /* Set the type */ new->type = type; + /* Add it to the gid+bid hashtable */ + g_hash_table_insert(list->idx_gid_bid, GINT_TO_POINTER((new->gid << 16) + new->bid), new); + + /* Set the name - do this *AFTER* setting the type because type is used for the key */ + aim_ssi_item_set_name(list, new, name); + /* Set the TLV list */ new->data = aim_tlvlist_copy(data); /* Add the item to the list in the correct numerical position. Fancy, eh? */ - if (*list) { - if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) { - new->next = *list; - *list = new; + if (list->data) { + if ((new->gid < list->data->gid) || ((new->gid == list->data->gid) && (new->bid < list->data->bid))) { + new->next = list->data; + list->data = new; } else { struct aim_ssi_item *prev; - for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); + for ((prev=list->data, cur=list->data->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); new->next = prev->next; prev->next = new; } } else { - new->next = *list; - *list = new; + new->next = list->data; + list->data = new; } return new; @@ -255,25 +285,31 @@ * @param del A pointer to the item you want to remove from the list. * @return Return 0 if no errors, otherwise return the error number. */ -static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del) +static int aim_ssi_itemlist_del(struct aim_ssi_itemlist *list, struct aim_ssi_item *del) { - if (!(*list) || !del) + gchar key[3000]; + + if (!(list->data) || !del) return -EINVAL; /* Remove the item from the list */ - if (*list == del) { - *list = (*list)->next; + if (list->data == del) { + list->data = list->data->next; } else { struct aim_ssi_item *cur; - for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next); + for (cur=list->data; (cur->next && (cur->next!=del)); cur=cur->next); if (cur->next) cur->next = del->next; } + /* Remove from the hashtables */ + g_hash_table_remove(list->idx_gid_bid, GINT_TO_POINTER((del->gid << 16) + del->bid)); + + snprintf(key, sizeof(key), "%hx%s", del->type, oscar_normalize(NULL, del->name)); + g_hash_table_remove(list->idx_all_named_items, key); + /* Free the removed item */ - g_free(del->name); - aim_tlvlist_free(del->data); - g_free(del); + aim_ssi_item_free(del); return 0; } @@ -320,10 +356,10 @@ return 0; } -static gboolean aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item) +static gboolean aim_ssi_itemlist_valid(struct aim_ssi_itemlist *list, struct aim_ssi_item *item) { struct aim_ssi_item *cur; - for (cur=list; cur; cur=cur->next) + for (cur=list->data; cur; cur=cur->next) if (cur == item) return TRUE; return FALSE; @@ -337,13 +373,10 @@ * @param bid The buddy ID# of the desired item. * @return Return a pointer to the item if found, else return NULL; */ -struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid) +struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid) { - struct aim_ssi_item *cur; - for (cur=list; cur; cur=cur->next) - if ((cur->gid == gid) && (cur->bid == bid)) - return cur; - return NULL; + guint32 id_key = (gid << 16) + bid; + return g_hash_table_lookup(list->idx_gid_bid, GINT_TO_POINTER(id_key)); } /** @@ -356,37 +389,30 @@ * @param type The type of the desired item. * @return Return a pointer to the item if found, else return NULL. */ -struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type) +struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type) { struct aim_ssi_item *cur; - if (!list) + gchar key[3000]; + + if (!list->data) return NULL; if (gn && bn) { /* For finding buddies in groups */ - for (cur=list; cur; cur=cur->next) + g_return_val_if_fail(type == AIM_SSI_TYPE_BUDDY, NULL); + for (cur=list->data; cur; cur=cur->next) if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) { struct aim_ssi_item *curg; - for (curg=list; curg; curg=curg->next) + for (curg=list->data; curg; curg=curg->next) if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(oscar_util_name_compare(curg->name, gn))) return cur; } - } else if (gn) { /* For finding groups */ - for (cur=list; cur; cur=cur->next) { - if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(oscar_util_name_compare(cur->name, gn))) { - return cur; - } - } - - } else if (bn) { /* For finding permits, denies, and ignores */ - for (cur=list; cur; cur=cur->next) { - if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) { - return cur; - } - } + } else if (gn || bn) { /* For finding groups, permits, denies and ignores */ + snprintf(key, sizeof(key), "%hx%s", type, oscar_normalize(NULL, gn ? gn : bn)); + return g_hash_table_lookup(list->idx_all_named_items, key); /* For stuff without names--permit deny setting, visibility mask, etc. */ - } else for (cur=list; cur; cur=cur->next) { + } else for (cur=list->data; cur; cur=cur->next) { if ((cur->type == type) && (!cur->name)) return cur; } @@ -401,7 +427,7 @@ * @param bn The group name of the desired item. * @return Return a pointer to the name of the item if found, else return NULL; */ -struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn) +struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn) { if (!bn) return NULL; @@ -415,10 +441,10 @@ * @param bn The buddy name of the desired item. * @return Return a pointer to the name of the item if found, else return NULL; */ -char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn) +char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn) { struct aim_ssi_item *cur, *curg; - if (!list || !bn) + if (!list->data || !bn) return NULL; if (!(cur = aim_ssi_itemlist_exists(list, bn))) return NULL; @@ -433,7 +459,7 @@ * @param list A pointer to the current list of items. * @return Return the current SSI permit deny setting, or 0 if no setting was found. */ -int aim_ssi_getpermdeny(struct aim_ssi_item *list) +int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list) { struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO); if (cur) { @@ -451,7 +477,7 @@ * @param list A pointer to the current list of items. * @return Return the current set of preferences. */ -guint32 aim_ssi_getpresence(struct aim_ssi_item *list) +guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list) { struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS); if (cur) { @@ -472,17 +498,23 @@ * alias, or NULL if the buddy has no alias. You should free * this returned value! */ -char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn) +char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn) { - struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); - if (cur) { - aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1); - if (tlv && tlv->length) - return g_strndup((const gchar *)tlv->value, tlv->length); + struct aim_ssi_item *item = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); + if (item) { + return aim_ssi_getalias_from_item(item); } return NULL; } +char *aim_ssi_getalias_from_item(struct aim_ssi_item *item) +{ + aim_tlv_t *tlv = aim_tlv_gettlv(item->data, 0x0131, 1); + if (tlv && tlv->length) + return g_strndup((const gchar *)tlv->value, tlv->length); + return NULL; +} + /** * Locally find the comment of the given buddy. * @@ -493,7 +525,7 @@ * comment, or NULL if the buddy has no comment. You should free * this returned value! */ -char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn) +char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn) { struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); if (cur) { @@ -513,7 +545,7 @@ * @param bn The name of the buddy. * @return 1 if you are waiting for authorization; 0 if you are not */ -gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn) +gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn) { struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); if (cur) { @@ -561,8 +593,8 @@ /* Deletions */ if (!od->ssi.pending) { - for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) { - if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) { + for (cur1=od->ssi.official.data; cur1 && (n < 15); cur1=cur1->next) { + if (!aim_ssi_itemlist_find(&od->ssi.local, cur1->gid, cur1->bid)) { n++; new = g_new(struct aim_ssi_tmp, 1); new->action = SNAC_SUBTYPE_FEEDBAG_DEL; @@ -575,15 +607,15 @@ cur->next = new; } else od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1); + aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1); } } } /* Additions */ if (!od->ssi.pending) { - for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) { - if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) { + for (cur1=od->ssi.local.data; cur1 && (n < 15); cur1=cur1->next) { + if (!aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid)) { n++; new = g_new(struct aim_ssi_tmp, 1); new->action = SNAC_SUBTYPE_FEEDBAG_ADD; @@ -596,15 +628,15 @@ cur->next = new; } else od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Adding item ", cur1); + aim_ssi_item_debug_append(debugstr, "Adding item ", cur1); } } } /* Modifications */ if (!od->ssi.pending) { - for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) { - cur2 = aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid); + for (cur1=od->ssi.local.data; cur1 && (n < 15); cur1=cur1->next) { + cur2 = aim_ssi_itemlist_find(&od->ssi.official, cur1->gid, cur1->bid); if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) { n++; new = g_new(struct aim_ssi_tmp, 1); @@ -618,15 +650,15 @@ cur->next = new; } else od->ssi.pending = new; - aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1); + aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1); } } } if (debugstr->len > 0) { purple_debug_info("oscar", "%s", debugstr->str); if (purple_debug_is_verbose()) { - g_string_truncate(debugstr, 0); - for (cur1 = od->ssi.local; cur1; cur1 = cur1->next) + g_string_truncate(debugstr, 0); + for (cur1 = od->ssi.local.data; cur1; cur1 = cur1->next) aim_ssi_item_debug_append(debugstr, "\t", cur1); purple_debug_misc("oscar", "Dumping item list of account %s:\n%s", purple_connection_get_account(od->gc)->username, debugstr->str); @@ -673,22 +705,18 @@ struct aim_ssi_item *cur, *del; struct aim_ssi_tmp *curtmp, *deltmp; - cur = od->ssi.official; + cur = od->ssi.official.data; while (cur) { del = cur; cur = cur->next; - g_free(del->name); - aim_tlvlist_free(del->data); - g_free(del); + aim_ssi_item_free(del); } - cur = od->ssi.local; + cur = od->ssi.local.data; while (cur) { del = cur; cur = cur->next; - g_free(del->name); - aim_tlvlist_free(del->data); - g_free(del); + aim_ssi_item_free(del); } curtmp = od->ssi.pending; @@ -699,8 +727,8 @@ } od->ssi.numitems = 0; - od->ssi.official = NULL; - od->ssi.local = NULL; + od->ssi.official.data = NULL; + od->ssi.local.data = NULL; od->ssi.pending = NULL; od->ssi.timestamp = (time_t)0; } @@ -726,7 +754,7 @@ /* DESTROY any buddies that are directly in the master group. */ /* Do the same for buddies that are in a non-existant group. */ /* This will kind of mess up if you hit the item limit, but this function isn't too critical */ - cur = od->ssi.local; + cur = od->ssi.local.data; while (cur) { next = cur->next; if (!cur->name) { @@ -734,8 +762,8 @@ aim_ssi_delbuddy(od, NULL, NULL); else if (cur->type == AIM_SSI_TYPE_PERMIT || cur->type == AIM_SSI_TYPE_DENY || cur->type == AIM_SSI_TYPE_ICQDENY) aim_ssi_del_from_private_list(od, NULL, cur->type); - } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(od->ssi.local, cur->gid, 0x0000)))) { - char *alias = aim_ssi_getalias(od->ssi.local, NULL, cur->name); + } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(&od->ssi.local, cur->gid, 0x0000)))) { + char *alias = aim_ssi_getalias(&od->ssi.local, NULL, cur->name); aim_ssi_addbuddy(od, cur->name, "orphans", NULL, alias, NULL, NULL, FALSE); aim_ssi_delbuddy(od, cur->name, NULL); g_free(alias); @@ -744,7 +772,7 @@ } /* Make sure there aren't any duplicate buddies in a group, or duplicate permits or denies */ - cur = od->ssi.local; + cur = od->ssi.local.data; while (cur) { if ((cur->type == AIM_SSI_TYPE_BUDDY) || (cur->type == AIM_SSI_TYPE_PERMIT) || (cur->type == AIM_SSI_TYPE_DENY)) { @@ -785,16 +813,16 @@ return -EINVAL; /* Find the parent */ - if (!(parent = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { + if (!(parent = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { /* Find the parent's parent (the master group) */ - if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) + if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL) aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); /* Add the parent */ parent = aim_ssi_itemlist_add(&od->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL); /* Modify the parent's parent (the master group) */ - aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL); + aim_ssi_itemlist_rebuildgroup(&od->ssi.local, NULL); } /* Create a TLV list for the new buddy */ @@ -812,7 +840,7 @@ aim_tlvlist_free(data); /* Modify the parent group */ - aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); + aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -824,7 +852,7 @@ if (!od || !name || !od->ssi.received_data) return -EINVAL; - if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) + if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL) aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, list_type, NULL); @@ -839,7 +867,7 @@ if (!od) return -EINVAL; - if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, list_type))) + if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, name, list_type))) return -EINVAL; aim_ssi_itemlist_del(&od->ssi.local, del); @@ -862,14 +890,14 @@ return -EINVAL; /* Find the buddy */ - if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY))) + if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, name, AIM_SSI_TYPE_BUDDY))) return -EINVAL; /* Remove the item from the list */ aim_ssi_itemlist_del(&od->ssi.local, del); /* Modify the parent group */ - aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); + aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -891,7 +919,7 @@ return -EINVAL; /* Find the group */ - if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) + if (!(del = aim_ssi_itemlist_finditem(&od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) return -EINVAL; /* Don't delete the group if it's not empty */ @@ -903,7 +931,7 @@ aim_ssi_itemlist_del(&od->ssi.local, del); /* Modify the parent group */ - aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); + aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -925,7 +953,7 @@ GSList *data; /* Find the buddy */ - buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY); + buddy = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY); if (buddy == NULL) return -EINVAL; @@ -958,11 +986,11 @@ if (!od || !gn || !bn) return -EINVAL; - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) + if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) return -EINVAL; /* Either add or remove the 0x0131 TLV from the TLV chain */ - if ((alias != NULL) && (strlen(alias) > 0)) + if (alias && *alias) aim_tlvlist_replace_str(&tmp->data, 0x0131, alias); else aim_tlvlist_remove(&tmp->data, 0x0131); @@ -988,11 +1016,11 @@ if (!od || !gn || !bn) return -EINVAL; - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) + if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) return -EINVAL; /* Either add or remove the 0x0131 TLV from the TLV chain */ - if ((comment != NULL) && (strlen(comment) > 0)) + if (comment && *comment) aim_tlvlist_replace_str(&tmp->data, 0x013c, comment); else aim_tlvlist_remove(&tmp->data, 0x013c); @@ -1016,11 +1044,10 @@ if (!od || !oldgn || !newgn) return -EINVAL; - if (!(group = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP))) + if (!(group = aim_ssi_itemlist_finditem(&od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP))) return -EINVAL; - g_free(group->name); - group->name = g_strdup(newgn); + aim_ssi_item_set_name(&od->ssi.local, group, newgn); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -1047,9 +1074,9 @@ return -EINVAL; /* Find the PDINFO item, or add it if it does not exist */ - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) { + if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) { /* Make sure the master group exists */ - if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) + if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL) aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, NULL); @@ -1079,9 +1106,9 @@ return -EINVAL; /* Find the ICONINFO item, or add it if it does not exist */ - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { + if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { /* Make sure the master group exists */ - if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) + if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL) aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); tmp = aim_ssi_itemlist_add(&od->ssi.local, "1", 0x0000, 0xFFFF, AIM_SSI_TYPE_ICONINFO, NULL); @@ -1139,9 +1166,9 @@ return -EINVAL; /* Find the PRESENCEPREFS item, or add it if it does not exist */ - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) { + if (!(tmp = aim_ssi_itemlist_finditem(&od->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) { /* Make sure the master group exists */ - if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) + if (aim_ssi_itemlist_find(&od->ssi.local, 0x0000, 0x0000) == NULL) aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); tmp = aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, NULL); @@ -1266,7 +1293,7 @@ if (!(snac->flags & 0x0001)) { /* Make a copy of the list */ struct aim_ssi_item *cur; - for (cur=od->ssi.official; cur; cur=cur->next) + for (cur=od->ssi.official.data; cur; cur=cur->next) aim_ssi_itemlist_add(&od->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data); od->ssi.received_data = TRUE; @@ -1416,18 +1443,16 @@ data = NULL; /* Replace the 2 local items with the given one */ - if ((item = aim_ssi_itemlist_find(od->ssi.local, gid, bid))) { + if ((item = aim_ssi_itemlist_find(&od->ssi.local, gid, bid))) { item->type = type; - g_free(item->name); - item->name = g_strdup(name); + aim_ssi_item_set_name(&od->ssi.local, item, name); aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } - if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) { + if ((item = aim_ssi_itemlist_find(&od->ssi.official, gid, bid))) { item->type = type; - g_free(item->name); - item->name = g_strdup(name); + aim_ssi_item_set_name(&od->ssi.official, item, name); aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } @@ -1461,9 +1486,9 @@ byte_stream_get16(bs); byte_stream_advance(bs, byte_stream_get16(bs)); - if ((del = aim_ssi_itemlist_find(od->ssi.local, gid, bid))) + if ((del = aim_ssi_itemlist_find(&od->ssi.local, gid, bid))) aim_ssi_itemlist_del(&od->ssi.local, del); - if ((del = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) + if ((del = aim_ssi_itemlist_find(&od->ssi.official, gid, bid))) aim_ssi_itemlist_del(&od->ssi.official, del); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) @@ -1504,7 +1529,8 @@ if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) { /* Remove the item from the local list */ /* Make sure cur->item is still valid memory */ - if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) { + /* TODO: "Still valid memory"? That's bad form. */ + if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) { cur->name = g_strdup(cur->item->name); aim_ssi_itemlist_del(&od->ssi.local, cur->item); } @@ -1512,11 +1538,10 @@ } else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) { /* Replace the local item with the item from the official list */ - if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) { + if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) { struct aim_ssi_item *cur1; - if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) { - g_free(cur->item->name); - cur->item->name = g_strdup(cur1->name); + if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) { + aim_ssi_item_set_name(&od->ssi.official, cur->item, cur1->name); aim_tlvlist_free(cur->item->data); cur->item->data = aim_tlvlist_copy(cur1->data); } @@ -1525,7 +1550,7 @@ } else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) { /* Add the item back into the local list */ - if (aim_ssi_itemlist_valid(od->ssi.official, cur->item)) { + if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item)) { aim_ssi_itemlist_add(&od->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); } else cur->item = NULL; @@ -1535,18 +1560,17 @@ /* Do the exact opposite */ if (cur->action == SNAC_SUBTYPE_FEEDBAG_ADD) { /* Add the local item to the official list */ - if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) { + if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) { aim_ssi_itemlist_add(&od->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); } else cur->item = NULL; } else if (cur->action == SNAC_SUBTYPE_FEEDBAG_MOD) { /* Replace the official item with the item from the local list */ - if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) { + if (aim_ssi_itemlist_valid(&od->ssi.local, cur->item)) { struct aim_ssi_item *cur1; - if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) { - g_free(cur1->name); - cur1->name = g_strdup(cur->item->name); + if ((cur1 = aim_ssi_itemlist_find(&od->ssi.official, cur->item->gid, cur->item->bid))) { + aim_ssi_item_set_name(&od->ssi.official, cur1, cur->item->name); aim_tlvlist_free(cur1->data); cur1->data = aim_tlvlist_copy(cur->item->data); } @@ -1555,7 +1579,7 @@ } else if (cur->action == SNAC_SUBTYPE_FEEDBAG_DEL) { /* Remove the item from the official list */ - if (aim_ssi_itemlist_valid(od->ssi.official, cur->item)) + if (aim_ssi_itemlist_valid(&od->ssi.official, cur->item)) aim_ssi_itemlist_del(&od->ssi.official, cur->item); cur->item = NULL; } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/flap_connection.c --- a/libpurple/protocols/oscar/flap_connection.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Mon Aug 22 16:00:57 2011 +0000 @@ -487,7 +487,7 @@ if (tmp != NULL) { - purple_connection_error_reason(od->gc, reason, tmp); + purple_connection_error(od->gc, reason, tmp); g_free(tmp); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/oscar.c Mon Aug 22 16:00:57 2011 +0000 @@ -308,7 +308,7 @@ gchar *msg; msg = g_strdup_printf(_("Unable to connect to authentication server: %s"), error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); } else if (conn->type == SNAC_FAMILY_LOCATE) @@ -316,7 +316,7 @@ gchar *msg; msg = g_strdup_printf(_("Unable to connect to BOS server: %s"), error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); } else @@ -578,7 +578,7 @@ gc = data; od = purple_connection_get_protocol_data(gc); report_idle = strcmp((const char *)value, "none") != 0; - presence = aim_ssi_getpresence(od->ssi.local); + presence = aim_ssi_getpresence(&od->ssi.local); if (report_idle) aim_ssi_setpresence(od, presence | AIM_SSI_PRESENCE_FLAG_SHOWIDLE); @@ -600,7 +600,7 @@ gc = data; od = purple_connection_get_protocol_data(gc); - presence = aim_ssi_getpresence(od->ssi.local); + presence = aim_ssi_getpresence(&od->ssi.local); if (value) aim_ssi_setpresence(od, presence & ~AIM_SSI_PRESENCE_FLAG_NORECENTBUDDIES); @@ -735,13 +735,13 @@ if (!oscar_util_valid_name(purple_account_get_username(account))) { gchar *buf; buf = g_strdup_printf(_("Unable to sign on as %s because the username is invalid. Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf); g_free(buf); return; } gc->flags |= PURPLE_CONNECTION_HTML; - if (oscar_util_valid_name_icq((purple_account_get_username(account)))) { + if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq")) { od->icq = TRUE; } else { gc->flags |= PURPLE_CONNECTION_AUTO_RESP; @@ -756,7 +756,7 @@ encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION); if (!purple_ssl_is_supported() && strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) { - purple_connection_error_reason( + purple_connection_error( gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("You required encryption in your account settings, but encryption is not supported by your system.")); @@ -825,7 +825,7 @@ } if (newconn->gsc == NULL && newconn->connect_data == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; } @@ -1048,7 +1048,7 @@ if (conn->gsc == NULL && conn->connect_data == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return 0; } @@ -1087,41 +1087,41 @@ switch (info->errorcode) { case 0x01: /* Unregistered username */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Username does not exist")); break; case 0x05: /* Incorrect password */ if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password")); break; case 0x11: /* Suspended account */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Your account is currently suspended")); break; case 0x02: case 0x14: /* service temporarily unavailable */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable.")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable.")); break; case 0x18: /* username connecting too frequently */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your username has 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; case 0x1c: { /* client too old */ g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"), oscar_get_ui_info_string("website", PURPLE_WEBSITE)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, buf); break; } case 0x1d: /* IP address connecting too frequently */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer.")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Your IP address has been connecting and disconnecting too frequently. Wait a minute and try again. If you continue to try, you will need to wait even longer.")); break; default: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Unknown reason")); break; } purple_debug_info("oscar", "Login Error Code 0x%04hx\n", info->errorcode); @@ -1169,7 +1169,7 @@ g_free(host); if (newconn->gsc == NULL && newconn->connect_data == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return 0; } @@ -1199,7 +1199,7 @@ PurpleConnection *gc = user_data; /* Disconnect */ - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("The SecurID key entered is invalid")); } @@ -1292,7 +1292,7 @@ purple_debug_warning("oscar", "We won't use SSL for FLAP type 0x%04hx.\n", redir->group); } else if (strcmp(encryption_type, OSCAR_REQUIRE_ENCRYPTION) == 0) { purple_debug_error("oscar", "FLAP server %s:%d of type 0x%04hx doesn't support encryption.", host, port, redir->group); - purple_connection_error_reason( + purple_connection_error( gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("You required encryption in your account settings, but one of the servers doesn't support it.")); @@ -2278,7 +2278,7 @@ return 0; } -static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason, guint32 state, char *msg) { +static int purple_parse_clientauto_ch4(OscarData *od, const char *who, guint16 reason, guint32 state, char *msg) { PurpleConnection *gc = od->gc; switch(reason) { @@ -2286,16 +2286,20 @@ char *statusmsg, **splitmsg; PurpleNotifyUserInfo *user_info; + statusmsg = oscar_icqstatus(state); + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ - statusmsg = oscar_icqstatus(state); + /* TODO: Don't we need to escape each piece? */ splitmsg = g_strsplit(msg, "\r\n", 0); user_info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(user_info, _("UIN"), who); - purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg); purple_notify_user_info_add_section_break(user_info); - purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("
", splitmsg)); + purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("
", splitmsg)); g_free(statusmsg); g_strfreev(splitmsg); @@ -2309,16 +2313,20 @@ char *statusmsg, **splitmsg; PurpleNotifyUserInfo *user_info; + statusmsg = oscar_icqstatus(state); + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ - statusmsg = oscar_icqstatus(state); + /* TODO: Don't we need to escape each piece? */ splitmsg = g_strsplit(msg, "\r\n", 0); user_info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(user_info, _("UIN"), who); - purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Status"), statusmsg); purple_notify_user_info_add_section_break(user_info); - purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("
", splitmsg)); + purple_notify_user_info_add_pair_html(user_info, NULL, g_strjoinv("
", splitmsg)); g_free(statusmsg); g_strfreev(splitmsg); @@ -3716,7 +3724,7 @@ } if (od->ssi.received_data) { - if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, 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", bname, gname); aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); @@ -3728,8 +3736,8 @@ purple_prpl_got_user_status(account, bname, OSCAR_STATUS_ID_MOBILE, NULL); } - } else if (aim_ssi_waitingforauth(od->ssi.local, - aim_ssi_itemlist_findparentname(od->ssi.local, bname), + } else if (aim_ssi_waitingforauth(&od->ssi.local, + aim_ssi_itemlist_findparentname(&od->ssi.local, bname), bname)) { /* Not authorized -- Re-request authorization */ oscar_auth_sendrequest(gc, bname, msg); @@ -3767,7 +3775,7 @@ OscarData *od = purple_connection_get_protocol_data(gc); if (od->ssi.received_data) { - char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name); + char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name); if (gname) { purple_debug_info("oscar", "ssi: changing the alias for buddy %s to %s\n", name, alias ? alias : "(none)"); @@ -3784,7 +3792,7 @@ if (od->ssi.received_data) { const char *gname = purple_group_get_name(group); - if (aim_ssi_itemlist_finditem(od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) { + if (aim_ssi_itemlist_finditem(&od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) { GList *cur, *groups = NULL; PurpleAccount *account = purple_connection_get_account(gc); @@ -3935,7 +3943,7 @@ gname = purple_group_get_name(g); bname = purple_buddy_get_name(b); - if (aim_ssi_itemlist_exists(od->ssi.local, bname)) { + if (aim_ssi_itemlist_exists(&od->ssi.local, bname)) { /* If the buddy is an ICQ user then load his nickname */ const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"); char *alias; @@ -3944,7 +3952,7 @@ serv_got_alias(gc, bname, servernick); /* Store local alias on server */ - alias = aim_ssi_getalias(od->ssi.local, gname, bname); + alias = aim_ssi_getalias(&od->ssi.local, gname, bname); balias = purple_buddy_get_local_buddy_alias(b); if (!alias && balias && *balias) aim_ssi_aliasbuddy(od, gname, bname, balias); @@ -3967,7 +3975,7 @@ while (next != NULL) { cur = next; next = next->next; - if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) { + if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) { purple_debug_info("oscar", "ssi: removing permit %s from local list\n", (const char *)cur->data); purple_privacy_permit_remove(account, cur->data, TRUE); @@ -3980,7 +3988,7 @@ while (next != NULL) { cur = next; next = next->next; - if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, deny_entry_type)) { + if (!aim_ssi_itemlist_finditem(&od->ssi.local, NULL, cur->data, deny_entry_type)) { purple_debug_info("oscar", "ssi: removing deny %s from local list\n", (const char *)cur->data); purple_privacy_deny_remove(account, cur->data, TRUE); @@ -3988,7 +3996,7 @@ } /* Presence settings (idle time visibility) */ - tmp = aim_ssi_getpresence(od->ssi.local); + tmp = aim_ssi_getpresence(&od->ssi.local); if (tmp != 0xFFFFFFFF) { const char *idle_reporting_pref; gboolean report_idle; @@ -4006,7 +4014,7 @@ /*** Begin code for adding from server list to local list ***/ - for (curitem=od->ssi.local; curitem; curitem=curitem->next) { + for (curitem=od->ssi.local.data; curitem; curitem=curitem->next) { if (curitem->name && !g_utf8_validate(curitem->name, -1, NULL)) { /* Got node with invalid UTF-8 in the name. Skip it. */ purple_debug_warning("oscar", "ssi: server list contains item of " @@ -4020,7 +4028,7 @@ struct aim_ssi_item *groupitem; char *gname, *gname_utf8, *alias, *alias_utf8; - groupitem = aim_ssi_itemlist_find(od->ssi.local, curitem->gid, 0x0000); + groupitem = aim_ssi_itemlist_find(&od->ssi.local, curitem->gid, 0x0000); gname = groupitem ? groupitem->name : NULL; gname_utf8 = oscar_utf8_try_convert(account, od, gname); @@ -4030,7 +4038,7 @@ purple_blist_add_group(g, NULL); } - alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name); + alias = aim_ssi_getalias_from_item(curitem); alias_utf8 = oscar_utf8_try_convert(account, od, alias); b = purple_find_buddy_in_group(account, curitem->name, g); @@ -4099,7 +4107,7 @@ * a part of your status and not really related to blocking. */ if (!od->icq && curitem->data) { - guint8 perm_deny = aim_ssi_getpermdeny(od->ssi.local); + guint8 perm_deny = aim_ssi_getpermdeny(&od->ssi.local); if (perm_deny != 0 && perm_deny != account->perm_deny) { purple_debug_info("oscar", @@ -4228,10 +4236,10 @@ if ((type != 0x0000) || (name == NULL)) return 1; - gname = aim_ssi_itemlist_findparentname(od->ssi.local, name); + gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name); gname_utf8 = gname ? oscar_utf8_try_convert(account, od, gname) : NULL; - alias = aim_ssi_getalias(od->ssi.local, gname, name); + alias = aim_ssi_getalias(&od->ssi.local, gname, name); alias_utf8 = oscar_utf8_try_convert(account, od, alias); g_free(alias); @@ -4269,7 +4277,7 @@ } - ssi_item = aim_ssi_itemlist_finditem(od->ssi.local, + ssi_item = aim_ssi_itemlist_finditem(&od->ssi.local, gname, name, AIM_SSI_TYPE_BUDDY); if (ssi_item == NULL) { @@ -4586,32 +4594,18 @@ const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b) { const char *name = b ? purple_buddy_get_name(b) : NULL; - if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name)) - { - if (a == NULL || oscar_util_valid_name_icq(purple_account_get_username(a))) - return "icq"; - else - return "aim"; - } - - if (oscar_util_valid_name_icq(name)) + if (name && !oscar_util_valid_name_sms(name) && oscar_util_valid_name_icq(name)) return "icq"; - return "aim"; + + return "icq"; } const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b) { const char *name = b ? purple_buddy_get_name(b) : NULL; - if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name)) - { - if (a != NULL && oscar_util_valid_name_icq(purple_account_get_username(a))) - return "icq"; - else - return "aim"; - } - - if (oscar_util_valid_name_icq(name)) + if (name && !oscar_util_valid_name_sms(name) && oscar_util_valid_name_icq(name)) return "icq"; + return "aim"; } @@ -4642,8 +4636,8 @@ if (purple_presence_is_online(presence) == FALSE) { char *gname; if ((name) && (od) && (od->ssi.received_data) && - (gname = aim_ssi_itemlist_findparentname(od->ssi.local, name)) && - (aim_ssi_waitingforauth(od->ssi.local, gname, name))) { + (gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name)) && + (aim_ssi_waitingforauth(&od->ssi.local, gname, name))) { return "not-authorized"; } } @@ -4710,8 +4704,8 @@ if ((od != NULL) && !purple_presence_is_online(presence)) { const char *name = purple_buddy_get_name(b); - char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name); - if (aim_ssi_waitingforauth(od->ssi.local, gname, name)) + char *gname = aim_ssi_itemlist_findparentname(&od->ssi.local, name); + if (aim_ssi_waitingforauth(&od->ssi.local, gname, name)) ret = g_strdup(_("Not Authorized")); else ret = g_strdup(_("Offline")); @@ -4954,7 +4948,7 @@ data = g_new(struct name_data, 1); - comment = aim_ssi_getcomment(od->ssi.local, purple_group_get_name(g), name); + comment = aim_ssi_getcomment(&od->ssi.local, purple_group_get_name(g), name); comment_utf8 = comment ? oscar_utf8_try_convert(account, od, comment) : NULL; data->gc = gc; @@ -5175,8 +5169,8 @@ * waiting for authorization. */ char *gname; - gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname); - if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname)) + gname = aim_ssi_itemlist_findparentname(&od->ssi.local, bname); + if (gname && aim_ssi_waitingforauth(&od->ssi.local, gname, bname)) { act = purple_menu_action_new(_("Re-request Authorization"), PURPLE_CALLBACK(oscar_auth_sendrequest_menu), @@ -5327,7 +5321,7 @@ buddy = cur->data; bname = purple_buddy_get_name(buddy); gname = purple_group_get_name(purple_buddy_get_group(buddy)); - if (aim_ssi_waitingforauth(od->ssi.local, gname, bname)) { + if (aim_ssi_waitingforauth(&od->ssi.local, gname, bname)) { filtered_buddies = g_slist_prepend(filtered_buddies, buddy); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/oscar.h Mon Aug 22 16:00:57 2011 +0000 @@ -308,9 +308,14 @@ #include "peer.h" -/* - * AIM Session: The main client-data interface. - * +struct aim_ssi_itemlist { + struct aim_ssi_item *data; + GHashTable *idx_gid_bid; + GHashTable *idx_all_named_items; +}; + +/** + * The main client-data interface. */ struct _OscarData { @@ -387,8 +392,8 @@ struct { gboolean received_data; guint16 numitems; - struct aim_ssi_item *official; - struct aim_ssi_item *local; + struct aim_ssi_itemlist official; + struct aim_ssi_itemlist local; struct aim_ssi_tmp *pending; time_t timestamp; gboolean waiting_for_ack; @@ -916,15 +921,16 @@ /* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, const char *bn, guint8 reply, const char *msg); /* Client functions for retrieving SSI data */ -struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid); -struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type); -struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn); -char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn); -int aim_ssi_getpermdeny(struct aim_ssi_item *list); -guint32 aim_ssi_getpresence(struct aim_ssi_item *list); -char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn); -char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn); -gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn); +struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_itemlist *list, guint16 gid, guint16 bid); +struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_itemlist *list, const char *gn, const char *bn, guint16 type); +struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_itemlist *list, const char *bn); +char *aim_ssi_itemlist_findparentname(struct aim_ssi_itemlist *list, const char *bn); +int aim_ssi_getpermdeny(struct aim_ssi_itemlist *list); +guint32 aim_ssi_getpresence(struct aim_ssi_itemlist *list); +char *aim_ssi_getalias(struct aim_ssi_itemlist *list, const char *gn, const char *bn); +char *aim_ssi_getalias_from_item(struct aim_ssi_item *item); +char *aim_ssi_getcomment(struct aim_ssi_itemlist *list, const char *gn, const char *bn); +gboolean aim_ssi_waitingforauth(struct aim_ssi_itemlist *list, const char *gn, const char *bn); /* Client functions for changing SSI data */ int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/oscar_data.c --- a/libpurple/protocols/oscar/oscar_data.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/oscar_data.c Mon Aug 22 16:00:57 2011 +0000 @@ -47,6 +47,12 @@ od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); od->handlerlist = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + od->ssi.local.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal); + od->ssi.local.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + od->ssi.official.idx_gid_bid = g_hash_table_new(g_direct_hash, g_direct_equal); + od->ssi.official.idx_all_named_items = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + /* * Register all the modules for this session... */ @@ -126,6 +132,12 @@ g_hash_table_destroy(od->buddyinfo); g_hash_table_destroy(od->handlerlist); + g_hash_table_destroy(od->ssi.local.idx_gid_bid); + g_hash_table_destroy(od->ssi.local.idx_all_named_items); + + g_hash_table_destroy(od->ssi.official.idx_gid_bid); + g_hash_table_destroy(od->ssi.official.idx_all_named_items); + g_free(od); } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/userinfo.c --- a/libpurple/protocols/oscar/userinfo.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/userinfo.c Mon Aug 22 16:00:57 2011 +0000 @@ -131,21 +131,16 @@ } static void -oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value) -{ - if (value && value[0]) { - purple_notify_user_info_add_pair(user_info, name, value); - } -} - -static void oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info, const char *name, const char *value) { gchar *utf8; if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) { - purple_notify_user_info_add_pair(user_info, name, utf8); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext. Will + need to check callers of this function. */ + purple_notify_user_info_add_pair_html(user_info, name, utf8); g_free(utf8); } } @@ -158,7 +153,10 @@ if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) { gchar *tmp = g_strdup_printf("%s", url_prefix, utf8, utf8); - purple_notify_user_info_add_pair(user_info, name, tmp); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext. Will + need to check callers of this function. */ + purple_notify_user_info_add_pair_html(user_info, name, tmp); g_free(utf8); g_free(tmp); } @@ -263,8 +261,8 @@ message = tmp; } - } else if (aim_ssi_waitingforauth(od->ssi.local, - aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)), + } else if (aim_ssi_waitingforauth(&od->ssi.local, + aim_ssi_itemlist_findparentname(&od->ssi.local, purple_buddy_get_name(b)), purple_buddy_get_name(b))) { /* Note if an offline buddy is not authorized */ @@ -295,12 +293,12 @@ } else { description = g_strdup(_(mood)); } - purple_notify_user_info_add_pair(user_info, _("Mood"), description); + purple_notify_user_info_add_pair_html(user_info, _("Mood"), description); g_free(description); } } - purple_notify_user_info_add_pair(user_info, _("Status"), message); + purple_notify_user_info_add_pair_html(user_info, _("Status"), message); g_free(message); } @@ -340,23 +338,23 @@ bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn)); if ((bi != NULL) && (bi->ipaddr != 0)) { - tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", - (bi->ipaddr & 0xff000000) >> 24, - (bi->ipaddr & 0x00ff0000) >> 16, - (bi->ipaddr & 0x0000ff00) >> 8, - (bi->ipaddr & 0x000000ff)); - oscar_user_info_add_pair(user_info, _("IP Address"), tmp); - g_free(tmp); + char tmp2[40]; + sprintf(tmp2, "%hhu.%hhu.%hhu.%hhu", + (bi->ipaddr & 0xff000000) >> 24, + (bi->ipaddr & 0x00ff0000) >> 16, + (bi->ipaddr & 0x0000ff00) >> 8, + (bi->ipaddr & 0x000000ff)); + purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tmp2); } if ((userinfo != NULL) && (userinfo->warnlevel != 0)) { - tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5)); - oscar_user_info_add_pair(user_info, _("Warning Level"), tmp); - g_free(tmp); + char tmp2[12]; + sprintf(tmp2, "%d", (int)(userinfo->warnlevel/10.0 + .5)); + purple_notify_user_info_add_pair_plaintext(user_info, _("Warning Level"), tmp2); } if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) { - tmp = aim_ssi_getcomment(od->ssi.local, gname, bname); + tmp = aim_ssi_getcomment(&od->ssi.local, gname, bname); if (tmp != NULL) { char *tmp2 = g_markup_escape_text(tmp, strlen(tmp)); g_free(tmp); @@ -372,7 +370,7 @@ { PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); gchar *buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(error_reason)); - purple_notify_user_info_add_pair(user_info, NULL, buf); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, buf); purple_notify_userinfo(od->gc, buddy, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); purple_conv_present_error(buddy, purple_connection_get_account(od->gc), buf); @@ -402,16 +400,16 @@ else bi = NULL; - purple_notify_user_info_add_pair(user_info, _("UIN"), who); + purple_notify_user_info_add_pair_plaintext(user_info, _("UIN"), who); oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick); if ((bi != NULL) && (bi->ipaddr != 0)) { - char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", - (bi->ipaddr & 0xff000000) >> 24, - (bi->ipaddr & 0x00ff0000) >> 16, - (bi->ipaddr & 0x0000ff00) >> 8, - (bi->ipaddr & 0x000000ff)); - purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr); - g_free(tstr); + char tstr[40]; + sprintf(tstr, "%hhu.%hhu.%hhu.%hhu", + (bi->ipaddr & 0xff000000) >> 24, + (bi->ipaddr & 0x00ff0000) >> 16, + (bi->ipaddr & 0x0000ff00) >> 8, + (bi->ipaddr & 0x000000ff)); + purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), tstr); } oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first); oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last); @@ -425,7 +423,7 @@ oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile); if (info->gender != 0) - purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male"))); + purple_notify_user_info_add_pair_plaintext(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male"))); if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) { /* Initialize the struct properly or strftime() will crash @@ -437,7 +435,7 @@ tm->tm_mon = (int)info->birthmonth - 1; tm->tm_year = (int)info->birthyear - 1900; - /* Ignore dst setting of today to avoid timezone shift between + /* Ignore dst setting of today to avoid timezone shift between * dates in summer and winter time. */ tm->tm_isdst = -1; @@ -451,8 +449,9 @@ if ((info->age > 0) && (info->age < 255)) { char age[5]; snprintf(age, sizeof(age), "%hhd", info->age); - purple_notify_user_info_add_pair(user_info, _("Age"), age); + purple_notify_user_info_add_pair_plaintext(user_info, _("Age"), age); } + /* TODO: Is it correct to pass info->email here...? */ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Personal Web Page"), info->email, ""); if (buddy != NULL) oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* use_html_status */ TRUE); @@ -482,6 +481,7 @@ oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany); oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision); oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition); + /* TODO: Is it correct to pass info->email here...? */ oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Web Page"), info->email, ""); } @@ -505,7 +505,7 @@ if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) { tmp = purple_str_seconds_to_string(userinfo->idletime*60); - oscar_user_info_add_pair(user_info, _("Idle"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp); g_free(tmp); } @@ -514,17 +514,18 @@ if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) { /* An SMS contact is always online; its Online Since value is not useful */ time_t t = userinfo->onlinesince; - oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t))); + purple_notify_user_info_add_pair_plaintext(user_info, _("Online Since"), purple_date_format_full(localtime(&t))); } if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { time_t t = userinfo->membersince; - oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t))); + purple_notify_user_info_add_pair_plaintext(user_info, _("Member Since"), purple_date_format_full(localtime(&t))); } if (userinfo->capabilities != 0) { tmp = oscar_caps_to_string(userinfo->capabilities); - oscar_user_info_add_pair(user_info, _("Capabilities"), tmp); + if (tmp && *tmp) + purple_notify_user_info_add_pair_plaintext(user_info, _("Capabilities"), tmp); g_free(tmp); } @@ -533,7 +534,11 @@ info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len); tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account)); purple_notify_user_info_add_section_break(user_info); - oscar_user_info_add_pair(user_info, _("Profile"), tmp); + if (tmp && *tmp) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Profile"), tmp); + } g_free(tmp); g_free(info_utf8); } @@ -542,9 +547,9 @@ base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com"; tmp = g_strdup_printf("%s", base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile")); - purple_notify_user_info_add_pair(user_info, NULL, tmp); + purple_notify_user_info_add_pair_html(user_info, NULL, tmp); g_free(tmp); purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); -} \ No newline at end of file +} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/oscar/visibility.c --- a/libpurple/protocols/oscar/visibility.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/oscar/visibility.c Mon Aug 22 16:00:57 2011 +0000 @@ -51,7 +51,7 @@ static gboolean is_buddy_on_list(OscarData *od, const char *bname) { - return aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL; + return aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, get_buddy_list_type(od)) != NULL; } static void @@ -102,7 +102,7 @@ buddy = cur->data; bname = purple_buddy_get_name(buddy); - if (aim_ssi_itemlist_finditem(od->ssi.local, NULL, bname, list_type)) { + if (aim_ssi_itemlist_finditem(&od->ssi.local, NULL, bname, list_type)) { filtered_buddies = g_slist_prepend(filtered_buddies, buddy); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/sametime/sametime.c --- a/libpurple/protocols/sametime/sametime.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/sametime/sametime.c Mon Aug 22 16:00:57 2011 +0000 @@ -413,7 +413,7 @@ g_strerror(errno)); DEBUG_ERROR("write returned %" G_GSSIZE_FORMAT ", %" G_GSIZE_FORMAT " bytes left unwritten\n", ret, len); - purple_connection_error_reason(pd->gc, + purple_connection_error(pd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); @@ -861,7 +861,7 @@ enum mwSametimeUserType type = mwSametimeUser_getType(stuser); g_return_val_if_fail(id != NULL, NULL); - g_return_val_if_fail(strlen(id) > 0, NULL); + g_return_val_if_fail(*id, NULL); buddy = purple_find_buddy_in_group(acct, id, group); if(! buddy) { @@ -1613,7 +1613,7 @@ default: reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; } - purple_connection_error_reason(gc, reason, err); + purple_connection_error(gc, reason, err); g_free(err); } break; @@ -1762,7 +1762,7 @@ if(! ret) { DEBUG_INFO("connection reset\n"); - purple_connection_error_reason(pd->gc, + purple_connection_error(pd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); @@ -1773,7 +1773,7 @@ DEBUG_INFO("error in read callback: %s\n", err_str); msg = g_strdup_printf(_("Lost connection with server: %s"), err_str); - purple_connection_error_reason(pd->gc, + purple_connection_error(pd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); @@ -1799,7 +1799,7 @@ /* this is a regular connect, error out */ gchar *tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason(pd->gc, + purple_connection_error(pd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); @@ -3334,23 +3334,21 @@ status = status_text(b); if(message != NULL && g_utf8_validate(message, -1, NULL) && purple_utf8_strcasecmp(status, message)) { - tmp = g_markup_escape_text(message, -1); - purple_notify_user_info_add_pair(user_info, status, tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, status, message); } else { - purple_notify_user_info_add_pair(user_info, _("Status"), status); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status); } if(full && pd != NULL) { tmp = user_supports_text(pd->srvc_aware, purple_buddy_get_name(b)); if(tmp) { - purple_notify_user_info_add_pair(user_info, _("Supports"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp); g_free(tmp); } if(buddy_is_external(b)) { - purple_notify_user_info_add_pair(user_info, NULL, _("External User")); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("External User")); } } } @@ -3691,7 +3689,7 @@ static void prompt_host_cancel_cb(PurpleConnection *gc) { const char *msg = _("No Sametime Community Server specified"); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, msg); } @@ -3806,7 +3804,7 @@ purple_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS); if (purple_proxy_connect(gc, account, host, port, connect_cb, pd) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } } @@ -4200,46 +4198,47 @@ user_info = purple_notify_user_info_new(); if(purple_str_has_prefix(who, "@E ")) { - purple_notify_user_info_add_pair(user_info, _("External User"), NULL); + purple_notify_user_info_add_pair_html(user_info, _("External User"), NULL); } - purple_notify_user_info_add_pair(user_info, _("User ID"), who); + purple_notify_user_info_add_pair_plaintext(user_info, _("User ID"), who); if(b) { guint32 type; if(purple_buddy_get_server_alias(b)) { - purple_notify_user_info_add_pair(user_info, _("Full Name"), purple_buddy_get_server_alias(b)); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Full Name"), purple_buddy_get_server_alias(b)); } type = purple_blist_node_get_int((PurpleBlistNode *) b, BUDDY_KEY_CLIENT); if(type) { - tmp = g_strdup(mw_client_name(type)); - if (!tmp) + tmp2 = mw_client_name(type); + if (tmp2) { + purple_notify_user_info_add_pair_plaintext(user_info, _("Last Known Client"), tmp2); + } else { tmp = g_strdup_printf(_("Unknown (0x%04x)
"), type); - - purple_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp); - - g_free(tmp); + purple_notify_user_info_add_pair_html(user_info, _("Last Known Client"), tmp); + g_free(tmp); + } } } tmp = user_supports_text(pd->srvc_aware, who); if(tmp) { - purple_notify_user_info_add_pair(user_info, _("Supports"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Supports"), tmp); g_free(tmp); } if(b) { - purple_notify_user_info_add_pair(user_info, _("Status"), status_text(b)); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status_text(b)); /* XXX Is this adding a status message in its own section rather than with the "Status" label? */ tmp2 = mwServiceAware_getText(pd->srvc_aware, &idb); if(tmp2 && g_utf8_validate(tmp2, -1, NULL)) { - tmp = g_markup_escape_text(tmp2, -1); purple_notify_user_info_add_section_break(user_info); - purple_notify_user_info_add_pair(user_info, NULL, tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, tmp2); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc/buddy.c --- a/libpurple/protocols/silc/buddy.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/silc/buddy.c Mon Aug 22 16:00:57 2011 +0000 @@ -1547,54 +1547,72 @@ return; if (client_entry->nickname) - purple_notify_user_info_add_pair(user_info, _("Nickname"), + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Nickname"), client_entry->nickname); if (client_entry->username && client_entry->hostname) { g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Username"), tmp); } if (client_entry->mode) { memset(tmp, 0, sizeof(tmp)); silcpurple_get_umode_string(client_entry->mode, tmp, sizeof(tmp) - strlen(tmp)); - purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("User Modes"), tmp); } silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); if (statusstr) { - purple_notify_user_info_add_pair(user_info, _("Message"), statusstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Message"), statusstr); g_free(statusstr); } if (full) { if (moodstr) { - purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr); g_free(moodstr); } if (contactstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr); g_free(contactstr); } if (langstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr); g_free(langstr); } if (devicestr) { - purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr); g_free(devicestr); } if (tzstr) { - purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr); g_free(tzstr); } if (geostr) { - purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr); g_free(geostr); } } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc/ops.c --- a/libpurple/protocols/silc/ops.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/silc/ops.c Mon Aug 22 16:00:57 2011 +0000 @@ -72,7 +72,7 @@ gc = client->application; if (gc != NULL) - purple_connection_error_reason(gc, reason, tmp); + purple_connection_error(gc, reason, tmp); else purple_notify_error(NULL, _("Error"), _("Error occurred"), tmp); } @@ -1162,7 +1162,7 @@ SilcUInt32 idle, *user_modes; SilcDList channels; SilcClientEntry client_entry; - char tmp[1024], *tmp2; + char tmp[1024]; char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; PurpleNotifyUserInfo *user_info; @@ -1184,71 +1184,80 @@ user_modes = va_arg(ap, SilcUInt32 *); user_info = purple_notify_user_info_new(); - tmp2 = g_markup_escape_text(client_entry->nickname, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2); - g_free(tmp2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), client_entry->nickname); if (client_entry->realname) { - tmp2 = g_markup_escape_text(client_entry->realname, -1); - purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2); - g_free(tmp2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), client_entry->realname); } - tmp2 = g_markup_escape_text(client_entry->username, -1); if (*client_entry->hostname) { - gchar *tmp3; - tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp3); - g_free(tmp3); + gchar *tmp2; + tmp2 = g_strdup_printf("%s@%s", client_entry->username, client_entry->hostname); + purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp2); + g_free(tmp2); } else - purple_notify_user_info_add_pair(user_info, _("Username"), tmp2); - g_free(tmp2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), client_entry->username); if (client_entry->mode) { memset(tmp, 0, sizeof(tmp)); silcpurple_get_umode_string(client_entry->mode, tmp, sizeof(tmp) - strlen(tmp)); - purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("User Modes"), tmp); } silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); if (moodstr) { - purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Mood"), moodstr); g_free(moodstr); } if (statusstr) { - tmp2 = g_markup_escape_text(statusstr, -1); - purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status Text"), statusstr); g_free(statusstr); - g_free(tmp2); } if (contactstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Preferred Contact"), contactstr); g_free(contactstr); } if (langstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Preferred Language"), langstr); g_free(langstr); } if (devicestr) { - purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Device"), devicestr); g_free(devicestr); } if (tzstr) { - purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Timezone"), tzstr); g_free(tzstr); } if (geostr) { - purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Geolocation"), geostr); g_free(geostr); } - if (*client_entry->server) - purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server); + if (*client_entry->server) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server); + } if (channels && user_modes) { SilcChannelPayload entry; @@ -1266,9 +1275,7 @@ silc_strncat(tmp, sizeof(tmp) - 1, " ", 1); silc_free(m); } - tmp2 = g_markup_escape_text(tmp, -1); - purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2); - g_free(tmp2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Currently on"), tmp); } if (client_entry->public_key) { @@ -1279,8 +1286,8 @@ if (pk) { fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint); - purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint); + purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint); + purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint); silc_free(fingerprint); silc_free(babbleprint); silc_free(pk); @@ -1304,7 +1311,7 @@ case SILC_COMMAND_WHOWAS: { SilcClientEntry client_entry; - char *nickname, *realname, *username, *tmp; + char *nickname, *realname, *username; PurpleNotifyUserInfo *user_info; if (status != SILC_STATUS_OK) { @@ -1322,27 +1329,23 @@ break; user_info = purple_notify_user_info_new(); - tmp = g_markup_escape_text(nickname, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp); - g_free(tmp); - if (realname) { - tmp = g_markup_escape_text(realname, -1); - purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp); - g_free(tmp); - } + purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), nickname); + if (realname) + purple_notify_user_info_add_pair_plaintext(user_info, _("Real Name"), realname); if (username) { - tmp = g_markup_escape_text(username, -1); if (client_entry && *client_entry->hostname) { - gchar *tmp3; - tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp3); - g_free(tmp3); + gchar *tmp; + tmp = g_strdup_printf("%s@%s", username, client_entry->hostname); + purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), tmp); + g_free(tmp); } else - purple_notify_user_info_add_pair(user_info, _("Username"), tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Username"), username); } - if (client_entry && *client_entry->server) - purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server); + if (client_entry && *client_entry->server) { + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("Server"), client_entry->server); + } if (client_entry && client_entry->public_key) { @@ -1353,8 +1356,8 @@ if (pk) { fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint); - purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint); + purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Fingerprint"), fingerprint); + purple_notify_user_info_add_pair_plaintext(user_info, _("Public Key Babbleprint"), babbleprint); silc_free(fingerprint); silc_free(babbleprint); silc_free(pk); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc/silc.c --- a/libpurple/protocols/silc/silc.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/silc/silc.c Mon Aug 22 16:00:57 2011 +0000 @@ -316,7 +316,7 @@ /* Close the connection */ if (!sg->detaching) - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Disconnected by server")); else @@ -325,30 +325,30 @@ break; case SILC_CLIENT_CONN_ERROR: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Error connecting to SILC Server")); g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); break; case SILC_CLIENT_CONN_ERROR_KE: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Key Exchange failed")); break; case SILC_CLIENT_CONN_ERROR_AUTH: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Authentication failed")); break; case SILC_CLIENT_CONN_ERROR_RESUME: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Resuming detached session failed. " "Press Reconnect to create new connection.")); g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); break; case SILC_CLIENT_CONN_ERROR_TIMEOUT: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection timed out")); break; } @@ -370,7 +370,7 @@ sg = gc->proto_data; if (status != SILC_SOCKET_OK) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection failed")); silc_pkcs_public_key_free(sg->public_key); @@ -418,7 +418,7 @@ sg = gc->proto_data; if (source < 0) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Connection failed")); silc_pkcs_public_key_free(sg->public_key); silc_pkcs_private_key_free(sg->private_key); @@ -447,7 +447,7 @@ purple_account_get_int(account, "port", 706), silcpurple_login_connected, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); gc->proto_data = NULL; silc_free(sg); @@ -490,7 +490,7 @@ (char *)purple_account_get_string(account, "private-key", prd), password, &sg->public_key, &sg->private_key)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to load SILC key pair")); gc->proto_data = NULL; silc_free(sg); @@ -506,7 +506,7 @@ if (!PURPLE_CONNECTION_IS_VALID(gc)) return; sg = gc->proto_data; - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to load SILC key pair")); gc->proto_data = NULL; silc_free(sg); @@ -535,7 +535,7 @@ G_CALLBACK(silcpurple_no_password_cb), gc); return; } - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to load SILC key pair")); gc->proto_data = NULL; silc_free(sg); @@ -566,7 +566,7 @@ /* Allocate SILC client */ client = silc_client_alloc(&ops, ¶ms, gc, NULL); if (!client) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Out of memory")); return; } @@ -617,7 +617,7 @@ /* Init SILC client */ if (!silc_client_init(client, username, hostname, realname, silcpurple_running, sg)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to initialize SILC protocol")); gc->proto_data = NULL; silc_free(sg); @@ -630,7 +630,7 @@ /* Check the ~/.silc dir and create it, and new key pair if necessary. */ if (!silcpurple_check_silc_dir(gc)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Error loading SILC key pair")); gc->proto_data = NULL; silc_free(sg); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc/util.c --- a/libpurple/protocols/silc/util.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/silc/util.c Mon Aug 22 16:00:57 2011 +0000 @@ -213,7 +213,7 @@ (gc->password == NULL) ? "" : gc->password, NULL, NULL, FALSE)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to create SILC key pair")); return FALSE; } @@ -256,7 +256,7 @@ (gc->password == NULL) ? "" : gc->password, NULL, NULL, FALSE)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unable to create SILC key pair")); return FALSE; } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/Makefile.am --- a/libpurple/protocols/silc10/Makefile.am Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -EXTRA_DIST = \ - Makefile.mingw \ - README \ - TODO - -pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION) - -SILCSOURCES = silc.c silcpurple.h buddy.c chat.c ft.c ops.c pk.c util.c wb.c wb.h - -AM_CFLAGS = $(st) - -libsilcpurple_la_LDFLAGS = -module -avoid-version - -if STATIC_SILC - -st = -DPURPLE_STATIC_PRPL $(SILC_CFLAGS) -noinst_LTLIBRARIES = libsilcpurple.la -libsilcpurple_la_SOURCES = $(SILCSOURCES) -libsilcpurple_la_CFLAGS = $(AM_CFLAGS) -libsilcpurple_la_LIBADD = $(SILC_LIBS) - -else - -st = $(SILC_CFLAGS) -pkg_LTLIBRARIES = libsilcpurple.la -libsilcpurple_la_SOURCES = $(SILCSOURCES) -libsilcpurple_la_LIBADD = $(GLIB_LIBS) $(SILC_LIBS) - -endif - -AM_CPPFLAGS = \ - -I$(top_srcdir)/libpurple \ - -I$(top_builddir)/libpurple \ - $(DEBUG_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(SILC_CFLAGS) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/Makefile.mingw --- a/libpurple/protocols/silc10/Makefile.mingw Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -# -# Makefile.mingw -# -# Description: Makefile for win32 (mingw) version of libsilc protocol plugin -# - -PIDGIN_TREE_TOP := ../../.. -include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak - -DEFINES := $(subst -DWIN32_LEAN_AND_MEAN,,$(DEFINES)) - -TARGET = libsilc -NEEDED_DLLS = $(SILC_TOOLKIT)/lib/silc.dll \ - $(SILC_TOOLKIT)/lib/silcclient.dll -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. \ - -I$(GTK_TOP)/include \ - -I$(GTK_TOP)/include/glib-2.0 \ - -I$(GTK_TOP)/lib/glib-2.0/include \ - -I$(PURPLE_TOP) \ - -I$(PURPLE_TOP)/win32 \ - -I$(PIDGIN_TREE_TOP) \ - -I$(SILC_TOOLKIT)/include - -LIB_PATHS += -L$(GTK_TOP)/lib \ - -L$(PURPLE_TOP) \ - -L$(SILC_TOOLKIT)/lib - -## -## SOURCES, OBJECTS -## -C_SRC = silc.c \ - buddy.c \ - chat.c \ - ft.c \ - ops.c \ - pk.c \ - util.c \ - wb.c - -OBJECTS = $(C_SRC:%.c=%.o) - -## -## LIBRARIES -## -LIBS = \ - -lglib-2.0 \ - -lws2_32 \ - -lintl \ - -lpurple \ - -lsilc \ - -lsilcclient - -include $(PIDGIN_COMMON_RULES) - -## -## TARGET DEFINITIONS -## -.PHONY: all install clean - -all: $(TARGET).dll - -install: all $(DLL_INSTALL_DIR) $(PURPLE_INSTALL_DIR) - cp $(TARGET).dll $(DLL_INSTALL_DIR) - cp $(NEEDED_DLLS) $(PURPLE_INSTALL_DIR) - -$(OBJECTS): $(PURPLE_CONFIG_H) - -$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS) - $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--image-base,0x64000000 -o $(TARGET).dll - -## -## CLEAN RULES -## -clean: - rm -f $(OBJECTS) - rm -f $(TARGET).dll - -include $(PIDGIN_COMMON_TARGETS) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/README --- a/libpurple/protocols/silc10/README Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -SILC Purple Plugin -================== - -This is the Purple protocol plugin of the protocol called Secure Internet -Live Conferencing (SILC). The implementation will use the SILC Toolkit, -freely available from the http://silcnet.org/ site, for the actual SILC -protocol implementation. - -To include SILC into Purple, one needs to first compile and install -the SILC Toolkit. It is done as follows: - - ./configure --enable-shared - make - make install - -This will compile shared libraries of the SILC Toolkit. If the --prefix -is not given to ./configure, the binaries are installed into the -/usr/local/silc directory. - -Once the Toolkit is installed one needs to tell Purple's ./configure -script where the SILC Toolkit is located. It is done as simply as: - - ./configure - -if pkg-config is installed in your system. If it is isn't it's done as: - - ./configure --with-silc-libs=/path/to/silc/lib - --with-silc-includes=/path/to/silc/include - -If the SILC Toolkit cannot be found then the SILC protocol plugin will -not be compiled. diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/TODO --- a/libpurple/protocols/silc10/TODO Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -Features TODO (maybe) -===================== - -Preferences - - Add joined channels to buddy list automatically (during - session) - - Add joined channels to buddy list automatically permanently - diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/buddy.c --- a/libpurple/protocols/silc10/buddy.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1748 +0,0 @@ -/* - - silcpurple_buddy.c - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "wb.h" - -/***************************** Key Agreement *********************************/ - -static void -silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data); - -static void -silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name, - gboolean force_local); - -typedef struct { - char *nick; - PurpleConnection *gc; -} *SilcPurpleResolve; - -static void -silcpurple_buddy_keyagr_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - PurpleConnection *gc = client->application; - SilcPurpleResolve r = context; - char tmp[256]; - - if (!clients) { - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), r->nick); - purple_notify_error(gc, _("Key Agreement"), - _("Cannot perform the key agreement"), tmp); - silc_free(r->nick); - silc_free(r); - return; - } - - silcpurple_buddy_keyagr_do(gc, r->nick, FALSE); - silc_free(r->nick); - silc_free(r); -} - -typedef struct { - gboolean responder; -} *SilcPurpleKeyAgr; - -static void -silcpurple_buddy_keyagr_cb(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - SilcKeyAgreementStatus status, - SilcSKEKeyMaterial *key, - void *context) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - SilcPurpleKeyAgr a = context; - - if (!sg->conn) - return; - - switch (status) { - case SILC_KEY_AGREEMENT_OK: - { - PurpleConversation *convo; - char tmp[128]; - - /* Set the private key for this client */ - silc_client_del_private_message_key(client, conn, client_entry); - silc_client_add_private_message_key_ske(client, conn, client_entry, - NULL, NULL, key, a->responder); - silc_ske_free_key_material(key); - - - /* Open IM window */ - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, - client_entry->nickname, sg->account); - if (convo) { - /* we don't have windows in the core anymore...but we may want to - * provide some method for asking the UI to show the window - purple_conv_window_show(purple_conversation_get_window(convo)); - */ - } else { - convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account, - client_entry->nickname); - } - g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname); - purple_conversation_set_title(convo, tmp); - } - break; - - case SILC_KEY_AGREEMENT_ERROR: - purple_notify_error(gc, _("Key Agreement"), - _("Error occurred during key agreement"), NULL); - break; - - case SILC_KEY_AGREEMENT_FAILURE: - purple_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL); - break; - - case SILC_KEY_AGREEMENT_TIMEOUT: - purple_notify_error(gc, _("Key Agreement"), - _("Timeout during key agreement"), NULL); - break; - - case SILC_KEY_AGREEMENT_ABORTED: - purple_notify_error(gc, _("Key Agreement"), - _("Key agreement was aborted"), NULL); - break; - - case SILC_KEY_AGREEMENT_ALREADY_STARTED: - purple_notify_error(gc, _("Key Agreement"), - _("Key agreement is already started"), NULL); - break; - - case SILC_KEY_AGREEMENT_SELF_DENIED: - purple_notify_error(gc, _("Key Agreement"), - _("Key agreement cannot be started with yourself"), - NULL); - break; - - default: - break; - } - - silc_free(a); -} - -static void -silcpurple_buddy_keyagr_do(PurpleConnection *gc, const char *name, - gboolean force_local) -{ - SilcPurple sg = gc->proto_data; - SilcClientEntry *clients; - SilcUInt32 clients_count; - char *local_ip = NULL, *remote_ip = NULL; - gboolean local = TRUE; - char *nickname; - SilcPurpleKeyAgr a; - - if (!sg->conn || !name) - return; - - if (!silc_parse_userfqdn(name, &nickname, NULL)) - return; - - /* Find client entry */ - clients = silc_client_get_clients_local(sg->client, sg->conn, nickname, name, - &clients_count); - if (!clients) { - /* Resolve unknown user */ - SilcPurpleResolve r = silc_calloc(1, sizeof(*r)); - if (!r) - return; - r->nick = g_strdup(name); - r->gc = gc; - silc_client_get_clients(sg->client, sg->conn, nickname, NULL, - silcpurple_buddy_keyagr_resolved, r); - silc_free(nickname); - return; - } - - /* Resolve the local IP from the outgoing socket connection. We resolve - it to check whether we have a private range IP address or public IP - address. If we have public then we will assume that we are not behind - NAT and will provide automatically the point of connection to the - agreement. If we have private range address we assume that we are - behind NAT and we let the responder provide the point of connection. - - The algorithm also checks the remote IP address of server connection. - If it is private range address and we have private range address we - assume that we are chatting in LAN and will provide the point of - connection. - - Naturally this algorithm does not always get things right. */ - - if (silc_net_check_local_by_sock(sg->conn->sock->sock, NULL, &local_ip)) { - /* Check if the IP is private */ - if (!force_local && silcpurple_ip_is_private(local_ip)) { - local = FALSE; - - /* Local IP is private, resolve the remote server IP to see whether - we are talking to Internet or just on LAN. */ - if (silc_net_check_host_by_sock(sg->conn->sock->sock, NULL, - &remote_ip)) - if (silcpurple_ip_is_private(remote_ip)) - /* We assume we are in LAN. Let's provide - the connection point. */ - local = TRUE; - } - } - - if (force_local) - local = TRUE; - - if (local && !local_ip) - local_ip = silc_net_localip(); - - a = silc_calloc(1, sizeof(*a)); - if (!a) - return; - a->responder = local; - - /* Send the key agreement request */ - silc_client_send_key_agreement(sg->client, sg->conn, clients[0], - local ? local_ip : NULL, NULL, 0, 60, - silcpurple_buddy_keyagr_cb, a); - - silc_free(local_ip); - silc_free(remote_ip); - silc_free(clients); -} - -typedef struct { - SilcClient client; - SilcClientConnection conn; - SilcClientID client_id; - char *hostname; - SilcUInt16 port; -} *SilcPurpleKeyAgrAsk; - -static void -silcpurple_buddy_keyagr_request_cb(SilcPurpleKeyAgrAsk a, gint id) -{ - SilcPurpleKeyAgr ai; - SilcClientEntry client_entry; - - if (id != 1) - goto out; - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(a->client, a->conn, - &a->client_id); - if (!client_entry) { - purple_notify_error(a->client->application, _("Key Agreement"), - _("The remote user is not present in the network any more"), - NULL); - goto out; - } - - /* If the hostname was provided by the requestor perform the key agreement - now. Otherwise, we will send him a request to connect to us. */ - if (a->hostname) { - ai = silc_calloc(1, sizeof(*ai)); - if (!ai) - goto out; - ai->responder = FALSE; - silc_client_perform_key_agreement(a->client, a->conn, client_entry, - a->hostname, a->port, - silcpurple_buddy_keyagr_cb, ai); - } else { - /* Send request. Force us as the point of connection since requestor - did not provide the point of connection. */ - silcpurple_buddy_keyagr_do(a->client->application, - client_entry->nickname, TRUE); - } - - out: - silc_free(a->hostname); - silc_free(a); -} - -void silcpurple_buddy_keyagr_request(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - const char *hostname, SilcUInt16 port) -{ - char tmp[128], tmp2[128]; - SilcPurpleKeyAgrAsk a; - PurpleConnection *gc = client->application; - - g_snprintf(tmp, sizeof(tmp), - _("Key agreement request received from %s. Would you like to " - "perform the key agreement?"), client_entry->nickname); - if (hostname) - g_snprintf(tmp2, sizeof(tmp2), - _("The remote user is waiting key agreement on:\n" - "Remote host: %s\nRemote port: %d"), hostname, port); - - a = silc_calloc(1, sizeof(*a)); - if (!a) - return; - a->client = client; - a->conn = conn; - a->client_id = *client_entry->id; - if (hostname) - a->hostname = strdup(hostname); - a->port = port; - - purple_request_action(client->application, _("Key Agreement Request"), tmp, - hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname, - NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb), - _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb)); -} - -static void -silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *buddy; - - buddy = (PurpleBuddy *)node; - silcpurple_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE); -} - - -/**************************** Static IM Key **********************************/ - -static void -silcpurple_buddy_resetkey(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *b; - PurpleConnection *gc; - SilcPurple sg; - char *nickname; - SilcClientEntry *clients; - SilcUInt32 clients_count; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); - sg = gc->proto_data; - - if (!silc_parse_userfqdn(b->name, &nickname, NULL)) - return; - - /* Find client entry */ - clients = silc_client_get_clients_local(sg->client, sg->conn, - nickname, b->name, - &clients_count); - if (!clients) { - silc_free(nickname); - return; - } - - clients[0]->prv_resp = FALSE; - silc_client_del_private_message_key(sg->client, sg->conn, - clients[0]); - silc_free(clients); - silc_free(nickname); -} - -typedef struct { - SilcClient client; - SilcClientConnection conn; - SilcClientID client_id; -} *SilcPurplePrivkey; - -static void -silcpurple_buddy_privkey(PurpleConnection *gc, const char *name); - -static void -silcpurple_buddy_privkey_cb(SilcPurplePrivkey p, const char *passphrase) -{ - SilcClientEntry client_entry; - - if (!passphrase || !(*passphrase)) { - silc_free(p); - return; - } - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(p->client, p->conn, - &p->client_id); - if (!client_entry) { - purple_notify_error(p->client->application, _("IM With Password"), - _("The remote user is not present in the network any more"), - NULL); - silc_free(p); - return; - } - - /* Set the private message key */ - silc_client_del_private_message_key(p->client, p->conn, - client_entry); - silc_client_add_private_message_key(p->client, p->conn, - client_entry, NULL, NULL, - (unsigned char *)passphrase, - strlen(passphrase), FALSE, - client_entry->prv_resp); - if (!client_entry->prv_resp) - silc_client_send_private_message_key_request(p->client, - p->conn, - client_entry); - silc_free(p); -} - -static void -silcpurple_buddy_privkey_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - char tmp[256]; - - if (!clients) { - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), - (const char *)context); - purple_notify_error(client->application, _("IM With Password"), - _("Cannot set IM key"), tmp); - g_free(context); - return; - } - - silcpurple_buddy_privkey(client->application, context); - silc_free(context); -} - -static void -silcpurple_buddy_privkey(PurpleConnection *gc, const char *name) -{ - SilcPurple sg = gc->proto_data; - char *nickname; - SilcPurplePrivkey p; - SilcClientEntry *clients; - SilcUInt32 clients_count; - - if (!name) - return; - if (!silc_parse_userfqdn(name, &nickname, NULL)) - return; - - /* Find client entry */ - clients = silc_client_get_clients_local(sg->client, sg->conn, - nickname, name, - &clients_count); - if (!clients) { - silc_client_get_clients(sg->client, sg->conn, nickname, NULL, - silcpurple_buddy_privkey_resolved, - g_strdup(name)); - silc_free(nickname); - return; - } - - p = silc_calloc(1, sizeof(*p)); - if (!p) - return; - p->client = sg->client; - p->conn = sg->conn; - p->client_id = *clients[0]->id; - purple_request_input(gc, _("IM With Password"), NULL, - _("Set IM Password"), NULL, FALSE, TRUE, NULL, - _("OK"), G_CALLBACK(silcpurple_buddy_privkey_cb), - _("Cancel"), G_CALLBACK(silcpurple_buddy_privkey_cb), - gc->account, NULL, NULL, p); - - silc_free(clients); - silc_free(nickname); -} - -static void -silcpurple_buddy_privkey_menu(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *buddy; - PurpleConnection *gc; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - - silcpurple_buddy_privkey(gc, buddy->name); -} - - -/**************************** Get Public Key *********************************/ - -typedef struct { - SilcClient client; - SilcClientConnection conn; - SilcClientID client_id; -} *SilcPurpleBuddyGetkey; - -static void -silcpurple_buddy_getkey(PurpleConnection *gc, const char *name); - -static void -silcpurple_buddy_getkey_cb(SilcPurpleBuddyGetkey g, - SilcClientCommandReplyContext cmd) -{ - SilcClientEntry client_entry; - unsigned char *pk; - SilcUInt32 pk_len; - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(g->client, g->conn, - &g->client_id); - if (!client_entry) { - purple_notify_error(g->client->application, _("Get Public Key"), - _("The remote user is not present in the network any more"), - NULL); - silc_free(g); - return; - } - - if (!client_entry->public_key) { - silc_free(g); - return; - } - - /* Now verify the public key */ - pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); - silcpurple_verify_public_key(g->client, g->conn, client_entry->nickname, - SILC_SOCKET_TYPE_CLIENT, - pk, pk_len, SILC_SKE_PK_TYPE_SILC, - NULL, NULL); - silc_free(pk); - silc_free(g); -} - -static void -silcpurple_buddy_getkey_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - char tmp[256]; - - if (!clients) { - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), - (const char *)context); - purple_notify_error(client->application, _("Get Public Key"), - _("Cannot fetch the public key"), tmp); - g_free(context); - return; - } - - silcpurple_buddy_getkey(client->application, context); - silc_free(context); -} - -static void -silcpurple_buddy_getkey(PurpleConnection *gc, const char *name) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientEntry *clients; - SilcUInt32 clients_count; - SilcPurpleBuddyGetkey g; - char *nickname; - - if (!name) - return; - - if (!silc_parse_userfqdn(name, &nickname, NULL)) - return; - - /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, name, - &clients_count); - if (!clients) { - silc_client_get_clients(client, conn, nickname, NULL, - silcpurple_buddy_getkey_resolved, - g_strdup(name)); - silc_free(nickname); - return; - } - - /* Call GETKEY */ - g = silc_calloc(1, sizeof(*g)); - if (!g) - return; - g->client = client; - g->conn = conn; - g->client_id = *clients[0]->id; - silc_client_command_call(client, conn, NULL, "GETKEY", - clients[0]->nickname, NULL); - silc_client_command_pending(conn, SILC_COMMAND_GETKEY, - conn->cmd_ident, - (SilcCommandCb)silcpurple_buddy_getkey_cb, g); - silc_free(clients); - silc_free(nickname); -} - -static void -silcpurple_buddy_getkey_menu(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *buddy; - PurpleConnection *gc; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - - silcpurple_buddy_getkey(gc, buddy->name); -} - -static void -silcpurple_buddy_showkey(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *b; - PurpleConnection *gc; - SilcPurple sg; - SilcPublicKey public_key; - const char *pkfile; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); - sg = gc->proto_data; - - pkfile = purple_blist_node_get_string(node, "public-key"); - if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) { - purple_notify_error(gc, - _("Show Public Key"), - _("Could not load public key"), NULL); - return; - } - - silcpurple_show_public_key(sg, b->name, public_key, NULL, NULL); - silc_pkcs_public_key_free(public_key); -} - - -/**************************** Buddy routines *********************************/ - -/* The buddies are implemented by using the WHOIS and WATCH commands that - can be used to search users by their public key. Since nicknames aren't - unique in SILC we cannot trust the buddy list using their nickname. We - associate public keys to buddies and use those to search and watch - in the network. - - The problem is that Purple does not return PurpleBuddy contexts to the - callbacks but the buddy names. Naturally, this is not going to work - with SILC. But, for now, we have to do what we can... */ - -typedef struct { - SilcClient client; - SilcClientConnection conn; - SilcClientID client_id; - PurpleBuddy *b; - unsigned char *offline_pk; - SilcUInt32 offline_pk_len; - unsigned int offline : 1; - unsigned int pubkey_search : 1; - unsigned int init : 1; -} *SilcPurpleBuddyRes; - -static void -silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id); -static void -silcpurple_add_buddy_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context); - -void silcpurple_get_info(PurpleConnection *gc, const char *who) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientEntry client_entry; - PurpleBuddy *b; - const char *filename, *nick = who; - char tmp[256]; - - if (!who) - return; - if (strlen(who) > 1 && who[0] == '@') - nick = who + 1; - if (strlen(who) > 1 && who[0] == '*') - nick = who + 1; - if (strlen(who) > 2 && who[0] == '*' && who[1] == '@') - nick = who + 2; - - b = purple_find_buddy(gc->account, nick); - if (b) { - /* See if we have this buddy's public key. If we do use that - to search the details. */ - filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); - if (filename) { - /* Call WHOIS. The user info is displayed in the WHOIS - command reply. */ - silc_client_command_call(client, conn, NULL, "WHOIS", - "-details", "-pubkey", filename, NULL); - return; - } - - if (!b->proto_data) { - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), b->name); - purple_notify_error(gc, _("User Information"), - _("Cannot get user information"), tmp); - return; - } - - client_entry = silc_client_get_client_by_id(client, conn, b->proto_data); - if (client_entry) { - /* Call WHOIS. The user info is displayed in the WHOIS - command reply. */ - silc_client_command_call(client, conn, NULL, "WHOIS", - client_entry->nickname, "-details", NULL); - } - } else { - /* Call WHOIS just with nickname. */ - silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL); - } -} - -static void -silcpurple_add_buddy_pk_no(SilcPurpleBuddyRes r) -{ - char tmp[512]; - g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"), - r->b->name); - purple_notify_error(r->client->application, _("Add Buddy"), tmp, - _("You cannot receive buddy notifications until you " - "import his/her public key. You can use the Get Public Key " - "command to get the public key.")); - purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); -} - -static void -silcpurple_add_buddy_save(bool success, void *context) -{ - SilcPurpleBuddyRes r = context; - PurpleBuddy *b = r->b; - SilcClient client = r->client; - SilcClientEntry client_entry; - SilcAttributePayload attr; - SilcAttribute attribute; - SilcVCardStruct vcard; - SilcAttributeObjMime message, extension; -#ifdef SILC_ATTRIBUTE_USER_ICON - SilcAttributeObjMime usericon; -#endif - SilcAttributeObjPk serverpk, usersign, serversign; - gboolean usign_success = TRUE, ssign_success = TRUE; - char filename[512], filename2[512], *fingerprint = NULL, *tmp; - SilcUInt32 len; - int i; - - if (!success) { - /* The user did not trust the public key. */ - silcpurple_add_buddy_pk_no(r); - silc_free(r); - return; - } - - if (r->offline) { - /* User is offline. Associate the imported public key with - this user. */ - fingerprint = silc_hash_fingerprint(NULL, r->offline_pk, - r->offline_pk_len); - for (i = 0; i < strlen(fingerprint); i++) - if (fingerprint[i] == ' ') - fingerprint[i] = '_'; - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", - silcpurple_silcdir(), fingerprint); - purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); - purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); - silc_free(fingerprint); - silc_free(r->offline_pk); - silc_free(r); - return; - } - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(r->client, r->conn, - &r->client_id); - if (!client_entry) { - silc_free(r); - return; - } - - memset(&vcard, 0, sizeof(vcard)); - memset(&message, 0, sizeof(message)); - memset(&extension, 0, sizeof(extension)); -#ifdef SILC_ATTRIBUTE_USER_ICON - memset(&usericon, 0, sizeof(usericon)); -#endif - memset(&serverpk, 0, sizeof(serverpk)); - memset(&usersign, 0, sizeof(usersign)); - memset(&serversign, 0, sizeof(serversign)); - - /* Now that we have the public key and we trust it now we - save the attributes of the buddy and update its status. */ - - if (client_entry->attrs) { - silc_dlist_start(client_entry->attrs); - while ((attr = silc_dlist_get(client_entry->attrs)) - != SILC_LIST_END) { - attribute = silc_attribute_get_attribute(attr); - - switch (attribute) { - case SILC_ATTRIBUTE_USER_INFO: - if (!silc_attribute_get_object(attr, (void *)&vcard, - sizeof(vcard))) - continue; - break; - - case SILC_ATTRIBUTE_STATUS_MESSAGE: - if (!silc_attribute_get_object(attr, (void *)&message, - sizeof(message))) - continue; - break; - - case SILC_ATTRIBUTE_EXTENSION: - if (!silc_attribute_get_object(attr, (void *)&extension, - sizeof(extension))) - continue; - break; - -#ifdef SILC_ATTRIBUTE_USER_ICON - case SILC_ATTRIBUTE_USER_ICON: - if (!silc_attribute_get_object(attr, (void *)&usericon, - sizeof(usericon))) - continue; - break; -#endif - - case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY: - if (serverpk.type) - continue; - if (!silc_attribute_get_object(attr, (void *)&serverpk, - sizeof(serverpk))) - continue; - break; - - case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE: - if (usersign.data) - continue; - if (!silc_attribute_get_object(attr, (void *)&usersign, - sizeof(usersign))) - continue; - break; - - case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE: - if (serversign.data) - continue; - if (!silc_attribute_get_object(attr, (void *)&serversign, - sizeof(serversign))) - continue; - break; - - default: - break; - } - } - } - - /* Verify the attribute signatures */ - - if (usersign.data) { - SilcPKCS pkcs; - unsigned char *verifyd; - SilcUInt32 verify_len; - - silc_pkcs_alloc((unsigned char*)"rsa", &pkcs); - verifyd = silc_attribute_get_verify_data(client_entry->attrs, - FALSE, &verify_len); - if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){ - if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, - usersign.data, - usersign.data_len, - verifyd, verify_len)) - usign_success = FALSE; - } - silc_free(verifyd); - } - - if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) { - SilcPublicKey public_key; - SilcPKCS pkcs; - unsigned char *verifyd; - SilcUInt32 verify_len; - - if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len, - &public_key)) { - silc_pkcs_alloc((unsigned char *)"rsa", &pkcs); - verifyd = silc_attribute_get_verify_data(client_entry->attrs, - TRUE, &verify_len); - if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) { - if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, - serversign.data, - serversign.data_len, - verifyd, verify_len)) - ssign_success = FALSE; - } - silc_pkcs_public_key_free(public_key); - silc_free(verifyd); - } - } - - fingerprint = silc_fingerprint(client_entry->fingerprint, - client_entry->fingerprint_len); - for (i = 0; i < strlen(fingerprint); i++) - if (fingerprint[i] == ' ') - fingerprint[i] = '_'; - - if (usign_success || ssign_success) { - struct passwd *pw; - struct stat st; - - memset(filename2, 0, sizeof(filename2)); - - /* Filename for dir */ - tmp = fingerprint + strlen(fingerprint) - 9; - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s", - silcpurple_silcdir(), tmp); - - pw = getpwuid(getuid()); - if (!pw) - return; - - /* Create dir if it doesn't exist */ - if ((g_stat(filename, &st)) == -1) { - if (errno == ENOENT) { - if (pw->pw_uid == geteuid()) { - int ret = g_mkdir(filename, 0755); - if (ret < 0) - return; - } - } - } - - /* Save VCard */ - g_snprintf(filename2, sizeof(filename2) - 1, - "%s" G_DIR_SEPARATOR_S "vcard", filename); - if (vcard.full_name) { - tmp = (char *)silc_vcard_encode(&vcard, &len); - silc_file_writefile(filename2, tmp, len); - silc_free(tmp); - } - - /* Save status message */ - if (message.mime) { - memset(filename2, 0, sizeof(filename2)); - g_snprintf(filename2, sizeof(filename2) - 1, - "%s" G_DIR_SEPARATOR_S "status_message.mime", - filename); - silc_file_writefile(filename2, (char *)message.mime, - message.mime_len); - } - - /* Save extension data */ - if (extension.mime) { - memset(filename2, 0, sizeof(filename2)); - g_snprintf(filename2, sizeof(filename2) - 1, - "%s" G_DIR_SEPARATOR_S "extension.mime", - filename); - silc_file_writefile(filename2, (char *)extension.mime, - extension.mime_len); - } - -#ifdef SILC_ATTRIBUTE_USER_ICON - /* Save user icon */ - if (usericon.mime) { - SilcMime m = silc_mime_decode(usericon.mime, - usericon.mime_len); - if (m) { - const char *type = silc_mime_get_field(m, "Content-Type"); - if (!strcmp(type, "image/jpeg") || - !strcmp(type, "image/gif") || - !strcmp(type, "image/bmp") || - !strcmp(type, "image/png")) { - const unsigned char *data; - SilcUInt32 data_len; - data = silc_mime_get_data(m, &data_len); - if (data) { - /* TODO: Check if SILC gives us something to use as the checksum instead */ - purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL); - } - } - silc_mime_free(m); - } - } -#endif - } - - /* Save the public key path to buddy properties, as it is used - to identify the buddy in the network (and not the nickname). */ - memset(filename, 0, sizeof(filename)); - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", - silcpurple_silcdir(), fingerprint); - purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); - - /* Update online status */ - purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); - - /* Finally, start watching this user so we receive its status - changes from the server */ - g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); - silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", - filename2, NULL); - - silc_free(fingerprint); - silc_free(r); -} - -static void -silcpurple_add_buddy_ask_import(void *user_data, const char *name) -{ - SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data; - SilcPublicKey public_key; - - /* Load the public key */ - if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) { - silcpurple_add_buddy_ask_pk_cb(r, 0); - purple_notify_error(r->client->application, - _("Add Buddy"), _("Could not load public key"), NULL); - return; - } - - /* Now verify the public key */ - r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len); - silcpurple_verify_public_key(r->client, r->conn, r->b->name, - SILC_SOCKET_TYPE_CLIENT, - r->offline_pk, r->offline_pk_len, - SILC_SKE_PK_TYPE_SILC, - silcpurple_add_buddy_save, r); -} - -static void -silcpurple_add_buddy_ask_pk_cancel(void *user_data, const char *name) -{ - SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data; - - /* The user did not import public key. The buddy is unusable. */ - silcpurple_add_buddy_pk_no(r); - silc_free(r); -} - -static void -silcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id) -{ - if (id != 0) { - /* The user did not import public key. The buddy is unusable. */ - silcpurple_add_buddy_pk_no(r); - silc_free(r); - return; - } - - /* Open file selector to select the public key. */ - purple_request_file(r->client->application, _("Open..."), NULL, FALSE, - G_CALLBACK(silcpurple_add_buddy_ask_import), - G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel), - purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r); - -} - -static void -silcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r) -{ - char tmp[512]; - g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"), - r->b->name); - purple_request_action(r->client->application, _("Add Buddy"), tmp, - _("To add the buddy you must import his/her public key. " - "Press Import to import a public key."), 0, - purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2, - _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb), - _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb)); -} - -static void -silcpurple_add_buddy_getkey_cb(SilcPurpleBuddyRes r, - SilcClientCommandReplyContext cmd) -{ - SilcClientEntry client_entry; - unsigned char *pk; - SilcUInt32 pk_len; - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(r->client, r->conn, - &r->client_id); - if (!client_entry || !client_entry->public_key) { - /* The buddy is offline/nonexistent. We will require user - to associate a public key with the buddy or the buddy - cannot be added. */ - r->offline = TRUE; - silcpurple_add_buddy_ask_pk(r); - return; - } - - /* Now verify the public key */ - pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); - silcpurple_verify_public_key(r->client, r->conn, client_entry->nickname, - SILC_SOCKET_TYPE_CLIENT, - pk, pk_len, SILC_SKE_PK_TYPE_SILC, - silcpurple_add_buddy_save, r); - silc_free(pk); -} - -static void -silcpurple_add_buddy_select_cb(SilcPurpleBuddyRes r, PurpleRequestFields *fields) -{ - PurpleRequestField *f; - GList *list; - SilcClientEntry client_entry; - - f = purple_request_fields_get_field(fields, "list"); - list = purple_request_field_list_get_selected(f); - if (!list) { - /* The user did not select any user. */ - silcpurple_add_buddy_pk_no(r); - silc_free(r); - return; - } - - client_entry = purple_request_field_list_get_data(f, list->data); - silcpurple_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r); -} - -static void -silcpurple_add_buddy_select_cancel(SilcPurpleBuddyRes r, PurpleRequestFields *fields) -{ - /* The user did not select any user. */ - silcpurple_add_buddy_pk_no(r); - silc_free(r); -} - -static void -silcpurple_add_buddy_select(SilcPurpleBuddyRes r, - SilcClientEntry *clients, - SilcUInt32 clients_count) -{ - PurpleRequestFields *fields; - PurpleRequestFieldGroup *g; - PurpleRequestField *f; - char tmp[512], tmp2[128]; - int i; - char *fingerprint; - - fields = purple_request_fields_new(); - g = purple_request_field_group_new(NULL); - f = purple_request_field_list_new("list", NULL); - purple_request_field_group_add_field(g, f); - purple_request_field_list_set_multi_select(f, FALSE); - purple_request_fields_add_group(fields, g); - - for (i = 0; i < clients_count; i++) { - fingerprint = NULL; - if (clients[i]->fingerprint) { - fingerprint = silc_fingerprint(clients[i]->fingerprint, - clients[i]->fingerprint_len); - g_snprintf(tmp2, sizeof(tmp2), "\n%s", fingerprint); - } - g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s", - clients[i]->realname, clients[i]->nickname, - clients[i]->username, clients[i]->hostname ? - clients[i]->hostname : "", - fingerprint ? tmp2 : ""); - purple_request_field_list_add_icon(f, tmp, NULL, clients[i]); - silc_free(fingerprint); - } - - purple_request_fields(r->client->application, _("Add Buddy"), - _("Select correct user"), - r->pubkey_search - ? _("More than one user was found with the same public key. Select " - "the correct user from the list to add to the buddy list.") - : _("More than one user was found with the same name. Select " - "the correct user from the list to add to the buddy list."), - fields, - _("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb), - _("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel), - purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r); -} - -static void -silcpurple_add_buddy_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - SilcPurpleBuddyRes r = context; - PurpleBuddy *b = r->b; - SilcAttributePayload pub; - SilcAttributeObjPk userpk; - unsigned char *pk; - SilcUInt32 pk_len; - const char *filename; - - filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); - - /* If the buddy is offline/nonexistent, we will require user - to associate a public key with the buddy or the buddy - cannot be added. */ - if (!clients_count) { - if (r->init) { - silc_free(r); - return; - } - - r->offline = TRUE; - /* If the user has already associated a public key, try loading it - * before prompting the user to load it again */ - if (filename != NULL) - silcpurple_add_buddy_ask_import(r, filename); - else - silcpurple_add_buddy_ask_pk(r); - return; - } - - /* If more than one client was found with nickname, we need to verify - from user which one is the correct. */ - if (clients_count > 1 && !r->pubkey_search) { - if (r->init) { - silc_free(r); - return; - } - - silcpurple_add_buddy_select(r, clients, clients_count); - return; - } - - /* If we searched using public keys and more than one entry was found - the same person is logged on multiple times. */ - if (clients_count > 1 && r->pubkey_search && b->name) { - if (r->init) { - /* Find the entry that closest matches to the - buddy nickname. */ - int i; - for (i = 0; i < clients_count; i++) { - if (!g_ascii_strncasecmp(b->name, clients[i]->nickname, - strlen(b->name))) { - clients[0] = clients[i]; - break; - } - } - } else { - /* Verify from user which one is correct */ - silcpurple_add_buddy_select(r, clients, clients_count); - return; - } - } - - /* The client was found. Now get its public key and verify - that before adding the buddy. */ - memset(&userpk, 0, sizeof(userpk)); - b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id)); - r->client_id = *clients[0]->id; - - /* Get the public key from attributes, if not present then - resolve it with GETKEY unless we have it cached already. */ - if (clients[0]->attrs && !clients[0]->public_key) { - pub = silcpurple_get_attr(clients[0]->attrs, - SILC_ATTRIBUTE_USER_PUBLIC_KEY); - if (!pub || !silc_attribute_get_object(pub, (void *)&userpk, - sizeof(userpk))) { - /* Get public key with GETKEY */ - silc_client_command_call(client, conn, NULL, - "GETKEY", clients[0]->nickname, NULL); - silc_client_command_pending(conn, SILC_COMMAND_GETKEY, - conn->cmd_ident, - (SilcCommandCb)silcpurple_add_buddy_getkey_cb, - r); - return; - } - if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len, - &clients[0]->public_key)) - return; - silc_free(userpk.data); - } else if (filename && !clients[0]->public_key) { - if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key, - SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(filename, &clients[0]->public_key, - SILC_PKCS_FILE_BIN)) { - /* Get public key with GETKEY */ - silc_client_command_call(client, conn, NULL, - "GETKEY", clients[0]->nickname, NULL); - silc_client_command_pending(conn, SILC_COMMAND_GETKEY, - conn->cmd_ident, - (SilcCommandCb)silcpurple_add_buddy_getkey_cb, - r); - return; - } - } else if (!clients[0]->public_key) { - /* Get public key with GETKEY */ - silc_client_command_call(client, conn, NULL, - "GETKEY", clients[0]->nickname, NULL); - silc_client_command_pending(conn, SILC_COMMAND_GETKEY, - conn->cmd_ident, - (SilcCommandCb)silcpurple_add_buddy_getkey_cb, - r); - return; - } - - /* We have the public key, verify it. */ - pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len); - silcpurple_verify_public_key(client, conn, clients[0]->nickname, - SILC_SOCKET_TYPE_CLIENT, - pk, pk_len, SILC_SKE_PK_TYPE_SILC, - silcpurple_add_buddy_save, r); - silc_free(pk); -} - -static void -silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcPurpleBuddyRes r; - SilcBuffer attrs; - const char *filename, *name = b->name; - - r = silc_calloc(1, sizeof(*r)); - if (!r) - return; - r->client = client; - r->conn = conn; - r->b = b; - r->init = init; - - /* See if we have this buddy's public key. If we do use that - to search the details. */ - filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); - if (filename) { - SilcPublicKey public_key; - SilcAttributeObjPk userpk; - - if (!silc_pkcs_load_public_key(filename, &public_key, - SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(filename, &public_key, - SILC_PKCS_FILE_BIN)) - return; - - /* Get all attributes, and use the public key to search user */ - name = NULL; - attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO, - SILC_ATTRIBUTE_SERVICE, - SILC_ATTRIBUTE_STATUS_MOOD, - SILC_ATTRIBUTE_STATUS_FREETEXT, - SILC_ATTRIBUTE_STATUS_MESSAGE, - SILC_ATTRIBUTE_PREFERRED_LANGUAGE, - SILC_ATTRIBUTE_PREFERRED_CONTACT, - SILC_ATTRIBUTE_TIMEZONE, - SILC_ATTRIBUTE_GEOLOCATION, -#ifdef SILC_ATTRIBUTE_USER_ICON - SILC_ATTRIBUTE_USER_ICON, -#endif - SILC_ATTRIBUTE_DEVICE_INFO, 0); - userpk.type = "silc-rsa"; - userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len); - attrs = silc_attribute_payload_encode(attrs, - SILC_ATTRIBUTE_USER_PUBLIC_KEY, - SILC_ATTRIBUTE_FLAG_VALID, - &userpk, sizeof(userpk)); - silc_free(userpk.data); - silc_pkcs_public_key_free(public_key); - r->pubkey_search = TRUE; - } else { - /* Get all attributes */ - attrs = silc_client_attributes_request(0); - } - - /* Resolve */ - silc_client_get_clients_whois(client, conn, name, NULL, attrs, - silcpurple_add_buddy_resolved, r); - silc_buffer_free(attrs); -} - -void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) -{ - /* 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 (purple_buddy_get_protocol_data(buddy) == NULL) - silcpurple_add_buddy_i(gc, buddy, FALSE); -} - -void silcpurple_send_buddylist(PurpleConnection *gc) -{ - PurpleBuddyList *blist; - PurpleBlistNode *gnode, *cnode, *bnode; - PurpleBuddy *buddy; - PurpleAccount *account; - - account = purple_connection_get_account(gc); - - if ((blist = purple_get_blist()) != NULL) - { - for (gnode = blist->root; gnode != NULL; gnode = gnode->next) - { - if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) - continue; - for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) - { - if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) - continue; - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) - { - if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - buddy = (PurpleBuddy *)bnode; - if (purple_buddy_get_account(buddy) == account) - silcpurple_add_buddy_i(gc, buddy, TRUE); - } - } - } - } -} - -void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, - PurpleGroup *group) -{ - silc_free(buddy->proto_data); -} - -void silcpurple_idle_set(PurpleConnection *gc, int idle) - -{ - SilcPurple sg; - SilcClient client; - SilcClientConnection conn; - SilcAttributeObjService service; - const char *server; - int port; - - sg = gc->proto_data; - if (sg == NULL) - return; - - client = sg->client; - if (client == NULL) - return; - - conn = sg->conn; - if (conn == NULL) - return; - - server = purple_account_get_string(sg->account, "server", - "silc.silcnet.org"); - port = purple_account_get_int(sg->account, "port", 706), - - memset(&service, 0, sizeof(service)); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_SERVICE, NULL); - service.port = port; - g_snprintf(service.address, sizeof(service.address), "%s", server); - service.idle = idle; - silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_SERVICE, - &service, sizeof(service)); -} - -char *silcpurple_status_text(PurpleBuddy *b) -{ - SilcPurple sg = b->account->gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientID *client_id = b->proto_data; - SilcClientEntry client_entry; - SilcAttributePayload attr; - SilcAttributeMood mood = 0; - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(client, conn, client_id); - if (!client_entry) - return NULL; - - /* If user is online, we show the mood status, if available. - If user is offline or away that status is indicated. */ - - if (client_entry->mode & SILC_UMODE_DETACHED) - return g_strdup(_("Detached")); - if (client_entry->mode & SILC_UMODE_GONE) - return g_strdup(_("Away")); - if (client_entry->mode & SILC_UMODE_INDISPOSED) - return g_strdup(_("Indisposed")); - if (client_entry->mode & SILC_UMODE_BUSY) - return g_strdup(_("Busy")); - if (client_entry->mode & SILC_UMODE_PAGE) - return g_strdup(_("Wake Me Up")); - if (client_entry->mode & SILC_UMODE_HYPER) - return g_strdup(_("Hyper Active")); - if (client_entry->mode & SILC_UMODE_ROBOT) - return g_strdup(_("Robot")); - - attr = silcpurple_get_attr(client_entry->attrs, SILC_ATTRIBUTE_STATUS_MOOD); - if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { - /* The mood is a bit mask, so we could show multiple moods, - but let's show only one for now. */ - if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) - return g_strdup(_("Happy")); - if (mood & SILC_ATTRIBUTE_MOOD_SAD) - return g_strdup(_("Sad")); - if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) - return g_strdup(_("Angry")); - if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) - return g_strdup(_("Jealous")); - if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) - return g_strdup(_("Ashamed")); - if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) - return g_strdup(_("Invincible")); - if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) - return g_strdup(_("In Love")); - if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) - return g_strdup(_("Sleepy")); - if (mood & SILC_ATTRIBUTE_MOOD_BORED) - return g_strdup(_("Bored")); - if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) - return g_strdup(_("Excited")); - if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) - return g_strdup(_("Anxious")); - } - - return NULL; -} - -void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) -{ - SilcPurple sg = b->account->gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientID *client_id = b->proto_data; - SilcClientEntry client_entry; - char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; - char tmp[256]; - - /* Get the client entry. */ - client_entry = silc_client_get_client_by_id(client, conn, client_id); - if (!client_entry) - return; - - if (client_entry->nickname) - purple_notify_user_info_add_pair(user_info, _("Nickname"), - client_entry->nickname); - if (client_entry->username && client_entry->hostname) { - g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp); - } - if (client_entry->mode) { - memset(tmp, 0, sizeof(tmp)); - silcpurple_get_umode_string(client_entry->mode, - tmp, sizeof(tmp) - strlen(tmp)); - purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); - } - - silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); - - if (statusstr) { - purple_notify_user_info_add_pair(user_info, _("Message"), statusstr); - g_free(statusstr); - } - - if (full) { - if (moodstr) { - purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); - g_free(moodstr); - } - - if (contactstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); - g_free(contactstr); - } - - if (langstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); - g_free(langstr); - } - - if (devicestr) { - purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); - g_free(devicestr); - } - - if (tzstr) { - purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); - g_free(tzstr); - } - - if (geostr) { - purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); - g_free(geostr); - } - } -} - -static void -silcpurple_buddy_kill(PurpleBlistNode *node, gpointer data) -{ - PurpleBuddy *b; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - - b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); - sg = gc->proto_data; - - /* Call KILL */ - silc_client_command_call(sg->client, sg->conn, NULL, "KILL", - b->name, "Killed by operator", NULL); -} - -typedef struct { - SilcPurple sg; - SilcClientEntry client_entry; -} *SilcPurpleBuddyWb; - -static void -silcpurple_buddy_wb(PurpleBlistNode *node, gpointer data) -{ - SilcPurpleBuddyWb wb = data; - silcpurple_wb_init(wb->sg, wb->client_entry); - silc_free(wb); -} - -GList *silcpurple_buddy_menu(PurpleBuddy *buddy) -{ - PurpleConnection *gc = purple_account_get_connection(buddy->account); - SilcPurple sg = gc->proto_data; - SilcClientConnection conn = sg->conn; - const char *pkfile = NULL; - SilcClientEntry client_entry = NULL; - PurpleMenuAction *act; - GList *m = NULL; - SilcPurpleBuddyWb wb; - - pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key"); - client_entry = silc_client_get_client_by_id(sg->client, - sg->conn, - buddy->proto_data); - - if (client_entry && client_entry->send_key) { - act = purple_menu_action_new(_("Reset IM Key"), - PURPLE_CALLBACK(silcpurple_buddy_resetkey), - NULL, NULL); - m = g_list_append(m, act); - - } else { - act = purple_menu_action_new(_("IM with Key Exchange"), - PURPLE_CALLBACK(silcpurple_buddy_keyagr), - NULL, NULL); - m = g_list_append(m, act); - - act = purple_menu_action_new(_("IM with Password"), - PURPLE_CALLBACK(silcpurple_buddy_privkey_menu), - NULL, NULL); - m = g_list_append(m, act); - } - - if (pkfile) { - act = purple_menu_action_new(_("Show Public Key"), - PURPLE_CALLBACK(silcpurple_buddy_showkey), - NULL, NULL); - m = g_list_append(m, act); - - } else { - act = purple_menu_action_new(_("Get Public Key..."), - PURPLE_CALLBACK(silcpurple_buddy_getkey_menu), - NULL, NULL); - m = g_list_append(m, act); - } - - if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { - act = purple_menu_action_new(_("Kill User"), - PURPLE_CALLBACK(silcpurple_buddy_kill), - NULL, NULL); - m = g_list_append(m, act); - } - - if (client_entry) { - wb = silc_calloc(1, sizeof(*wb)); - wb->sg = sg; - wb->client_entry = client_entry; - act = purple_menu_action_new(_("Draw On Whiteboard"), - PURPLE_CALLBACK(silcpurple_buddy_wb), - (void *)wb, NULL); - m = g_list_append(m, act); - } - return m; -} - -#ifdef SILC_ATTRIBUTE_USER_ICON -void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcMime mime; - char type[32]; - unsigned char *icon; - const char *t; - SilcAttributeObjMime obj; - - /* Remove */ - if (!img) { - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_USER_ICON, NULL); - return; - } - - /* Add */ - mime = silc_mime_alloc(); - if (!mime) - return; - - t = purple_imgstore_get_extension(img); - if (!t || !strcmp(t, "icon")) { - silc_mime_free(mime); - return; - } - if (!strcmp(t, "jpg")) - t = "jpeg"; - g_snprintf(type, sizeof(type), "image/%s", t); - silc_mime_add_field(mime, "Content-Type", type); - silc_mime_add_data(mime, purple_imgstore_get_data(img), purple_imgstore_get_size(img)); - - obj.mime = icon = silc_mime_encode(mime, &obj.mime_len); - if (obj.mime) - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_USER_ICON, &obj, sizeof(obj)); - - silc_free(icon); - silc_mime_free(mime); -} -#endif diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/chat.c --- a/libpurple/protocols/silc10/chat.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1456 +0,0 @@ -/* - - silcpurple_chat.c - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "wb.h" - -/***************************** Channel Routines ******************************/ - -GList *silcpurple_chat_info(PurpleConnection *gc) -{ - GList *ci = NULL; - struct proto_chat_entry *pce; - - pce = g_new0(struct proto_chat_entry, 1); - pce->label = _("_Channel:"); - pce->identifier = "channel"; - pce->required = TRUE; - ci = g_list_append(ci, pce); - - pce = g_new0(struct proto_chat_entry, 1); - pce->label = _("_Passphrase:"); - pce->identifier = "passphrase"; - pce->secret = TRUE; - ci = g_list_append(ci, pce); - - return ci; -} - -GHashTable *silcpurple_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, "channel", g_strdup(chat_name)); - - return defaults; -} - -static void -silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components); - -static void -silcpurple_chat_getinfo_res(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry *channels, - SilcUInt32 channels_count, - void *context) -{ - GHashTable *components = context; - PurpleConnection *gc = client->application; - const char *chname; - char tmp[256]; - - chname = g_hash_table_lookup(components, "channel"); - if (!chname) - return; - - if (!channels) { - g_snprintf(tmp, sizeof(tmp), - _("Channel %s does not exist in the network"), chname); - purple_notify_error(gc, _("Channel Information"), - _("Cannot get channel information"), tmp); - return; - } - - silcpurple_chat_getinfo(gc, components); -} - - -static void -silcpurple_chat_getinfo(PurpleConnection *gc, GHashTable *components) -{ - SilcPurple sg = gc->proto_data; - const char *chname; - char *buf, tmp[256], *tmp2; - GString *s; - SilcChannelEntry channel; - SilcHashTableList htl; - SilcChannelUser chu; - - if (!components) - return; - - chname = g_hash_table_lookup(components, "channel"); - if (!chname) - return; - channel = silc_client_get_channel(sg->client, sg->conn, - (char *)chname); - if (!channel) { - silc_client_get_channel_resolve(sg->client, sg->conn, - (char *)chname, - silcpurple_chat_getinfo_res, - components); - return; - } - - s = g_string_new(""); - tmp2 = g_markup_escape_text(channel->channel_name, -1); - g_string_append_printf(s, _("Channel Name: %s"), tmp2); - g_free(tmp2); - if (channel->user_list && silc_hash_table_count(channel->user_list)) - g_string_append_printf(s, _("
User Count: %d"), - (int)silc_hash_table_count(channel->user_list)); - - silc_hash_table_list(channel->user_list, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) { - tmp2 = g_markup_escape_text(chu->client->nickname, -1); - g_string_append_printf(s, _("
Channel Founder: %s"), - tmp2); - g_free(tmp2); - break; - } - } - silc_hash_table_list_reset(&htl); - - if (channel->channel_key) - g_string_append_printf(s, _("
Channel Cipher: %s"), - silc_cipher_get_name(channel->channel_key)); - if (channel->hmac) - /* Definition of HMAC: http://en.wikipedia.org/wiki/HMAC */ - g_string_append_printf(s, _("
Channel HMAC: %s"), - silc_hmac_get_name(channel->hmac)); - - if (channel->topic) { - tmp2 = g_markup_escape_text(channel->topic, -1); - g_string_append_printf(s, _("
Channel Topic:
%s"), tmp2); - g_free(tmp2); - } - - if (channel->mode) { - g_string_append_printf(s, _("
Channel Modes: ")); - silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp)); - g_string_append(s, tmp); - } - - if (channel->founder_key) { - char *fingerprint, *babbleprint; - unsigned char *pk; - SilcUInt32 pk_len; - pk = silc_pkcs_public_key_encode(channel->founder_key, &pk_len); - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - - g_string_append_printf(s, _("
Founder Key Fingerprint:
%s"), fingerprint); - g_string_append_printf(s, _("
Founder Key Babbleprint:
%s"), babbleprint); - - silc_free(fingerprint); - silc_free(babbleprint); - silc_free(pk); - } - - buf = g_string_free(s, FALSE); - purple_notify_formatted(gc, NULL, _("Channel Information"), NULL, buf, NULL, NULL); - g_free(buf); -} - - -static void -silcpurple_chat_getinfo_menu(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat = (PurpleChat *)node; - silcpurple_chat_getinfo(chat->account->gc, chat->components); -} - - -#if 0 /* XXX For now these are not implemented. We need better - listview dialog from Purple for these. */ -/************************** Channel Invite List ******************************/ - -static void -silcpurple_chat_invitelist(PurpleBlistNode *node, gpointer data); -{ - -} - - -/**************************** Channel Ban List *******************************/ - -static void -silcpurple_chat_banlist(PurpleBlistNode *node, gpointer data); -{ - -} -#endif - - -/************************* Channel Authentication ****************************/ - -typedef struct { - SilcPurple sg; - SilcChannelEntry channel; - PurpleChat *c; - SilcBuffer pubkeys; -} *SilcPurpleChauth; - -static void -silcpurple_chat_chpk_add(void *user_data, const char *name) -{ - SilcPurpleChauth sgc = (SilcPurpleChauth)user_data; - SilcPurple sg = sgc->sg; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcPublicKey public_key; - SilcBuffer chpks, pk, chidp; - unsigned char mode[4]; - SilcUInt32 m; - - /* Load the public key */ - if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) { - silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys); - silc_buffer_free(sgc->pubkeys); - silc_free(sgc); - purple_notify_error(client->application, - _("Add Channel Public Key"), - _("Could not load public key"), NULL); - return; - } - - pk = silc_pkcs_public_key_payload_encode(public_key); - chpks = silc_buffer_alloc_size(2); - SILC_PUT16_MSB(1, chpks->head); - chpks = silc_argument_payload_encode_one(chpks, pk->data, - pk->len, 0x00); - silc_buffer_free(pk); - - m = sgc->channel->mode; - m |= SILC_CHANNEL_MODE_CHANNEL_AUTH; - - /* Send CMODE */ - SILC_PUT32_MSB(m, mode); - chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL); - silc_client_command_send(client, conn, SILC_COMMAND_CMODE, - ++conn->cmd_ident, 3, - 1, chidp->data, chidp->len, - 2, mode, sizeof(mode), - 9, chpks->data, chpks->len); - silc_buffer_free(chpks); - silc_buffer_free(chidp); - silc_buffer_free(sgc->pubkeys); - silc_free(sgc); -} - -static void -silcpurple_chat_chpk_cancel(void *user_data, const char *name) -{ - SilcPurpleChauth sgc = (SilcPurpleChauth)user_data; - silcpurple_chat_chauth_show(sgc->sg, sgc->channel, sgc->pubkeys); - silc_buffer_free(sgc->pubkeys); - silc_free(sgc); -} - -static void -silcpurple_chat_chpk_cb(SilcPurpleChauth sgc, PurpleRequestFields *fields) -{ - SilcPurple sg = sgc->sg; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - PurpleRequestField *f; - GList *list; - SilcPublicKey public_key; - SilcBuffer chpks, pk, chidp; - SilcUInt16 c = 0, ct; - unsigned char mode[4]; - SilcUInt32 m; - - f = purple_request_fields_get_field(fields, "list"); - if (!purple_request_field_list_get_selected(f)) { - /* Add new public key */ - purple_request_file(sg->gc, _("Open Public Key..."), NULL, FALSE, - G_CALLBACK(silcpurple_chat_chpk_add), - G_CALLBACK(silcpurple_chat_chpk_cancel), - purple_connection_get_account(sg->gc), NULL, NULL, sgc); - return; - } - - list = purple_request_field_list_get_items(f); - chpks = silc_buffer_alloc_size(2); - - for (ct = 0; list; list = list->next, ct++) { - public_key = purple_request_field_list_get_data(f, list->data); - if (purple_request_field_list_is_selected(f, list->data)) { - /* Delete this public key */ - pk = silc_pkcs_public_key_payload_encode(public_key); - chpks = silc_argument_payload_encode_one(chpks, pk->data, - pk->len, 0x01); - silc_buffer_free(pk); - c++; - } - silc_pkcs_public_key_free(public_key); - } - if (!c) { - silc_buffer_free(chpks); - return; - } - SILC_PUT16_MSB(c, chpks->head); - - m = sgc->channel->mode; - if (ct == c) - m &= ~SILC_CHANNEL_MODE_CHANNEL_AUTH; - - /* Send CMODE */ - SILC_PUT32_MSB(m, mode); - chidp = silc_id_payload_encode(sgc->channel->id, SILC_ID_CHANNEL); - silc_client_command_send(client, conn, SILC_COMMAND_CMODE, - ++conn->cmd_ident, 3, - 1, chidp->data, chidp->len, - 2, mode, sizeof(mode), - 9, chpks->data, chpks->len); - silc_buffer_free(chpks); - silc_buffer_free(chidp); - silc_buffer_free(sgc->pubkeys); - silc_free(sgc); -} - -static void -silcpurple_chat_chauth_ok(SilcPurpleChauth sgc, PurpleRequestFields *fields) -{ - SilcPurple sg = sgc->sg; - PurpleRequestField *f; - const char *curpass, *val; - int set; - - f = purple_request_fields_get_field(fields, "passphrase"); - val = purple_request_field_string_get_value(f); - curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase"); - - if (!val && curpass) - set = 0; - else if (val && !curpass) - set = 1; - else if (val && curpass && strcmp(val, curpass)) - set = 1; - else - set = -1; - - if (set == 1) { - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - sgc->channel->channel_name, "+a", val, NULL); - purple_blist_node_set_string((PurpleBlistNode *)sgc->c, "passphrase", val); - } else if (set == 0) { - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - sgc->channel->channel_name, "-a", NULL); - purple_blist_node_remove_setting((PurpleBlistNode *)sgc->c, "passphrase"); - } - - silc_buffer_free(sgc->pubkeys); - silc_free(sgc); -} - -void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel, - SilcBuffer channel_pubkeys) -{ - SilcUInt16 argc; - SilcArgumentPayload chpks; - unsigned char *pk; - SilcUInt32 pk_len, type; - char *fingerprint, *babbleprint; - SilcPublicKey pubkey; - SilcPublicKeyIdentifier ident; - char tmp2[1024], t[512]; - PurpleRequestFields *fields; - PurpleRequestFieldGroup *g; - PurpleRequestField *f; - SilcPurpleChauth sgc; - const char *curpass = NULL; - - sgc = silc_calloc(1, sizeof(*sgc)); - if (!sgc) - return; - sgc->sg = sg; - sgc->channel = channel; - - fields = purple_request_fields_new(); - - if (sgc->c) - curpass = purple_blist_node_get_string((PurpleBlistNode *)sgc->c, "passphrase"); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("passphrase", _("Channel Passphrase"), - curpass, FALSE); - purple_request_field_string_set_masked(f, TRUE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_label_new("l1", _("Channel Public Keys List")); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g_snprintf(t, sizeof(t), - _("Channel authentication is used to secure the channel from " - "unauthorized access. The authentication may be based on " - "passphrase and digital signatures. If passphrase is set, it " - "is required to be able to join. If channel public keys are set " - "then only users whose public keys are listed are able to join.")); - - if (!channel_pubkeys) { - f = purple_request_field_list_new("list", NULL); - purple_request_field_group_add_field(g, f); - purple_request_fields(sg->gc, _("Channel Authentication"), - _("Channel Authentication"), t, fields, - _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb), - _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok), - purple_connection_get_account(sg->gc), NULL, NULL, sgc); - return; - } - sgc->pubkeys = silc_buffer_copy(channel_pubkeys); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_list_new("list", NULL); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - SILC_GET16_MSB(argc, channel_pubkeys->data); - chpks = silc_argument_payload_parse(channel_pubkeys->data + 2, - channel_pubkeys->len - 2, argc); - if (!chpks) - return; - - pk = silc_argument_get_first_arg(chpks, &type, &pk_len); - while (pk) { - fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4); - babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4); - silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey); - ident = silc_pkcs_decode_identifier(pubkey->identifier); - - g_snprintf(tmp2, sizeof(tmp2), "%s\n %s\n %s", - ident->realname ? ident->realname : ident->username ? - ident->username : "", fingerprint, babbleprint); - purple_request_field_list_add_icon(f, tmp2, NULL, pubkey); - - silc_free(fingerprint); - silc_free(babbleprint); - silc_pkcs_free_identifier(ident); - pk = silc_argument_get_next_arg(chpks, &type, &pk_len); - } - - purple_request_field_list_set_multi_select(f, FALSE); - purple_request_fields(sg->gc, _("Channel Authentication"), - _("Channel Authentication"), t, fields, - _("Add / Remove"), G_CALLBACK(silcpurple_chat_chpk_cb), - _("OK"), G_CALLBACK(silcpurple_chat_chauth_ok), - purple_connection_get_account(sg->gc), NULL, NULL, sgc); - - silc_argument_payload_free(chpks); -} - -static void -silcpurple_chat_chauth(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "+C", NULL); -} - - -/************************** Channel Private Groups **************************/ - -/* Private groups are "virtual" channels. They are groups inside a channel. - This is implemented by using channel private keys. By knowing a channel - private key user becomes part of that group and is able to talk on that - group. Other users, on the same channel, won't be able to see the - messages of that group. It is possible to have multiple groups inside - a channel - and thus having multiple private keys on the channel. */ - -typedef struct { - SilcPurple sg; - PurpleChat *c; - const char *channel; -} *SilcPurpleCharPrv; - -static void -silcpurple_chat_prv_add(SilcPurpleCharPrv p, PurpleRequestFields *fields) -{ - SilcPurple sg = p->sg; - char tmp[512]; - PurpleRequestField *f; - const char *name, *passphrase, *alias; - GHashTable *comp; - PurpleGroup *g; - PurpleChat *cn; - - f = purple_request_fields_get_field(fields, "name"); - name = purple_request_field_string_get_value(f); - if (!name) { - silc_free(p); - return; - } - f = purple_request_fields_get_field(fields, "passphrase"); - passphrase = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "alias"); - alias = purple_request_field_string_get_value(f); - - /* Add private group to buddy list */ - g_snprintf(tmp, sizeof(tmp), "%s [Private Group]", name); - comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - g_hash_table_replace(comp, g_strdup("channel"), g_strdup(tmp)); - g_hash_table_replace(comp, g_strdup("passphrase"), g_strdup(passphrase)); - - cn = purple_chat_new(sg->account, alias, comp); - g = (PurpleGroup *)p->c->node.parent; - purple_blist_add_chat(cn, g, (PurpleBlistNode *)p->c); - - /* Associate to a real channel */ - purple_blist_node_set_string((PurpleBlistNode *)cn, "parentch", p->channel); - - /* Join the group */ - silcpurple_chat_join(sg->gc, comp); - - silc_free(p); -} - -static void -silcpurple_chat_prv_cancel(SilcPurpleCharPrv p, PurpleRequestFields *fields) -{ - silc_free(p); -} - -static void -silcpurple_chat_prv(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - SilcPurpleCharPrv p; - PurpleRequestFields *fields; - PurpleRequestFieldGroup *g; - PurpleRequestField *f; - char tmp[512]; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - p = silc_calloc(1, sizeof(*p)); - if (!p) - return; - p->sg = sg; - - p->channel = g_hash_table_lookup(chat->components, "channel"); - p->c = purple_blist_find_chat(sg->account, p->channel); - - fields = purple_request_fields_new(); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("name", _("Group Name"), - NULL, FALSE); - purple_request_field_group_add_field(g, f); - - f = purple_request_field_string_new("passphrase", _("Passphrase"), - NULL, FALSE); - purple_request_field_string_set_masked(f, TRUE); - purple_request_field_group_add_field(g, f); - - f = purple_request_field_string_new("alias", _("Alias"), - NULL, FALSE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g_snprintf(tmp, sizeof(tmp), - _("Please enter the %s channel private group name and passphrase."), - p->channel); - purple_request_fields(gc, _("Add Channel Private Group"), NULL, tmp, fields, - _("Add"), G_CALLBACK(silcpurple_chat_prv_add), - _("Cancel"), G_CALLBACK(silcpurple_chat_prv_cancel), - purple_connection_get_account(gc), NULL, NULL, p); -} - - -/****************************** Channel Modes ********************************/ - -static void -silcpurple_chat_permanent_reset(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "-f", NULL); -} - -static void -silcpurple_chat_permanent(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - const char *channel; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - if (!sg->conn) - return; - - /* XXX we should have ability to define which founder - key to use. Now we use the user's own public key - (default key). */ - - /* Call CMODE */ - channel = g_hash_table_lookup(chat->components, "channel"); - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", channel, - "+f", NULL); -} - -typedef struct { - SilcPurple sg; - char *channel; -} *SilcPurpleChatInput; - -static void -silcpurple_chat_ulimit_cb(SilcPurpleChatInput s, const char *limit) -{ - SilcChannelEntry channel; - int ulimit = 0; - - channel = silc_client_get_channel(s->sg->client, s->sg->conn, - (char *)s->channel); - if (!channel) - return; - if (limit) - ulimit = atoi(limit); - - if (!limit || !(*limit) || *limit == '0') { - if (limit && ulimit == channel->user_limit) { - silc_free(s); - return; - } - silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE", - s->channel, "-l", NULL); - - silc_free(s); - return; - } - - if (ulimit == channel->user_limit) { - silc_free(s); - return; - } - - /* Call CMODE */ - silc_client_command_call(s->sg->client, s->sg->conn, NULL, "CMODE", - s->channel, "+l", limit, NULL); - - silc_free(s); -} - -static void -silcpurple_chat_ulimit(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - SilcPurpleChatInput s; - SilcChannelEntry channel; - char *ch; - char tmp[32]; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - if (!sg->conn) - return; - - ch = g_strdup(g_hash_table_lookup(chat->components, "channel")); - channel = silc_client_get_channel(sg->client, sg->conn, (char *)ch); - if (!channel) - return; - - s = silc_calloc(1, sizeof(*s)); - if (!s) - return; - s->channel = ch; - s->sg = sg; - g_snprintf(tmp, sizeof(tmp), "%d", (int)channel->user_limit); - purple_request_input(gc, _("User Limit"), NULL, - _("Set user limit on channel. Set to zero to reset user limit."), - tmp, FALSE, FALSE, NULL, - _("OK"), G_CALLBACK(silcpurple_chat_ulimit_cb), - _("Cancel"), G_CALLBACK(silcpurple_chat_ulimit_cb), - purple_connection_get_account(gc), NULL, NULL, s); -} - -static void -silcpurple_chat_resettopic(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "-t", NULL); -} - -static void -silcpurple_chat_settopic(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "+t", NULL); -} - -static void -silcpurple_chat_resetprivate(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "-p", NULL); -} - -static void -silcpurple_chat_setprivate(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "+p", NULL); -} - -static void -silcpurple_chat_resetsecret(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "-s", NULL); -} - -static void -silcpurple_chat_setsecret(PurpleBlistNode *node, gpointer data) -{ - PurpleChat *chat; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); - - chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); - sg = gc->proto_data; - - silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), - "+s", NULL); -} - -typedef struct { - SilcPurple sg; - SilcChannelEntry channel; -} *SilcPurpleChatWb; - -static void -silcpurple_chat_wb(PurpleBlistNode *node, gpointer data) -{ - SilcPurpleChatWb wb = data; - silcpurple_wb_init_ch(wb->sg, wb->channel); - silc_free(wb); -} - -GList *silcpurple_chat_menu(PurpleChat *chat) -{ - GHashTable *components = chat->components; - PurpleConnection *gc = purple_account_get_connection(chat->account); - SilcPurple sg = gc->proto_data; - SilcClientConnection conn = sg->conn; - const char *chname = NULL; - SilcChannelEntry channel = NULL; - SilcChannelUser chu = NULL; - SilcUInt32 mode = 0; - - GList *m = NULL; - PurpleMenuAction *act; - - if (components) - chname = g_hash_table_lookup(components, "channel"); - if (chname) - channel = silc_client_get_channel(sg->client, sg->conn, - (char *)chname); - if (channel) { - chu = silc_client_on_channel(channel, conn->local_entry); - if (chu) - mode = chu->mode; - } - - if (strstr(chname, "[Private Group]")) - return NULL; - - act = purple_menu_action_new(_("Get Info"), - PURPLE_CALLBACK(silcpurple_chat_getinfo_menu), - NULL, NULL); - m = g_list_append(m, act); - -#if 0 /* XXX For now these are not implemented. We need better - listview dialog from Purple for these. */ - if (mode & SILC_CHANNEL_UMODE_CHANOP) { - act = purple_menu_action_new(_("Invite List"), - PURPLE_CALLBACK(silcpurple_chat_invitelist), - NULL, NULL); - m = g_list_append(m, act); - - act = purple_menu_action_new(_("Ban List"), - PURPLE_CALLBACK(silcpurple_chat_banlist), - NULL, NULL); - m = g_list_append(m, act); - } -#endif - - if (chu) { - act = purple_menu_action_new(_("Add Private Group"), - PURPLE_CALLBACK(silcpurple_chat_prv), - NULL, NULL); - m = g_list_append(m, act); - } - - if (mode & SILC_CHANNEL_UMODE_CHANFO) { - act = purple_menu_action_new(_("Channel Authentication"), - PURPLE_CALLBACK(silcpurple_chat_chauth), - NULL, NULL); - m = g_list_append(m, act); - - if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) { - act = purple_menu_action_new(_("Reset Permanent"), - PURPLE_CALLBACK(silcpurple_chat_permanent_reset), - NULL, NULL); - m = g_list_append(m, act); - } else { - act = purple_menu_action_new(_("Set Permanent"), - PURPLE_CALLBACK(silcpurple_chat_permanent), - NULL, NULL); - m = g_list_append(m, act); - } - } - - if (mode & SILC_CHANNEL_UMODE_CHANOP) { - act = purple_menu_action_new(_("Set User Limit"), - PURPLE_CALLBACK(silcpurple_chat_ulimit), - NULL, NULL); - m = g_list_append(m, act); - - if (channel->mode & SILC_CHANNEL_MODE_TOPIC) { - act = purple_menu_action_new(_("Reset Topic Restriction"), - PURPLE_CALLBACK(silcpurple_chat_resettopic), - NULL, NULL); - m = g_list_append(m, act); - } else { - act = purple_menu_action_new(_("Set Topic Restriction"), - PURPLE_CALLBACK(silcpurple_chat_settopic), - NULL, NULL); - m = g_list_append(m, act); - } - - if (channel->mode & SILC_CHANNEL_MODE_PRIVATE) { - act = purple_menu_action_new(_("Reset Private Channel"), - PURPLE_CALLBACK(silcpurple_chat_resetprivate), - NULL, NULL); - m = g_list_append(m, act); - } else { - act = purple_menu_action_new(_("Set Private Channel"), - PURPLE_CALLBACK(silcpurple_chat_setprivate), - NULL, NULL); - m = g_list_append(m, act); - } - - if (channel->mode & SILC_CHANNEL_MODE_SECRET) { - act = purple_menu_action_new(_("Reset Secret Channel"), - PURPLE_CALLBACK(silcpurple_chat_resetsecret), - NULL, NULL); - m = g_list_append(m, act); - } else { - act = purple_menu_action_new(_("Set Secret Channel"), - PURPLE_CALLBACK(silcpurple_chat_setsecret), - NULL, NULL); - m = g_list_append(m, act); - } - } - - if (channel) { - SilcPurpleChatWb wb; - wb = silc_calloc(1, sizeof(*wb)); - wb->sg = sg; - wb->channel = channel; - act = purple_menu_action_new(_("Draw On Whiteboard"), - PURPLE_CALLBACK(silcpurple_chat_wb), - (void *)wb, NULL); - m = g_list_append(m, act); - } - - return m; -} - - -/******************************* Joining Etc. ********************************/ - -void silcpurple_chat_join_done(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - SilcChannelEntry channel = context; - PurpleConversation *convo; - SilcUInt32 retry = SILC_PTR_TO_32(channel->context); - SilcHashTableList htl; - SilcChannelUser chu; - GList *users = NULL, *flags = NULL; - char tmp[256]; - - if (!clients && retry < 1) { - /* Resolving users failed, try again. */ - channel->context = SILC_32_TO_PTR(retry + 1); - silc_client_get_clients_by_channel(client, conn, channel, - silcpurple_chat_join_done, channel); - return; - } - - /* Add channel to Purple */ - channel->context = SILC_32_TO_PTR(++sg->channel_ids); - serv_got_joined_chat(gc, sg->channel_ids, channel->channel_name); - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - return; - - /* Add all users to channel */ - silc_hash_table_list(channel->user_list, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE; - if (!chu->client->nickname) - continue; - chu->context = SILC_32_TO_PTR(sg->channel_ids); - - if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) - f |= PURPLE_CBFLAGS_FOUNDER; - if (chu->mode & SILC_CHANNEL_UMODE_CHANOP) - f |= PURPLE_CBFLAGS_OP; - users = g_list_append(users, g_strdup(chu->client->nickname)); - flags = g_list_append(flags, GINT_TO_POINTER(f)); - - if (chu->mode & SILC_CHANNEL_UMODE_CHANFO) { - if (chu->client == conn->local_entry) - g_snprintf(tmp, sizeof(tmp), - _("You are channel founder on %s"), - channel->channel_name); - else - g_snprintf(tmp, sizeof(tmp), - _("Channel founder on %s is %s"), - channel->channel_name, chu->client->nickname); - - purple_conversation_write(convo, NULL, tmp, - PURPLE_MESSAGE_SYSTEM, time(NULL)); - - } - } - silc_hash_table_list_reset(&htl); - - purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE); - g_list_free(users); - g_list_free(flags); - - /* Set topic */ - if (channel->topic) - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic); - - /* Set nick */ - purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), conn->local_entry->nickname); -} - -char *silcpurple_get_chat_name(GHashTable *data) -{ - return g_strdup(g_hash_table_lookup(data, "channel")); -} - -void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - const char *channel, *passphrase, *parentch; - - if (!conn) - return; - - channel = g_hash_table_lookup(data, "channel"); - passphrase = g_hash_table_lookup(data, "passphrase"); - - /* Check if we are joining a private group. Handle it - purely locally as it's not a real channel */ - if (strstr(channel, "[Private Group]")) { - SilcChannelEntry channel_entry; - SilcChannelPrivateKey key; - PurpleChat *c; - SilcPurplePrvgrp grp; - - c = purple_blist_find_chat(sg->account, channel); - parentch = purple_blist_node_get_string((PurpleBlistNode *)c, "parentch"); - if (!parentch) - return; - - channel_entry = silc_client_get_channel(sg->client, sg->conn, - (char *)parentch); - if (!channel_entry || - !silc_client_on_channel(channel_entry, sg->conn->local_entry)) { - char tmp[512]; - g_snprintf(tmp, sizeof(tmp), - _("You have to join the %s channel before you are " - "able to join the private group"), parentch); - purple_notify_error(gc, _("Join Private Group"), - _("Cannot join private group"), tmp); - return; - } - - /* Add channel private key */ - if (!silc_client_add_channel_private_key(client, conn, - channel_entry, channel, - NULL, NULL, - (unsigned char *)passphrase, - strlen(passphrase), &key)) - return; - - /* Join the group */ - grp = silc_calloc(1, sizeof(*grp)); - if (!grp) - return; - grp->id = ++sg->channel_ids + SILCPURPLE_PRVGRP; - grp->chid = SILC_PTR_TO_32(channel_entry->context); - grp->parentch = parentch; - grp->channel = channel; - grp->key = key; - sg->grps = g_list_append(sg->grps, grp); - serv_got_joined_chat(gc, grp->id, channel); - return; - } - - /* XXX We should have other properties here as well: - 1. whether to try to authenticate to the channel - 1a. with default key, - 1b. with specific key. - 2. whether to try to authenticate to become founder. - 2a. with default key, - 2b. with specific key. - - Since now such variety is not possible in the join dialog - we always use -founder and -auth options, which try to - do both 1 and 2 with default keys. */ - - /* Call JOIN */ - if ((passphrase != NULL) && (*passphrase != '\0')) - silc_client_command_call(client, conn, NULL, "JOIN", - channel, passphrase, "-auth", "-founder", NULL); - else - silc_client_command_call(client, conn, NULL, "JOIN", - channel, "-auth", "-founder", NULL); -} - -void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg, - const char *name) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcHashTableList htl; - SilcChannelUser chu; - gboolean found = FALSE; - - if (!conn) - return; - - /* See if we are inviting on a private group. Invite - to the actual channel */ - if (id > SILCPURPLE_PRVGRP) { - GList *l; - SilcPurplePrvgrp prv; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->id == id) - break; - if (!l) - return; - prv = l->data; - id = prv->chid; - } - - /* Find channel by id */ - silc_hash_table_list(conn->local_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - if (SILC_PTR_TO_32(chu->channel->context) == id ) { - found = TRUE; - break; - } - } - silc_hash_table_list_reset(&htl); - if (!found) - return; - - /* Call INVITE */ - silc_client_command_call(client, conn, NULL, "INVITE", - chu->channel->channel_name, - name, NULL); -} - -void silcpurple_chat_leave(PurpleConnection *gc, int id) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcHashTableList htl; - SilcChannelUser chu; - gboolean found = FALSE; - GList *l; - SilcPurplePrvgrp prv; - - if (!conn) - return; - - /* See if we are leaving a private group */ - if (id > SILCPURPLE_PRVGRP) { - SilcChannelEntry channel; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->id == id) - break; - if (!l) - return; - prv = l->data; - channel = silc_client_get_channel(sg->client, sg->conn, - (char *)prv->parentch); - if (!channel) - return; - silc_client_del_channel_private_key(client, conn, - channel, prv->key); - silc_free(prv); - sg->grps = g_list_remove(sg->grps, prv); - serv_got_chat_left(gc, id); - return; - } - - /* Find channel by id */ - silc_hash_table_list(conn->local_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - if (SILC_PTR_TO_32(chu->channel->context) == id ) { - found = TRUE; - break; - } - } - silc_hash_table_list_reset(&htl); - if (!found) - return; - - /* Call LEAVE */ - silc_client_command_call(client, conn, NULL, "LEAVE", - chu->channel->channel_name, NULL); - - serv_got_chat_left(gc, id); - - /* Leave from private groups on this channel as well */ - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->chid == id) { - prv = l->data; - silc_client_del_channel_private_key(client, conn, - chu->channel, - prv->key); - serv_got_chat_left(gc, prv->id); - silc_free(prv); - sg->grps = g_list_remove(sg->grps, prv); - if (!sg->grps) - break; - } -} - -int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags msgflags) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcHashTableList htl; - SilcChannelUser chu; - SilcChannelEntry channel = NULL; - SilcChannelPrivateKey key = NULL; - SilcUInt32 flags; - int ret; - char *msg2, *tmp; - gboolean found = FALSE; - gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE); - - if (!msg || !conn) - return 0; - - flags = SILC_MESSAGE_FLAG_UTF8; - - tmp = msg2 = purple_unescape_html(msg); - - if (!g_ascii_strncasecmp(msg2, "/me ", 4)) - { - msg2 += 4; - if (!*msg2) { - g_free(tmp); - return 0; - } - flags |= SILC_MESSAGE_FLAG_ACTION; - } else if (strlen(msg) > 1 && msg[0] == '/') { - if (!silc_client_command_call(client, conn, msg + 1)) - purple_notify_error(gc, _("Call Command"), _("Cannot call command"), - _("Unknown command")); - g_free(tmp); - return 0; - } - - - if (sign) - flags |= SILC_MESSAGE_FLAG_SIGNED; - - /* Get the channel private key if we are sending on - private group */ - if (id > SILCPURPLE_PRVGRP) { - GList *l; - SilcPurplePrvgrp prv; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->id == id) - break; - if (!l) { - g_free(tmp); - return 0; - } - prv = l->data; - channel = silc_client_get_channel(sg->client, sg->conn, - (char *)prv->parentch); - if (!channel) { - g_free(tmp); - return 0; - } - key = prv->key; - } - - if (!channel) { - /* Find channel by id */ - silc_hash_table_list(conn->local_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - if (SILC_PTR_TO_32(chu->channel->context) == id ) { - found = TRUE; - break; - } - } - silc_hash_table_list_reset(&htl); - if (!found) { - g_free(tmp); - return 0; - } - channel = chu->channel; - } - - /* Send channel message */ - ret = silc_client_send_channel_message(client, conn, channel, key, - flags, (unsigned char *)msg2, - strlen(msg2), TRUE); - if (ret) { - serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), msgflags, msg, - time(NULL)); - } - g_free(tmp); - - return ret; -} - -void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcHashTableList htl; - SilcChannelUser chu; - gboolean found = FALSE; - - if (!conn) - return; - - /* See if setting topic on private group. Set it - on the actual channel */ - if (id > SILCPURPLE_PRVGRP) { - GList *l; - SilcPurplePrvgrp prv; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->id == id) - break; - if (!l) - return; - prv = l->data; - id = prv->chid; - } - - /* Find channel by id */ - silc_hash_table_list(conn->local_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - if (SILC_PTR_TO_32(chu->channel->context) == id ) { - found = TRUE; - break; - } - } - silc_hash_table_list_reset(&htl); - if (!found) - return; - - /* Call TOPIC */ - silc_client_command_call(client, conn, NULL, "TOPIC", - chu->channel->channel_name, topic, NULL); -} - -PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - GList *fields = NULL; - PurpleRoomlistField *f; - - if (!conn) - return NULL; - - if (sg->roomlist) - purple_roomlist_unref(sg->roomlist); - - sg->roomlist_cancelled = FALSE; - - sg->roomlist = purple_roomlist_new(purple_connection_get_account(gc)); - f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE); - fields = g_list_append(fields, f); - f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, - _("Users"), "users", FALSE); - fields = g_list_append(fields, f); - f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, - _("Topic"), "topic", FALSE); - fields = g_list_append(fields, f); - purple_roomlist_set_fields(sg->roomlist, fields); - - /* Call LIST */ - silc_client_command_call(client, conn, "LIST"); - - purple_roomlist_set_in_progress(sg->roomlist, TRUE); - - return sg->roomlist; -} - -void silcpurple_roomlist_cancel(PurpleRoomlist *list) -{ - PurpleConnection *gc = purple_account_get_connection(list->account); - SilcPurple sg; - - if (!gc) - return; - sg = gc->proto_data; - - purple_roomlist_set_in_progress(list, FALSE); - if (sg->roomlist == list) { - purple_roomlist_unref(sg->roomlist); - sg->roomlist = NULL; - sg->roomlist_cancelled = TRUE; - } -} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/ft.c --- a/libpurple/protocols/silc10/ft.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/* - - silcpurple_ft.c - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" - -/****************************** File Transfer ********************************/ - -/* This implements the secure file transfer protocol (SFTP) using the SILC - SFTP library implementation. The API we use from the SILC Toolkit is the - SILC Client file transfer API, as it provides a simple file transfer we - need in this case. We could use the SILC SFTP API directly, but it would - be an overkill since we'd effectively re-implement the file transfer what - the SILC Client's file transfer API already provides. - - From Purple we do NOT use the FT API to do the transfer as it is very limiting. - In fact it does not suite to file transfers like SFTP at all. For example, - it assumes that read operations are synchronous what they are not in SFTP. - It also assumes that the file transfer socket is to be handled by the Purple - eventloop, and this naturally is something we don't want to do in case of - SILC Toolkit. The FT API suites well to purely stream based file transfers - like HTTP GET and similar. - - For this reason, we directly access the Purple GKT FT API and hack the FT - API to merely provide the user interface experience and all the magic - is done in the SILC Toolkit. Ie. we update the statistics information in - the FT API for user interface, and that's it. A bit dirty but until the - FT API gets better this is the way to go. Good thing that FT API allowed - us to do this. */ - -typedef struct { - SilcPurple sg; - SilcClientEntry client_entry; - SilcUInt32 session_id; - char *hostname; - SilcUInt16 port; - PurpleXfer *xfer; - - SilcClientFileName completion; - void *completion_context; -} *SilcPurpleXfer; - -static void -silcpurple_ftp_monitor(SilcClient client, - SilcClientConnection conn, - SilcClientMonitorStatus status, - SilcClientFileError error, - SilcUInt64 offset, - SilcUInt64 filesize, - SilcClientEntry client_entry, - SilcUInt32 session_id, - const char *filepath, - void *context) -{ - SilcPurpleXfer xfer = context; - PurpleConnection *gc = xfer->sg->gc; - char tmp[256]; - - if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) { - purple_xfer_unref(xfer->xfer); - silc_free(xfer); - return; - } - - if (status == SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT) - return; - - if (status == SILC_CLIENT_FILE_MONITOR_ERROR) { - if (error == SILC_CLIENT_FILE_NO_SUCH_FILE) { - g_snprintf(tmp, sizeof(tmp), "No such file %s", - filepath ? filepath : "[N/A]"); - purple_notify_error(gc, _("Secure File Transfer"), - _("Error during file transfer"), tmp); - } else if (error == SILC_CLIENT_FILE_PERMISSION_DENIED) { - purple_notify_error(gc, _("Secure File Transfer"), - _("Error during file transfer"), - _("Permission denied")); - } else if (error == SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED) { - purple_notify_error(gc, _("Secure File Transfer"), - _("Error during file transfer"), - _("Key agreement failed")); - } else if (error == SILC_CLIENT_FILE_UNKNOWN_SESSION) { - purple_notify_error(gc, _("Secure File Transfer"), - _("Error during file transfer"), - _("File transfer session does not exist")); - } else { - purple_notify_error(gc, _("Secure File Transfer"), - _("Error during file transfer"), NULL); - } - silc_client_file_close(client, conn, session_id); - purple_xfer_unref(xfer->xfer); - silc_free(xfer); - return; - } - - /* Update file transfer UI */ - if (!offset && filesize) - purple_xfer_set_size(xfer->xfer, filesize); - if (offset && filesize) { - xfer->xfer->bytes_sent = offset; - xfer->xfer->bytes_remaining = filesize - offset; - } - purple_xfer_update_progress(xfer->xfer); - - if (status == SILC_CLIENT_FILE_MONITOR_SEND || - status == SILC_CLIENT_FILE_MONITOR_RECEIVE) { - if (offset == filesize) { - /* Download finished */ - purple_xfer_set_completed(xfer->xfer, TRUE); - silc_client_file_close(client, conn, session_id); - } - } -} - -static void -silcpurple_ftp_cancel(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - xfer->xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL; - purple_xfer_update_progress(xfer->xfer); - silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); -} - -static void -silcpurple_ftp_ask_name_cancel(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - - /* Cancel the transmission */ - xfer->completion(NULL, xfer->completion_context); - silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); -} - -static void -silcpurple_ftp_ask_name_ok(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - const char *name; - - name = purple_xfer_get_local_filename(x); - g_unlink(name); - xfer->completion(name, xfer->completion_context); -} - -static void -silcpurple_ftp_ask_name(SilcClient client, - SilcClientConnection conn, - SilcUInt32 session_id, - const char *remote_filename, - SilcClientFileName completion, - void *completion_context, - void *context) -{ - SilcPurpleXfer xfer = context; - - xfer->completion = completion; - xfer->completion_context = completion_context; - - purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_ask_name_ok); - purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_ask_name_cancel); - - /* Request to save the file */ - purple_xfer_set_filename(xfer->xfer, remote_filename); - purple_xfer_request(xfer->xfer); -} - -static void -silcpurple_ftp_request_result(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - SilcClientFileError status; - PurpleConnection *gc = xfer->sg->gc; - - if (purple_xfer_get_status(x) != PURPLE_XFER_STATUS_ACCEPTED) - return; - - /* Start the file transfer */ - status = silc_client_file_receive(xfer->sg->client, xfer->sg->conn, - silcpurple_ftp_monitor, xfer, - NULL, xfer->session_id, - silcpurple_ftp_ask_name, xfer); - switch (status) { - case SILC_CLIENT_FILE_OK: - return; - break; - - case SILC_CLIENT_FILE_UNKNOWN_SESSION: - purple_notify_error(gc, _("Secure File Transfer"), - _("No file transfer session active"), NULL); - break; - - case SILC_CLIENT_FILE_ALREADY_STARTED: - purple_notify_error(gc, _("Secure File Transfer"), - _("File transfer already started"), NULL); - break; - - case SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED: - purple_notify_error(gc, _("Secure File Transfer"), - _("Could not perform key agreement for file transfer"), - NULL); - break; - - default: - purple_notify_error(gc, _("Secure File Transfer"), - _("Could not start the file transfer"), NULL); - break; - } - - /* Error */ - purple_xfer_unref(xfer->xfer); - g_free(xfer->hostname); - silc_free(xfer); -} - -static void -silcpurple_ftp_request_denied(PurpleXfer *x) -{ - -} - -void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, SilcUInt32 session_id, - const char *hostname, SilcUInt16 port) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - SilcPurpleXfer xfer; - - xfer = silc_calloc(1, sizeof(*xfer)); - if (!xfer) { - silc_client_file_close(sg->client, sg->conn, session_id); - return; - } - - xfer->sg = sg; - xfer->client_entry = client_entry; - xfer->session_id = session_id; - xfer->hostname = g_strdup(hostname); - xfer->port = port; - xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_RECEIVE, - xfer->client_entry->nickname); - if (!xfer->xfer) { - silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); - g_free(xfer->hostname); - silc_free(xfer); - return; - } - purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_request_result); - purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied); - purple_xfer_set_cancel_recv_fnc(xfer->xfer, silcpurple_ftp_cancel); - xfer->xfer->remote_ip = g_strdup(hostname); - xfer->xfer->remote_port = port; - xfer->xfer->data = xfer; - - /* File transfer request */ - purple_xfer_request(xfer->xfer); -} - -static void -silcpurple_ftp_send_cancel(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); - purple_xfer_unref(xfer->xfer); - g_free(xfer->hostname); - silc_free(xfer); -} - -static void -silcpurple_ftp_send(PurpleXfer *x) -{ - SilcPurpleXfer xfer = x->data; - const char *name; - char *local_ip = NULL, *remote_ip = NULL; - gboolean local = TRUE; - - name = purple_xfer_get_local_filename(x); - - /* Do the same magic what we do with key agreement (see silcpurple_buddy.c) - to see if we are behind NAT. */ - if (silc_net_check_local_by_sock(xfer->sg->conn->sock->sock, - NULL, &local_ip)) { - /* Check if the IP is private */ - if (silcpurple_ip_is_private(local_ip)) { - local = FALSE; - /* Local IP is private, resolve the remote server IP to see whether - we are talking to Internet or just on LAN. */ - if (silc_net_check_host_by_sock(xfer->sg->conn->sock->sock, NULL, - &remote_ip)) - if (silcpurple_ip_is_private(remote_ip)) - /* We assume we are in LAN. Let's provide the connection point. */ - local = TRUE; - } - } - - if (local && !local_ip) - local_ip = silc_net_localip(); - - /* Send the file */ - silc_client_file_send(xfer->sg->client, xfer->sg->conn, - silcpurple_ftp_monitor, xfer, - local_ip, 0, !local, xfer->client_entry, - name, &xfer->session_id); - - silc_free(local_ip); - silc_free(remote_ip); -} - -static void -silcpurple_ftp_send_file_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - PurpleConnection *gc = client->application; - char tmp[256]; - - if (!clients) { - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), - (const char *)context); - purple_notify_error(gc, _("Secure File Transfer"), - _("Cannot send file"), tmp); - silc_free(context); - return; - } - - silcpurple_ftp_send_file(client->application, (const char *)context, NULL); - silc_free(context); -} - -PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientEntry *clients; - SilcUInt32 clients_count; - SilcPurpleXfer xfer; - char *nickname; - - g_return_val_if_fail(name != NULL, NULL); - - if (!silc_parse_userfqdn(name, &nickname, NULL)) - return NULL; - - /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, name, - &clients_count); - if (!clients) { - silc_client_get_clients(client, conn, nickname, NULL, - silcpurple_ftp_send_file_resolved, - strdup(name)); - silc_free(nickname); - return NULL; - } - - xfer = silc_calloc(1, sizeof(*xfer)); - - g_return_val_if_fail(xfer != NULL, NULL); - - xfer->sg = sg; - xfer->client_entry = clients[0]; - xfer->xfer = purple_xfer_new(xfer->sg->account, PURPLE_XFER_SEND, - xfer->client_entry->nickname); - if (!xfer->xfer) { - silc_client_file_close(xfer->sg->client, xfer->sg->conn, xfer->session_id); - g_free(xfer->hostname); - silc_free(xfer); - return NULL; - } - purple_xfer_set_init_fnc(xfer->xfer, silcpurple_ftp_send); - purple_xfer_set_request_denied_fnc(xfer->xfer, silcpurple_ftp_request_denied); - purple_xfer_set_cancel_send_fnc(xfer->xfer, silcpurple_ftp_send_cancel); - xfer->xfer->data = xfer; - - silc_free(clients); - silc_free(nickname); - - return xfer->xfer; -} - -void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file) -{ - PurpleXfer *xfer = silcpurple_ftp_new_xfer(gc, name); - - g_return_if_fail(xfer != NULL); - - /* Choose file to send */ - if (file) - purple_xfer_request_accepted(xfer, file); - else - purple_xfer_request(xfer); -} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/ops.c --- a/libpurple/protocols/silc10/ops.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2063 +0,0 @@ -/* - - silcpurple_ops.c - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "imgstore.h" -#include "wb.h" - -static void -silc_channel_message(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcChannelEntry channel, - SilcMessagePayload payload, SilcChannelPrivateKey key, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len); -static void -silc_private_message(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcMessagePayload payload, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len); - -/* Message sent to the application by library. `conn' associates the - message to a specific connection. `conn', however, may be NULL. - The `type' indicates the type of the message sent by the library. - The application can for example filter the message according the - type. */ - -static void -silc_say(SilcClient client, SilcClientConnection conn, - SilcClientMessageType type, char *msg, ...) -{ - /* Nothing */ -} - -#ifdef HAVE_SILCMIME_H -/* Processes incoming MIME message. Can be private message or channel - message. */ - -static void -silcpurple_mime_message(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcChannelEntry channel, - SilcMessagePayload payload, SilcChannelPrivateKey key, - SilcMessageFlags flags, SilcMime mime, - gboolean recursive) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - const char *type; - const unsigned char *data; - SilcUInt32 data_len; - PurpleMessageFlags cflags = 0; - PurpleConversation *convo = NULL; - - if (!mime) - return; - - /* Check for fragmented MIME message */ - if (silc_mime_is_partial(mime)) { - if (!sg->mimeass) - sg->mimeass = silc_mime_assembler_alloc(); - - /* Defragment */ - mime = silc_mime_assemble(sg->mimeass, mime); - if (!mime) - /* More fragments to come */ - return; - - /* Process the complete message */ - silcpurple_mime_message(client, conn, sender, channel, - payload, key, flags, mime, FALSE); - return; - } - - /* Check for multipart message */ - if (silc_mime_is_multipart(mime)) { - SilcMime p; - const char *mtype; - SilcDList parts = silc_mime_get_multiparts(mime, &mtype); - - /* Only "mixed" type supported */ - if (strcmp(mtype, "mixed")) - goto out; - - silc_dlist_start(parts); - while ((p = silc_dlist_get(parts)) != SILC_LIST_END) { - /* Recursively process parts */ - silcpurple_mime_message(client, conn, sender, channel, - payload, key, flags, p, TRUE); - } - goto out; - } - - /* Get content type and MIME data */ - type = silc_mime_get_field(mime, "Content-Type"); - if (!type) - goto out; - data = silc_mime_get_data(mime, &data_len); - if (!data) - goto out; - - /* Process according to content type */ - - /* Plain text */ - if (strstr(type, "text/plain")) { - /* Default is UTF-8, don't check for other charsets */ - if (!strstr(type, "utf-8")) - goto out; - - if (channel) - silc_channel_message(client, conn, sender, channel, - payload, key, - SILC_MESSAGE_FLAG_UTF8, data, - data_len); - else - silc_private_message(client, conn, sender, payload, - SILC_MESSAGE_FLAG_UTF8, data, - data_len); - goto out; - } - - /* Image */ - if (strstr(type, "image/png") || - strstr(type, "image/jpeg") || - strstr(type, "image/gif") || - strstr(type, "image/tiff")) { - char tmp[32]; - int imgid; - - /* Get channel convo (if message is for channel) */ - if (key && channel) { - GList *l; - SilcPurplePrvgrp prv; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->key == key) { - prv = l->data; - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - prv->channel, sg->account); - break; - } - } - if (channel && !convo) - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (channel && !convo) - goto out; - - imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, ""); - if (imgid) { - cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV; - g_snprintf(tmp, sizeof(tmp), "", imgid); - - if (channel) - serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), - sender->nickname ? - sender->nickname : - "", cflags, - tmp, time(NULL)); - else - serv_got_im(gc, sender->nickname ? - sender->nickname : "", - tmp, cflags, time(NULL)); - - purple_imgstore_unref_by_id(imgid); - cflags = 0; - } - goto out; - } - - /* Whiteboard message */ - if (strstr(type, "application/x-wb") && - !purple_account_get_bool(sg->account, "block-wb", FALSE)) { - if (channel) - silcpurple_wb_receive_ch(client, conn, sender, channel, - payload, flags, data, data_len); - else - silcpurple_wb_receive(client, conn, sender, payload, - flags, data, data_len); - goto out; - } - - out: - if (!recursive) - silc_mime_free(mime); -} -#endif /* HAVE_SILCMIME_H */ - -/* Message for a channel. The `sender' is the sender of the message - The `channel' is the channel. The `message' is the message. Note - that `message' maybe NULL. The `flags' indicates message flags - and it is used to determine how the message can be interpreted - (like it may tell the message is multimedia message). */ - -static void -silc_channel_message(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcChannelEntry channel, - SilcMessagePayload payload, SilcChannelPrivateKey key, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - PurpleConversation *convo = NULL; - char *msg, *tmp; - - if (!message) - return; - - if (key) { - GList *l; - SilcPurplePrvgrp prv; - - for (l = sg->grps; l; l = l->next) - if (((SilcPurplePrvgrp)l->data)->key == key) { - prv = l->data; - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - prv->channel, sg->account); - break; - } - } - if (!convo) - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - return; - - if (flags & SILC_MESSAGE_FLAG_SIGNED && - purple_account_get_bool(sg->account, "sign-verify", FALSE)) { - /* XXX */ - } - - if (flags & SILC_MESSAGE_FLAG_DATA) { - /* Process MIME message */ -#ifdef HAVE_SILCMIME_H - SilcMime mime; - mime = silc_mime_decode(message, message_len); - silcpurple_mime_message(client, conn, sender, channel, payload, - key, flags, mime, FALSE); -#else - char type[128], enc[128]; - unsigned char *data; - SilcUInt32 data_len; - - memset(type, 0, sizeof(type)); - memset(enc, 0, sizeof(enc)); - - if (!silc_mime_parse(message, message_len, NULL, 0, - type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, - &data_len)) - return; - - if (!strcmp(type, "application/x-wb") && - !strcmp(enc, "binary") && - !purple_account_get_bool(sg->account, "block-wb", FALSE)) - silcpurple_wb_receive_ch(client, conn, sender, channel, - payload, flags, data, data_len); -#endif - return; - } - - if (flags & SILC_MESSAGE_FLAG_ACTION) { - msg = g_strdup_printf("/me %s", - (const char *)message); - if (!msg) - return; - - tmp = g_markup_escape_text(msg, -1); - /* Send to Purple */ - serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), - sender->nickname ? - sender->nickname : "", 0, - tmp, time(NULL)); - g_free(tmp); - g_free(msg); - return; - } - - if (flags & SILC_MESSAGE_FLAG_NOTICE) { - msg = g_strdup_printf("(notice) %s %s", - sender->nickname ? - sender->nickname : "", - (const char *)message); - if (!msg) - return; - - /* Send to Purple */ - purple_conversation_write(convo, NULL, (const char *)msg, - PURPLE_MESSAGE_SYSTEM, time(NULL)); - g_free(msg); - return; - } - - if (flags & SILC_MESSAGE_FLAG_UTF8) { - tmp = g_markup_escape_text((const char *)message, -1); - /* Send to Purple */ - serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), - sender->nickname ? - sender->nickname : "", 0, - tmp, time(NULL)); - g_free(tmp); - } -} - - -/* Private message to the client. The `sender' is the sender of the - message. The message is `message'and maybe NULL. The `flags' - indicates message flags and it is used to determine how the message - can be interpreted (like it may tell the message is multimedia - message). */ - -static void -silc_private_message(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcMessagePayload payload, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - PurpleConversation *convo = NULL; - char *msg, *tmp; - - if (!message) - return; - - if (sender->nickname) - /* XXX - Should this be PURPLE_CONV_TYPE_IM? */ - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, - sender->nickname, sg->account); - - if (flags & SILC_MESSAGE_FLAG_SIGNED && - purple_account_get_bool(sg->account, "sign-verify", FALSE)) { - /* XXX */ - } - - if (flags & SILC_MESSAGE_FLAG_DATA) { -#ifdef HAVE_SILCMIME_H - /* Process MIME message */ - SilcMime mime; - mime = silc_mime_decode(message, message_len); - silcpurple_mime_message(client, conn, sender, NULL, payload, - NULL, flags, mime, FALSE); -#else - char type[128], enc[128]; - unsigned char *data; - SilcUInt32 data_len; - - memset(type, 0, sizeof(type)); - memset(enc, 0, sizeof(enc)); - - if (!silc_mime_parse(message, message_len, NULL, 0, - type, sizeof(type) - 1, enc, sizeof(enc) - 1, &data, - &data_len)) - return; - - if (!strcmp(type, "application/x-wb") && - !strcmp(enc, "binary") && - !purple_account_get_bool(sg->account, "block-wb", FALSE)) - silcpurple_wb_receive(client, conn, sender, payload, - flags, data, data_len); -#endif - return; - } - - if (flags & SILC_MESSAGE_FLAG_ACTION && convo) { - msg = g_strdup_printf("/me %s", - (const char *)message); - if (!msg) - return; - - tmp = g_markup_escape_text(msg, -1); - /* Send to Purple */ - serv_got_im(gc, sender->nickname ? - sender->nickname : "", - tmp, 0, time(NULL)); - g_free(msg); - g_free(tmp); - return; - } - - if (flags & SILC_MESSAGE_FLAG_NOTICE && convo) { - msg = g_strdup_printf("(notice) %s %s", - sender->nickname ? - sender->nickname : "", - (const char *)message); - if (!msg) - return; - - /* Send to Purple */ - purple_conversation_write(convo, NULL, (const char *)msg, - PURPLE_MESSAGE_SYSTEM, time(NULL)); - g_free(msg); - return; - } - - if (flags & SILC_MESSAGE_FLAG_UTF8) { - tmp = g_markup_escape_text((const char *)message, -1); - /* Send to Purple */ - serv_got_im(gc, sender->nickname ? - sender->nickname : "", - tmp, 0, time(NULL)); - g_free(tmp); - } -} - - -/* Notify message to the client. The notify arguments are sent in the - same order as servers sends them. The arguments are same as received - from the server except for ID's. If ID is received application receives - the corresponding entry to the ID. For example, if Client ID is received - application receives SilcClientEntry. Also, if the notify type is - for channel the channel entry is sent to application (even if server - does not send it because client library gets the channel entry from - the Channel ID in the packet's header). */ - -static void -silc_notify(SilcClient client, SilcClientConnection conn, - SilcNotifyType type, ...) -{ - va_list va; - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - PurpleConversation *convo; - SilcClientEntry client_entry, client_entry2; - SilcChannelEntry channel; - SilcServerEntry server_entry; - SilcIdType idtype; - void *entry; - SilcUInt32 mode; - SilcHashTableList htl; - SilcChannelUser chu; - char buf[512], buf2[512], *tmp, *name; - SilcNotifyType notify; - PurpleBuddy *b; - int i; - - va_start(va, type); - memset(buf, 0, sizeof(buf)); - - switch (type) { - - case SILC_NOTIFY_TYPE_NONE: - break; - - case SILC_NOTIFY_TYPE_INVITE: - { - GHashTable *components; - va_arg(va, SilcChannelEntry); - name = va_arg(va, char *); - client_entry = va_arg(va, SilcClientEntry); - - components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - g_hash_table_insert(components, strdup("channel"), strdup(name)); - serv_got_chat_invite(gc, name, client_entry->nickname, NULL, components); - } - break; - - case SILC_NOTIFY_TYPE_JOIN: - client_entry = va_arg(va, SilcClientEntry); - channel = va_arg(va, SilcChannelEntry); - - /* If we joined channel, do nothing */ - if (client_entry == conn->local_entry) - break; - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - /* Join user to channel */ - g_snprintf(buf, sizeof(buf), "%s@%s", - client_entry->username, client_entry->hostname); - purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), - g_strdup(client_entry->nickname), buf, PURPLE_CBFLAGS_NONE, TRUE); - - break; - - case SILC_NOTIFY_TYPE_LEAVE: - client_entry = va_arg(va, SilcClientEntry); - channel = va_arg(va, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - /* Remove user from channel */ - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), - client_entry->nickname, NULL); - - break; - - case SILC_NOTIFY_TYPE_SIGNOFF: - client_entry = va_arg(va, SilcClientEntry); - tmp = va_arg(va, char *); - - if (!client_entry->nickname) - break; - - /* Remove from all channels */ - silc_hash_table_list(client_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), - client_entry->nickname, - tmp); - } - silc_hash_table_list_reset(&htl); - - break; - - case SILC_NOTIFY_TYPE_TOPIC_SET: - { - char *esc, *tmp2; - idtype = va_arg(va, int); - entry = va_arg(va, void *); - tmp = va_arg(va, char *); - channel = va_arg(va, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - if (!tmp) - break; - - esc = g_markup_escape_text(tmp, -1); - tmp2 = purple_markup_linkify(esc); - g_free(esc); - - if (idtype == SILC_ID_CLIENT) { - client_entry = (SilcClientEntry)entry; - g_snprintf(buf, sizeof(buf), - _("%s has changed the topic of %s to: %s"), - client_entry->nickname, channel->channel_name, tmp2); - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), - client_entry->nickname, tmp); - } else if (idtype == SILC_ID_SERVER) { - server_entry = (SilcServerEntry)entry; - g_snprintf(buf, sizeof(buf), - _("%s has changed the topic of %s to: %s"), - server_entry->server_name, channel->channel_name, tmp2); - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), server_entry->server_name, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), - server_entry->server_name, tmp); - } else if (idtype == SILC_ID_CHANNEL) { - channel = (SilcChannelEntry)entry; - g_snprintf(buf, sizeof(buf), - _("%s has changed the topic of %s to: %s"), - channel->channel_name, channel->channel_name, tmp2); - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), - channel->channel_name, tmp); - } else { - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, tmp); - } - - g_free(tmp2); - - break; - - } - case SILC_NOTIFY_TYPE_NICK_CHANGE: - client_entry = va_arg(va, SilcClientEntry); - client_entry2 = va_arg(va, SilcClientEntry); - - if (!strcmp(client_entry->nickname, client_entry2->nickname)) - break; - - /* Change nick on all channels */ - silc_hash_table_list(client_entry2->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), client_entry->nickname)) - purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo), - client_entry->nickname, - client_entry2->nickname); - } - silc_hash_table_list_reset(&htl); - - break; - - case SILC_NOTIFY_TYPE_CMODE_CHANGE: - idtype = va_arg(va, int); - entry = va_arg(va, void *); - mode = va_arg(va, SilcUInt32); - (void)va_arg(va, char *); - (void)va_arg(va, char *); - (void)va_arg(va, char *); - (void)va_arg(va, SilcPublicKey); - (void)va_arg(va, SilcBuffer); - channel = va_arg(va, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - if (idtype == SILC_ID_CLIENT) - name = ((SilcClientEntry)entry)->nickname; - else if (idtype == SILC_ID_SERVER) - name = ((SilcServerEntry)entry)->server_name; - else - name = ((SilcChannelEntry)entry)->channel_name; - if (!name) - break; - - if (mode) { - silcpurple_get_chmode_string(mode, buf2, sizeof(buf2)); - g_snprintf(buf, sizeof(buf), - _("%s set channel %s modes to: %s"), name, - channel->channel_name, buf2); - } else { - g_snprintf(buf, sizeof(buf), - _("%s removed all channel %s modes"), name, - channel->channel_name); - } - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - break; - - case SILC_NOTIFY_TYPE_CUMODE_CHANGE: - { - PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE; - idtype = va_arg(va, int); - entry = va_arg(va, void *); - mode = va_arg(va, SilcUInt32); - client_entry2 = va_arg(va, SilcClientEntry); - channel = va_arg(va, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - if (idtype == SILC_ID_CLIENT) - name = ((SilcClientEntry)entry)->nickname; - else if (idtype == SILC_ID_SERVER) - name = ((SilcServerEntry)entry)->server_name; - else - name = ((SilcChannelEntry)entry)->channel_name; - if (!name) - break; - - if (mode) { - silcpurple_get_chumode_string(mode, buf2, sizeof(buf2)); - g_snprintf(buf, sizeof(buf), - _("%s set %s's modes to: %s"), name, - client_entry2->nickname, buf2); - if (mode & SILC_CHANNEL_UMODE_CHANFO) - flags |= PURPLE_CBFLAGS_FOUNDER; - if (mode & SILC_CHANNEL_UMODE_CHANOP) - flags |= PURPLE_CBFLAGS_OP; - } else { - g_snprintf(buf, sizeof(buf), - _("%s removed all %s's modes"), name, - client_entry2->nickname); - } - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel->channel_name, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(convo), client_entry2->nickname, flags); - break; - } - - case SILC_NOTIFY_TYPE_MOTD: - tmp = va_arg(va, char *); - silc_free(sg->motd); - sg->motd = silc_memdup(tmp, strlen(tmp)); - break; - - case SILC_NOTIFY_TYPE_KICKED: - client_entry = va_arg(va, SilcClientEntry); - tmp = va_arg(va, char *); - client_entry2 = va_arg(va, SilcClientEntry); - channel = va_arg(va, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) - break; - - if (client_entry == conn->local_entry) { - /* Remove us from channel */ - g_snprintf(buf, sizeof(buf), - _("You have been kicked off %s by %s (%s)"), - channel->channel_name, client_entry2->nickname, - tmp ? tmp : ""); - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo))); - } else { - /* Remove user from channel */ - g_snprintf(buf, sizeof(buf), _("Kicked by %s (%s)"), - client_entry2->nickname, tmp ? tmp : ""); - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), - client_entry->nickname, - buf); - } - - break; - - case SILC_NOTIFY_TYPE_KILLED: - client_entry = va_arg(va, SilcClientEntry); - tmp = va_arg(va, char *); - idtype = va_arg(va, int); - entry = va_arg(va, SilcClientEntry); - - if (!client_entry->nickname) - break; - - if (client_entry == conn->local_entry) { - if (idtype == SILC_ID_CLIENT) { - client_entry2 = (SilcClientEntry)entry; - g_snprintf(buf, sizeof(buf), - _("You have been killed by %s (%s)"), - client_entry2->nickname, tmp ? tmp : ""); - } else if (idtype == SILC_ID_SERVER) { - server_entry = (SilcServerEntry)entry; - g_snprintf(buf, sizeof(buf), - _("You have been killed by %s (%s)"), - server_entry->server_name, tmp ? tmp : ""); - } else if (idtype == SILC_ID_CHANNEL) { - channel = (SilcChannelEntry)entry; - g_snprintf(buf, sizeof(buf), - _("You have been killed by %s (%s)"), - channel->channel_name, tmp ? tmp : ""); - } - - /* Remove us from all channels */ - silc_hash_table_list(client_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - purple_conv_chat_write(PURPLE_CONV_CHAT(convo), client_entry->nickname, - buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); - serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo))); - } - silc_hash_table_list_reset(&htl); - - } else { - if (idtype == SILC_ID_CLIENT) { - client_entry2 = (SilcClientEntry)entry; - g_snprintf(buf, sizeof(buf), - _("Killed by %s (%s)"), - client_entry2->nickname, tmp ? tmp : ""); - } else if (idtype == SILC_ID_SERVER) { - server_entry = (SilcServerEntry)entry; - g_snprintf(buf, sizeof(buf), - _("Killed by %s (%s)"), - server_entry->server_name, tmp ? tmp : ""); - } else if (idtype == SILC_ID_CHANNEL) { - channel = (SilcChannelEntry)entry; - g_snprintf(buf, sizeof(buf), - _("Killed by %s (%s)"), - channel->channel_name, tmp ? tmp : ""); - } - - /* Remove user from all channels */ - silc_hash_table_list(client_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), - client_entry->nickname, tmp); - } - silc_hash_table_list_reset(&htl); - } - - break; - - case SILC_NOTIFY_TYPE_CHANNEL_CHANGE: - break; - - case SILC_NOTIFY_TYPE_SERVER_SIGNOFF: - { - int i; - SilcClientEntry *clients; - SilcUInt32 clients_count; - - (void)va_arg(va, void *); - clients = va_arg(va, SilcClientEntry *); - clients_count = va_arg(va, SilcUInt32); - - for (i = 0; i < clients_count; i++) { - if (!clients[i]->nickname) - break; - - /* Remove from all channels */ - silc_hash_table_list(clients[i]->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = - purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), - clients[i]->nickname, - _("Server signoff")); - } - silc_hash_table_list_reset(&htl); - } - } - break; - - case SILC_NOTIFY_TYPE_ERROR: - { - SilcStatus error = va_arg(va, int); - purple_notify_error(gc, "Error Notify", - silc_get_status_message(error), - NULL); - } - break; - - case SILC_NOTIFY_TYPE_WATCH: - { - SilcPublicKey public_key; - unsigned char *pk; - SilcUInt32 pk_len; - char *fingerprint; - - client_entry = va_arg(va, SilcClientEntry); - (void)va_arg(va, char *); - mode = va_arg(va, SilcUInt32); - notify = va_arg(va, int); - public_key = va_arg(va, SilcPublicKey); - - b = NULL; - if (public_key) { - PurpleBlistNode *gnode, *cnode, *bnode; - const char *f; - - pk = silc_pkcs_public_key_encode(public_key, &pk_len); - if (!pk) - break; - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - for (i = 0; i < strlen(fingerprint); i++) - if (fingerprint[i] == ' ') - fingerprint[i] = '_'; - g_snprintf(buf, sizeof(buf) - 1, - "%s" G_DIR_SEPARATOR_S "clientkeys" - G_DIR_SEPARATOR_S "clientkey_%s.pub", - silcpurple_silcdir(), fingerprint); - silc_free(fingerprint); - silc_free(pk); - - /* Find buddy by associated public key */ - for (gnode = purple_get_blist()->root; gnode; - gnode = gnode->next) { - if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) - continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { - if( !PURPLE_BLIST_NODE_IS_CONTACT(cnode)) - continue; - for (bnode = cnode->child; bnode; - bnode = bnode->next) { - if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - b = (PurpleBuddy *)bnode; - if (b->account != gc->account) - continue; - f = purple_blist_node_get_string(bnode, "public-key"); - if (f && !strcmp(f, buf)) - goto cont; - b = NULL; - } - } - } - } - cont: - if (!b) { - /* Find buddy by nickname */ - b = purple_find_buddy(sg->account, client_entry->nickname); - if (!b) { - purple_debug_warning("silc", "WATCH for %s, unknown buddy\n", - client_entry->nickname); - break; - } - } - - silc_free(b->proto_data); - b->proto_data = silc_memdup(client_entry->id, - sizeof(*client_entry->id)); - if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) { - break; - } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) { - /* See if client was away and is now present */ - if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED | - SILC_UMODE_BUSY | SILC_UMODE_PAGE | - SILC_UMODE_DETACHED)) && - (client_entry->mode & SILC_UMODE_GONE || - client_entry->mode & SILC_UMODE_INDISPOSED || - client_entry->mode & SILC_UMODE_BUSY || - client_entry->mode & SILC_UMODE_PAGE || - client_entry->mode & SILC_UMODE_DETACHED)) { - client_entry->mode = mode; - purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); - } - else if ((mode & SILC_UMODE_GONE) || - (mode & SILC_UMODE_INDISPOSED) || - (mode & SILC_UMODE_BUSY) || - (mode & SILC_UMODE_PAGE) || - (mode & SILC_UMODE_DETACHED)) { - client_entry->mode = mode; - purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); - } - } else if (notify == SILC_NOTIFY_TYPE_SIGNOFF || - notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF || - notify == SILC_NOTIFY_TYPE_KILLED) { - client_entry->mode = mode; - purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); - } else if (notify == SILC_NOTIFY_TYPE_NONE) { - client_entry->mode = mode; - purple_prpl_got_user_status(purple_buddy_get_account(b), purple_buddy_get_name(b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); - } - } - break; - - default: - purple_debug_info("silc", "Unhandled notification: %d\n", type); - break; - } - - va_end(va); -} - - -/* Command handler. This function is called always in the command function. - If error occurs it will be called as well. `conn' is the associated - client connection. `cmd_context' is the command context that was - originally sent to the command. `success' is FALSE if error occurred - during command. `command' is the command being processed. It must be - noted that this is not reply from server. This is merely called just - after application has called the command. Just to tell application - that the command really was processed. */ - -static void -silc_command(SilcClient client, SilcClientConnection conn, - SilcClientCommandContext cmd_context, bool success, - SilcCommand command, SilcStatus status) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - - switch (command) { - - case SILC_COMMAND_CMODE: - if (cmd_context->argc == 3 && - !strcmp((char *)cmd_context->argv[2], "+C")) - sg->chpk = TRUE; - else - sg->chpk = FALSE; - break; - - default: - break; - } -} - -#if 0 -static void -silcpurple_whois_more(SilcClientEntry client_entry, gint id) -{ - SilcAttributePayload attr; - SilcAttribute attribute; - char *buf; - GString *s; - SilcVCardStruct vcard; - int i; - - if (id != 0) - return; - - memset(&vcard, 0, sizeof(vcard)); - - s = g_string_new(""); - - silc_dlist_start(client_entry->attrs); - while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) { - attribute = silc_attribute_get_attribute(attr); - switch (attribute) { - - case SILC_ATTRIBUTE_USER_INFO: - if (!silc_attribute_get_object(attr, (void *)&vcard, - sizeof(vcard))) - continue; - g_string_append_printf(s, "%s:\n\n", _("Personal Information")); - if (vcard.full_name) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Full Name"), - vcard.full_name); - if (vcard.first_name) - g_string_append_printf(s, "%s:\t%s\n", - _("First Name"), - vcard.first_name); - if (vcard.middle_names) - g_string_append_printf(s, "%s:\t%s\n", - _("Middle Name"), - vcard.middle_names); - if (vcard.family_name) - g_string_append_printf(s, "%s:\t%s\n", - _("Family Name"), - vcard.family_name); - if (vcard.nickname) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Nickname"), - vcard.nickname); - if (vcard.bday) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Birth Day"), - vcard.bday); - if (vcard.title) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Job Title"), - vcard.title); - if (vcard.role) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Job Role"), - vcard.role); - if (vcard.org_name) - g_string_append_printf(s, "%s:\t%s\n", - _("Organization"), - vcard.org_name); - if (vcard.org_unit) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Unit"), - vcard.org_unit); - if (vcard.url) - g_string_append_printf(s, "%s:\t%s\n", - _("Homepage"), - vcard.url); - if (vcard.label) - g_string_append_printf(s, "%s:\t%s\n", - _("Address"), - vcard.label); - for (i = 0; i < vcard.num_tels; i++) { - if (vcard.tels[i].telnum) - g_string_append_printf(s, "%s:\t\t\t%s\n", - _("Phone"), - vcard.tels[i].telnum); - } - for (i = 0; i < vcard.num_emails; i++) { - if (vcard.emails[i].address) - g_string_append_printf(s, "%s:\t\t%s\n", - _("Email"), - vcard.emails[i].address); - } - if (vcard.note) - g_string_append_printf(s, "\n%s:\t\t%s\n", - _("Note"), - vcard.note); - break; - } - } - - buf = g_string_free(s, FALSE); - purple_notify_info(NULL, _("User Information"), _("User Information"), - buf); - g_free(buf); -} -#endif - -/* Command reply handler. This function is called always in the command reply - function. If error occurs it will be called as well. Normal scenario - is that it will be called after the received command data has been parsed - and processed. The function is used to pass the received command data to - the application. - - `conn' is the associated client connection. `cmd_payload' is the command - payload data received from server and it can be ignored. It is provided - if the application would like to re-parse the received command data, - however, it must be noted that the data is parsed already by the library - thus the payload can be ignored. `success' is FALSE if error occurred. - In this case arguments are not sent to the application. The `status' is - the command reply status server returned. The `command' is the command - reply being processed. The function has variable argument list and each - command defines the number and type of arguments it passes to the - application (on error they are not sent). */ - -static void -silc_command_reply(SilcClient client, SilcClientConnection conn, - SilcCommandPayload cmd_payload, bool success, - SilcCommand command, SilcStatus status, ...) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - PurpleConversation *convo; - va_list vp; - - va_start(vp, status); - - switch (command) { - case SILC_COMMAND_JOIN: - { - SilcChannelEntry channel_entry; - - if (!success) { - purple_notify_error(gc, _("Join Chat"), _("Cannot join channel"), - silc_get_status_message(status)); - return; - } - - (void)va_arg(vp, char *); - channel_entry = va_arg(vp, SilcChannelEntry); - - /* Resolve users on channel */ - silc_client_get_clients_by_channel(client, conn, channel_entry, - silcpurple_chat_join_done, - channel_entry); - } - break; - - case SILC_COMMAND_LEAVE: - break; - - case SILC_COMMAND_USERS: - break; - - case SILC_COMMAND_WHOIS: - { - SilcUInt32 idle, mode; - SilcBuffer channels, user_modes; - SilcClientEntry client_entry; - char tmp[1024], *tmp2; - char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; - PurpleNotifyUserInfo *user_info; - - if (!success) { - purple_notify_error(gc, _("User Information"), - _("Cannot get user information"), - silc_get_status_message(status)); - break; - } - - client_entry = va_arg(vp, SilcClientEntry); - if (!client_entry->nickname) - break; - (void)va_arg(vp, char *); - (void)va_arg(vp, char *); - (void)va_arg(vp, char *); - channels = va_arg(vp, SilcBuffer); - mode = va_arg(vp, SilcUInt32); - idle = va_arg(vp, SilcUInt32); - (void)va_arg(vp, unsigned char *); - user_modes = va_arg(vp, SilcBuffer); - - user_info = purple_notify_user_info_new(); - tmp2 = g_markup_escape_text(client_entry->nickname, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp2); - g_free(tmp2); - if (client_entry->realname) { - tmp2 = g_markup_escape_text(client_entry->realname, -1); - purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp2); - g_free(tmp2); - } - if (client_entry->username) { - tmp2 = g_markup_escape_text(client_entry->username, -1); - if (client_entry->hostname) { - gchar *tmp3; - tmp3 = g_strdup_printf("%s@%s", tmp2, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp3); - g_free(tmp3); - } else - purple_notify_user_info_add_pair(user_info, _("Username"), tmp2); - g_free(tmp2); - } - - if (client_entry->mode) { - memset(tmp, 0, sizeof(tmp)); - silcpurple_get_umode_string(client_entry->mode, - tmp, sizeof(tmp) - strlen(tmp)); - purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); - } - - silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); - if (moodstr) { - purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); - g_free(moodstr); - } - - if (statusstr) { - tmp2 = g_markup_escape_text(statusstr, -1); - purple_notify_user_info_add_pair(user_info, _("Status Text"), tmp2); - g_free(statusstr); - g_free(tmp2); - } - - if (contactstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); - g_free(contactstr); - } - - if (langstr) { - purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); - g_free(langstr); - } - - if (devicestr) { - purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); - g_free(devicestr); - } - - if (tzstr) { - purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); - g_free(tzstr); - } - - if (geostr) { - purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); - g_free(geostr); - } - - if (client_entry->server) - purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server); - - if (channels && user_modes) { - SilcUInt32 *umodes; - SilcDList list = - silc_channel_payload_parse_list(channels->data, - channels->len); - if (list && silc_get_mode_list(user_modes, - silc_dlist_count(list), - &umodes)) { - SilcChannelPayload entry; - int i = 0; - - memset(tmp, 0, sizeof(tmp)); - silc_dlist_start(list); - while ((entry = silc_dlist_get(list)) - != SILC_LIST_END) { - SilcUInt32 name_len; - char *m = silc_client_chumode_char(umodes[i++]); - char *name = (char *)silc_channel_get_name(entry, &name_len); - if (m) - silc_strncat(tmp, sizeof(tmp) - 1, m, strlen(m)); - silc_strncat(tmp, sizeof(tmp) - 1, name, name_len); - silc_strncat(tmp, sizeof(tmp) - 1, " ", 1); - silc_free(m); - - } - tmp2 = g_markup_escape_text(tmp, -1); - purple_notify_user_info_add_pair(user_info, _("Currently on"), tmp2); - g_free(tmp2); - silc_free(umodes); - } - } - - if (client_entry->public_key) { - char *fingerprint, *babbleprint; - unsigned char *pk; - SilcUInt32 pk_len; - pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint); - purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint); - silc_free(fingerprint); - silc_free(babbleprint); - silc_free(pk); - } - -#if 0 /* XXX for now, let's not show attrs here */ - if (client_entry->attrs) - purple_request_action(gc, _("User Information"), - _("User Information"), - buf, 1, client_entry, 2, - _("OK"), G_CALLBACK(silcpurple_whois_more), - _("_More..."), G_CALLBACK(silcpurple_whois_more), gc->account, NULL, NULL); - else -#endif - purple_notify_userinfo(gc, client_entry->nickname, user_info, NULL, NULL); - purple_notify_user_info_destroy(user_info); - } - break; - - case SILC_COMMAND_WHOWAS: - { - SilcClientEntry client_entry; - char *nickname, *realname, *username, *tmp; - PurpleNotifyUserInfo *user_info; - - if (!success) { - purple_notify_error(gc, _("User Information"), - _("Cannot get user information"), - silc_get_status_message(status)); - break; - } - - client_entry = va_arg(vp, SilcClientEntry); - nickname = va_arg(vp, char *); - username = va_arg(vp, char *); - realname = va_arg(vp, char *); - if (!nickname) - break; - - user_info = purple_notify_user_info_new(); - tmp = g_markup_escape_text(nickname, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp); - g_free(tmp); - if (realname) { - tmp = g_markup_escape_text(realname, -1); - purple_notify_user_info_add_pair(user_info, _("Real Name"), tmp); - g_free(tmp); - } - if (username) { - tmp = g_markup_escape_text(username, -1); - if (client_entry && client_entry->hostname) { - gchar *tmp3; - tmp3 = g_strdup_printf("%s@%s", tmp, client_entry->hostname); - purple_notify_user_info_add_pair(user_info, _("Username"), tmp3); - g_free(tmp3); - } else - purple_notify_user_info_add_pair(user_info, _("Username"), tmp); - g_free(tmp); - } - if (client_entry && client_entry->server) - purple_notify_user_info_add_pair(user_info, _("Server"), client_entry->server); - - - if (client_entry && client_entry->public_key) { - char *fingerprint, *babbleprint; - unsigned char *pk; - SilcUInt32 pk_len; - pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint); - purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint); - silc_free(fingerprint); - silc_free(babbleprint); - silc_free(pk); - } - - purple_notify_userinfo(gc, nickname, user_info, NULL, NULL); - purple_notify_user_info_destroy(user_info); - } - break; - - case SILC_COMMAND_DETACH: - if (!success) { - purple_notify_error(gc, _("Detach From Server"), _("Cannot detach"), - silc_get_status_message(status)); - return; - } - break; - - case SILC_COMMAND_TOPIC: - { - SilcChannelEntry channel; - - if (!success) { - purple_notify_error(gc, _("Topic"), _("Cannot set topic"), - silc_get_status_message(status)); - return; - } - - channel = va_arg(vp, SilcChannelEntry); - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - channel->channel_name, sg->account); - if (!convo) { - purple_debug_error("silc", "Got a topic for %s, which doesn't exist\n", - channel->channel_name); - break; - } - - /* Set topic */ - if (channel->topic) - purple_conv_chat_set_topic(PURPLE_CONV_CHAT(convo), NULL, channel->topic); - } - break; - - case SILC_COMMAND_NICK: - { - /* I don't think we should need to do this because the server should - * be sending a SILC_NOTIFY_TYPE_NICK_CHANGE when we change our own - * nick, but it isn't, so we deal with it here instead. Stu. */ - SilcClientEntry local_entry; - SilcHashTableList htl; - SilcChannelUser chu; - const char *oldnick; - - if (!success) { - purple_notify_error(gc, _("Nick"), _("Failed to change nickname"), - silc_get_status_message(status)); - return; - } - - local_entry = va_arg(vp, SilcClientEntry); - - /* Change nick on all channels */ - silc_hash_table_list(local_entry->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, - chu->channel->channel_name, sg->account); - if (!convo) - continue; - oldnick = purple_conv_chat_get_nick(PURPLE_CONV_CHAT(convo)); - if (strcmp(oldnick, purple_normalize(purple_conversation_get_account(convo), local_entry->nickname))) { - purple_conv_chat_rename_user(PURPLE_CONV_CHAT(convo), - oldnick, local_entry->nickname); - purple_conv_chat_set_nick(PURPLE_CONV_CHAT(convo), local_entry->nickname); - } - } - silc_hash_table_list_reset(&htl); - - purple_connection_set_display_name(gc, local_entry->nickname); - } - break; - - case SILC_COMMAND_LIST: - { - char *topic, *name; - int usercount; - PurpleRoomlistRoom *room; - - if (sg->roomlist_cancelled) - break; - - if (!success) { - purple_notify_error(gc, _("Error"), _("Error retrieving room list"), - silc_get_status_message(status)); - purple_roomlist_set_in_progress(sg->roomlist, FALSE); - purple_roomlist_unref(sg->roomlist); - sg->roomlist = NULL; - return; - } - - (void)va_arg(vp, SilcChannelEntry); - name = va_arg(vp, char *); - if (!name) { - purple_notify_error(gc, _("Roomlist"), _("Cannot get room list"), - silc_get_status_message(status)); - purple_roomlist_set_in_progress(sg->roomlist, FALSE); - purple_roomlist_unref(sg->roomlist); - sg->roomlist = NULL; - return; - } - topic = va_arg(vp, char *); - usercount = va_arg(vp, int); - - room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); - purple_roomlist_room_add_field(sg->roomlist, room, name); - purple_roomlist_room_add_field(sg->roomlist, room, - SILC_32_TO_PTR(usercount)); - purple_roomlist_room_add_field(sg->roomlist, room, - topic ? topic : ""); - purple_roomlist_room_add(sg->roomlist, room); - - if (status == SILC_STATUS_LIST_END || - status == SILC_STATUS_OK) { - purple_roomlist_set_in_progress(sg->roomlist, FALSE); - purple_roomlist_unref(sg->roomlist); - sg->roomlist = NULL; - } - } - break; - - case SILC_COMMAND_GETKEY: - { - SilcPublicKey public_key; - - if (!success) { - purple_notify_error(gc, _("Get Public Key"), - _("Cannot fetch the public key"), - silc_get_status_message(status)); - return; - } - - (void)va_arg(vp, SilcUInt32); - (void)va_arg(vp, void *); - public_key = va_arg(vp, SilcPublicKey); - - if (!public_key) - purple_notify_error(gc, _("Get Public Key"), - _("Cannot fetch the public key"), - _("No public key was received")); - } - break; - - case SILC_COMMAND_INFO: - { - - char *server_name; - char *server_info; - char tmp[256]; - - if (!success) { - purple_notify_error(gc, _("Server Information"), - _("Cannot get server information"), - silc_get_status_message(status)); - return; - } - - (void)va_arg(vp, SilcServerEntry); - server_name = va_arg(vp, char *); - server_info = va_arg(vp, char *); - - if (server_name && server_info) { - g_snprintf(tmp, sizeof(tmp), "Server: %s\n%s", - server_name, server_info); - purple_notify_info(gc, NULL, _("Server Information"), tmp); - } - } - break; - - case SILC_COMMAND_STATS: - { - SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops, - my_router_ops, cell_clients, cell_channels, cell_servers, - clients, channels, servers, routers, server_ops, router_ops; - SilcUInt32 buffer_length; - SilcBufferStruct buf; - - unsigned char *server_stats; - char *msg; - - if (!success) { - purple_notify_error(gc, _("Server Statistics"), - _("Cannot get server statistics"), - silc_get_status_message(status)); - return; - } - - server_stats = va_arg(vp, unsigned char *); - buffer_length = va_arg(vp, SilcUInt32); - if (!server_stats || !buffer_length) { - purple_notify_error(gc, _("Server Statistics"), - _("No server statistics available"), NULL); - break; - } - silc_buffer_set(&buf, server_stats, buffer_length); - silc_buffer_unformat(&buf, - SILC_STR_UI_INT(&starttime), - SILC_STR_UI_INT(&uptime), - SILC_STR_UI_INT(&my_clients), - SILC_STR_UI_INT(&my_channels), - SILC_STR_UI_INT(&my_server_ops), - SILC_STR_UI_INT(&my_router_ops), - SILC_STR_UI_INT(&cell_clients), - SILC_STR_UI_INT(&cell_channels), - SILC_STR_UI_INT(&cell_servers), - SILC_STR_UI_INT(&clients), - SILC_STR_UI_INT(&channels), - SILC_STR_UI_INT(&servers), - SILC_STR_UI_INT(&routers), - SILC_STR_UI_INT(&server_ops), - SILC_STR_UI_INT(&router_ops), - SILC_STR_END); - - msg = g_strdup_printf(_("Local server start time: %s\n" - "Local server uptime: %s\n" - "Local server clients: %d\n" - "Local server channels: %d\n" - "Local server operators: %d\n" - "Local router operators: %d\n" - "Local cell clients: %d\n" - "Local cell channels: %d\n" - "Local cell servers: %d\n" - "Total clients: %d\n" - "Total channels: %d\n" - "Total servers: %d\n" - "Total routers: %d\n" - "Total server operators: %d\n" - "Total router operators: %d\n"), - silc_get_time(starttime), - purple_str_seconds_to_string((int)uptime), - (int)my_clients, (int)my_channels, (int)my_server_ops, (int)my_router_ops, - (int)cell_clients, (int)cell_channels, (int)cell_servers, - (int)clients, (int)channels, (int)servers, (int)routers, - (int)server_ops, (int)router_ops); - - purple_notify_info(gc, NULL, - _("Network Statistics"), msg); - g_free(msg); - } - break; - - case SILC_COMMAND_PING: - { - if (!success) { - purple_notify_error(gc, _("Ping"), _("Ping failed"), - silc_get_status_message(status)); - return; - } - - purple_notify_info(gc, _("Ping"), _("Ping reply received from server"), - NULL); - } - break; - - case SILC_COMMAND_KILL: - if (!success) { - purple_notify_error(gc, _("Kill User"), - _("Could not kill user"), - silc_get_status_message(status)); - return; - } - break; - - case SILC_COMMAND_CMODE: - { - SilcChannelEntry channel_entry; - SilcBuffer channel_pubkeys; - - if (!success) - return; - - channel_entry = va_arg(vp, SilcChannelEntry); - (void)va_arg(vp, SilcUInt32); - (void)va_arg(vp, SilcPublicKey); - channel_pubkeys = va_arg(vp, SilcBuffer); - - if (sg->chpk) - silcpurple_chat_chauth_show(sg, channel_entry, channel_pubkeys); - } - break; - - default: - if (success) - purple_debug_info("silc", "Unhandled command: %d (succeeded)\n", command); - else - purple_debug_info("silc", "Unhandled command: %d (failed: %s)\n", command, - silc_get_status_message(status)); - break; - } - - va_end(vp); -} - - -/* Called to indicate that connection was either successfully established - or connecting failed. This is also the first time application receives - the SilcClientConnection object which it should save somewhere. - If the `success' is FALSE the application must always call the function - silc_client_close_connection. */ - -static void -silc_connected(SilcClient client, SilcClientConnection conn, - SilcClientConnectionStatus status) -{ - PurpleConnection *gc = client->application; - SilcPurple sg; - - if (gc == NULL) { - silc_client_close_connection(client, conn); - return; - } - sg = gc->proto_data; - - switch (status) { - case SILC_CLIENT_CONN_SUCCESS: - case SILC_CLIENT_CONN_SUCCESS_RESUME: - purple_connection_set_state(gc, PURPLE_CONNECTED); - - /* Send the server our buddy list */ - silcpurple_send_buddylist(gc); - - g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); - - /* Send any UMODEs configured for account */ - if (purple_account_get_bool(sg->account, "block-ims", FALSE)) { - silc_client_command_call(sg->client, sg->conn, NULL, - "UMODE", "+P", NULL); - } - - return; - break; - case SILC_CLIENT_CONN_ERROR: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Error during connecting to SILC Server")); - g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); - break; - - case SILC_CLIENT_CONN_ERROR_KE: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, - _("Key Exchange failed")); - break; - - case SILC_CLIENT_CONN_ERROR_AUTH: - purple_connection_error_reason(gc, - PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, - _("Authentication failed")); - break; - - case SILC_CLIENT_CONN_ERROR_RESUME: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - _("Resuming detached session failed. " - "Press Reconnect to create new connection.")); - g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); - break; - - case SILC_CLIENT_CONN_ERROR_TIMEOUT: - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Connection timed out")); - break; - } - - /* Error */ - sg->conn = NULL; - silc_client_close_connection(client, conn); -} - - -/* Called to indicate that connection was disconnected to the server. - The `status' may tell the reason of the disconnection, and if the - `message' is non-NULL it may include the disconnection message - received from server. */ - -static void -silc_disconnected(SilcClient client, SilcClientConnection conn, - SilcStatus status, const char *message) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - - if (sg->resuming && !sg->detaching) - g_unlink(silcpurple_session_file(purple_account_get_username(sg->account))); - - sg->conn = NULL; - - /* Close the connection */ - if (!sg->detaching) - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Disconnected by server")); - else - /* TODO: Does this work correctly? Maybe we need to set wants_to_die? */ - purple_account_disconnect(purple_connection_get_account(gc)); -} - - -typedef struct { - SilcGetAuthMeth completion; - void *context; -} *SilcPurpleGetAuthMethod; - -/* Callback called when we've received the authentication method information - from the server after we've requested it. */ - -static void silc_get_auth_method_callback(SilcClient client, - SilcClientConnection conn, - SilcAuthMethod auth_meth, - void *context) -{ - SilcPurpleGetAuthMethod internal = context; - - switch (auth_meth) { - case SILC_AUTH_NONE: - /* No authentication required. */ - (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); - break; - - case SILC_AUTH_PASSWORD: - /* By returning NULL here the library will ask the passphrase from us - by calling the silc_ask_passphrase. */ - (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); - break; - - case SILC_AUTH_PUBLIC_KEY: - /* Do not get the authentication data now, the library will generate - it using our default key, if we do not provide it here. */ - (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); - break; - } - - silc_free(internal); -} - -/* Find authentication method and authentication data by hostname and - port. The hostname may be IP address as well. When the authentication - method has been resolved the `completion' callback with the found - authentication method and authentication data is called. The `conn' - may be NULL. */ - -static void -silc_get_auth_method(SilcClient client, SilcClientConnection conn, - char *hostname, SilcUInt16 port, - SilcGetAuthMeth completion, void *context) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - SilcPurpleGetAuthMethod internal; - const char *password; - - /* Progress */ - if (sg->resuming) - purple_connection_update_progress(gc, _("Resuming session"), 4, 5); - else - purple_connection_update_progress(gc, _("Authenticating connection"), 4, 5); - - /* Check configuration if we have this connection configured. If we - have then return that data immediately, as it's faster way. */ - if (purple_account_get_bool(sg->account, "pubkey-auth", FALSE)) { - completion(TRUE, SILC_AUTH_PUBLIC_KEY, NULL, 0, context); - return; - } - password = purple_connection_get_password(gc); - if (password && *password) { - completion(TRUE, SILC_AUTH_PASSWORD, (unsigned char *)password, strlen(password), context); - return; - } - - /* Resolve the authentication method from server, as we may not know it. */ - internal = silc_calloc(1, sizeof(*internal)); - if (!internal) - return; - internal->completion = completion; - internal->context = context; - silc_client_request_authentication_method(client, conn, - silc_get_auth_method_callback, - internal); -} - - -/* Verifies received public key. The `conn_type' indicates which entity - (server, client etc.) has sent the public key. If user decides to trust - the application may save the key as trusted public key for later - use. The `completion' must be called after the public key has been - verified. */ - -static void -silc_verify_public_key(SilcClient client, SilcClientConnection conn, - SilcSocketType conn_type, unsigned char *pk, - SilcUInt32 pk_len, SilcSKEPKType pk_type, - SilcVerifyPublicKey completion, void *context) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - - if (!sg->conn && (conn_type == SILC_SOCKET_TYPE_SERVER || - conn_type == SILC_SOCKET_TYPE_ROUTER)) { - /* Progress */ - if (sg->resuming) - purple_connection_update_progress(gc, _("Resuming session"), 3, 5); - else - purple_connection_update_progress(gc, _("Verifying server public key"), - 3, 5); - } - - /* Verify public key */ - silcpurple_verify_public_key(client, conn, NULL, conn_type, pk, - pk_len, pk_type, completion, context); -} - -typedef struct { - SilcAskPassphrase completion; - void *context; -} *SilcPurpleAskPassphrase; - -static void -silc_ask_passphrase_cb(SilcPurpleAskPassphrase internal, const char *passphrase) -{ - if (!passphrase || !(*passphrase)) - internal->completion(NULL, 0, internal->context); - else - internal->completion((unsigned char *)passphrase, - strlen(passphrase), internal->context); - silc_free(internal); -} - -/* Ask (interact, that is) a passphrase from user. The passphrase is - returned to the library by calling the `completion' callback with - the `context'. The returned passphrase SHOULD be in UTF-8 encoded, - if not then the library will attempt to encode. */ - -static void -silc_ask_passphrase(SilcClient client, SilcClientConnection conn, - SilcAskPassphrase completion, void *context) -{ - PurpleConnection *gc = client->application; - SilcPurpleAskPassphrase internal = silc_calloc(1, sizeof(*internal)); - - if (!internal) - return; - internal->completion = completion; - internal->context = context; - purple_request_input(gc, _("Passphrase"), NULL, - _("Passphrase required"), NULL, FALSE, TRUE, NULL, - _("OK"), G_CALLBACK(silc_ask_passphrase_cb), - _("Cancel"), G_CALLBACK(silc_ask_passphrase_cb), - purple_connection_get_account(gc), NULL, NULL, internal); -} - - -/* Notifies application that failure packet was received. This is called - if there is some protocol active in the client. The `protocol' is the - protocol context. The `failure' is opaque pointer to the failure - indication. Note, that the `failure' is protocol dependant and - application must explicitly cast it to correct type. Usually `failure' - is 32 bit failure type (see protocol specs for all protocol failure - types). */ - -static void -silc_failure(SilcClient client, SilcClientConnection conn, - SilcProtocol protocol, void *failure) -{ - PurpleConnection *gc = client->application; - char buf[128]; - - memset(buf, 0, sizeof(buf)); - - if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) { - SilcSKEStatus status = (SilcSKEStatus)SILC_PTR_TO_32(failure); - - if (status == SILC_SKE_STATUS_BAD_VERSION) - g_snprintf(buf, sizeof(buf), - _("Failure: Version mismatch, upgrade your client")); - if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not trust/support your public key")); - if (status == SILC_SKE_STATUS_UNKNOWN_GROUP) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not support proposed KE group")); - if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not support proposed cipher")); - if (status == SILC_SKE_STATUS_UNKNOWN_PKCS) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not support proposed PKCS")); - if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not support proposed hash function")); - if (status == SILC_SKE_STATUS_UNKNOWN_HMAC) - g_snprintf(buf, sizeof(buf), - _("Failure: Remote does not support proposed HMAC")); - if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE) - g_snprintf(buf, sizeof(buf), _("Failure: Incorrect signature")); - if (status == SILC_SKE_STATUS_INVALID_COOKIE) - g_snprintf(buf, sizeof(buf), _("Failure: Invalid cookie")); - - /* Show the error on the progress bar. A more generic error message - is going to be showed to user after this in the silc_connected. */ - purple_connection_update_progress(gc, buf, 2, 5); - } - - if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) { - SilcUInt32 err = SILC_PTR_TO_32(failure); - - if (err == SILC_AUTH_FAILED) - g_snprintf(buf, sizeof(buf), _("Failure: Authentication failed")); - - /* Show the error on the progress bar. A more generic error message - is going to be showed to user after this in the silc_connected. */ - purple_connection_update_progress(gc, buf, 4, 5); - } -} - -/* Asks whether the user would like to perform the key agreement protocol. - This is called after we have received an key agreement packet or an - reply to our key agreement packet. This returns TRUE if the user wants - the library to perform the key agreement protocol and FALSE if it is not - desired (application may start it later by calling the function - silc_client_perform_key_agreement). If TRUE is returned also the - `completion' and `context' arguments must be set by the application. */ - -static bool -silc_key_agreement(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, const char *hostname, - SilcUInt16 port, SilcKeyAgreementCallback *completion, - void **context) -{ - silcpurple_buddy_keyagr_request(client, conn, client_entry, hostname, port); - *completion = NULL; - *context = NULL; - return FALSE; -} - - -/* Notifies application that file transfer protocol session is being - requested by the remote client indicated by the `client_entry' from - the `hostname' and `port'. The `session_id' is the file transfer - session and it can be used to either accept or reject the file - transfer request, by calling the silc_client_file_receive or - silc_client_file_close, respectively. */ - -static void -silc_ftp(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, SilcUInt32 session_id, - const char *hostname, SilcUInt16 port) -{ - silcpurple_ftp_request(client, conn, client_entry, session_id, - hostname, port); -} - - -/* Delivers SILC session detachment data indicated by `detach_data' to the - application. If application has issued SILC_COMMAND_DETACH command - the client session in the SILC network is not quit. The client remains - in the network but is detached. The detachment data may be used later - to resume the session in the SILC Network. The appliation is - responsible of saving the `detach_data', to for example in a file. - - The detachment data can be given as argument to the functions - silc_client_connect_to_server, or silc_client_add_connection when - creating connection to remote server, inside SilcClientConnectionParams - structure. If it is provided the client library will attempt to resume - the session in the network. After the connection is created - successfully, the application is responsible of setting the user - interface for user into the same state it was before detaching (showing - same channels, channel modes, etc). It can do this by fetching the - information (like joined channels) from the client library. */ - -static void -silc_detach(SilcClient client, SilcClientConnection conn, - const unsigned char *detach_data, SilcUInt32 detach_data_len) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - const char *file; - - /* Save the detachment data to file. */ - file = silcpurple_session_file(purple_account_get_username(sg->account)); - g_unlink(file); - silc_file_writefile(file, (char *)detach_data, detach_data_len); -} - -SilcClientOperations ops = { - silc_say, - silc_channel_message, - silc_private_message, - silc_notify, - silc_command, - silc_command_reply, - silc_connected, - silc_disconnected, - silc_get_auth_method, - silc_verify_public_key, - silc_ask_passphrase, - silc_failure, - silc_key_agreement, - silc_ftp, - silc_detach -}; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/pk.c --- a/libpurple/protocols/silc10/pk.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -/* - - silcpurple_pk.c - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" - -/************************* Public Key Verification ***************************/ - -typedef struct { - SilcClient client; - SilcClientConnection conn; - char *filename; - char *entity; - char *entity_name; - char *fingerprint; - char *babbleprint; - unsigned char *pk; - SilcUInt32 pk_len; - SilcSKEPKType pk_type; - SilcVerifyPublicKey completion; - void *context; - gboolean changed; -} *PublicKeyVerify; - -static void silcpurple_verify_ask(const char *entity, - const char *fingerprint, - const char *babbleprint, - PublicKeyVerify verify); - -static void silcpurple_verify_cb(PublicKeyVerify verify, gint id) -{ - if (id != 2) { - if (verify->completion) - verify->completion(FALSE, verify->context); - } else { - if (verify->completion) - verify->completion(TRUE, verify->context); - - /* Save the key for future checking */ - silc_pkcs_save_public_key_data(verify->filename, verify->pk, - verify->pk_len, SILC_PKCS_FILE_PEM); - } - - silc_free(verify->filename); - silc_free(verify->entity); - silc_free(verify->entity_name); - silc_free(verify->fingerprint); - silc_free(verify->babbleprint); - silc_free(verify->pk); - silc_free(verify); -} - -static void silcpurple_verify_details_cb(PublicKeyVerify verify) -{ - /* What a hack. We have to display the accept dialog _again_ - because Purple closes the dialog after you press the button. Purple - should have option for the dialogs whether the buttons close them - or not. */ - silcpurple_verify_ask(verify->entity, verify->fingerprint, - verify->babbleprint, verify); -} - -static void silcpurple_verify_details(PublicKeyVerify verify, gint id) -{ - SilcPublicKey public_key; - PurpleConnection *gc = verify->client->application; - SilcPurple sg = gc->proto_data; - - silc_pkcs_public_key_decode(verify->pk, verify->pk_len, - &public_key); - silcpurple_show_public_key(sg, verify->entity_name, public_key, - G_CALLBACK(silcpurple_verify_details_cb), - verify); - silc_pkcs_public_key_free(public_key); -} - -static void silcpurple_verify_ask(const char *entity, - const char *fingerprint, - const char *babbleprint, - PublicKeyVerify verify) -{ - PurpleConnection *gc = verify->client->application; - char tmp[256], tmp2[256]; - - if (verify->changed) { - g_snprintf(tmp, sizeof(tmp), - _("Received %s's public key. Your local copy does not match this " - "key. Would you still like to accept this public key?"), - entity); - } else { - g_snprintf(tmp, sizeof(tmp), - _("Received %s's public key. Would you like to accept this " - "public key?"), entity); - } - g_snprintf(tmp2, sizeof(tmp2), - _("Fingerprint and babbleprint for the %s key are:\n\n" - "%s\n%s\n"), entity, fingerprint, babbleprint); - - purple_request_action(gc, _("Verify Public Key"), tmp, tmp2, - PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), entity, NULL, verify, 3, - _("Yes"), G_CALLBACK(silcpurple_verify_cb), - _("No"), G_CALLBACK(silcpurple_verify_cb), - _("_View..."), G_CALLBACK(silcpurple_verify_details)); -} - -void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn, - const char *name, SilcSocketType conn_type, - unsigned char *pk, SilcUInt32 pk_len, - SilcSKEPKType pk_type, - SilcVerifyPublicKey completion, void *context) -{ - PurpleConnection *gc = client->application; - int i; - char file[256], filename[256], filename2[256], *ipf, *hostf = NULL; - char *fingerprint, *babbleprint; - struct passwd *pw; - struct stat st; - char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER || - conn_type == SILC_SOCKET_TYPE_ROUTER) ? - "server" : "client"); - PublicKeyVerify verify; - - if (pk_type != SILC_SKE_PK_TYPE_SILC) { - purple_notify_error(gc, _("Verify Public Key"), - _("Unsupported public key type"), NULL); - if (completion) - completion(FALSE, context); - return; - } - - pw = getpwuid(getuid()); - if (!pw) { - if (completion) - completion(FALSE, context); - return; - } - - memset(filename, 0, sizeof(filename)); - memset(filename2, 0, sizeof(filename2)); - memset(file, 0, sizeof(file)); - - if (conn_type == SILC_SOCKET_TYPE_SERVER || - conn_type == SILC_SOCKET_TYPE_ROUTER) { - if (!name) { - g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, - conn->sock->ip, conn->sock->port); - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", - silcpurple_silcdir(), entity, file); - - g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, - conn->sock->hostname, conn->sock->port); - g_snprintf(filename2, sizeof(filename2) - 1, - "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", - silcpurple_silcdir(), entity, file); - - ipf = filename; - hostf = filename2; - } else { - g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, - name, conn->sock->port); - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", - silcpurple_silcdir(), entity, file); - - ipf = filename; - } - } else { - /* Replace all whitespaces with `_'. */ - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - for (i = 0; i < strlen(fingerprint); i++) - if (fingerprint[i] == ' ') - fingerprint[i] = '_'; - - g_snprintf(file, sizeof(file) - 1, "%skey_%s.pub", entity, fingerprint); - g_snprintf(filename, sizeof(filename) - 1, - "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", - silcpurple_silcdir(), entity, file); - silc_free(fingerprint); - - ipf = filename; - } - - verify = silc_calloc(1, sizeof(*verify)); - if (!verify) - return; - verify->client = client; - verify->conn = conn; - verify->filename = strdup(ipf); - verify->entity = strdup(entity); - verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ? - (name ? strdup(name) : strdup(conn->sock->hostname)) - : NULL); - verify->pk = silc_memdup(pk, pk_len); - verify->pk_len = pk_len; - verify->pk_type = pk_type; - verify->completion = completion; - verify->context = context; - fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - - /* Check whether this key already exists */ - if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) { - /* Key does not exist, ask user to verify the key and save it */ - silcpurple_verify_ask(name ? name : entity, - fingerprint, babbleprint, verify); - return; - } else { - /* The key already exists, verify it. */ - SilcPublicKey public_key; - unsigned char *encpk; - SilcUInt32 encpk_len; - - /* Load the key file, try for both IP filename and hostname filename */ - if (!silc_pkcs_load_public_key(ipf, &public_key, - SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(ipf, &public_key, - SILC_PKCS_FILE_BIN) && - (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key, - SILC_PKCS_FILE_PEM) && - !silc_pkcs_load_public_key(hostf, &public_key, - SILC_PKCS_FILE_BIN)))) { - silcpurple_verify_ask(name ? name : entity, - fingerprint, babbleprint, verify); - return; - } - - /* Encode the key data */ - encpk = silc_pkcs_public_key_encode(public_key, &encpk_len); - if (!encpk) { - silcpurple_verify_ask(name ? name : entity, - fingerprint, babbleprint, verify); - return; - } - - /* Compare the keys */ - if (memcmp(encpk, pk, encpk_len)) { - /* Ask user to verify the key and save it */ - verify->changed = TRUE; - silcpurple_verify_ask(name ? name : entity, - fingerprint, babbleprint, verify); - return; - } - - /* Local copy matched */ - if (completion) - completion(TRUE, context); - silc_free(verify->filename); - silc_free(verify->entity); - silc_free(verify->entity_name); - silc_free(verify->pk); - silc_free(verify->fingerprint); - silc_free(verify->babbleprint); - silc_free(verify); - } -} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/silc.c --- a/libpurple/protocols/silc10/silc.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1965 +0,0 @@ -/* - - silcpurple.c - - Author: Pekka Riikonen - - Copyright (C) 2004 - 2005 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "version.h" -#include "wb.h" -#include "core.h" - -extern SilcClientOperations ops; -static PurplePlugin *silc_plugin = NULL; - -static const char * -silcpurple_list_icon(PurpleAccount *a, PurpleBuddy *b) -{ - return (const char *)"silc"; -} - -static GList * -silcpurple_away_states(PurpleAccount *account) -{ - PurpleStatusType *type; - GList *types = NULL; - - type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_AVAILABLE, NULL, TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, SILCPURPLE_STATUS_ID_HYPER, _("Hyper Active"), TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_AWAY, NULL, TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_UNAVAILABLE, SILCPURPLE_STATUS_ID_BUSY, _("Busy"), TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_INDISPOSED, _("Indisposed"), TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AWAY, SILCPURPLE_STATUS_ID_PAGE, _("Wake Me Up"), TRUE, TRUE, FALSE); - types = g_list_append(types, type); - type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, SILCPURPLE_STATUS_ID_OFFLINE, NULL, TRUE, TRUE, FALSE); - types = g_list_append(types, type); - - return types; -} - -static void -silcpurple_set_status(PurpleAccount *account, PurpleStatus *status) -{ - PurpleConnection *gc = purple_account_get_connection(account); - SilcPurple sg = NULL; - SilcUInt32 mode; - SilcBuffer idp; - unsigned char mb[4]; - const char *state; - - if (gc != NULL) - sg = gc->proto_data; - - if (status == NULL) - return; - - state = purple_status_get_id(status); - - if (state == NULL) - return; - - if ((sg == NULL) || (sg->conn == NULL)) - return; - - mode = sg->conn->local_entry->mode; - mode &= ~(SILC_UMODE_GONE | - SILC_UMODE_HYPER | - SILC_UMODE_BUSY | - SILC_UMODE_INDISPOSED | - SILC_UMODE_PAGE); - - if (!strcmp(state, "hyper")) - mode |= SILC_UMODE_HYPER; - else if (!strcmp(state, "away")) - mode |= SILC_UMODE_GONE; - else if (!strcmp(state, "busy")) - mode |= SILC_UMODE_BUSY; - else if (!strcmp(state, "indisposed")) - mode |= SILC_UMODE_INDISPOSED; - else if (!strcmp(state, "page")) - mode |= SILC_UMODE_PAGE; - - /* Send UMODE */ - idp = silc_id_payload_encode(sg->conn->local_id, SILC_ID_CLIENT); - SILC_PUT32_MSB(mode, mb); - silc_client_command_send(sg->client, sg->conn, SILC_COMMAND_UMODE, - ++sg->conn->cmd_ident, 2, - 1, idp->data, idp->len, - 2, mb, sizeof(mb)); - silc_buffer_free(idp); -} - - -/*************************** Connection Routines *****************************/ - -static void -silcpurple_keepalive(PurpleConnection *gc) -{ - SilcPurple sg = gc->proto_data; - silc_client_send_packet(sg->client, sg->conn, SILC_PACKET_HEARTBEAT, - NULL, 0); -} - -static gboolean -silcpurple_scheduler(gpointer *context) -{ - SilcPurple sg = (SilcPurple)context; - silc_client_run_one(sg->client); - return TRUE; -} - -static void -silcpurple_nickname_parse(const char *nickname, - char **ret_nickname) -{ - silc_parse_userfqdn(nickname, ret_nickname, NULL); -} - -static void -silcpurple_login_connected(gpointer data, gint source, const gchar *error_message) -{ - PurpleConnection *gc = data; - SilcPurple sg; - SilcClient client; - SilcClientConnection conn; - PurpleAccount *account; - SilcClientConnectionParams params; - SilcUInt32 mask; - const char *dfile, *tmp; -#ifdef SILC_ATTRIBUTE_USER_ICON - PurpleStoredImage *img; -#endif -#ifdef HAVE_SYS_UTSNAME_H - struct utsname u; -#endif - - - g_return_if_fail(gc != NULL); - - sg = gc->proto_data; - - if (source < 0) { - purple_connection_error_reason(gc, - PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Connection failed")); - return; - } - - client = sg->client; - account = sg->account; - - /* Get session detachment data, if available */ - memset(¶ms, 0, sizeof(params)); - dfile = silcpurple_session_file(purple_account_get_username(sg->account)); - params.detach_data = (unsigned char *)silc_file_readfile(dfile, ¶ms.detach_data_len); - if (params.detach_data) - params.detach_data[params.detach_data_len] = 0; - - /* Add connection to SILC client library */ - conn = silc_client_add_connection( - sg->client, ¶ms, - (char *)purple_account_get_string(account, "server", - "silc.silcnet.org"), - purple_account_get_int(account, "port", 706), sg); - if (!conn) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Unable to initialize SILC Client connection")); - gc->proto_data = NULL; - return; - } - sg->conn = conn; - - /* Progress */ - if (params.detach_data) { - purple_connection_update_progress(gc, _("Resuming session"), 2, 5); - sg->resuming = TRUE; - } else { - purple_connection_update_progress(gc, _("Performing key exchange"), 2, 5); - } - - /* Perform SILC Key Exchange. The "silc_connected" will be called - eventually. */ - silc_client_start_key_exchange(sg->client, sg->conn, source); - - /* Set default attributes */ - mask = SILC_ATTRIBUTE_MOOD_NORMAL; - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_STATUS_MOOD, - SILC_32_TO_PTR(mask), - sizeof(SilcUInt32)); - mask = SILC_ATTRIBUTE_CONTACT_CHAT; - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_PREFERRED_CONTACT, - SILC_32_TO_PTR(mask), - sizeof(SilcUInt32)); -#ifdef HAVE_SYS_UTSNAME_H - if (!uname(&u)) { - SilcAttributeObjDevice dev; - memset(&dev, 0, sizeof(dev)); - dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER; - dev.version = u.release; - dev.model = u.sysname; - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_DEVICE_INFO, - (void *)&dev, sizeof(dev)); - } -#endif -#ifdef _WIN32 - tmp = _tzname[0]; -#else - tmp = tzname[0]; -#endif - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_TIMEZONE, - (void *)tmp, strlen(tmp)); - -#ifdef SILC_ATTRIBUTE_USER_ICON - /* Set our buddy icon */ - img = purple_buddy_icons_find_account_icon(account); - silcpurple_buddy_set_icon(gc, img); - purple_imgstore_unref(img); -#endif - - silc_free(params.detach_data); -} - -static void -silcpurple_login(PurpleAccount *account) -{ - SilcPurple sg; - SilcClient client; - SilcClientParams params; - PurpleConnection *gc; - char pkd[256], prd[256]; - const char *cipher, *hmac; - char *realname; - int i; - - gc = account->gc; - if (!gc) - return; - gc->proto_data = NULL; - - memset(¶ms, 0, sizeof(params)); - strcat(params.nickname_format, "%n@%h%a"); - params.nickname_parse = silcpurple_nickname_parse; - params.ignore_requested_attributes = FALSE; - - /* Allocate SILC client */ - client = silc_client_alloc(&ops, ¶ms, gc, NULL); - if (!client) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - _("Out of memory")); - return; - } - - /* Get username, real name and local hostname for SILC library */ - if (purple_account_get_username(account)) { - const char *u = purple_account_get_username(account); - char **up = g_strsplit(u, "@", 2); - client->username = strdup(up[0]); - g_strfreev(up); - } else { - client->username = silc_get_username(); - purple_account_set_username(account, client->username); - } - realname = silc_get_real_name(); - if (purple_account_get_user_info(account)) { - client->realname = strdup(purple_account_get_user_info(account)); - free(realname); - } else if ((silc_get_real_name() != NULL) && (*realname != '\0')) { - client->realname = realname; - purple_account_set_user_info(account, client->realname); - } else { - free(realname); - client->realname = strdup(_("John Noname")); - } - client->hostname = silc_net_localhost(); - - purple_connection_set_display_name(gc, client->username); - - /* Register requested cipher and HMAC */ - cipher = purple_account_get_string(account, "cipher", SILC_DEFAULT_CIPHER); - for (i = 0; silc_default_ciphers[i].name; i++) - if (!strcmp(silc_default_ciphers[i].name, cipher)) { - silc_cipher_register(&(silc_default_ciphers[i])); - break; - } - hmac = purple_account_get_string(account, "hmac", SILC_DEFAULT_HMAC); - for (i = 0; silc_default_hmacs[i].name; i++) - if (!strcmp(silc_default_hmacs[i].name, hmac)) { - silc_hmac_register(&(silc_default_hmacs[i])); - break; - } - - /* Init SILC client */ - if (!silc_client_init(client)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - _("Unable to initialize SILC protocol")); - return; - } - - /* Check the ~/.silc dir and create it, and new key pair if necessary. */ - if (!silcpurple_check_silc_dir(gc)) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - _("Error loading SILC key pair")); - return; - } - - /* Progress */ - purple_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5); - - /* Load SILC key pair */ - g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir()); - g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir()); - if (!silc_load_key_pair((char *)purple_account_get_string(account, "public-key", pkd), - (char *)purple_account_get_string(account, "private-key", prd), - (gc->password == NULL) ? "" : gc->password, &client->pkcs, - &client->public_key, &client->private_key)) { - g_snprintf(pkd, sizeof(pkd), _("Unable to load SILC key pair: %s"), g_strerror(errno)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, - pkd); - return; - } - - sg = silc_calloc(1, sizeof(*sg)); - if (!sg) - return; - memset(sg, 0, sizeof(*sg)); - sg->client = client; - sg->gc = gc; - sg->account = account; - gc->proto_data = sg; - - /* Connect to the SILC server */ - if (purple_proxy_connect(gc, account, - purple_account_get_string(account, "server", - "silc.silcnet.org"), - purple_account_get_int(account, "port", 706), - silcpurple_login_connected, gc) == NULL) - { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Unable to create connection")); - return; - } - - /* Schedule SILC using Glib's event loop */ - sg->scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, sg); -} - -static int -silcpurple_close_final(gpointer *context) -{ - SilcPurple sg = (SilcPurple)context; - silc_client_stop(sg->client); - silc_client_free(sg->client); -#ifdef HAVE_SILCMIME_H - if (sg->mimeass) - silc_mime_assembler_free(sg->mimeass); -#endif - silc_free(sg); - return 0; -} - -static void -silcpurple_close(PurpleConnection *gc) -{ - SilcPurple sg = gc->proto_data; - GHashTable *ui_info; - const char *ui_name = NULL, *ui_website = NULL; - char *quit_msg; - - g_return_if_fail(sg != NULL); - - ui_info = purple_core_get_ui_info(); - - if(ui_info) { - ui_name = g_hash_table_lookup(ui_info, "name"); - ui_website = g_hash_table_lookup(ui_info, "website"); - } - - if(!ui_name || !ui_website) { - ui_name = "Pidgin"; - ui_website = PURPLE_WEBSITE; - } - quit_msg = g_strdup_printf(_("Download %s: %s"), - ui_name, ui_website); - - /* Send QUIT */ - silc_client_command_call(sg->client, sg->conn, NULL, - "QUIT", quit_msg, NULL); - g_free(quit_msg); - - if (sg->conn) - silc_client_close_connection(sg->client, sg->conn); - - purple_timeout_remove(sg->scheduler); - purple_timeout_add(1, (GSourceFunc)silcpurple_close_final, sg); -} - - -/****************************** Protocol Actions *****************************/ - -static void -silcpurple_attrs_cancel(PurpleConnection *gc, PurpleRequestFields *fields) -{ - /* Nothing */ -} - -static void -silcpurple_attrs_cb(PurpleConnection *gc, PurpleRequestFields *fields) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - PurpleRequestField *f; - char *tmp; - SilcUInt32 tmp_len, mask; - SilcAttributeObjService service; - SilcAttributeObjDevice dev; - SilcVCardStruct vcard; - const char *val; - - sg = gc->proto_data; - if (!sg) - return; - - memset(&service, 0, sizeof(service)); - memset(&dev, 0, sizeof(dev)); - memset(&vcard, 0, sizeof(vcard)); - - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_USER_INFO, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_SERVICE, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_STATUS_MOOD, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_STATUS_FREETEXT, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_STATUS_MESSAGE, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_TIMEZONE, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_GEOLOCATION, NULL); - silc_client_attribute_del(client, conn, - SILC_ATTRIBUTE_DEVICE_INFO, NULL); - - /* Set mood */ - mask = 0; - f = purple_request_fields_get_field(fields, "mood_normal"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_NORMAL; - f = purple_request_fields_get_field(fields, "mood_happy"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_HAPPY; - f = purple_request_fields_get_field(fields, "mood_sad"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_SAD; - f = purple_request_fields_get_field(fields, "mood_angry"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_ANGRY; - f = purple_request_fields_get_field(fields, "mood_jealous"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_JEALOUS; - f = purple_request_fields_get_field(fields, "mood_ashamed"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_ASHAMED; - f = purple_request_fields_get_field(fields, "mood_invincible"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE; - f = purple_request_fields_get_field(fields, "mood_inlove"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_INLOVE; - f = purple_request_fields_get_field(fields, "mood_sleepy"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_SLEEPY; - f = purple_request_fields_get_field(fields, "mood_bored"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_BORED; - f = purple_request_fields_get_field(fields, "mood_excited"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_EXCITED; - f = purple_request_fields_get_field(fields, "mood_anxious"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS; - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_STATUS_MOOD, - SILC_32_TO_PTR(mask), - sizeof(SilcUInt32)); - - /* Set preferred contact */ - mask = 0; - f = purple_request_fields_get_field(fields, "contact_chat"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_CHAT; - f = purple_request_fields_get_field(fields, "contact_email"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_EMAIL; - f = purple_request_fields_get_field(fields, "contact_call"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_CALL; - f = purple_request_fields_get_field(fields, "contact_sms"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_SMS; - f = purple_request_fields_get_field(fields, "contact_mms"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_MMS; - f = purple_request_fields_get_field(fields, "contact_video"); - if (f && purple_request_field_bool_get_value(f)) - mask |= SILC_ATTRIBUTE_CONTACT_VIDEO; - if (mask) - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_PREFERRED_CONTACT, - SILC_32_TO_PTR(mask), - sizeof(SilcUInt32)); - - /* Set status text */ - val = NULL; - f = purple_request_fields_get_field(fields, "status_text"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_STATUS_FREETEXT, - (void *)val, strlen(val)); - - /* Set vcard */ - val = NULL; - f = purple_request_fields_get_field(fields, "vcard"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) { - purple_account_set_string(sg->account, "vcard", val); - tmp = silc_file_readfile(val, &tmp_len); - if (tmp) { - tmp[tmp_len] = 0; - if (silc_vcard_decode((unsigned char *)tmp, tmp_len, &vcard)) - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_USER_INFO, - (void *)&vcard, - sizeof(vcard)); - } - silc_vcard_free(&vcard); - silc_free(tmp); - } else { - purple_account_set_string(sg->account, "vcard", ""); - } - -#ifdef HAVE_SYS_UTSNAME_H - /* Set device info */ - f = purple_request_fields_get_field(fields, "device"); - if (f && purple_request_field_bool_get_value(f)) { - struct utsname u; - if (!uname(&u)) { - dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER; - dev.version = u.release; - dev.model = u.sysname; - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_DEVICE_INFO, - (void *)&dev, sizeof(dev)); - } - } -#endif - - /* Set timezone */ - val = NULL; - f = purple_request_fields_get_field(fields, "timezone"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) - silc_client_attribute_add(client, conn, - SILC_ATTRIBUTE_TIMEZONE, - (void *)val, strlen(val)); -} - -static void -silcpurple_attrs(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - PurpleRequestFields *fields; - PurpleRequestFieldGroup *g; - PurpleRequestField *f; - SilcHashTable attrs; - SilcAttributePayload attr; - gboolean mnormal = TRUE, mhappy = FALSE, msad = FALSE, - mangry = FALSE, mjealous = FALSE, mashamed = FALSE, - minvincible = FALSE, minlove = FALSE, msleepy = FALSE, - mbored = FALSE, mexcited = FALSE, manxious = FALSE; - gboolean cemail = FALSE, ccall = FALSE, csms = FALSE, - cmms = FALSE, cchat = TRUE, cvideo = FALSE; - gboolean device = TRUE; - char status[1024]; - - sg = gc->proto_data; - if (!sg) - return; - - memset(status, 0, sizeof(status)); - - attrs = silc_client_attributes_get(client, conn); - if (attrs) { - if (silc_hash_table_find(attrs, - SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_MOOD), - NULL, (void *)&attr)) { - SilcUInt32 mood = 0; - silc_attribute_get_object(attr, &mood, sizeof(mood)); - mnormal = !mood; - mhappy = (mood & SILC_ATTRIBUTE_MOOD_HAPPY); - msad = (mood & SILC_ATTRIBUTE_MOOD_SAD); - mangry = (mood & SILC_ATTRIBUTE_MOOD_ANGRY); - mjealous = (mood & SILC_ATTRIBUTE_MOOD_JEALOUS); - mashamed = (mood & SILC_ATTRIBUTE_MOOD_ASHAMED); - minvincible = (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE); - minlove = (mood & SILC_ATTRIBUTE_MOOD_INLOVE); - msleepy = (mood & SILC_ATTRIBUTE_MOOD_SLEEPY); - mbored = (mood & SILC_ATTRIBUTE_MOOD_BORED); - mexcited = (mood & SILC_ATTRIBUTE_MOOD_EXCITED); - manxious = (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS); - } - - if (silc_hash_table_find(attrs, - SILC_32_TO_PTR(SILC_ATTRIBUTE_PREFERRED_CONTACT), - NULL, (void *)&attr)) { - SilcUInt32 contact = 0; - silc_attribute_get_object(attr, &contact, sizeof(contact)); - cemail = (contact & SILC_ATTRIBUTE_CONTACT_EMAIL); - ccall = (contact & SILC_ATTRIBUTE_CONTACT_CALL); - csms = (contact & SILC_ATTRIBUTE_CONTACT_SMS); - cmms = (contact & SILC_ATTRIBUTE_CONTACT_MMS); - cchat = (contact & SILC_ATTRIBUTE_CONTACT_CHAT); - cvideo = (contact & SILC_ATTRIBUTE_CONTACT_VIDEO); - } - - if (silc_hash_table_find(attrs, - SILC_32_TO_PTR(SILC_ATTRIBUTE_STATUS_FREETEXT), - NULL, (void *)&attr)) - silc_attribute_get_object(attr, &status, sizeof(status)); - - if (!silc_hash_table_find(attrs, - SILC_32_TO_PTR(SILC_ATTRIBUTE_DEVICE_INFO), - NULL, (void *)&attr)) - device = FALSE; - } - - fields = purple_request_fields_new(); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_label_new("l3", _("Your Current Mood")); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_normal", _("Normal"), mnormal); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_happy", _("Happy"), mhappy); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_sad", _("Sad"), msad); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_angry", _("Angry"), mangry); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_jealous", _("Jealous"), mjealous); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_ashamed", _("Ashamed"), mashamed); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_invincible", _("Invincible"), minvincible); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_inlove", _("In love"), minlove); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_sleepy", _("Sleepy"), msleepy); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_bored", _("Bored"), mbored); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_excited", _("Excited"), mexcited); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("mood_anxious", _("Anxious"), manxious); - purple_request_field_group_add_field(g, f); - - f = purple_request_field_label_new("l4", _("\nYour Preferred Contact Methods")); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_chat", _("Chat"), cchat); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_email", _("Email"), cemail); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_call", _("Phone"), ccall); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_sms", _("SMS"), csms); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_mms", _("MMS"), cmms); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("contact_video", _("Video conferencing"), cvideo); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("status_text", _("Your Current Status"), - status[0] ? status : NULL, TRUE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); -#if 0 - f = purple_request_field_label_new("l2", _("Online Services")); - purple_request_field_group_add_field(g, f); - f = purple_request_field_bool_new("services", - _("Let others see what services you are using"), - TRUE); - purple_request_field_group_add_field(g, f); -#endif -#ifdef HAVE_SYS_UTSNAME_H - f = purple_request_field_bool_new("device", - _("Let others see what computer you are using"), - device); - purple_request_field_group_add_field(g, f); -#endif - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("vcard", _("Your VCard File"), - purple_account_get_string(sg->account, "vcard", ""), - FALSE); - purple_request_field_group_add_field(g, f); -#ifdef _WIN32 - f = purple_request_field_string_new("timezone", _("Timezone"), _tzname[0], FALSE); -#else - f = purple_request_field_string_new("timezone", _("Timezone"), tzname[0], FALSE); -#endif - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - purple_request_fields(gc, _("User Online Status Attributes"), - _("User Online Status Attributes"), - _("You can let other users see your online status information " - "and your personal information. Please fill the information " - "you would like other users to see about yourself."), - fields, - _("OK"), G_CALLBACK(silcpurple_attrs_cb), - _("Cancel"), G_CALLBACK(silcpurple_attrs_cancel), - gc->account, NULL, NULL, gc); -} - -static void -silcpurple_detach(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - SilcPurple sg; - - if (!gc) - return; - sg = gc->proto_data; - if (!sg) - return; - - /* Call DETACH */ - silc_client_command_call(sg->client, sg->conn, "DETACH"); - sg->detaching = TRUE; -} - -static void -silcpurple_view_motd(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - SilcPurple sg; - char *tmp; - - if (!gc) - return; - sg = gc->proto_data; - if (!sg) - return; - - if (!sg->motd) { - purple_notify_error( - gc, _("Message of the Day"), _("No Message of the Day available"), - _("There is no Message of the Day associated with this connection")); - return; - } - - tmp = g_markup_escape_text(sg->motd, -1); - purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL, - tmp, NULL, NULL); - g_free(tmp); -} - -static void -silcpurple_create_keypair_cancel(PurpleConnection *gc, PurpleRequestFields *fields) -{ - /* Nothing */ -} - -static void -silcpurple_create_keypair_cb(PurpleConnection *gc, PurpleRequestFields *fields) -{ - SilcPurple sg = gc->proto_data; - PurpleRequestField *f; - const char *val, *pkfile = NULL, *prfile = NULL; - const char *pass1 = NULL, *pass2 = NULL, *un = NULL, *hn = NULL; - const char *rn = NULL, *e = NULL, *o = NULL, *c = NULL; - char *identifier; - int keylen = SILCPURPLE_DEF_PKCS_LEN; - SilcPublicKey public_key; - - sg = gc->proto_data; - if (!sg) - return; - - val = NULL; - f = purple_request_fields_get_field(fields, "pass1"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) - pass1 = val; - else - pass1 = ""; - val = NULL; - f = purple_request_fields_get_field(fields, "pass2"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) - pass2 = val; - else - pass2 = ""; - - if (strcmp(pass1, pass2)) { - purple_notify_error( - gc, _("Create New SILC Key Pair"), _("Passphrases do not match"), NULL); - return; - } - - val = NULL; - f = purple_request_fields_get_field(fields, "key"); - if (f) - val = purple_request_field_string_get_value(f); - if (val && *val) - keylen = atoi(val); - f = purple_request_fields_get_field(fields, "pkfile"); - if (f) - pkfile = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "prfile"); - if (f) - prfile = purple_request_field_string_get_value(f); - - f = purple_request_fields_get_field(fields, "un"); - if (f) - un = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "hn"); - if (f) - hn = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "rn"); - if (f) - rn = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "e"); - if (f) - e = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "o"); - if (f) - o = purple_request_field_string_get_value(f); - f = purple_request_fields_get_field(fields, "c"); - if (f) - c = purple_request_field_string_get_value(f); - - identifier = silc_pkcs_encode_identifier((char *)un, (char *)hn, - (char *)rn, (char *)e, (char *)o, (char *)c); - - /* Create the key pair */ - if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, keylen, pkfile, prfile, - identifier, pass1, NULL, &public_key, NULL, - FALSE)) { - purple_notify_error( - gc, _("Create New SILC Key Pair"), _("Key Pair Generation failed"), NULL); - return; - } - - silcpurple_show_public_key(sg, NULL, public_key, NULL, NULL); - - silc_pkcs_public_key_free(public_key); - silc_free(identifier); -} - -static void -silcpurple_create_keypair(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - SilcPurple sg = gc->proto_data; - PurpleRequestFields *fields; - PurpleRequestFieldGroup *g; - PurpleRequestField *f; - const char *username, *realname; - char *hostname, **u; - char tmp[256], pkd[256], pkd2[256], prd[256], prd2[256]; - - username = purple_account_get_username(sg->account); - u = g_strsplit(username, "@", 2); - username = u[0]; - realname = purple_account_get_user_info(sg->account); - hostname = silc_net_localhost(); - g_snprintf(tmp, sizeof(tmp), "%s@%s", username, hostname); - - g_snprintf(pkd2, sizeof(pkd2), "%s" G_DIR_SEPARATOR_S"public_key.pub", silcpurple_silcdir()); - g_snprintf(prd2, sizeof(prd2), "%s" G_DIR_SEPARATOR_S"private_key.prv", silcpurple_silcdir()); - g_snprintf(pkd, sizeof(pkd) - 1, "%s", - purple_account_get_string(gc->account, "public-key", pkd2)); - g_snprintf(prd, sizeof(prd) - 1, "%s", - purple_account_get_string(gc->account, "private-key", prd2)); - - fields = purple_request_fields_new(); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("key", _("Key length"), "2048", FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("pkfile", _("Public key file"), pkd, FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("prfile", _("Private key file"), prd, FALSE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("un", _("Username"), username ? username : "", FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("hn", _("Hostname"), hostname ? hostname : "", FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("rn", _("Real name"), realname ? realname : "", FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("e", _("Email"), tmp, FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("o", _("Organization"), "", FALSE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("c", _("Country"), "", FALSE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - g = purple_request_field_group_new(NULL); - f = purple_request_field_string_new("pass1", _("Passphrase"), "", FALSE); - purple_request_field_string_set_masked(f, TRUE); - purple_request_field_group_add_field(g, f); - f = purple_request_field_string_new("pass2", _("Passphrase (retype)"), "", FALSE); - purple_request_field_string_set_masked(f, TRUE); - purple_request_field_group_add_field(g, f); - purple_request_fields_add_group(fields, g); - - purple_request_fields(gc, _("Create New SILC Key Pair"), - _("Create New SILC Key Pair"), NULL, fields, - _("Generate Key Pair"), G_CALLBACK(silcpurple_create_keypair_cb), - _("Cancel"), G_CALLBACK(silcpurple_create_keypair_cancel), - gc->account, NULL, NULL, gc); - - g_strfreev(u); - silc_free(hostname); -} - -static void -silcpurple_change_pass(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - purple_account_request_change_password(purple_connection_get_account(gc)); -} - -static void -silcpurple_change_passwd(PurpleConnection *gc, const char *old, const char *new) -{ - char prd[256]; - g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.pub", silcpurple_silcdir()); - silc_change_private_key_passphrase(purple_account_get_string(gc->account, - "private-key", - prd), old ? old : "", new ? new : ""); -} - -static void -silcpurple_show_set_info(PurplePluginAction *action) -{ - PurpleConnection *gc = (PurpleConnection *) action->context; - purple_account_request_change_user_info(purple_connection_get_account(gc)); -} - -static void -silcpurple_set_info(PurpleConnection *gc, const char *text) -{ -} - -static GList * -silcpurple_actions(PurplePlugin *plugin, gpointer context) -{ - GList *list = NULL; - PurplePluginAction *act; - - act = purple_plugin_action_new(_("Online Status"), - silcpurple_attrs); - list = g_list_append(list, act); - - act = purple_plugin_action_new(_("Detach From Server"), - silcpurple_detach); - list = g_list_append(list, act); - - act = purple_plugin_action_new(_("View Message of the Day"), - silcpurple_view_motd); - list = g_list_append(list, act); - - act = purple_plugin_action_new(_("Create SILC Key Pair..."), - silcpurple_create_keypair); - list = g_list_append(list, act); - - act = purple_plugin_action_new(_("Change Password..."), - silcpurple_change_pass); - list = g_list_append(list, act); - - act = purple_plugin_action_new(_("Set User Info..."), - silcpurple_show_set_info); - list = g_list_append(list, act); - - return list; -} - - -/******************************* IM Routines *********************************/ - -typedef struct { - char *nick; - char *message; - SilcUInt32 message_len; - SilcMessageFlags flags; - PurpleMessageFlags gflags; -} *SilcPurpleIM; - -static void -silcpurple_send_im_resolved(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context) -{ - PurpleConnection *gc = client->application; - SilcPurple sg = gc->proto_data; - SilcPurpleIM im = context; - PurpleConversation *convo; - char tmp[256], *nickname = NULL; - SilcClientEntry client_entry; -#ifdef HAVE_SILCMIME_H - SilcDList list; -#endif - - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->nick, - sg->account); - if (!convo) - return; - - if (!clients) - goto err; - - if (clients_count > 1) { - silc_parse_userfqdn(im->nick, &nickname, NULL); - - /* Find the correct one. The im->nick might be a formatted nick - so this will find the correct one. */ - clients = silc_client_get_clients_local(client, conn, - nickname, im->nick, - &clients_count); - if (!clients) - goto err; - client_entry = clients[0]; - silc_free(clients); - } else { - client_entry = clients[0]; - } - -#ifdef HAVE_SILCMIME_H - /* Check for images */ - if (im->gflags & PURPLE_MESSAGE_IMAGES) { - list = silcpurple_image_message(im->message, (SilcUInt32 *)&im->flags); - if (list) { - /* Send one or more MIME message. If more than one, they - are MIME fragments due to over large message */ - SilcBuffer buf; - - silc_dlist_start(list); - while ((buf = silc_dlist_get(list)) != SILC_LIST_END) - silc_client_send_private_message(client, conn, - client_entry, im->flags, - buf->data, buf->len, - TRUE); - silc_mime_partial_free(list); - purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname, - im->message, 0, time(NULL)); - goto out; - } - } -#endif - - /* Send the message */ - silc_client_send_private_message(client, conn, client_entry, im->flags, - (unsigned char *)im->message, im->message_len, TRUE); - purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname, - im->message, 0, time(NULL)); - goto out; - - err: - g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), im->nick); - purple_conversation_write(convo, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); - - out: - g_free(im->nick); - g_free(im->message); - silc_free(im); - silc_free(nickname); -} - -static int -silcpurple_send_im(PurpleConnection *gc, const char *who, const char *message, - PurpleMessageFlags flags) -{ - SilcPurple sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; - SilcClientEntry *clients; - SilcUInt32 clients_count, mflags; - char *nickname, *msg, *tmp; - int ret = 0; - gboolean sign = purple_account_get_bool(sg->account, "sign-verify", FALSE); -#ifdef HAVE_SILCMIME_H - SilcDList list; -#endif - - if (!who || !message) - return 0; - - mflags = SILC_MESSAGE_FLAG_UTF8; - - tmp = msg = purple_unescape_html(message); - - if (!g_ascii_strncasecmp(msg, "/me ", 4)) { - msg += 4; - if (!*msg) { - g_free(tmp); - return 0; - } - mflags |= SILC_MESSAGE_FLAG_ACTION; - } else if (strlen(msg) > 1 && msg[0] == '/') { - if (!silc_client_command_call(client, conn, msg + 1)) - purple_notify_error(gc, _("Call Command"), _("Cannot call command"), - _("Unknown command")); - g_free(tmp); - return 0; - } - - - if (!silc_parse_userfqdn(who, &nickname, NULL)) { - g_free(tmp); - return 0; - } - - if (sign) - mflags |= SILC_MESSAGE_FLAG_SIGNED; - - /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, who, - &clients_count); - if (!clients) { - /* Resolve unknown user */ - SilcPurpleIM im = silc_calloc(1, sizeof(*im)); - if (!im) { - g_free(tmp); - return 0; - } - im->nick = g_strdup(who); - im->message = g_strdup(message); - im->message_len = strlen(im->message); - im->flags = mflags; - im->gflags = flags; - silc_client_get_clients(client, conn, nickname, NULL, - silcpurple_send_im_resolved, im); - silc_free(nickname); - g_free(tmp); - return 0; - } - -#ifdef HAVE_SILCMIME_H - /* Check for images */ - if (flags & PURPLE_MESSAGE_IMAGES) { - list = silcpurple_image_message(message, &mflags); - if (list) { - /* Send one or more MIME message. If more than one, they - are MIME fragments due to over large message */ - SilcBuffer buf; - - silc_dlist_start(list); - while ((buf = silc_dlist_get(list)) != SILC_LIST_END) - ret = - silc_client_send_private_message(client, conn, - clients[0], mflags, - buf->data, buf->len, - TRUE); - silc_mime_partial_free(list); - g_free(tmp); - silc_free(nickname); - silc_free(clients); - return ret; - } - } -#endif - - /* Send private message directly */ - ret = silc_client_send_private_message(client, conn, clients[0], - mflags, - (unsigned char *)msg, - strlen(msg), TRUE); - - g_free(tmp); - silc_free(nickname); - silc_free(clients); - return ret; -} - - -static GList *silcpurple_blist_node_menu(PurpleBlistNode *node) { - /* split this single menu building function back into the two - original: one for buddies and one for chats */ - - if(PURPLE_BLIST_NODE_IS_CHAT(node)) { - return silcpurple_chat_menu((PurpleChat *) node); - } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { - return silcpurple_buddy_menu((PurpleBuddy *) node); - } else { - g_return_val_if_reached(NULL); - } -} - -/********************************* Commands **********************************/ - -static PurpleCmdRet silcpurple_cmd_chat_part(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - PurpleConversation *convo = conv; - int id = 0; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - if(args && args[0]) - convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], - gc->account); - - if (convo != NULL) - id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)); - - if (id == 0) - return PURPLE_CMD_RET_FAILED; - - silcpurple_chat_leave(gc, id); - - return PURPLE_CMD_RET_OK; - -} - -static PurpleCmdRet silcpurple_cmd_chat_topic(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - int id = 0; - char *buf, *tmp, *tmp2; - const char *topic; - - gc = purple_conversation_get_gc(conv); - id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)); - - if (gc == NULL || id == 0) - return PURPLE_CMD_RET_FAILED; - - if (!args || !args[0]) { - topic = purple_conv_chat_get_topic (PURPLE_CONV_CHAT(conv)); - if (topic) { - tmp = g_markup_escape_text(topic, -1); - tmp2 = purple_markup_linkify(tmp); - buf = g_strdup_printf(_("current topic is: %s"), tmp2); - g_free(tmp); - g_free(tmp2); - } else - buf = g_strdup(_("No topic is set")); - purple_conv_chat_write(PURPLE_CONV_CHAT(conv), gc->account->username, buf, - PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL)); - g_free(buf); - - } - - if (args && args[0] && (strlen(args[0]) > 255)) { - *error = g_strdup(_("Topic too long")); - return PURPLE_CMD_RET_FAILED; - } - - silcpurple_chat_set_topic(gc, id, args ? args[0] : NULL); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_chat_join(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - GHashTable *comp; - - if(!args || !args[0]) - return PURPLE_CMD_RET_FAILED; - - comp = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); - - g_hash_table_replace(comp, "channel", args[0]); - if(args[1]) - g_hash_table_replace(comp, "passphrase", args[1]); - - silcpurple_chat_join(purple_conversation_get_gc(conv), comp); - - g_hash_table_destroy(comp); - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_chat_list(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - gc = purple_conversation_get_gc(conv); - purple_roomlist_show_with_account(purple_connection_get_account(gc)); - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_whois(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - silcpurple_get_info(gc, args[0]); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_msg(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - int ret; - PurpleConnection *gc; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND); - - if (ret) - return PURPLE_CMD_RET_OK; - else - return PURPLE_CMD_RET_FAILED; -} - -static PurpleCmdRet silcpurple_cmd_query(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - int ret = 1; - PurpleConversation *convo; - PurpleConnection *gc; - PurpleAccount *account; - - if (!args || !args[0]) { - *error = g_strdup(_("You must specify a nick")); - return PURPLE_CMD_RET_FAILED; - } - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - account = purple_connection_get_account(gc); - - convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, args[0]); - - if (args[1]) { - ret = silcpurple_send_im(gc, args[0], args[1], PURPLE_MESSAGE_SEND); - purple_conv_im_write(PURPLE_CONV_IM(convo), purple_connection_get_display_name(gc), - args[1], PURPLE_MESSAGE_SEND, time(NULL)); - } - - if (ret) - return PURPLE_CMD_RET_OK; - else - return PURPLE_CMD_RET_FAILED; -} - -static PurpleCmdRet silcpurple_cmd_motd(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - char *tmp; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (sg == NULL) - return PURPLE_CMD_RET_FAILED; - - if (!sg->motd) { - *error = g_strdup(_("There is no Message of the Day associated with this connection")); - return PURPLE_CMD_RET_FAILED; - } - - tmp = g_markup_escape_text(sg->motd, -1); - purple_notify_formatted(gc, NULL, _("Message of the Day"), NULL, - tmp, NULL, NULL); - g_free(tmp); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_detach(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (sg == NULL) - return PURPLE_CMD_RET_FAILED; - - silc_client_command_call(sg->client, sg->conn, "DETACH"); - sg->detaching = TRUE; - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_cmode(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - SilcChannelEntry channel; - char *silccmd, *silcargs, *msg, tmp[256]; - const char *chname; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL || !args || gc->proto_data == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (args[0]) - chname = args[0]; - else - chname = purple_conversation_get_name(conv); - - if (!args[1]) { - channel = silc_client_get_channel(sg->client, sg->conn, - (char *)chname); - if (!channel) { - *error = g_strdup_printf(_("channel %s not found"), chname); - return PURPLE_CMD_RET_FAILED; - } - if (channel->mode) { - silcpurple_get_chmode_string(channel->mode, tmp, sizeof(tmp)); - msg = g_strdup_printf(_("channel modes for %s: %s"), chname, tmp); - } else { - msg = g_strdup_printf(_("no channel modes are set on %s"), chname); - } - purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "", - msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL)); - g_free(msg); - return PURPLE_CMD_RET_OK; - } - - silcargs = g_strjoinv(" ", args); - silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL); - g_free(silcargs); - if (!silc_client_command_call(sg->client, sg->conn, silccmd)) { - g_free(silccmd); - *error = g_strdup_printf(_("Failed to set cmodes for %s"), args[0]); - return PURPLE_CMD_RET_FAILED; - } - g_free(silccmd); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_generic(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - char *silccmd, *silcargs; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (sg == NULL) - return PURPLE_CMD_RET_FAILED; - - silcargs = g_strjoinv(" ", args); - silccmd = g_strconcat(cmd, " ", args ? silcargs : NULL, NULL); - g_free(silcargs); - if (!silc_client_command_call(sg->client, sg->conn, silccmd)) { - g_free(silccmd); - *error = g_strdup_printf(_("Unknown command: %s, (may be a client bug)"), cmd); - return PURPLE_CMD_RET_FAILED; - } - g_free(silccmd); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_quit(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - GHashTable *ui_info; - const char *ui_name = NULL, *ui_website = NULL; - char *quit_msg; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (sg == NULL) - return PURPLE_CMD_RET_FAILED; - - ui_info = purple_core_get_ui_info(); - - if(ui_info) { - ui_name = g_hash_table_lookup(ui_info, "name"); - ui_website = g_hash_table_lookup(ui_info, "website"); - } - - if(!ui_name || !ui_website) { - ui_name = "Pidgin"; - ui_website = PURPLE_WEBSITE; - } - quit_msg = g_strdup_printf(_("Download %s: %s"), - ui_name, ui_website); - - silc_client_command_call(sg->client, sg->conn, NULL, - "QUIT", (args && args[0]) ? args[0] : quit_msg, NULL); - g_free(quit_msg); - - return PURPLE_CMD_RET_OK; -} - -static PurpleCmdRet silcpurple_cmd_call(PurpleConversation *conv, - const char *cmd, char **args, char **error, void *data) -{ - PurpleConnection *gc; - SilcPurple sg; - - gc = purple_conversation_get_gc(conv); - - if (gc == NULL) - return PURPLE_CMD_RET_FAILED; - - sg = gc->proto_data; - - if (sg == NULL) - return PURPLE_CMD_RET_FAILED; - - if (!silc_client_command_call(sg->client, sg->conn, args[0])) { - *error = g_strdup_printf(_("Unknown command: %s"), args[0]); - return PURPLE_CMD_RET_FAILED; - } - - return PURPLE_CMD_RET_OK; -} - - -/************************** Plugin Initialization ****************************/ - -static void -silcpurple_register_commands(void) -{ - purple_cmd_register("part", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | - PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, - "prpl-silc", silcpurple_cmd_chat_part, _("part [channel]: Leave the chat"), NULL); - purple_cmd_register("leave", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | - PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, - "prpl-silc", silcpurple_cmd_chat_part, _("leave [channel]: Leave the chat"), NULL); - purple_cmd_register("topic", "s", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", - silcpurple_cmd_chat_topic, _("topic [<new topic>]: View or change the topic"), NULL); - purple_cmd_register("join", "ws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | - PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, - "prpl-silc", silcpurple_cmd_chat_join, - _("join <channel> [<password>]: Join a chat on this network"), NULL); - purple_cmd_register("list", "", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", - silcpurple_cmd_chat_list, _("list: List channels on this network"), NULL); - purple_cmd_register("whois", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", - silcpurple_cmd_whois, _("whois <nick>: View nick's information"), NULL); - purple_cmd_register("msg", "ws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_msg, - _("msg <nick> <message>: Send a private message to a user"), NULL); - purple_cmd_register("query", "ws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_query, - _("query <nick> [<message>]: Send a private message to a user"), NULL); - purple_cmd_register("motd", "", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_motd, - _("motd: View the server's Message Of The Day"), NULL); - purple_cmd_register("detach", "", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_detach, - _("detach: Detach this session"), NULL); - purple_cmd_register("quit", "s", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_quit, - _("quit [message]: Disconnect from the server, with an optional message"), NULL); - purple_cmd_register("call", "s", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_call, - _("call <command>: Call any silc client command"), NULL); - /* These below just get passed through for the silc client library to deal - * with */ - purple_cmd_register("kill", "ws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("kill <nick> [-pubkey|<reason>]: Kill nick"), NULL); - purple_cmd_register("nick", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("nick <newnick>: Change your nickname"), NULL); - purple_cmd_register("whowas", "ww", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("whowas <nick>: View nick's information"), NULL); - purple_cmd_register("cmode", "wws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_cmode, - _("cmode <channel> [+|-<modes>] [arguments]: Change or display channel modes"), NULL); - purple_cmd_register("cumode", "wws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("cumode <channel> +|-<modes> <nick>: Change nick's modes on channel"), NULL); - purple_cmd_register("umode", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("umode <usermodes>: Set your modes in the network"), NULL); - purple_cmd_register("oper", "s", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("oper <nick> [-pubkey]: Get server operator privileges"), NULL); - purple_cmd_register("invite", "ws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("invite <channel> [-|+]<nick>: invite nick or add/remove from channel invite list"), NULL); - purple_cmd_register("kick", "wws", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("kick <channel> <nick> [comment]: Kick client from channel"), NULL); - purple_cmd_register("info", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("info [server]: View server administrative details"), NULL); - purple_cmd_register("ban", "ww", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_generic, - _("ban [<channel> +|-<nick>]: Ban client from channel"), NULL); - purple_cmd_register("getkey", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("getkey <nick|server>: Retrieve client's or server's public key"), NULL); - purple_cmd_register("stats", "", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("stats: View server and network statistics"), NULL); - purple_cmd_register("ping", "", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_generic, - _("ping: Send PING to the connected server"), NULL); -#if 0 /* Purple doesn't handle these yet */ - purple_cmd_register("users", "w", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, - "prpl-silc", silcpurple_cmd_users, - _("users <channel>: List users in channel")); - purple_cmd_register("names", "ww", PURPLE_CMD_P_PRPL, - PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY | - PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-silc", silcpurple_cmd_names, - _("names [-count|-ops|-halfops|-voices|-normal] <channel(s)>: List specific users in channel(s)")); -#endif -} - -static PurpleWhiteboardPrplOps silcpurple_wb_ops = -{ - silcpurple_wb_start, - silcpurple_wb_end, - silcpurple_wb_get_dimensions, - silcpurple_wb_set_dimensions, - silcpurple_wb_get_brush, - silcpurple_wb_set_brush, - silcpurple_wb_send, - silcpurple_wb_clear, - - /* padding */ - NULL, - NULL, - NULL, - NULL -}; - -static PurplePluginProtocolInfo prpl_info = -{ -#ifdef HAVE_SILCMIME_H - OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | - OPT_PROTO_PASSWORD_OPTIONAL | OPT_PROTO_IM_IMAGE | - OPT_PROTO_SLASH_COMMANDS_NATIVE, -#else - OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | - OPT_PROTO_PASSWORD_OPTIONAL | - OPT_PROTO_SLASH_COMMANDS_NATIVE, -#endif - NULL, /* user_splits */ - NULL, /* protocol_options */ -#ifdef SILC_ATTRIBUTE_USER_ICON - {"jpeg,gif,png,bmp", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */ -#else - NO_BUDDY_ICONS, -#endif - silcpurple_list_icon, /* list_icon */ - NULL, /* list_emblems */ - silcpurple_status_text, /* status_text */ - silcpurple_tooltip_text, /* tooltip_text */ - silcpurple_away_states, /* away_states */ - silcpurple_blist_node_menu, /* blist_node_menu */ - silcpurple_chat_info, /* chat_info */ - silcpurple_chat_info_defaults,/* chat_info_defaults */ - silcpurple_login, /* login */ - silcpurple_close, /* close */ - silcpurple_send_im, /* send_im */ - silcpurple_set_info, /* set_info */ - NULL, /* send_typing */ - silcpurple_get_info, /* get_info */ - silcpurple_set_status, /* set_status */ - silcpurple_idle_set, /* set_idle */ - silcpurple_change_passwd, /* change_passwd */ - silcpurple_add_buddy, /* add_buddy */ - NULL, /* add_buddies */ - silcpurple_remove_buddy, /* remove_buddy */ - NULL, /* remove_buddies */ - NULL, /* add_permit */ - NULL, /* add_deny */ - NULL, /* rem_permit */ - NULL, /* rem_deny */ - NULL, /* set_permit_deny */ - silcpurple_chat_join, /* join_chat */ - NULL, /* reject_chat */ - silcpurple_get_chat_name, /* get_chat_name */ - silcpurple_chat_invite, /* chat_invite */ - silcpurple_chat_leave, /* chat_leave */ - NULL, /* chat_whisper */ - silcpurple_chat_send, /* chat_send */ - silcpurple_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 */ - NULL, /* normalize */ -#ifdef SILC_ATTRIBUTE_USER_ICON - silcpurple_buddy_set_icon, /* set_buddy_icon */ -#else - NULL, -#endif - NULL, /* remove_group */ - NULL, /* get_cb_real_name */ - silcpurple_chat_set_topic, /* set_chat_topic */ - NULL, /* find_blist_chat */ - silcpurple_roomlist_get_list, /* roomlist_get_list */ - silcpurple_roomlist_cancel, /* roomlist_cancel */ - NULL, /* roomlist_expand_category */ - NULL, /* can_receive_file */ - silcpurple_ftp_send_file, /* send_file */ - silcpurple_ftp_new_xfer, /* new_xfer */ - NULL, /* offline_message */ - &silcpurple_wb_ops, /* whiteboard_prpl_ops */ - NULL, /* send_raw */ - NULL, /* roomlist_room_serialize */ - NULL, /* unregister_user */ - NULL, /* send_attention */ - NULL, /* get_attention_types */ - sizeof(PurplePluginProtocolInfo), /* struct_size */ - NULL, /* get_account_text_table */ - NULL, /* initiate_media */ - NULL, /* get_media_caps */ - NULL, /* get_moods */ - NULL, /* set_public_alias */ - NULL, /* get_public_alias */ - NULL, /* add_buddy_with_invite */ - NULL /* add_buddies_with_invite */ -}; - -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-silc", /**< id */ - "SILC", /**< name */ - "1.0", /**< version */ - /** summary */ - N_("SILC Protocol Plugin"), - /** description */ - N_("Secure Internet Live Conferencing (SILC) Protocol"), - "Pekka Riikonen", /**< author */ - "http://silcnet.org/", /**< homepage */ - - NULL, /**< load */ - NULL, /**< unload */ - NULL, /**< destroy */ - - NULL, /**< ui_info */ - &prpl_info, /**< extra_info */ - NULL, /**< prefs_info */ - silcpurple_actions, - - /* padding */ - NULL, - NULL, - NULL, - NULL -}; - -static void -init_plugin(PurplePlugin *plugin) -{ - PurpleAccountOption *option; - PurpleAccountUserSplit *split; - char tmp[256]; - int i; - PurpleKeyValuePair *kvp; - GList *list = NULL; - - silc_plugin = plugin; - - split = purple_account_user_split_new(_("Network"), "silcnet.org", '@'); - prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); - - /* Account options */ - option = purple_account_option_string_new(_("Connect server"), - "server", - "silc.silcnet.org"); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_int_new(_("Port"), "port", 706); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir()); - option = purple_account_option_string_new(_("Public Key file"), - "public-key", tmp); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir()); - option = purple_account_option_string_new(_("Private Key file"), - "private-key", tmp); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - - for (i = 0; silc_default_ciphers[i].name; i++) { - kvp = g_new0(PurpleKeyValuePair, 1); - kvp->key = g_strdup(silc_default_ciphers[i].name); - kvp->value = g_strdup(silc_default_ciphers[i].name); - list = g_list_append(list, kvp); - } - option = purple_account_option_list_new(_("Cipher"), "cipher", list); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - - list = NULL; - for (i = 0; silc_default_hmacs[i].name; i++) { - kvp = g_new0(PurpleKeyValuePair, 1); - kvp->key = g_strdup(silc_default_hmacs[i].name); - kvp->value = g_strdup(silc_default_hmacs[i].name); - list = g_list_append(list, kvp); - } - option = purple_account_option_list_new(_("HMAC"), "hmac", list); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - - option = purple_account_option_bool_new(_("Public key authentication"), - "pubkey-auth", FALSE); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_bool_new(_("Block IMs without Key Exchange"), - "block-ims", FALSE); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_bool_new(_("Block messages to whiteboard"), - "block-wb", FALSE); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_bool_new(_("Automatically open whiteboard"), - "open-wb", FALSE); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_bool_new(_("Digitally sign and verify all messages"), - "sign-verify", FALSE); - prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - - purple_prefs_remove("/plugins/prpl/silc"); - - silcpurple_register_commands(); - -#ifdef _WIN32 - silc_net_win32_init(); -#endif -} - -PURPLE_INIT_PLUGIN(silc10, init_plugin, info); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/silcpurple.h --- a/libpurple/protocols/silc10/silcpurple.h Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - - silcpurple.h - - Author: Pekka Riikonen - - Copyright (C) 2004 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#ifndef SILCPURPLE_H -#define SILCPURPLE_H - -/* Purple includes */ -#include "internal.h" -#include "account.h" -#include "accountopt.h" -#include "cmds.h" -#include "conversation.h" -#include "debug.h" -#include "ft.h" -#include "notify.h" -#include "prpl.h" -#include "request.h" -#include "roomlist.h" -#include "server.h" -#include "util.h" - -/* Default public and private key file names */ -#define SILCPURPLE_PUBLIC_KEY_NAME "public_key.pub" -#define SILCPURPLE_PRIVATE_KEY_NAME "private_key.prv" - -/* Default settings for creating key pair */ -#define SILCPURPLE_DEF_PKCS "rsa" -#define SILCPURPLE_DEF_PKCS_LEN 2048 - -#define SILCPURPLE_PRVGRP 0x001fffff - -/* Status IDs */ -#define SILCPURPLE_STATUS_ID_OFFLINE "offline" -#define SILCPURPLE_STATUS_ID_AVAILABLE "available" -#define SILCPURPLE_STATUS_ID_HYPER "hyper" -#define SILCPURPLE_STATUS_ID_AWAY "away" -#define SILCPURPLE_STATUS_ID_BUSY "busy" -#define SILCPURPLE_STATUS_ID_INDISPOSED "indisposed" -#define SILCPURPLE_STATUS_ID_PAGE "page" - -typedef struct { - unsigned long id; - const char *channel; - unsigned long chid; - const char *parentch; - SilcChannelPrivateKey key; -} *SilcPurplePrvgrp; - -/* The SILC Purple plugin context */ -typedef struct SilcPurpleStruct { - SilcClient client; - SilcClientConnection conn; - - guint scheduler; - PurpleConnection *gc; - PurpleAccount *account; - unsigned long channel_ids; - GList *grps; - - char *motd; - PurpleRoomlist *roomlist; -#ifdef HAVE_SILCMIME_H - SilcMimeAssembler mimeass; -#endif - unsigned int detaching : 1; - unsigned int resuming : 1; - unsigned int roomlist_cancelled : 1; - unsigned int chpk : 1; -} *SilcPurple; - - -gboolean silcpurple_check_silc_dir(PurpleConnection *gc); -void silcpurple_chat_join_done(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context); -const char *silcpurple_silcdir(void); -const char *silcpurple_session_file(const char *account); -void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn, - const char *name, SilcSocketType conn_type, - unsigned char *pk, SilcUInt32 pk_len, - SilcSKEPKType pk_type, - SilcVerifyPublicKey completion, void *context); -GList *silcpurple_buddy_menu(PurpleBuddy *buddy); -void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group); -void silcpurple_send_buddylist(PurpleConnection *gc); -void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group); -void silcpurple_buddy_keyagr_request(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - const char *hostname, SilcUInt16 port); -void silcpurple_idle_set(PurpleConnection *gc, int idle); -void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full); -char *silcpurple_status_text(PurpleBuddy *b); -gboolean silcpurple_ip_is_private(const char *ip); -void silcpurple_ftp_send_file(PurpleConnection *gc, const char *name, const char *file); -PurpleXfer *silcpurple_ftp_new_xfer(PurpleConnection *gc, const char *name); -void silcpurple_ftp_request(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, SilcUInt32 session_id, - const char *hostname, SilcUInt16 port); -void silcpurple_show_public_key(SilcPurple sg, - const char *name, SilcPublicKey public_key, - GCallback callback, void *context); -void silcpurple_get_info(PurpleConnection *gc, const char *who); -SilcAttributePayload -silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute); -void silcpurple_get_umode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size); -void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size); -void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size); -GList *silcpurple_chat_info(PurpleConnection *gc); -GHashTable *silcpurple_chat_info_defaults(PurpleConnection *gc, const char *chat_name); -GList *silcpurple_chat_menu(PurpleChat *); -void silcpurple_chat_join(PurpleConnection *gc, GHashTable *data); -char *silcpurple_get_chat_name(GHashTable *data); -void silcpurple_chat_invite(PurpleConnection *gc, int id, const char *msg, - const char *name); -void silcpurple_chat_leave(PurpleConnection *gc, int id); -int silcpurple_chat_send(PurpleConnection *gc, int id, const char *msg, PurpleMessageFlags flags); -void silcpurple_chat_set_topic(PurpleConnection *gc, int id, const char *topic); -PurpleRoomlist *silcpurple_roomlist_get_list(PurpleConnection *gc); -void silcpurple_roomlist_cancel(PurpleRoomlist *list); -void silcpurple_chat_chauth_show(SilcPurple sg, SilcChannelEntry channel, - SilcBuffer channel_pubkeys); -void silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr, - char **contactstr, char **langstr, char **devicestr, - char **tzstr, char **geostr); -#ifdef SILC_ATTRIBUTE_USER_ICON -void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img); -#endif -#ifdef HAVE_SILCMIME_H -char *silcpurple_file2mime(const char *filename); -SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags); -#endif - -#ifdef _WIN32 -typedef int uid_t; - -struct passwd { - char *pw_name; /* user name */ - char *pw_passwd; /* user password */ - int pw_uid; /* user id */ - int pw_gid; /* group id */ - char *pw_gecos; /* real name */ - char *pw_dir; /* home directory */ - char *pw_shell; /* shell program */ -}; - -struct passwd *getpwuid(int uid); -int getuid(void); -int geteuid(void); -#endif - -#endif /* SILCPURPLE_H */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/util.c --- a/libpurple/protocols/silc10/util.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,776 +0,0 @@ -/* - - silcpurple_util.c - - Author: Pekka Riikonen - - Copyright (C) 2004 - 2005 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "imgstore.h" - -/**************************** Utility Routines *******************************/ - -static char str[256], str2[256]; - -const char *silcpurple_silcdir(void) -{ - const char *hd = purple_home_dir(); - memset(str, 0, sizeof(str)); - g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp"); - return (const char *)str; -} - -const char *silcpurple_session_file(const char *account) -{ - memset(str2, 0, sizeof(str2)); - g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session", - silcpurple_silcdir(), account); - return (const char *)str2; -} - -gboolean silcpurple_ip_is_private(const char *ip) -{ - if (silc_net_is_ip4(ip)) { - if (!strncmp(ip, "10.", 3)) { - return TRUE; - } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) { - char tmp[3]; - int s; - memset(tmp, 0, sizeof(tmp)); - strncpy(tmp, ip + 4, 2); - s = atoi(tmp); - if (s >= 16 && s <= 31) - return TRUE; - } else if (!strncmp(ip, "192.168.", 8)) { - return TRUE; - } - } - - return FALSE; -} - -/* This checks stats for various SILC files and directories. First it - checks if ~/.silc directory exist and is owned by the correct user. If - it doesn't exist, it will create the directory. After that it checks if - user's Public and Private key files exists and creates them if needed. */ - -gboolean silcpurple_check_silc_dir(PurpleConnection *gc) -{ - char filename[256], file_public_key[256], file_private_key[256]; - char servfilename[256], clientfilename[256], friendsfilename[256]; - char pkd[256], prd[256]; - struct stat st; - struct passwd *pw; - int fd; - - pw = getpwuid(getuid()); - if (!pw) { - purple_debug_error("silc", "silc: %s\n", g_strerror(errno)); - return FALSE; - } - - g_snprintf(filename, sizeof(filename) - 1, "%s", silcpurple_silcdir()); - g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys", - silcpurple_silcdir()); - g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys", - silcpurple_silcdir()); - g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends", - silcpurple_silcdir()); - - /* - * Check ~/.silc directory - */ - if ((g_stat(filename, &st)) == -1) { - /* If dir doesn't exist */ - if (errno == ENOENT) { - if (pw->pw_uid == geteuid()) { - if ((g_mkdir(filename, 0755)) == -1) { - purple_debug_error("silc", "Couldn't create '%s' directory\n", filename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", - filename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, g_strerror(errno)); - return FALSE; - } - } else { -#ifndef _WIN32 - /* Check the owner of the dir */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { - purple_debug_error("silc", "You don't seem to own '%s' directory\n", - filename); - return FALSE; - } -#endif - } - - /* - * Check ~./silc/serverkeys directory - */ - if ((g_stat(servfilename, &st)) == -1) { - /* If dir doesn't exist */ - if (errno == ENOENT) { - if (pw->pw_uid == geteuid()) { - if ((g_mkdir(servfilename, 0755)) == -1) { - purple_debug_error("silc", "Couldn't create '%s' directory\n", servfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", - servfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", - servfilename, g_strerror(errno)); - return FALSE; - } - } - - /* - * Check ~./silc/clientkeys directory - */ - if ((g_stat(clientfilename, &st)) == -1) { - /* If dir doesn't exist */ - if (errno == ENOENT) { - if (pw->pw_uid == geteuid()) { - if ((g_mkdir(clientfilename, 0755)) == -1) { - purple_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", - clientfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", - clientfilename, g_strerror(errno)); - return FALSE; - } - } - - /* - * Check ~./silc/friends directory - */ - if ((g_stat(friendsfilename, &st)) == -1) { - /* If dir doesn't exist */ - if (errno == ENOENT) { - if (pw->pw_uid == geteuid()) { - if ((g_mkdir(friendsfilename, 0755)) == -1) { - purple_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", - friendsfilename); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", - friendsfilename, g_strerror(errno)); - return FALSE; - } - } - - /* - * Check Public and Private keys - */ - g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir()); - g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir()); - g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s", - purple_account_get_string(gc->account, "public-key", pkd)); - g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s", - purple_account_get_string(gc->account, "private-key", prd)); - - if ((g_stat(file_public_key, &st)) == -1) { - /* If file doesn't exist */ - if (errno == ENOENT) { - purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); - if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, - SILCPURPLE_DEF_PKCS_LEN, - file_public_key, file_private_key, NULL, - (gc->password == NULL) ? "" : gc->password, - NULL, NULL, NULL, FALSE)) { - purple_debug_error("silc", "Couldn't create key pair\n"); - return FALSE; - } - - if ((g_stat(file_public_key, &st)) == -1) { - purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", - file_public_key, g_strerror(errno)); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", - file_public_key, g_strerror(errno)); - return FALSE; - } - } - -#ifndef _WIN32 - /* Check the owner of the public key */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { - purple_debug_error("silc", "You don't seem to own your public key!?\n"); - return FALSE; - } -#endif - - if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) { - if ((fstat(fd, &st)) == -1) { - purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", - file_private_key, g_strerror(errno)); - close(fd); - return FALSE; - } - } else if ((g_stat(file_private_key, &st)) == -1) { - /* If file doesn't exist */ - if (errno == ENOENT) { - purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); - if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS, - SILCPURPLE_DEF_PKCS_LEN, - file_public_key, file_private_key, NULL, - (gc->password == NULL) ? "" : gc->password, - NULL, NULL, NULL, FALSE)) { - purple_debug_error("silc", "Couldn't create key pair\n"); - return FALSE; - } - - if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) { - if ((fstat(fd, &st)) == -1) { - purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", - file_private_key, g_strerror(errno)); - close(fd); - return FALSE; - } - } - /* This shouldn't really happen because silc_create_key_pair() - * will set the permissions */ - else if ((g_stat(file_private_key, &st)) == -1) { - purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", - file_private_key, g_strerror(errno)); - return FALSE; - } - } else { - purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", - file_private_key, g_strerror(errno)); - return FALSE; - } - } - -#ifndef _WIN32 - /* Check the owner of the private key */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { - purple_debug_error("silc", "You don't seem to own your private key!?\n"); - if (fd != -1) - close(fd); - return FALSE; - } - - /* Check the permissions for the private key */ - if ((st.st_mode & 0777) != 0600) { - purple_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n" - "Trying to change them ...\n", file_private_key); - if ((fd == -1) || (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) { - purple_debug_error("silc", - "Failed to change permissions for private key file!\n" - "Permissions for your private key file must be 0600.\n"); - if (fd != -1) - close(fd); - return FALSE; - } - purple_debug_warning("silc", "Done.\n\n"); - } -#endif - - if (fd != -1) - close(fd); - - return TRUE; -} - -#ifdef _WIN32 -struct passwd *getpwuid(uid_t uid) { - struct passwd *pwd = calloc(1, sizeof(struct passwd)); - return pwd; -} - -uid_t getuid() { - return 0; -} - -uid_t geteuid() { - return 0; -} -#endif - -void silcpurple_show_public_key(SilcPurple sg, - const char *name, SilcPublicKey public_key, - GCallback callback, void *context) -{ - SilcPublicKeyIdentifier ident; - SilcPKCS pkcs; - char *fingerprint, *babbleprint; - unsigned char *pk; - SilcUInt32 pk_len, key_len = 0; - GString *s; - char *buf; - - ident = silc_pkcs_decode_identifier(public_key->identifier); - if (!ident) - return; - - pk = silc_pkcs_public_key_encode(public_key, &pk_len); - fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); - babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); - - if (silc_pkcs_alloc((unsigned char *)public_key->name, &pkcs)) { - key_len = silc_pkcs_public_key_set(pkcs, public_key); - silc_pkcs_free(pkcs); - } - - s = g_string_new(""); - if (ident->realname) - /* Hint for translators: Please check the tabulator width here and in - the next strings (short strings: 2 tabs, longer strings 1 tab, - sum: 3 tabs or 24 characters) */ - g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname); - if (ident->username) - g_string_append_printf(s, _("User Name: \t%s\n"), ident->username); - if (ident->email) - g_string_append_printf(s, _("Email: \t\t%s\n"), ident->email); - if (ident->host) - g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host); - if (ident->org) - g_string_append_printf(s, _("Organization: \t%s\n"), ident->org); - if (ident->country) - g_string_append_printf(s, _("Country: \t%s\n"), ident->country); - g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name); - g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len); - g_string_append_printf(s, "\n"); - g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint); - g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint); - - buf = g_string_free(s, FALSE); - - purple_request_action(sg->gc, _("Public Key Information"), - _("Public Key Information"), - buf, 0, purple_connection_get_account(sg->gc), - NULL, NULL, context, 1, _("Close"), callback); - - g_free(buf); - silc_free(fingerprint); - silc_free(babbleprint); - silc_free(pk); - silc_pkcs_free_identifier(ident); -} - -SilcAttributePayload -silcpurple_get_attr(SilcDList attrs, SilcAttribute attribute) -{ - SilcAttributePayload attr = NULL; - - if (!attrs) - return NULL; - - silc_dlist_start(attrs); - while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) - if (attribute == silc_attribute_get_attribute(attr)) - break; - - return attr; -} - -void silcpurple_get_umode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size) -{ - memset(buf, 0, buf_size); - if ((mode & SILC_UMODE_SERVER_OPERATOR) || - (mode & SILC_UMODE_ROUTER_OPERATOR)) { - strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ? - "[server operator] " : - (mode & SILC_UMODE_ROUTER_OPERATOR) ? - "[SILC operator] " : "[unknown mode] "); - } - if (mode & SILC_UMODE_GONE) - strcat(buf, "[away] "); - if (mode & SILC_UMODE_INDISPOSED) - strcat(buf, "[indisposed] "); - if (mode & SILC_UMODE_BUSY) - strcat(buf, "[busy] "); - if (mode & SILC_UMODE_PAGE) - strcat(buf, "[wake me up] "); - if (mode & SILC_UMODE_HYPER) - strcat(buf, "[hyperactive] "); - if (mode & SILC_UMODE_ROBOT) - strcat(buf, "[robot] "); - if (mode & SILC_UMODE_ANONYMOUS) - strcat(buf, "[anonymous] "); - if (mode & SILC_UMODE_BLOCK_PRIVMSG) - strcat(buf, "[blocks private messages] "); - if (mode & SILC_UMODE_DETACHED) - strcat(buf, "[detached] "); - if (mode & SILC_UMODE_REJECT_WATCHING) - strcat(buf, "[rejects watching] "); - if (mode & SILC_UMODE_BLOCK_INVITE) - strcat(buf, "[blocks invites] "); - g_strchomp(buf); -} - -void silcpurple_get_chmode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size) -{ - memset(buf, 0, buf_size); - if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) - strcat(buf, "[permanent] "); - if (mode & SILC_CHANNEL_MODE_PRIVATE) - strcat(buf, "[private] "); - if (mode & SILC_CHANNEL_MODE_SECRET) - strcat(buf, "[secret] "); - if (mode & SILC_CHANNEL_MODE_PRIVKEY) - strcat(buf, "[private key] "); - if (mode & SILC_CHANNEL_MODE_INVITE) - strcat(buf, "[invite only] "); - if (mode & SILC_CHANNEL_MODE_TOPIC) - strcat(buf, "[topic restricted] "); - if (mode & SILC_CHANNEL_MODE_ULIMIT) - strcat(buf, "[user count limit] "); - if (mode & SILC_CHANNEL_MODE_PASSPHRASE) - strcat(buf, "[passphrase auth] "); - if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) - strcat(buf, "[public key auth] "); - if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) - strcat(buf, "[users silenced] "); - if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) - strcat(buf, "[operators silenced] "); - g_strchomp(buf); -} - -void silcpurple_get_chumode_string(SilcUInt32 mode, char *buf, - SilcUInt32 buf_size) -{ - memset(buf, 0, buf_size); - if (mode & SILC_CHANNEL_UMODE_CHANFO) - strcat(buf, "[founder] "); - if (mode & SILC_CHANNEL_UMODE_CHANOP) - strcat(buf, "[operator] "); - if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) - strcat(buf, "[blocks messages] "); - if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) - strcat(buf, "[blocks user messages] "); - if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) - strcat(buf, "[blocks robot messages] "); - if (mode & SILC_CHANNEL_UMODE_QUIET) - strcat(buf, "[quieted] "); - g_strchomp(buf); -} - -void -silcpurple_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr, - char **contactstr, char **langstr, char **devicestr, - char **tzstr, char **geostr) -{ - SilcAttributePayload attr; - SilcAttributeMood mood = 0; - SilcAttributeContact contact; - SilcAttributeObjDevice device; - SilcAttributeObjGeo geo; - - char tmp[1024]; - GString *s; - - *moodstr = NULL; - *statusstr = NULL; - *contactstr = NULL; - *langstr = NULL; - *devicestr = NULL; - *tzstr = NULL; - *geostr = NULL; - - if (!attrs) - return; - - s = g_string_new(""); - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD); - if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { - if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) - g_string_append_printf(s, "[%s] ", _("Happy")); - if (mood & SILC_ATTRIBUTE_MOOD_SAD) - g_string_append_printf(s, "[%s] ", _("Sad")); - if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) - g_string_append_printf(s, "[%s] ", _("Angry")); - if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) - g_string_append_printf(s, "[%s] ", _("Jealous")); - if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) - g_string_append_printf(s, "[%s] ", _("Ashamed")); - if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) - g_string_append_printf(s, "[%s] ", _("Invincible")); - if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) - g_string_append_printf(s, "[%s] ", _("In Love")); - if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) - g_string_append_printf(s, "[%s] ", _("Sleepy")); - if (mood & SILC_ATTRIBUTE_MOOD_BORED) - g_string_append_printf(s, "[%s] ", _("Bored")); - if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) - g_string_append_printf(s, "[%s] ", _("Excited")); - if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) - g_string_append_printf(s, "[%s] ", _("Anxious")); - } - if (strlen(s->str)) { - *moodstr = s->str; - g_string_free(s, FALSE); - g_strchomp(*moodstr); - } else - g_string_free(s, TRUE); - - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT); - memset(tmp, 0, sizeof(tmp)); - if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) - *statusstr = g_strdup(tmp); - - s = g_string_new(""); - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT); - if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) { - if (contact & SILC_ATTRIBUTE_CONTACT_CHAT) - g_string_append_printf(s, "[%s] ", _("Chat")); - if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL) - g_string_append_printf(s, "[%s] ", _("Email")); - if (contact & SILC_ATTRIBUTE_CONTACT_CALL) - g_string_append_printf(s, "[%s] ", _("Phone")); - if (contact & SILC_ATTRIBUTE_CONTACT_PAGE) - g_string_append_printf(s, "[%s] ", _("Paging")); - if (contact & SILC_ATTRIBUTE_CONTACT_SMS) - g_string_append_printf(s, "[%s] ", _("SMS")); - if (contact & SILC_ATTRIBUTE_CONTACT_MMS) - g_string_append_printf(s, "[%s] ", _("MMS")); - if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO) - g_string_append_printf(s, "[%s] ", _("Video Conferencing")); - } - if (strlen(s->str)) { - *contactstr = s->str; - g_string_free(s, FALSE); - g_strchomp(*contactstr); - } else - g_string_free(s, TRUE); - - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE); - memset(tmp, 0, sizeof(tmp)); - if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) - *langstr = g_strdup(tmp); - - s = g_string_new(""); - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO); - memset(&device, 0, sizeof(device)); - if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) { - if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER) - g_string_append_printf(s, "%s: ", _("Computer")); - if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE) - g_string_append_printf(s, "%s: ", _("Mobile Phone")); - if (device.type == SILC_ATTRIBUTE_DEVICE_PDA) - g_string_append_printf(s, "%s: ", _("PDA")); - if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL) - g_string_append_printf(s, "%s: ", _("Terminal")); - g_string_append_printf(s, "%s %s %s %s", - device.manufacturer ? device.manufacturer : "", - device.version ? device.version : "", - device.model ? device.model : "", - device.language ? device.language : ""); - } - if (strlen(s->str)) { - *devicestr = s->str; - g_string_free(s, FALSE); - } else - g_string_free(s, TRUE); - - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE); - memset(tmp, 0, sizeof(tmp)); - if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) - *tzstr = g_strdup(tmp); - - attr = silcpurple_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION); - memset(&geo, 0, sizeof(geo)); - if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo))) - *geostr = g_strdup_printf("%s %s %s (%s)", - geo.longitude ? geo.longitude : "", - geo.latitude ? geo.latitude : "", - geo.altitude ? geo.altitude : "", - geo.accuracy ? geo.accuracy : ""); -} - -#ifdef HAVE_SILCMIME_H -/* Returns MIME type of filetype */ - -char *silcpurple_file2mime(const char *filename) -{ - const char *ct; - - ct = strrchr(filename, '.'); - if (!ct) - return NULL; - else if (!g_ascii_strcasecmp(".png", ct)) - return strdup("image/png"); - else if (!g_ascii_strcasecmp(".jpg", ct)) - return strdup("image/jpeg"); - else if (!g_ascii_strcasecmp(".jpeg", ct)) - return strdup("image/jpeg"); - else if (!g_ascii_strcasecmp(".gif", ct)) - return strdup("image/gif"); - else if (!g_ascii_strcasecmp(".tiff", ct)) - return strdup("image/tiff"); - - return NULL; -} - -/* Checks if message has images, and assembles MIME message if it has. - If only one image is present, creates simple MIME image message. If - there are multiple images and/or text with images multipart MIME - message is created. */ - -SilcDList silcpurple_image_message(const char *msg, SilcUInt32 *mflags) -{ - SilcMime mime = NULL, p; - SilcDList list, parts = NULL; - const char *start, *end, *last; - GData *attribs; - char *type; - gboolean images = FALSE; - - last = msg; - while (last && *last && purple_markup_find_tag("img", last, &start, - &end, &attribs)) { - PurpleStoredImage *image = NULL; - const char *id; - - /* Check if there is text before image */ - if (start - last) { - char *text, *tmp; - p = silc_mime_alloc(); - - /* Add content type */ - silc_mime_add_field(p, "Content-Type", - "text/plain; charset=utf-8"); - - tmp = g_strndup(last, start - last); - text = purple_unescape_html(tmp); - g_free(tmp); - /* Add text */ - silc_mime_add_data(p, (unsigned char *)text, strlen(text)); - g_free(text); - - if (!parts) - parts = silc_dlist_init(); - silc_dlist_add(parts, p); - } - - id = g_datalist_get_data(&attribs, "id"); - if (id && (image = purple_imgstore_find_by_id(atoi(id)))) { - unsigned long imglen = purple_imgstore_get_size(image); - gconstpointer img = purple_imgstore_get_data(image); - - p = silc_mime_alloc(); - - /* Add content type */ - type = silcpurple_file2mime(purple_imgstore_get_filename(image)); - if (!type) { - g_datalist_clear(&attribs); - last = end + 1; - continue; - } - silc_mime_add_field(p, "Content-Type", type); - silc_free(type); - - /* Add content transfer encoding */ - silc_mime_add_field(p, "Content-Transfer-Encoding", "binary"); - - /* Add image data */ - silc_mime_add_data(p, img, imglen); - - if (!parts) - parts = silc_dlist_init(); - silc_dlist_add(parts, p); - images = TRUE; - } - - g_datalist_clear(&attribs); - - /* Continue after tag */ - last = end + 1; - } - - /* Check for text after the image(s) */ - if (images && last && *last) { - char *tmp = purple_unescape_html(last); - p = silc_mime_alloc(); - - /* Add content type */ - silc_mime_add_field(p, "Content-Type", - "text/plain; charset=utf-8"); - - /* Add text */ - silc_mime_add_data(p, (unsigned char *)tmp, strlen(tmp)); - g_free(tmp); - - if (!parts) - parts = silc_dlist_init(); - silc_dlist_add(parts, p); - } - - /* If there weren't any images, don't return anything. */ - if (!images) { - if (parts) - silc_dlist_uninit(parts); - return NULL; - } - - if (silc_dlist_count(parts) > 1) { - /* Multipart MIME message */ - char b[32]; - mime = silc_mime_alloc(); - silc_mime_add_field(mime, "MIME-Version", "1.0"); - g_snprintf(b, sizeof(b), "b%4X%4X", - (unsigned int)time(NULL), - silc_dlist_count(parts)); - silc_mime_set_multipart(mime, "mixed", b); - silc_dlist_start(parts); - while ((p = silc_dlist_get(parts)) != SILC_LIST_END) - silc_mime_add_multipart(mime, p); - } else { - /* Simple MIME message */ - silc_dlist_start(parts); - mime = silc_dlist_get(parts); - silc_mime_add_field(mime, "MIME-Version", "1.0"); - } - - *mflags &= ~SILC_MESSAGE_FLAG_UTF8; - *mflags |= SILC_MESSAGE_FLAG_DATA; - - /* Encode message. Fragment if it is too large */ - list = silc_mime_encode_partial(mime, 0xfc00); - - silc_dlist_uninit(parts); - - /* Added multiparts gets freed here */ - silc_mime_free(mime); - - return list; -} - -#endif /* HAVE_SILCMIME_H */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/wb.c --- a/libpurple/protocols/silc10/wb.c Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,520 +0,0 @@ -/* - - wb.c - - Author: Pekka Riikonen - - Copyright (C) 2005 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include "silcpurple.h" -#include "wb.h" - -/* - SILC Whiteboard packet: - - 1 byte command - 2 bytes width - 2 bytes height - 4 bytes brush color - 2 bytes brush size - n bytes data - - Data: - - 4 bytes x - 4 bytes y - - Commands: - - 0x01 draw - 0x02 clear - - MIME: - - MIME-Version: 1.0 - Content-Type: application/x-wb - Content-Transfer-Encoding: binary - -*/ - -#define SILCPURPLE_WB_MIME "MIME-Version: 1.0\r\nContent-Type: application/x-wb\r\nContent-Transfer-Encoding: binary\r\n\r\n" -#define SILCPURPLE_WB_HEADER strlen(SILCPURPLE_WB_MIME) + 11 - -#define SILCPURPLE_WB_WIDTH 500 -#define SILCPURPLE_WB_HEIGHT 400 -#define SILCPURPLE_WB_WIDTH_MAX 1024 -#define SILCPURPLE_WB_HEIGHT_MAX 1024 - -/* Commands */ -typedef enum { - SILCPURPLE_WB_DRAW = 0x01, - SILCPURPLE_WB_CLEAR = 0x02 -} SilcPurpleWbCommand; - -/* Brush size */ -typedef enum { - SILCPURPLE_WB_BRUSH_SMALL = 2, - SILCPURPLE_WB_BRUSH_MEDIUM = 5, - SILCPURPLE_WB_BRUSH_LARGE = 10 -} SilcPurpleWbBrushSize; - -/* Brush color (XXX Purple should provide default colors) */ -typedef enum { - SILCPURPLE_WB_COLOR_BLACK = 0, - SILCPURPLE_WB_COLOR_RED = 13369344, - SILCPURPLE_WB_COLOR_GREEN = 52224, - SILCPURPLE_WB_COLOR_BLUE = 204, - SILCPURPLE_WB_COLOR_YELLOW = 15658496, - SILCPURPLE_WB_COLOR_ORANGE = 16737792, - SILCPURPLE_WB_COLOR_CYAN = 52428, - SILCPURPLE_WB_COLOR_VIOLET = 5381277, - SILCPURPLE_WB_COLOR_PURPLE = 13369548, - SILCPURPLE_WB_COLOR_TAN = 12093547, - SILCPURPLE_WB_COLOR_BROWN = 5256485, - SILCPURPLE_WB_COLOR_GREY = 11184810, - SILCPURPLE_WB_COLOR_WHITE = 16777215 -} SilcPurpleWbColor; - -typedef struct { - int type; /* 0 = buddy, 1 = channel */ - union { - SilcClientEntry client; - SilcChannelEntry channel; - } u; - int width; - int height; - int brush_size; - int brush_color; -} *SilcPurpleWb; - -/* Initialize whiteboard */ - -PurpleWhiteboard *silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry) -{ - SilcClientConnection conn; - PurpleWhiteboard *wb; - SilcPurpleWb wbs; - - conn = sg->conn; - wb = purple_whiteboard_get_session(sg->account, client_entry->nickname); - if (!wb) - wb = purple_whiteboard_create(sg->account, client_entry->nickname, 0); - if (!wb) - return NULL; - - if (!wb->proto_data) { - wbs = silc_calloc(1, sizeof(*wbs)); - if (!wbs) - return NULL; - wbs->type = 0; - wbs->u.client = client_entry; - wbs->width = SILCPURPLE_WB_WIDTH; - wbs->height = SILCPURPLE_WB_HEIGHT; - wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL; - wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK; - wb->proto_data = wbs; - - /* Start the whiteboard */ - purple_whiteboard_start(wb); - purple_whiteboard_clear(wb); - } - - return wb; -} - -PurpleWhiteboard *silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel) -{ - PurpleWhiteboard *wb; - SilcPurpleWb wbs; - - wb = purple_whiteboard_get_session(sg->account, channel->channel_name); - if (!wb) - wb = purple_whiteboard_create(sg->account, channel->channel_name, 0); - if (!wb) - return NULL; - - if (!wb->proto_data) { - wbs = silc_calloc(1, sizeof(*wbs)); - if (!wbs) - return NULL; - wbs->type = 1; - wbs->u.channel = channel; - wbs->width = SILCPURPLE_WB_WIDTH; - wbs->height = SILCPURPLE_WB_HEIGHT; - wbs->brush_size = SILCPURPLE_WB_BRUSH_SMALL; - wbs->brush_color = SILCPURPLE_WB_COLOR_BLACK; - wb->proto_data = wbs; - - /* Start the whiteboard */ - purple_whiteboard_start(wb); - purple_whiteboard_clear(wb); - } - - return wb; -} - -static void -silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb, - unsigned char *message, SilcUInt32 message_len) -{ - SilcUInt8 command; - SilcUInt16 width, height, brush_size; - SilcUInt32 brush_color, x, y, dx, dy; - SilcBufferStruct buf; - int ret; - - /* Parse the packet */ - silc_buffer_set(&buf, message, message_len); - ret = silc_buffer_unformat(&buf, - SILC_STR_UI_CHAR(&command), - SILC_STR_UI_SHORT(&width), - SILC_STR_UI_SHORT(&height), - SILC_STR_UI_INT(&brush_color), - SILC_STR_UI_SHORT(&brush_size), - SILC_STR_END); - if (ret < 0) - return; - silc_buffer_pull(&buf, ret); - - /* Update whiteboard if its dimensions changed */ - if (width != wbs->width || height != wbs->height) - silcpurple_wb_set_dimensions(wb, height, width); - - if (command == SILCPURPLE_WB_DRAW) { - /* Parse data and draw it */ - ret = silc_buffer_unformat(&buf, - SILC_STR_UI_INT(&dx), - SILC_STR_UI_INT(&dy), - SILC_STR_END); - if (ret < 0) - return; - silc_buffer_pull(&buf, 8); - x = dx; - y = dy; - while (buf.len > 0) { - ret = silc_buffer_unformat(&buf, - SILC_STR_UI_INT(&dx), - SILC_STR_UI_INT(&dy), - SILC_STR_END); - if (ret < 0) - return; - silc_buffer_pull(&buf, 8); - - purple_whiteboard_draw_line(wb, x, y, x + dx, y + dy, - brush_color, brush_size); - x += dx; - y += dy; - } - } - - if (command == SILCPURPLE_WB_CLEAR) - purple_whiteboard_clear(wb); -} - -typedef struct { - unsigned char *message; - SilcUInt32 message_len; - SilcPurple sg; - SilcClientEntry sender; - SilcChannelEntry channel; -} *SilcPurpleWbRequest; - -static void -silcpurple_wb_request_cb(SilcPurpleWbRequest req, gint id) -{ - PurpleWhiteboard *wb; - - if (id != 1) - goto out; - - if (!req->channel) - wb = silcpurple_wb_init(req->sg, req->sender); - else - wb = silcpurple_wb_init_ch(req->sg, req->channel); - - silcpurple_wb_parse(wb->proto_data, wb, req->message, req->message_len); - - out: - silc_free(req->message); - silc_free(req); -} - -static void -silcpurple_wb_request(SilcClient client, const unsigned char *message, - SilcUInt32 message_len, SilcClientEntry sender, - SilcChannelEntry channel) -{ - char tmp[128]; - SilcPurpleWbRequest req; - PurpleConnection *gc; - SilcPurple sg; - - gc = client->application; - sg = gc->proto_data; - - /* Open whiteboard automatically if requested */ - if (purple_account_get_bool(sg->account, "open-wb", FALSE)) { - PurpleWhiteboard *wb; - - if (!channel) - wb = silcpurple_wb_init(sg, sender); - else - wb = silcpurple_wb_init_ch(sg, channel); - - silcpurple_wb_parse(wb->proto_data, wb, (unsigned char *)message, - message_len); - return; - } - - /* Close any previous unaccepted requests */ - purple_request_close_with_handle(sender); - - if (!channel) { - g_snprintf(tmp, sizeof(tmp), - _("%s sent message to whiteboard. Would you like " - "to open the whiteboard?"), sender->nickname); - } else { - g_snprintf(tmp, sizeof(tmp), - _("%s sent message to whiteboard on %s channel. " - "Would you like to open the whiteboard?"), - sender->nickname, channel->channel_name); - } - - req = silc_calloc(1, sizeof(*req)); - if (!req) - return; - req->message = silc_memdup(message, message_len); - req->message_len = message_len; - req->sender = sender; - req->channel = channel; - req->sg = sg; - - purple_request_action(sender, _("Whiteboard"), tmp, NULL, 1, - sg->account, sender->nickname, NULL, req, 2, - _("Yes"), G_CALLBACK(silcpurple_wb_request_cb), - _("No"), G_CALLBACK(silcpurple_wb_request_cb)); -} - -/* Process incoming whiteboard message */ - -void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcMessagePayload payload, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len) -{ - SilcPurple sg; - PurpleConnection *gc; - PurpleWhiteboard *wb; - SilcPurpleWb wbs; - - gc = client->application; - sg = gc->proto_data; - - wb = purple_whiteboard_get_session(sg->account, sender->nickname); - if (!wb) { - /* Ask user if they want to open the whiteboard */ - silcpurple_wb_request(client, message, message_len, - sender, NULL); - return; - } - - wbs = wb->proto_data; - silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len); -} - -/* Process incoming whiteboard message on channel */ - -void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcChannelEntry channel, - SilcMessagePayload payload, - SilcMessageFlags flags, - const unsigned char *message, - SilcUInt32 message_len) -{ - SilcPurple sg; - PurpleConnection *gc; - PurpleWhiteboard *wb; - SilcPurpleWb wbs; - - gc = client->application; - sg = gc->proto_data; - - wb = purple_whiteboard_get_session(sg->account, channel->channel_name); - if (!wb) { - /* Ask user if they want to open the whiteboard */ - silcpurple_wb_request(client, message, message_len, - sender, channel); - return; - } - - wbs = wb->proto_data; - silcpurple_wb_parse(wbs, wb, (unsigned char *)message, message_len); -} - -/* Send whiteboard message */ - -void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list) -{ - SilcPurpleWb wbs = wb->proto_data; - SilcBuffer packet; - GList *list; - int len; - PurpleConnection *gc; - SilcPurple sg; - - g_return_if_fail(draw_list); - gc = purple_account_get_connection(wb->account); - g_return_if_fail(gc); - sg = gc->proto_data; - g_return_if_fail(sg); - - len = SILCPURPLE_WB_HEADER; - for (list = draw_list; list; list = list->next) - len += 4; - - packet = silc_buffer_alloc_size(len); - if (!packet) - return; - - /* Assmeble packet */ - silc_buffer_format(packet, - SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME), - SILC_STR_UI_CHAR(SILCPURPLE_WB_DRAW), - SILC_STR_UI_SHORT(wbs->width), - SILC_STR_UI_SHORT(wbs->height), - SILC_STR_UI_INT(wbs->brush_color), - SILC_STR_UI_SHORT(wbs->brush_size), - SILC_STR_END); - silc_buffer_pull(packet, SILCPURPLE_WB_HEADER); - for (list = draw_list; list; list = list->next) { - silc_buffer_format(packet, - SILC_STR_UI_INT(GPOINTER_TO_INT(list->data)), - SILC_STR_END); - silc_buffer_pull(packet, 4); - } - - /* Send the message */ - if (wbs->type == 0) { - /* Private message */ - silc_client_send_private_message(sg->client, sg->conn, - wbs->u.client, - SILC_MESSAGE_FLAG_DATA, - packet->head, len, TRUE); - } else if (wbs->type == 1) { - /* Channel message. Channel private keys are not supported. */ - silc_client_send_channel_message(sg->client, sg->conn, - wbs->u.channel, NULL, - SILC_MESSAGE_FLAG_DATA, - packet->head, len, TRUE); - } - - silc_buffer_free(packet); -} - -/* Purple Whiteboard operations */ - -void silcpurple_wb_start(PurpleWhiteboard *wb) -{ - /* Nothing here. Everything is in initialization */ -} - -void silcpurple_wb_end(PurpleWhiteboard *wb) -{ - silc_free(wb->proto_data); - wb->proto_data = NULL; -} - -void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height) -{ - SilcPurpleWb wbs = wb->proto_data; - *width = wbs->width; - *height = wbs->height; -} - -void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height) -{ - SilcPurpleWb wbs = wb->proto_data; - wbs->width = width > SILCPURPLE_WB_WIDTH_MAX ? SILCPURPLE_WB_WIDTH_MAX : - width; - wbs->height = height > SILCPURPLE_WB_HEIGHT_MAX ? SILCPURPLE_WB_HEIGHT_MAX : - height; - - /* Update whiteboard */ - purple_whiteboard_set_dimensions(wb, wbs->width, wbs->height); -} - -void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color) -{ - SilcPurpleWb wbs = wb->proto_data; - *size = wbs->brush_size; - *color = wbs->brush_color; -} - -void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color) -{ - SilcPurpleWb wbs = wb->proto_data; - wbs->brush_size = size; - wbs->brush_color = color; - - /* Update whiteboard */ - purple_whiteboard_set_brush(wb, size, color); -} - -void silcpurple_wb_clear(PurpleWhiteboard *wb) -{ - SilcPurpleWb wbs = wb->proto_data; - SilcBuffer packet; - int len; - PurpleConnection *gc; - SilcPurple sg; - - gc = purple_account_get_connection(wb->account); - g_return_if_fail(gc); - sg = gc->proto_data; - g_return_if_fail(sg); - - len = SILCPURPLE_WB_HEADER; - packet = silc_buffer_alloc_size(len); - if (!packet) - return; - - /* Assmeble packet */ - silc_buffer_format(packet, - SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME), - SILC_STR_UI_CHAR(SILCPURPLE_WB_CLEAR), - SILC_STR_UI_SHORT(wbs->width), - SILC_STR_UI_SHORT(wbs->height), - SILC_STR_UI_INT(wbs->brush_color), - SILC_STR_UI_SHORT(wbs->brush_size), - SILC_STR_END); - - /* Send the message */ - if (wbs->type == 0) { - /* Private message */ - silc_client_send_private_message(sg->client, sg->conn, - wbs->u.client, - SILC_MESSAGE_FLAG_DATA, - packet->head, len, TRUE); - } else if (wbs->type == 1) { - /* Channel message */ - silc_client_send_channel_message(sg->client, sg->conn, - wbs->u.channel, NULL, - SILC_MESSAGE_FLAG_DATA, - packet->head, len, TRUE); - } - - silc_buffer_free(packet); -} diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/silc10/wb.h --- a/libpurple/protocols/silc10/wb.h Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - - silcpurple.h - - Author: Pekka Riikonen - - Copyright (C) 2005 Pekka Riikonen - - 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; version 2 of the License. - - 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. - -*/ - -#ifndef SILCPURPLE_WB_H -#define SILCPURPLE_WB_H - -#include "silcpurple.h" -#include "whiteboard.h" - -PurpleWhiteboard * -silcpurple_wb_init(SilcPurple sg, SilcClientEntry client_entry); -PurpleWhiteboard * -silcpurple_wb_init_ch(SilcPurple sg, SilcChannelEntry channel); -void silcpurple_wb_receive(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcMessagePayload payload, - SilcMessageFlags flags, const unsigned char *message, - SilcUInt32 message_len); -void silcpurple_wb_receive_ch(SilcClient client, SilcClientConnection conn, - SilcClientEntry sender, SilcChannelEntry channel, - SilcMessagePayload payload, - SilcMessageFlags flags, - const unsigned char *message, - SilcUInt32 message_len); -void silcpurple_wb_start(PurpleWhiteboard *wb); -void silcpurple_wb_end(PurpleWhiteboard *wb); -void silcpurple_wb_get_dimensions(const PurpleWhiteboard *wb, int *width, int *height); -void silcpurple_wb_set_dimensions(PurpleWhiteboard *wb, int width, int height); -void silcpurple_wb_get_brush(const PurpleWhiteboard *wb, int *size, int *color); -void silcpurple_wb_set_brush(PurpleWhiteboard *wb, int size, int color); -void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list); -void silcpurple_wb_clear(PurpleWhiteboard *wb); - -#endif /* SILCPURPLE_WB_H */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/simple/simple.c --- a/libpurple/protocols/simple/simple.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/simple/simple.c Mon Aug 22 16:00:57 2011 +0000 @@ -432,7 +432,7 @@ /*TODO: do we really want to disconnect on a failure to write?*/ gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -451,7 +451,7 @@ if(source < 0) { gchar *tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -479,7 +479,7 @@ if(!sip->connecting) { purple_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); if (purple_proxy_connect(gc, sip->account, sip->realhostname, sip->realport, send_later_cb, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } sip->connecting = TRUE; } @@ -1122,7 +1122,7 @@ if(sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) { if (!purple_account_get_remember_password(sip->gc->account)) purple_account_set_password(sip->gc->account, NULL); - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password")); return TRUE; @@ -1137,7 +1137,7 @@ if (sip->registerstatus != SIMPLE_REGISTER_RETRY) { purple_debug_info("simple", "Unrecognized return code for REGISTER.\n"); if (sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("Unknown server response")); return TRUE; @@ -1739,7 +1739,7 @@ if(source < 0) { gchar *tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; @@ -1775,7 +1775,7 @@ sip->listen_data = NULL; if(listenfd == -1) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to create listen socket")); return; @@ -1804,7 +1804,7 @@ sip->query_data = NULL; if (!hosts || !hosts->data) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to resolve hostname")); return; @@ -1825,7 +1825,7 @@ sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_DGRAM, simple_udp_host_resolved_listen_cb, sip); if (sip->listen_data == NULL) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to create listen socket")); return; @@ -1840,7 +1840,7 @@ sip->listenfd = listenfd; if(sip->listenfd == -1) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to create listen socket")); return; @@ -1855,7 +1855,7 @@ /* open tcp connection to the server */ if (purple_proxy_connect(sip->gc, sip->account, sip->realhostname, sip->realport, login_cb, sip->gc) == NULL) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } @@ -1895,7 +1895,7 @@ sip->listen_data = purple_network_listen_range(5060, 5160, SOCK_STREAM, simple_tcp_connect_listen_cb, sip); if (sip->listen_data == NULL) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to create listen socket")); return; @@ -1906,7 +1906,7 @@ sip->query_data = purple_dnsquery_a_account(sip->account, hostname, port, simple_udp_host_resolved, sip); if (sip->query_data == NULL) { - purple_connection_error_reason(sip->gc, + purple_connection_error(sip->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to resolve hostname")); } @@ -1924,7 +1924,7 @@ gc = purple_account_get_connection(account); if (strpbrk(username, " \t\v\r\n") != NULL) { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("SIP usernames may not contain whitespaces or @ symbols")); return; @@ -1943,7 +1943,7 @@ userserver = g_strsplit(username, "@", 2); if (userserver[1] == NULL || userserver[1][0] == '\0') { - purple_connection_error_reason(gc, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("SIP connect server not specified")); return; diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/yahoo/libymsg.c --- a/libpurple/protocols/yahoo/libymsg.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/yahoo/libymsg.c Mon Aug 22 16:00:57 2011 +0000 @@ -159,7 +159,7 @@ if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _("You have signed on from another location")); return; } @@ -1803,7 +1803,7 @@ if (error_message != NULL) { purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); g_free(auth_data->seed); g_free(auth_data); return; @@ -1890,7 +1890,7 @@ if(error_reason) { purple_debug_error("yahoo", "Authentication error: %s. " "Code %d\n", error_reason, response_no); - purple_connection_error_reason(gc, error, error_reason); + purple_connection_error(gc, error, error_reason); g_free(error_reason); g_free(auth_data->seed); g_free(auth_data); @@ -1919,7 +1919,7 @@ if (error_message != NULL) { purple_debug_error("yahoo", "Login Failed, unable to retrieve login url: %s\n", error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); g_free(auth_data->seed); g_free(auth_data); return; @@ -2000,7 +2000,7 @@ } purple_debug_error("yahoo", "Authentication error: %s. Code %d\n", error_reason, response_no); - purple_connection_error_reason(gc, error, error_reason); + purple_connection_error(gc, error, error_reason); g_free(error_reason); g_free(auth_data->seed); g_free(auth_data); @@ -2014,7 +2014,7 @@ gboolean proxy_ssl = purple_account_get_bool(account, "proxy_ssl", FALSE); url = g_strdup_printf(yahoojp ? YAHOOJP_LOGIN_URL : YAHOO_LOGIN_URL, token); - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT, TRUE, NULL, TRUE, -1, yahoo_auth16_stage2, auth_data); if (url_data) @@ -2040,7 +2040,7 @@ purple_debug_info("yahoo", "Authentication: In yahoo_auth16_stage1\n"); if(!purple_ssl_is_supported()) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("SSL support unavailable")); return; } @@ -2055,7 +2055,7 @@ g_free(encoded_password); g_free(encoded_username); - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( proxy_ssl ? account : NULL, url, TRUE, YAHOO_CLIENT_USERAGENT, TRUE, NULL, FALSE, -1, yahoo_auth16_stage1_cb, auth_data); @@ -2285,7 +2285,7 @@ else fullmsg = g_strdup(msg); - purple_connection_error_reason(gc, reason, fullmsg); + purple_connection_error(gc, reason, fullmsg); g_free(msg); g_free(fullmsg); } @@ -3147,11 +3147,11 @@ tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); return; } @@ -3235,7 +3235,7 @@ if (source < 0) { gchar *tmp; tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -3261,7 +3261,7 @@ if (source < 0) { gchar *tmp; tmp = g_strdup_printf(_("Unable to connect: %s"), error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -3301,11 +3301,11 @@ tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } else if (len == 0) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Server closed the connection")); return; } @@ -3321,7 +3321,7 @@ if ((strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302")) && strncmp(buf, "HTTP/1.1 302", strlen("HTTP/1.1 302")))) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Received unexpected HTTP response from server")); purple_debug_misc("yahoo", "Unexpected HTTP response: %s\n", buf); return; @@ -3351,7 +3351,7 @@ if (purple_proxy_connect(gc, account, "wcs2.msg.dcn.yahoo.com", purple_account_get_int(account, "port", YAHOO_PAGER_PORT), yahoo_got_web_connected, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; } @@ -3380,7 +3380,7 @@ gc->inpa = 0; tmp = g_strdup_printf(_("Lost connection with %s: %s"), "login.yahoo.com:80", g_strerror(errno)); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -3405,7 +3405,7 @@ gchar *tmp; tmp = g_strdup_printf(_("Unable to establish a connection with %s: %s"), "login.yahoo.com:80", error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } @@ -3489,7 +3489,7 @@ if (error_message != NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); return; } @@ -3539,7 +3539,7 @@ g_hash_table_destroy(hash); yd->auth = g_string_free(url, FALSE); if (purple_proxy_connect(gc, account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); return; } @@ -3619,12 +3619,12 @@ error_message ? error_message : "(null)"); if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect: The server returned an empty response.")); } else { if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port, yahoo_got_connected, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } } @@ -3646,20 +3646,20 @@ if(cs_server) { /* got an address; get on with connecting */ if(purple_proxy_connect(gc, a, cs_server, port, yahoo_got_connected, gc) == NULL) - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } else { purple_debug_error("yahoo", "No CS address retrieved! Server " "response:\n%s\n", url_text ? url_text : "(null)"); if(yahoo_is_japan(a)) { /* We don't know fallback hosts for Yahoo Japan :( */ - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect: The server's response did not contain " "the necessary information")); } else if(purple_proxy_connect(gc, a, YAHOO_PAGER_HOST_FALLBACK, port, yahoo_got_connected, gc) == NULL) { - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); } } @@ -3708,7 +3708,7 @@ /* Get the pager server. Actually start connecting in the callback since we * must have the contents of the HTTP response to proceed. */ - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( proxy_ssl ? purple_connection_get_account(gc) : NULL, yd->jp ? YAHOOJP_PAGER_HOST_REQ_URL : YAHOO_PAGER_HOST_REQ_URL, use_whole_url ? TRUE : FALSE, @@ -4036,22 +4036,12 @@ if (f && full) { YahooPersonalDetails *ypd = &f->ypd; - int i; - struct { - char *id; - char *text; - char *value; - } yfields[] = { - {"hp", N_("Home Phone Number"), ypd->phone.home}, - {"wp", N_("Work Phone Number"), ypd->phone.work}, - {"mo", N_("Mobile Phone Number"), ypd->phone.mobile}, - {NULL, NULL, NULL} - }; - for (i = 0; yfields[i].id; i++) { - if (!yfields[i].value || !*yfields[i].value) - continue; - purple_notify_user_info_add_pair(user_info, _(yfields[i].text), yfields[i].value); - } + if (ypd->phone.home && *ypd->phone.home) + purple_notify_user_info_add_pair_plaintext(user_info, _("Home Phone Number"), ypd->phone.home); + if (ypd->phone.work && *ypd->phone.work) + purple_notify_user_info_add_pair_plaintext(user_info, _("Work Phone Number"), ypd->phone.work); + if (ypd->phone.mobile && *ypd->phone.mobile) + purple_notify_user_info_add_pair_plaintext(user_info, _("Mobile Phone Number"), ypd->phone.mobile); } } @@ -4296,7 +4286,7 @@ use_whole_url ? base_url : "", yd->cookie_t, yd->cookie_y); - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( purple_connection_get_account(gc), base_url, use_whole_url, YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1, yahoo_get_inbox_token_cb, gc); @@ -4488,7 +4478,7 @@ if ((gc->account->proxy_info) && (gc->account->proxy_info->type == PURPLE_PROXY_HTTP)) use_whole_url = TRUE; - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( purple_connection_get_account(gc), YAHOO_SMS_CARRIER_URL, use_whole_url, YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1, yahoo_get_sms_carrier_cb, data); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/yahoo/yahoo_aliases.c --- a/libpurple/protocols/yahoo/yahoo_aliases.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/yahoo/yahoo_aliases.c Mon Aug 22 16:00:57 2011 +0000 @@ -207,7 +207,7 @@ webaddress); /* We have a URL and some header information, let's connect and get some aliases */ - url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc), + url_data = purple_util_fetch_url_request_len(purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE, request, FALSE, -1, yahoo_fetch_aliases_cb, gc); if (url_data != NULL) @@ -379,7 +379,7 @@ content); /* We have a URL and some header information, let's connect and update the alias */ - url_data = purple_util_fetch_url_request_len_with_account( + url_data = purple_util_fetch_url_request_len( purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE, request, FALSE, -1, yahoo_update_alias_cb, cb); if (url_data != NULL) @@ -517,7 +517,7 @@ } #endif - url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE, + url_data = purple_util_fetch_url_request_len(account, webaddress, FALSE, YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1, yahoo_fetch_aliases_cb, gc); if (url_data != NULL) diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/yahoo/yahoo_packet.c --- a/libpurple/protocols/yahoo/yahoo_packet.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.c Mon Aug 22 16:00:57 2011 +0000 @@ -302,7 +302,7 @@ return; else if (ret < 0) { /* TODO: what to do here - do we really have to disconnect? */ - purple_connection_error_reason(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + purple_connection_error(yd->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Write Error")); return; } diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/yahoo/yahoo_profile.c --- a/libpurple/protocols/yahoo/yahoo_profile.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/yahoo/yahoo_profile.c Mon Aug 22 16:00:57 2011 +0000 @@ -805,7 +805,7 @@ * to send back HTML, with a 200 status code. */ if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0) { - purple_notify_user_info_add_pair(user_info, _("Error retrieving profile"), NULL); + purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL); purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); @@ -840,7 +840,7 @@ _("If you wish to view this profile, " "you will need to visit this link in your web browser:"), profile_url_text, profile_url_text); - purple_notify_user_info_add_pair(user_info, NULL, tmp); + purple_notify_user_info_add_pair_html(user_info, NULL, tmp); g_free(tmp); purple_notify_userinfo(info_data->gc, info_data->name, @@ -1048,7 +1048,7 @@ id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL); tmp = g_strdup_printf("
", id); - purple_notify_user_info_add_pair(user_info, NULL, tmp); + purple_notify_user_info_add_pair_html(user_info, NULL, tmp); g_free(tmp); } } @@ -1195,7 +1195,7 @@ const gchar *str; purple_notify_user_info_add_section_break(user_info); - purple_notify_user_info_add_pair(user_info, + purple_notify_user_info_add_pair_html(user_info, _("Error retrieving profile"), NULL); if (profile_state == PROFILE_STATE_UNKNOWN_LANGUAGE) { @@ -1228,14 +1228,14 @@ str = _("The user's profile is empty."); } - purple_notify_user_info_add_pair(user_info, NULL, str); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, str); } /* put a link to the actual profile URL */ purple_notify_user_info_add_section_break(user_info); tmp = g_strdup_printf("%s", profile_url_text, _("View web profile")); - purple_notify_user_info_add_pair(user_info, NULL, tmp); + purple_notify_user_info_add_pair_html(user_info, NULL, tmp); g_free(tmp); g_free(stripped); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/yahoo/ycht.c --- a/libpurple/protocols/yahoo/ycht.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/yahoo/ycht.c Mon Aug 22 16:00:57 2011 +0000 @@ -285,7 +285,7 @@ /* gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), g_strerror(errno)); - purple_connection_error_reason(purple_account_get_connection(irc->account), + purple_connection_error(purple_account_get_connection(irc->account), PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/protocols/zephyr/zephyr.c --- a/libpurple/protocols/zephyr/zephyr.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/protocols/zephyr/zephyr.c Mon Aug 22 16:00:57 2011 +0000 @@ -146,7 +146,7 @@ return TRUE; #define z_call_s(func, err) if (func != ZERR_NONE) {\ - purple_connection_error(gc, err);\ + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, err);\ return;\ } @@ -791,20 +791,23 @@ char *tmp; const char *balias; - purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user)); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user)); balias = purple_buddy_get_local_buddy_alias(b); if (b && balias) - purple_notify_user_info_add_pair(user_info, _("Alias"), balias); + purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias); if (!nlocs) { - purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in")); } for (; nlocs > 0; nlocs--) { /* XXX add real error reporting */ ZGetLocations(&locs, &one); + /* TODO: Need to escape locs.host and locs.time? */ tmp = g_strdup_printf(_("
At %s since %s"), locs.host, locs.time); - purple_notify_user_info_add_pair(user_info, _("Location"), tmp); + purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp); g_free(tmp); } purple_notify_userinfo(gc, (b ? bname : user), @@ -1161,7 +1164,7 @@ locations = find_node(newparsetree,"locations"); locval = tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents; - if (!locval || !g_ascii_strcasecmp(locval," ") || (strlen(locval) == 0)) { + if (!locval || !g_ascii_strcasecmp(locval," ") || !*locval) { nlocs = 0; } else { nlocs = 1; @@ -1173,19 +1176,22 @@ char *tmp; const char *balias; - purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user)); + /* TODO: Check whether it's correct to call add_pair_html, + or if we should be using add_pair_plaintext */ + purple_notify_user_info_add_pair_html(user_info, _("User"), (b ? bname : user)); balias = b ? purple_buddy_get_local_buddy_alias(b) : NULL; if (balias) - purple_notify_user_info_add_pair(user_info, _("Alias"), balias); + purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias); if (!nlocs) { - purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); + purple_notify_user_info_add_pair_plaintext(user_info, NULL, _("Hidden or not logged-in")); } else { + /* TODO: Need to escape the two strings that make up tmp? */ tmp = g_strdup_printf(_("
At %s since %s"), tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents, tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents); - purple_notify_user_info_add_pair(user_info, _("Location"), tmp); + purple_notify_user_info_add_pair_html(user_info, _("Location"), tmp); g_free(tmp); } @@ -1585,7 +1591,7 @@ /* XXX z_call_s should actually try to report the com_err determined error */ if (use_tzc(zephyr)) { pid_t pid; - /* purple_connection_error(gc,"tzc not supported yet"); */ + /* purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "tzc not supported yet"); */ if ((pipe(zephyr->totzc) != 0) || (pipe(zephyr->fromtzc) != 0)) { purple_debug_error("zephyr", "pipe creation failed. killing\n"); exit(-1); @@ -1706,7 +1712,7 @@ ptr++; } if (ptr >=bufcur) { - purple_connection_error(gc,"invalid output by tzc (or bad parsing code)"); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "invalid output by tzc (or bad parsing code)"); free(buf); return; } @@ -1821,7 +1827,7 @@ purple_debug_info("zephyr","realm: %s\n",zephyr->realm); } else { - purple_connection_error(gc,"Only ZEPH0.2 supported currently"); + purple_connection_error(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Only ZEPH0.2 supported currently"); return; } purple_debug_info("zephyr","does it get here\n"); @@ -2079,7 +2085,7 @@ int pos2 = 0; char *newmsg; - if (message && (strlen(message) > 0)) { + if (message && *message) { newmsg = g_new0(char,1+strlen(message)*2); while(pos < strlen(message)) { if (message[pos]=='\\') { @@ -2111,7 +2117,7 @@ int pos2 = 0; char *newmsg; - if (message && (strlen(message) > 0)) { + if (message && *message) { newmsg = g_new0(char,strlen(message)+1); while(pos < strlen(message)) { if (message[pos]=='\\') { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple-2-uninstalled.pc.in --- a/libpurple/purple-2-uninstalled.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -abs_srcdir=@abs_srcdir@ -abs_builddir=@abs_builddir@ - -abs_top_srcdir=@abs_top_srcdir@ -abs_top_builddir=@abs_top_builddir@ - -plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ - -Name: libpurple -Description: libpurple is a GLib-based instant messenger library. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${abs_top_srcdir} -I${abs_top_builddir} -Libs: ${abs_builddir}/libpurple.la diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple-2.pc.in --- a/libpurple/purple-2.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ - -Name: libpurple -Description: libpurple is a GLib-based instant messenger library. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${includedir} -Libs: -L${libdir} -lpurple diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple-3-uninstalled.pc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/purple-3-uninstalled.pc.in Mon Aug 22 16:00:57 2011 +0000 @@ -0,0 +1,22 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ + +abs_srcdir=@abs_srcdir@ +abs_builddir=@abs_builddir@ + +abs_top_srcdir=@abs_top_srcdir@ +abs_top_builddir=@abs_top_builddir@ + +plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ + +Name: libpurple +Description: libpurple is a GLib-based instant messenger library. +Version: @VERSION@ +Requires: glib-2.0 +Cflags: -I${abs_top_srcdir} -I${abs_top_builddir} +Libs: ${abs_builddir}/libpurple.la diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple-3.pc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/purple-3.pc.in Mon Aug 22 16:00:57 2011 +0000 @@ -0,0 +1,16 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ + +plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ + +Name: libpurple +Description: libpurple is a GLib-based instant messenger library. +Version: @VERSION@ +Requires: glib-2.0 +Cflags: -I${includedir} +Libs: -L${libdir} -lpurple diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple-uninstalled.pc.in --- a/libpurple/purple-uninstalled.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -abs_srcdir=@abs_srcdir@ -abs_builddir=@abs_builddir@ - -plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ - -Name: libpurple -Description: libpurple is a GLib-based instant messenger library. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${abs_srcdir} -I${abs_builddir} -Libs: ${abs_builddir}/libpurple.la diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/purple.pc.in --- a/libpurple/purple.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -plugindir=${libdir}/purple-@PURPLE_MAJOR_VERSION@ - -Name: libpurple -Description: libpurple is a GLib-based instant messenger library. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${includedir}/libpurple -Libs: -L${libdir} -lpurple diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/request.c --- a/libpurple/request.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/request.c Mon Aug 22 16:00:57 2011 +0000 @@ -365,6 +365,7 @@ g_free(field->id); g_free(field->label); g_free(field->type_hint); + g_free(field->tooltip); if (field->type == PURPLE_REQUEST_FIELD_STRING) { @@ -428,6 +429,15 @@ } void +purple_request_field_set_tooltip(PurpleRequestField *field, const char *tooltip) +{ + g_return_if_fail(field != NULL); + + g_free(field->tooltip); + field->tooltip = g_strdup(tooltip); +} + +void purple_request_field_set_required(PurpleRequestField *field, gboolean required) { g_return_if_fail(field != NULL); @@ -502,6 +512,14 @@ return field->type_hint; } +const char * +purple_request_field_get_tooltip(const PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + + return field->tooltip; +} + gboolean purple_request_field_is_required(const PurpleRequestField *field) { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/request.h --- a/libpurple/request.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/request.h Mon Aug 22 16:00:57 2011 +0000 @@ -180,6 +180,7 @@ } u; void *ui_data; + char *tooltip; }; #endif @@ -517,6 +518,18 @@ const char *type_hint); /** + * Sets the tooltip for the field. + * + * This is optionally used by the UIs to provide a tooltip for + * the field. + * + * @param field The field. + * @param tooltip The tooltip text. + */ +void purple_request_field_set_tooltip(PurpleRequestField *field, + const char *tooltip); + +/** * Sets whether or not a field is required. * * @param field The field. @@ -582,6 +595,15 @@ const char *purple_request_field_get_type_hint(const PurpleRequestField *field); /** + * Returns the field's tooltip. + * + * @param field The field. + * + * @return The field's tooltip. + */ +const char *purple_request_field_get_tooltip(const PurpleRequestField *field); + +/** * Returns whether or not a field is required. * * @param field The field. diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/savedstatuses.c --- a/libpurple/savedstatuses.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/savedstatuses.c Mon Aug 22 16:00:57 2011 +0000 @@ -387,7 +387,6 @@ const char *protocol; acct_name = xmlnode_get_data(node); protocol = xmlnode_get_attrib(node, "protocol"); - protocol = _purple_oscar_convert(acct_name, protocol); /* XXX: Remove */ if ((acct_name != NULL) && (protocol != NULL)) ret->account = purple_accounts_find(acct_name, protocol); g_free(acct_name); diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/sound.h --- a/libpurple/sound.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/sound.h Mon Aug 22 16:00:57 2011 +0000 @@ -38,7 +38,7 @@ * A type of sound. */ -typedef enum _PurpleSoundEventID +typedef enum { PURPLE_SOUND_BUDDY_ARRIVE = 0, /**< Buddy signs on. */ PURPLE_SOUND_BUDDY_LEAVE, /**< Buddy signs off. */ diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/status.c --- a/libpurple/status.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/status.c Mon Aug 22 16:00:57 2011 +0000 @@ -44,7 +44,6 @@ char *id; char *name; - char *primary_attr_id; gboolean saveable; gboolean user_settable; @@ -294,7 +293,6 @@ g_free(status_type->id); g_free(status_type->name); - g_free(status_type->primary_attr_id); g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL); g_list_free(status_type->attrs); @@ -304,15 +302,6 @@ } void -purple_status_type_set_primary_attr(PurpleStatusType *status_type, const char *id) -{ - g_return_if_fail(status_type != NULL); - - g_free(status_type->primary_attr_id); - status_type->primary_attr_id = g_strdup(id); -} - -void purple_status_type_add_attr(PurpleStatusType *status_type, const char *id, const char *name, PurpleValue *value) { @@ -435,14 +424,6 @@ return (primitive == PURPLE_STATUS_AVAILABLE); } -const char * -purple_status_type_get_primary_attr(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, NULL); - - return status_type->primary_attr_id; -} - PurpleStatusAttr * purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id) { diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/status.h --- a/libpurple/status.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/status.h Mon Aug 22 16:00:57 2011 +0000 @@ -273,23 +273,6 @@ #if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** - * Sets a status type's primary attribute. - * - * The value for the primary attribute is used as the description for - * the particular status type. An example is an away message. The message - * would be the primary attribute. - * - * @param status_type The status type. - * @param attr_id The ID of the primary attribute. - * - * @deprecated This function isn't used and should be removed in 3.0.0. - */ -void purple_status_type_set_primary_attr(PurpleStatusType *status_type, - const char *attr_id); -#endif - -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) -/** * Adds an attribute to a status type. * * @param status_type The status type to add the attribute to. @@ -419,19 +402,6 @@ */ gboolean purple_status_type_is_available(const PurpleStatusType *status_type); -#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) -/** - * Returns a status type's primary attribute ID. - * - * @param type The status type. - * - * @return The primary attribute's ID. - * - * @deprecated This function isn't used and should be removed in 3.0.0. - */ -const char *purple_status_type_get_primary_attr(const PurpleStatusType *type); -#endif - /** * Returns the attribute with the specified ID. * diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/upnp.c --- a/libpurple/upnp.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/upnp.c Mon Aug 22 16:00:57 2011 +0000 @@ -464,7 +464,7 @@ purple_timeout_remove(dd->tima); dd->tima = 0; - purple_util_fetch_url_request_len(descriptionURL, TRUE, NULL, TRUE, httpRequest, + purple_util_fetch_url_request_len(NULL, descriptionURL, TRUE, NULL, TRUE, httpRequest, TRUE, MAX_UPNP_DOWNLOAD, upnp_parse_description_cb, dd); g_free(httpRequest); @@ -730,7 +730,7 @@ g_free(pathOfControl); g_free(soapMessage); - gfud = purple_util_fetch_url_request_len(control_info.control_url, FALSE, NULL, TRUE, + gfud = purple_util_fetch_url_request_len(NULL, control_info.control_url, FALSE, NULL, TRUE, totalSendMessage, TRUE, MAX_UPNP_DOWNLOAD, cb, cb_data); g_free(totalSendMessage); @@ -744,7 +744,7 @@ { if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED && control_info.publicip - && strlen(control_info.publicip) > 0) + && *control_info.publicip) return control_info.publicip; /* Trigger another UPnP discovery if 5 minutes have elapsed since the @@ -803,7 +803,7 @@ { if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED && control_info.internalip - && strlen(control_info.internalip) > 0) + && *control_info.internalip) return control_info.internalip; /* Trigger another UPnP discovery if 5 minutes have elapsed since the diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/util.c --- a/libpurple/util.c Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/util.c Mon Aug 22 16:00:57 2011 +0000 @@ -147,7 +147,7 @@ len = strlen(str); - g_return_val_if_fail(strlen(str) > 0, 0); + g_return_val_if_fail(*str, 0); g_return_val_if_fail(len % 2 == 0, 0); data = g_malloc(len / 2); @@ -612,7 +612,7 @@ } else { - purple_strlcpy(buf, utf8); + g_strlcpy(buf, utf8, sizeof(buf)); g_free(utf8); } @@ -1321,7 +1321,7 @@ g_string_append_len(dest, p, q - p); } - purple_notify_user_info_add_pair(user_info, display_name, dest->str); + purple_notify_user_info_add_pair_html(user_info, display_name, dest->str); g_string_free(dest, TRUE); return TRUE; @@ -2267,7 +2267,7 @@ url_buf = g_string_free(gurl_buf, FALSE); /* strip off trailing periods */ - if (strlen(url_buf) > 0) { + if (*url_buf) { for (d = url_buf + strlen(url_buf) - 1; *d == '.'; d--, t--) *d = '\0'; } @@ -4108,25 +4108,14 @@ const char *request, gboolean include_headers, PurpleUtilFetchUrlCallback callback, void *user_data) { - return purple_util_fetch_url_request_len_with_account(NULL, url, full, + return purple_util_fetch_url_request_len(NULL, url, full, user_agent, http11, request, include_headers, -1, callback, user_data); } PurpleUtilFetchUrlData * -purple_util_fetch_url_request_len(const char *url, gboolean full, - const char *user_agent, gboolean http11, - const char *request, gboolean include_headers, gssize max_len, - PurpleUtilFetchUrlCallback callback, void *user_data) -{ - return purple_util_fetch_url_request_len_with_account(NULL, url, full, - user_agent, http11, request, include_headers, max_len, callback, - user_data); -} - -PurpleUtilFetchUrlData * -purple_util_fetch_url_request_len_with_account(PurpleAccount *account, +purple_util_fetch_url_request_len(PurpleAccount *account, const char *url, gboolean full, const char *user_agent, gboolean http11, const char *request, gboolean include_headers, gssize max_len, PurpleUtilFetchUrlCallback callback, void *user_data) @@ -4943,18 +4932,6 @@ return buf; } -const char *_purple_oscar_convert(const char *act, const char *protocol) -{ - if (act && purple_strequal(protocol, "prpl-oscar")) { - int i; - for (i = 0; act[i] != '\0'; i++) - if (!isdigit(act[i])) - return "prpl-aim"; - return "prpl-icq"; - } - return protocol; -} - void purple_restore_default_signal_handlers(void) { #ifndef _WIN32 diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/util.h --- a/libpurple/util.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/util.h Mon Aug 22 16:00:57 2011 +0000 @@ -1138,7 +1138,7 @@ * @deprecated In 3.0.0, we'll rename this to "purple_util_fetch_url" and get rid of the old one */ #define purple_util_fetch_url_len(url, full, user_agent, http11, max_len, cb, data) \ - purple_util_fetch_url_request_len(url, full, user_agent, http11, NULL, \ + purple_util_fetch_url_request_len(NULL, url, full, user_agent, http11, NULL, \ FALSE, max_len, cb, data); /** @@ -1164,28 +1164,6 @@ /** * Fetches the data from a URL, and passes it to a callback function. * - * @param url The URL. - * @param full TRUE if this is the full URL, or FALSE if it's a - * partial URL. - * @param user_agent The user agent field to use, or NULL. - * @param http11 TRUE if HTTP/1.1 should be used to download the file. - * @param request A HTTP request to send to the server instead of the - * standard GET - * @param include_headers - * If TRUE, include the HTTP headers in the response. - * @param max_len The maximum number of bytes to retrieve (-1 for unlimited) - * @param callback The callback function. - * @param data The user data to pass to the callback function. - * @deprecated In 3.0.0, this will go away. - */ -PurpleUtilFetchUrlData *purple_util_fetch_url_request_len(const gchar *url, - gboolean full, const gchar *user_agent, gboolean http11, - const gchar *request, gboolean include_headers, gssize max_len, - PurpleUtilFetchUrlCallback callback, gpointer data); - -/** - * Fetches the data from a URL, and passes it to a callback function. - * * @param account The account for which the request is needed, or NULL. * @param url The URL. * @param full TRUE if this is the full URL, or FALSE if it's a @@ -1201,7 +1179,7 @@ * @param data The user data to pass to the callback function. * @deprecated In 3.0.0, we'll rename this to "purple_util_fetch_url_request" and get rid of the old one */ -PurpleUtilFetchUrlData *purple_util_fetch_url_request_len_with_account( +PurpleUtilFetchUrlData *purple_util_fetch_url_request_len( PurpleAccount *account, const gchar *url, gboolean full, const gchar *user_agent, gboolean http11, const gchar *request, gboolean include_headers, gssize max_len, @@ -1450,16 +1428,6 @@ const char *purple_escape_filename(const char *str); /** - * This is added temporarily to assist the split of oscar into aim and icq. - * This should not be used by plugins. - * - * @deprecated This function should not be used in new code and should be - * removed in 3.0.0. The aim/icq prpl split happened a long - * time ago, and we don't need to keep migrating old data. - */ -const char *_purple_oscar_convert(const char *act, const char *protocol); - -/** * Restore default signal handlers for signals which might reasonably have * handlers. This should be called by a fork()'d child process, since child processes * inherit the handlers of the parent. diff -r 8c6254c23e32 -r e44af4d2e01b libpurple/xmlnode.h --- a/libpurple/xmlnode.h Sun Aug 21 23:45:07 2011 +0000 +++ b/libpurple/xmlnode.h Mon Aug 22 16:00:57 2011 +0000 @@ -35,7 +35,7 @@ /** * The valid types for an xmlnode */ -typedef enum _XMLNodeType +typedef enum { XMLNODE_TYPE_TAG, /**< Just a tag */ XMLNODE_TYPE_ATTRIB, /**< Has attributes */ diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/Makefile.am --- a/pidgin/Makefile.am Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/Makefile.am Mon Aug 22 16:00:57 2011 +0000 @@ -3,8 +3,8 @@ getopt.h \ getopt1.c \ Makefile.mingw \ - pidgin.pc.in \ - pidgin-uninstalled.pc.in \ + pidgin-3.pc.in \ + pidgin-3-uninstalled.pc.in \ win32/MinimizeToTray.h \ win32/MinimizeToTray.c \ win32/pidgin_dll_rc.rc.in \ @@ -32,7 +32,7 @@ if ENABLE_GTK pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = pidgin.pc +pkgconfig_DATA = pidgin-3.pc SUBDIRS = pixmaps plugins @@ -107,7 +107,6 @@ gtkicon-theme.h \ gtkicon-theme-loader.h \ gtkidle.h \ - gtkgaim-compat.h \ gtkimhtml.h \ gtkimhtmltoolbar.h \ gtklog.h \ diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkblist.c Mon Aug 22 16:00:57 2011 +0000 @@ -3774,10 +3774,8 @@ connections = purple_connections_get_all(); if (full && connections && connections->next) { - tmp = g_markup_escape_text(purple_account_get_username( - purple_buddy_get_account(b)), -1); - purple_notify_user_info_add_pair(user_info, _("Account"), tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Account"), + purple_account_get_username(purple_buddy_get_account(b))); } /* Alias */ @@ -3787,9 +3785,8 @@ (c->alias != NULL && c->alias[0] != '\0') && strcmp(c->alias, b->alias) != 0) { - tmp = g_markup_escape_text(b->alias, -1); - purple_notify_user_info_add_pair(user_info, _("Buddy Alias"), tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, + _("Buddy Alias"), b->alias); } /* Nickname/Server Alias */ @@ -3799,9 +3796,8 @@ * to look at the tooltip. */ if (full && b->server_alias != NULL && b->server_alias[0] != '\0') { - tmp = g_markup_escape_text(b->server_alias, -1); - purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, + _("Nickname"), b->server_alias); } /* Logged In */ @@ -3817,7 +3813,7 @@ tmp = g_strdup(purple_date_format_long(localtime(&signon))); } else tmp = purple_str_seconds_to_string(time(NULL) - signon); - purple_notify_user_info_add_pair(user_info, _("Logged In"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Logged In"), tmp); g_free(tmp); } @@ -3828,7 +3824,7 @@ if (idle_secs > 0) { tmp = purple_str_seconds_to_string(time(NULL) - idle_secs); - purple_notify_user_info_add_pair(user_info, _("Idle"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), tmp); g_free(tmp); } } @@ -3863,7 +3859,7 @@ if (lastseen > 0) { tmp = purple_str_seconds_to_string(time(NULL) - lastseen); - purple_notify_user_info_add_pair(user_info, _("Last Seen"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Last Seen"), tmp); g_free(tmp); } } @@ -3873,7 +3869,7 @@ /* FIXME: Why is this status special-cased by the core? --rlaager * FIXME: Alternatively, why not have the core do all of them? --rlaager */ if (!PURPLE_BUDDY_IS_ONLINE(b)) { - purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline")); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Offline")); } if (purple_account_is_connected(b->account) && @@ -3885,11 +3881,11 @@ /* These are Easter Eggs. Patches to remove them will be rejected. */ if (!g_ascii_strcasecmp(b->name, "robflynn")) - purple_notify_user_info_add_pair(user_info, _("Description"), _("Spooky")); + purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), _("Spooky")); if (!g_ascii_strcasecmp(b->name, "seanegn")) - purple_notify_user_info_add_pair(user_info, _("Status"), _("Awesome")); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Awesome")); if (!g_ascii_strcasecmp(b->name, "chipx86")) - purple_notify_user_info_add_pair(user_info, _("Status"), _("Rockin'")); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Rockin'")); tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n"); g_string_append(str, tmp); @@ -3904,24 +3900,21 @@ user_info = purple_notify_user_info_new(); count = purple_blist_get_group_online_count(group); - if (count != 0) { /* Online buddies in group */ - tmp = g_strdup_printf("%d", count); - purple_notify_user_info_add_pair(user_info, - _("Online Buddies"), - tmp); - g_free(tmp); + char tmp2[12]; + sprintf(tmp2, "%d", count); + purple_notify_user_info_add_pair_plaintext(user_info, + _("Online Buddies"), tmp2); } count = purple_blist_get_group_size(group, FALSE); if (count != 0) { /* Total buddies (from online accounts) in group */ - tmp = g_strdup_printf("%d", count); - purple_notify_user_info_add_pair(user_info, - _("Total Buddies"), - tmp); - g_free(tmp); + char tmp2[12]; + sprintf(tmp2, "%d", count); + purple_notify_user_info_add_pair_html(user_info, + _("Total Buddies"), tmp2); } tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n"); @@ -5343,6 +5336,28 @@ } +/** + * Was used by the connection API to tell the blist if an account has a + * connection error or no longer has a connection error, but the blist now does + * this itself with the @ref account-error-changed signal. + * + * @param account The account that either has a connection error + * or no longer has a connection error. + * @param message The connection error message, or NULL if this + * account is no longer in an error state. + */ +static void +pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text) +{ + /* connection_errors isn't actually used anywhere; it's just kept in + * sync with reality in case a plugin uses it. + */ + if (text == NULL) + g_hash_table_remove(gtkblist->connection_errors, account); + else + g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text)); +} + /* Call appropriate error notification code based on error types */ static void update_account_error_state(PurpleAccount *account, @@ -5427,18 +5442,6 @@ } } -void -pidgin_blist_update_account_error_state(PurpleAccount *account, const char *text) -{ - /* connection_errors isn't actually used anywhere; it's just kept in - * sync with reality in case a plugin uses it. - */ - if (text == NULL) - g_hash_table_remove(gtkblist->connection_errors, account); - else - g_hash_table_insert(gtkblist->connection_errors, account, g_strdup(text)); -} - static gboolean paint_headline_hbox (GtkWidget *widget, GdkEventExpose *event, diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkblist.h --- a/pidgin/gtkblist.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkblist.h Mon Aug 22 16:00:57 2011 +0000 @@ -370,20 +370,6 @@ void pidgin_append_blist_node_extended_menu(GtkWidget *menu, PurpleBlistNode *node); /** - * Was used by the connection API to tell the blist if an account has a - * connection error or no longer has a connection error, but the blist now does - * this itself with the @ref account-error-changed signal. - * - * @param account The account that either has a connection error - * or no longer has a connection error. - * @param message The connection error message, or NULL if this - * account is no longer in an error state. - * @deprecated There was no good reason for code other than gtkconn to call - * this. - */ -void pidgin_blist_update_account_error_state(PurpleAccount *account, const char *message); - -/** * Sets a headline notification * * This is currently used for mail notification, but could theoretically be used for anything. diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkconn.c --- a/pidgin/gtkconn.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkconn.c Mon Aug 22 16:00:57 2011 +0000 @@ -136,9 +136,9 @@ } static void -pidgin_connection_report_disconnect_reason (PurpleConnection *gc, - PurpleConnectionError reason, - const char *text) +pidgin_connection_report_disconnect(PurpleConnection *gc, + PurpleConnectionError reason, + const char *text) { PurpleAccount *account = NULL; PidginAutoRecon *info; @@ -215,10 +215,9 @@ pidgin_connection_connected, pidgin_connection_disconnected, pidgin_connection_notice, - NULL, /* report_disconnect */ pidgin_connection_network_connected, pidgin_connection_network_disconnected, - pidgin_connection_report_disconnect_reason, + pidgin_connection_report_disconnect, NULL, NULL, NULL diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkconv.c Mon Aug 22 16:00:57 2011 +0000 @@ -578,7 +578,7 @@ gtk_widget_grab_focus(gtkconv->entry); - if (strlen(clean) == 0) { + if (!*clean) { g_free(buf); g_free(clean); return; diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkconv.h --- a/pidgin/gtkconv.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkconv.h Mon Aug 22 16:00:57 2011 +0000 @@ -132,8 +132,8 @@ GtkTextBuffer *entry_buffer; GtkWidget *entry; gboolean auto_resize; /* this is set to TRUE if the conversation - * is being resized by a non-user-initiated - * event, such as the buddy icon appearing + * is being resized by a non-user-initiated + * event, such as the buddy icon appearing */ gboolean entry_growing; /* True if the size of the entry was set * automatically by typing too much to fit @@ -144,12 +144,6 @@ GtkWidget *tab_label; GtkWidget *menu_icon; GtkWidget *menu_label; -#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKCONV_C_) - /** @deprecated */ - GtkSizeGroup *sg; -#else - gpointer depr1; -#endif GtkWidget *lower_hbox; diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkdialogs.c Mon Aug 22 16:00:57 2011 +0000 @@ -1114,26 +1114,6 @@ } static void -pidgin_dialogs_alias_contact_cb(PurpleContact *contact, const char *new_alias) -{ - purple_blist_alias_contact(contact, new_alias); -} - -void -pidgin_dialogs_alias_contact(PurpleContact *contact) -{ - g_return_if_fail(contact != NULL); - - purple_request_input(NULL, _("Alias Contact"), NULL, - _("Enter an alias for this contact."), - contact->alias, FALSE, FALSE, NULL, - _("Alias"), G_CALLBACK(pidgin_dialogs_alias_contact_cb), - _("Cancel"), NULL, - NULL, purple_contact_get_alias(contact), NULL, - contact); -} - -static void pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias) { purple_blist_alias_buddy(buddy, new_alias); diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkdialogs.h --- a/pidgin/gtkdialogs.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkdialogs.h Mon Aug 22 16:00:57 2011 +0000 @@ -42,14 +42,6 @@ void pidgin_dialogs_info(void); void pidgin_dialogs_log(void); -#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKDIALOGS_C_) -/** - * @deprecated This function is no longer used and will be removed in - * Pidgin 3.0.0 unless there is sufficient demand to keep it. - */ -void pidgin_dialogs_alias_contact(PurpleContact *); -#endif - void pidgin_dialogs_alias_buddy(PurpleBuddy *); void pidgin_dialogs_alias_chat(PurpleChat *); void pidgin_dialogs_remove_buddy(PurpleBuddy *); @@ -58,15 +50,7 @@ void pidgin_dialogs_remove_contact(PurpleContact *); void pidgin_dialogs_merge_groups(PurpleGroup *, const char *); -/* Everything after this should probably be moved elsewhere */ - -#ifndef PIDGIN_DISABLE_DEPRECATED -/* This PIDGIN_DISABLE_DEPRECATED doesn't need to be deactivated by - * _PIDGIN_GTKDIALOGS_C_, because it shouldn't be using this macro. */ -#define PIDGIN_DIALOG(x) x = gtk_window_new(GTK_WINDOW_TOPLEVEL); \ - gtk_window_set_type_hint(GTK_WINDOW(x), GDK_WINDOW_TYPE_HINT_DIALOG) -#endif - +/* This macro should probably be moved elsewhere */ #define PIDGIN_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED) #endif /* _PIDGINDIALOGS_H_ */ diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkgaim-compat.h --- a/pidgin/gtkgaim-compat.h Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/** - * @file gtkgaim-compat.h Gtk Gaim Compat macros - */ - -/* pidgin - * - * Pidgin is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * 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 - * - */ -#ifndef _GTKGAIM_COMPAT_H_ -#define _GTKGAIM_COMPAT_H_ - -#include - -#define GAIM_ALERT_TITLE PIDGIN_ALERT_TITLE -#define GAIM_BROWSER_CURRENT PIDGIN_BROWSER_CURRENT -#define GAIM_BROWSER_DEFAULT PIDGIN_BROWSER_DEFAULT -#define GAIM_BROWSER_NEW_TAB PIDGIN_BROWSER_NEW_TAB -#define GAIM_BROWSER_NEW_WINDOW PIDGIN_BROWSER_NEW_WINDOW -#define GaimBrowserPlace PidginBrowserPlace -#define GAIM_BUTTON_HORIZONTAL PIDGIN_BUTTON_HORIZONTAL -#define GAIM_BUTTON_IMAGE PIDGIN_BUTTON_IMAGE -#define GAIM_BUTTON_NONE PIDGIN_BUTTON_NONE -#define GaimButtonOrientation PidginButtonOrientation -#define GaimButtonStyle PidginButtonStyle -#define GAIM_BUTTON_TEXT_IMAGE PIDGIN_BUTTON_TEXT_IMAGE -#define GAIM_BUTTON_TEXT PIDGIN_BUTTON_TEXT -#define GAIM_BUTTON_VERTICAL PIDGIN_BUTTON_VERTICAL -#define GaimConvPlacementFunc PidginConvPlacementFunc -#define GAIM_DIALOG PIDGIN_DIALOG -#define gaim_dnd_file_manage pidgin_dnd_file_manage -#define gaim_get_gtkxfer_dialog pidgin_get_xfer_dialog -#define gaim_gtk_account_dialog_show pidgin_account_dialog_show -#define GaimGtkAccountDialogType PidginAccountDialogType -#define gaim_gtk_account_get_handle pidgin_account_get_handle -#define gaim_gtk_account_init pidgin_account_init -#define gaim_gtk_account_option_menu_get_selected pidgin_account_option_menu_get_selected -#define gaim_gtk_account_option_menu_new pidgin_account_option_menu_new -#define gaim_gtk_account_option_menu_set_selected pidgin_account_option_menu_set_selected -#define gaim_gtk_accounts_get_ui_ops pidgin_accounts_get_ui_ops -#define gaim_gtk_accounts_window_hide pidgin_accounts_window_hide -#define gaim_gtk_accounts_window_show pidgin_accounts_window_show -#define gaim_gtk_account_uninit pidgin_account_uninit -#define GAIM_GTK_ADD_ACCOUNT_DIALOG PIDGIN_ADD_ACCOUNT_DIALOG -#define gaim_gtk_append_blist_node_extended_menu pidgin_append_blist_node_extended_menu -#define gaim_gtk_append_blist_node_privacy_menu pidgin_append_blist_node_privacy_menu -#define gaim_gtk_append_blist_node_proto_menu pidgin_append_blist_node_proto_menu -#define gaim_gtk_append_menu_action pidgin_append_menu_action -#define gaim_gtk_blist_add_alert pidgin_blist_add_alert -#define gaim_gtk_blist_get_default_gtk_blist pidgin_blist_get_default_gtk_blist -#define gaim_gtk_blist_get_handle pidgin_blist_get_handle -#define gaim_gtk_blist_get_sort_methods pidgin_blist_get_sort_methods -#define gaim_gtk_blist_get_status_icon pidgin_blist_get_status_icon -#define gaim_gtk_blist_get_ui_ops pidgin_blist_get_ui_ops -#define gaim_gtk_blist_init pidgin_blist_init -#define gaim_gtk_blist_joinchat_is_showable pidgin_blist_joinchat_is_showable -#define gaim_gtk_blist_joinchat_show pidgin_blist_joinchat_show -#define gaim_gtk_blist_make_buddy_menu pidgin_blist_make_buddy_menu -#define gaim_gtk_blist_node_is_contact_expanded pidgin_blist_node_is_contact_expanded -#define GAIM_GTK_BLIST PIDGIN_BLIST -#define gaim_gtk_blist_refresh pidgin_blist_refresh -#define gaim_gtk_blist_set_headline pidgin_blist_set_headline -#define gaim_gtk_blist_setup_sort_methods pidgin_blist_setup_sort_methods -#define gaim_gtk_blist_sort_function pidgin_blist_sort_function -#define gaim_gtk_blist_sort_method pidgin_blist_sort_method -#define GaimGtkBlistSortMethod PidginBlistSortMethod -#define gaim_gtk_blist_sort_method_reg pidgin_blist_sort_method_reg -#define gaim_gtk_blist_sort_method_set pidgin_blist_sort_method_set -#define gaim_gtk_blist_sort_method_unreg pidgin_blist_sort_method_unreg -#define gaim_gtk_blist_toggle_visibility pidgin_blist_toggle_visibility -#define gaim_gtk_blist_uninit pidgin_blist_uninit -#define gaim_gtk_blist_update_account_error_state pidgin_blist_update_account_error_state -#define gaim_gtk_blist_update_accounts_menu pidgin_blist_update_accounts_menu -#define gaim_gtk_blist_update_columns pidgin_blist_update_columns -#define gaim_gtk_blist_update_plugin_actions pidgin_blist_update_plugin_actions -#define gaim_gtk_blist_update_refresh_timeout pidgin_blist_update_refresh_timeout -#define gaim_gtk_blist_update_sort_methods pidgin_blist_update_sort_methods -#define gaim_gtk_blist_visibility_manager_add pidgin_blist_visibility_manager_add -#define gaim_gtk_blist_visibility_manager_remove pidgin_blist_visibility_manager_remove -#define gaim_gtk_buddy_icon_chooser_new pidgin_buddy_icon_chooser_new -#define gaim_gtk_buddy_icon_get_scale_size pidgin_buddy_icon_get_scale_size -#define GaimGtkBuddyList PidginBuddyList -#define GaimGtkCellRendererExpanderClass PidginCellRendererExpanderClass -#define gaim_gtk_cell_renderer_expander_get_type pidgin_cell_renderer_expander_get_type -#define gaim_gtk_cell_renderer_expander_new pidgin_cell_renderer_expander_new -#define GaimGtkCellRendererExpander PidginCellRendererExpander -#define GaimGtkCellRendererProgressClass PidginCellRendererProgressClass -#define gaim_gtk_cell_renderer_progress_get_type pidgin_cell_renderer_progress_get_type -#define gaim_gtk_cell_renderer_progress_new pidgin_cell_renderer_progress_new -#define GaimGtkCellRendererProgress PidginCellRendererProgress -#define GaimGtkChatPane PidginChatPane -#define gaim_gtk_check_if_dir pidgin_check_if_dir -#define gaim_gtk_clear_cursor pidgin_clear_cursor -#define gaim_gtk_connection_get_handle pidgin_connection_get_handle -#define gaim_gtk_connection_init pidgin_connection_init -#define gaim_gtk_connections_get_ui_ops pidgin_connections_get_ui_ops -#define gaim_gtk_connection_uninit pidgin_connection_uninit -#define GaimGtkConversation PidginConversation -#define GAIM_GTK_CONVERSATION PIDGIN_CONVERSATION -#define gaim_gtk_conversations_fill_menu pidgin_conversations_fill_menu -#define gaim_gtk_conversations_find_unseen_list pidgin_conversations_find_unseen_list -#define gaim_gtk_conversations_get_conv_ui_ops pidgin_conversations_get_conv_ui_ops -#define gaim_gtk_conversations_get_handle pidgin_conversations_get_handle -#define gaim_gtk_conversations_init pidgin_conversations_init -#define gaim_gtk_conversations_uninit pidgin_conversations_uninit -#define gaim_gtk_convert_buddy_icon pidgin_convert_buddy_icon -#define gaim_gtkconv_get_tab_at_xy pidgin_conv_get_tab_at_xy -#define gaim_gtkconv_get_tab_icon pidgin_conv_get_tab_icon -#define gaim_gtkconv_get_window pidgin_conv_get_window -#define gaim_gtkconv_is_hidden pidgin_conv_is_hidden -#define gaim_gtkconv_new pidgin_conv_new -#define gaim_gtkconv_placement_add_fnc pidgin_conv_placement_add_fnc -#define gaim_gtkconv_placement_get_current_func pidgin_conv_placement_get_current_func -#define gaim_gtkconv_placement_get_fnc pidgin_conv_placement_get_fnc -#define gaim_gtkconv_placement_get_name pidgin_conv_placement_get_name -#define gaim_gtkconv_placement_get_options pidgin_conv_placement_get_options -#define gaim_gtkconv_placement_place pidgin_conv_placement_place -#define gaim_gtkconv_placement_remove_fnc pidgin_conv_placement_remove_fnc -#define gaim_gtkconv_placement_set_current_func pidgin_conv_placement_set_current_func -#define gaim_gtkconv_present_conversation pidgin_conv_present_conversation -#define gaim_gtkconv_switch_active_conversation pidgin_conv_switch_active_conversation -#define gaim_gtkconv_update_buddy_icon pidgin_conv_update_buddy_icon -#define gaim_gtkconv_update_buttons_by_protocol pidgin_conv_update_buttons_by_protocol -#define gaim_gtk_conv_window_add_gtkconv pidgin_conv_window_add_gtkconv -#define gaim_gtk_conv_window_destroy pidgin_conv_window_destroy -#define gaim_gtk_conv_window_first_with_type pidgin_conv_window_first_with_type -#define gaim_gtk_conv_window_get_active_conversation pidgin_conv_window_get_active_conversation -#define gaim_gtk_conv_window_get_active_gtkconv pidgin_conv_window_get_active_gtkconv -#define gaim_gtk_conv_window_get_at_xy pidgin_conv_window_get_at_xy -#define gaim_gtk_conv_window_get_gtkconv_at_index pidgin_conv_window_get_gtkconv_at_index -#define gaim_gtk_conv_window_get_gtkconv_count pidgin_conv_window_get_gtkconv_count -#define gaim_gtk_conv_window_get_gtkconvs pidgin_conv_window_get_gtkconvs -#define gaim_gtk_conv_window_has_focus pidgin_conv_window_has_focus -#define gaim_gtk_conv_window_hide pidgin_conv_window_hide -#define gaim_gtk_conv_window_is_active_conversation pidgin_conv_window_is_active_conversation -#define gaim_gtk_conv_window_last_with_type pidgin_conv_window_last_with_type -#define gaim_gtk_conv_window_new pidgin_conv_window_new -#define gaim_gtk_conv_window_raise pidgin_conv_window_raise -#define gaim_gtk_conv_window_remove_gtkconv pidgin_conv_window_remove_gtkconv -#define gaim_gtk_conv_windows_get_list pidgin_conv_windows_get_list -#define gaim_gtk_conv_window_show pidgin_conv_window_show -#define gaim_gtk_conv_window_switch_gtkconv pidgin_conv_window_switch_gtkconv -#define gaim_gtk_create_imhtml pidgin_create_imhtml -#define gaim_gtk_debug_get_handle pidgin_debug_get_handle -#define gaim_gtk_debug_get_ui_ops pidgin_debug_get_ui_ops -#define gaim_gtk_debug_init pidgin_debug_init -#define gaim_gtk_debug_uninit pidgin_debug_uninit -#define gaim_gtk_debug_window_hide pidgin_debug_window_hide -#define gaim_gtk_debug_window_show pidgin_debug_window_show -#define gaim_gtkdialogs_about pidgin_dialogs_about -#define gaim_gtkdialogs_alias_buddy pidgin_dialogs_alias_buddy -#define gaim_gtkdialogs_alias_chat pidgin_dialogs_alias_chat -#define gaim_gtkdialogs_alias_contact pidgin_dialogs_alias_contact -#define gaim_gtkdialogs_destroy_all pidgin_dialogs_destroy_all -#define gaim_gtkdialogs_im pidgin_dialogs_im -#define gaim_gtkdialogs_im_with_user pidgin_dialogs_im_with_user -#define gaim_gtkdialogs_info pidgin_dialogs_info -#define gaim_gtkdialogs_log pidgin_dialogs_log -#define gaim_gtkdialogs_merge_groups pidgin_dialogs_merge_groups -#define gaim_gtkdialogs_remove_buddy pidgin_dialogs_remove_buddy -#define gaim_gtkdialogs_remove_chat pidgin_dialogs_remove_chat -#define gaim_gtkdialogs_remove_contact pidgin_dialogs_remove_contact -#define gaim_gtkdialogs_remove_group pidgin_dialogs_remove_group -#define gaim_gtk_docklet_clicked pidgin_docklet_clicked -#define gaim_gtk_docklet_embedded pidgin_docklet_embedded -#define gaim_gtk_docklet_get_handle pidgin_docklet_get_handle -#define gaim_gtk_docklet_init pidgin_docklet_init -#define gaim_gtk_docklet_remove pidgin_docklet_remove -#define gaim_gtk_docklet_set_ui_ops pidgin_docklet_set_ui_ops -#define gaim_gtk_docklet_uninit pidgin_docklet_uninit -#define gaim_gtk_docklet_unload pidgin_docklet_unload -#define gaim_gtk_eventloop_get_ui_ops pidgin_eventloop_get_ui_ops -#define gaim_gtk_idle_get_ui_ops pidgin_idle_get_ui_ops -#define GaimGtkImPane PidginImPane -#define gaim_gtk_load_accels pidgin_load_accels -#define gaim_gtk_log_get_handle pidgin_log_get_handle -#define gaim_gtk_log_init pidgin_log_init -#define gaim_gtk_log_show_contact pidgin_log_show_contact -#define gaim_gtk_log_show pidgin_log_show -#define gaim_gtk_log_uninit pidgin_log_uninit -#define GaimGtkLogViewer PidginLogViewer -#define gaim_gtk_make_frame pidgin_make_frame -#define gaim_gtk_make_mini_dialog pidgin_make_mini_dialog -#define gaim_gtk_make_pretty_arrows pidgin_make_pretty_arrows -#define gaim_gtk_menu_tray_append pidgin_menu_tray_append -#define GaimGtkMenuTrayClass PidginMenuTrayClass -#define gaim_gtk_menu_tray_get_box pidgin_menu_tray_get_box -#define gaim_gtk_menu_tray_get_gtype pidgin_menu_tray_get_gtype -#define gaim_gtk_menu_tray_new pidgin_menu_tray_new -#define GaimGtkMenuTray PidginMenuTray -#define GAIM_GTK_MENU_TRAY PIDGIN_MENU_TRAY -#define gaim_gtk_menu_tray_prepend pidgin_menu_tray_prepend -#define gaim_gtk_menu_tray_set_tooltip pidgin_menu_tray_set_tooltip -#define GAIM_GTK_MODIFY_ACCOUNT_DIALOG PIDGIN_MODIFY_ACCOUNT_DIALOG -#define gaim_gtk_notify_get_ui_ops pidgin_notify_get_ui_ops -#define gaim_gtk_parse_x_im_contact pidgin_parse_x_im_contact -#define gaim_gtk_plugin_dialog_show pidgin_plugin_dialog_show -#define gaim_gtk_plugin_get_config_frame pidgin_plugin_get_config_frame -#define GAIM_GTK_PLUGIN PIDGIN_PLUGIN -#define gaim_gtk_plugin_pref_create_frame pidgin_plugin_pref_create_frame -#define gaim_gtk_plugins_save pidgin_plugins_save -#define GAIM_GTK_PLUGIN_TYPE PIDGIN_PLUGIN_TYPE -#define GaimGtkPluginUiInfo PidginPluginUiInfo -#define GAIM_GTK_PLUGIN_UI_INFO PIDGIN_PLUGIN_UI_INFO -#define gaim_gtk_pounce_editor_show pidgin_pounce_editor_show -#define gaim_gtk_pounces_get_handle pidgin_pounces_get_handle -#define gaim_gtk_pounces_init pidgin_pounces_init -#define gaim_gtk_pounces_manager_hide pidgin_pounces_manager_hide -#define gaim_gtk_pounces_manager_show pidgin_pounces_manager_show -#define gaim_gtk_prefs_checkbox pidgin_prefs_checkbox -#define gaim_gtk_prefs_dropdown_from_list pidgin_prefs_dropdown_from_list -#define gaim_gtk_prefs_dropdown pidgin_prefs_dropdown -#define gaim_gtk_prefs_init pidgin_prefs_init -#define gaim_gtk_prefs_labeled_entry pidgin_prefs_labeled_entry -#define gaim_gtk_prefs_labeled_spin_button pidgin_prefs_labeled_spin_button -#define gaim_gtk_prefs_show pidgin_prefs_show -#define gaim_gtk_prefs_update_old pidgin_prefs_update_old -#define gaim_gtk_privacy_dialog_hide pidgin_privacy_dialog_hide -#define gaim_gtk_privacy_dialog_show pidgin_privacy_dialog_show -#define gaim_gtk_privacy_get_ui_ops pidgin_privacy_get_ui_ops -#define gaim_gtk_privacy_init pidgin_privacy_init -#define gaim_gtk_protocol_option_menu_new pidgin_protocol_option_menu_new -#define gaim_gtk_request_add_block pidgin_request_add_block -#define gaim_gtk_request_add_permit pidgin_request_add_permit -#define gaim_gtk_request_get_ui_ops pidgin_request_get_ui_ops -#define gaim_gtk_roomlist_dialog_show pidgin_roomlist_dialog_show -#define gaim_gtk_roomlist_dialog_show_with_account pidgin_roomlist_dialog_show_with_account -#define gaim_gtk_roomlist_init pidgin_roomlist_init -#define gaim_gtk_roomlist_is_showable pidgin_roomlist_is_showable -#define gaim_gtk_save_accels_cb pidgin_save_accels_cb -#define gaim_gtk_save_accels pidgin_save_accels -#define gaim_gtk_session_end pidgin_session_end -#define gaim_gtk_session_init pidgin_session_init -#define gaim_gtk_set_cursor pidgin_set_cursor -#define gaim_gtk_set_custom_buddy_icon pidgin_set_custom_buddy_icon -#define gaim_gtk_set_sensitive_if_input pidgin_set_sensitive_if_input -#define gaim_gtk_setup_gtkspell pidgin_setup_gtkspell -#define gaim_gtk_setup_screenname_autocomplete pidgin_setup_screenname_autocomplete -#define gaim_gtk_set_urgent pidgin_set_urgent -#define gaim_gtk_sound_get_event_label pidgin_sound_get_event_label -#define gaim_gtk_sound_get_event_option pidgin_sound_get_event_option -#define gaim_gtk_sound_get_handle pidgin_sound_get_handle -#define gaim_gtk_sound_get_ui_ops pidgin_sound_get_ui_ops -#define gaim_gtk_status_editor_show pidgin_status_editor_show -#define gaim_gtk_status_get_handle pidgin_status_get_handle -#define gaim_gtk_status_init pidgin_status_init -#define gaim_gtk_status_menu pidgin_status_menu -#define gaim_gtk_status_uninit pidgin_status_uninit -#define gaim_gtk_status_window_hide pidgin_status_window_hide -#define gaim_gtk_status_window_show pidgin_status_window_show -#define gaim_gtk_stock_init pidgin_stock_init -#define gaim_gtk_syslog_show pidgin_syslog_show -#define gaim_gtkthemes_get_proto_smileys pidgin_themes_get_proto_smileys -#define gaim_gtkthemes_init pidgin_themes_init -#define gaim_gtkthemes_load_smiley_theme pidgin_themes_load_smiley_theme -#define gaim_gtkthemes_smileys_disabled pidgin_themes_smileys_disabled -#define gaim_gtkthemes_smiley_themeize pidgin_themes_smiley_themeize -#define gaim_gtkthemes_smiley_theme_probe pidgin_themes_smiley_theme_probe -#define gaim_gtk_toggle_sensitive_array pidgin_toggle_sensitive_array -#define gaim_gtk_toggle_sensitive pidgin_toggle_sensitive -#define gaim_gtk_toggle_showhide pidgin_toggle_showhide -#define gaim_gtk_treeview_popup_menu_position_func pidgin_treeview_popup_menu_position_func -#define gaim_gtk_tree_view_search_equal_func pidgin_tree_view_search_equal_func -#define GAIM_GTK_TYPE_MENU_TRAY PIDGIN_TYPE_MENU_TRAY -#define GAIM_GTK_UI PIDGIN_UI -#define gaim_gtk_whiteboard_get_ui_ops pidgin_whiteboard_get_ui_ops -#define GaimGtkWhiteboard PidginWhiteboard -#define GaimGtkWindow PidginWindow -#define gaim_gtkxfer_dialog_add_xfer pidgin_xfer_dialog_add_xfer -#define gaim_gtkxfer_dialog_cancel_xfer pidgin_xfer_dialog_cancel_xfer -#define gaim_gtkxfer_dialog_destroy pidgin_xfer_dialog_destroy -#define gaim_gtkxfer_dialog_hide pidgin_xfer_dialog_hide -#define gaim_gtkxfer_dialog_new pidgin_xfer_dialog_new -#define GaimGtkXferDialog PidginXferDialog -#define gaim_gtkxfer_dialog_remove_xfer pidgin_xfer_dialog_remove_xfer -#define gaim_gtkxfer_dialog_show pidgin_xfer_dialog_show -#define gaim_gtkxfer_dialog_update_xfer pidgin_xfer_dialog_update_xfer -#define gaim_gtk_xfers_get_ui_ops pidgin_xfers_get_ui_ops -#define gaim_gtk_xfers_init pidgin_xfers_init -#define gaim_gtk_xfers_uninit pidgin_xfers_uninit -#define GAIM_HIG_BORDER PIDGIN_HIG_BORDER -#define GAIM_HIG_BOX_SPACE PIDGIN_HIG_BOX_SPACE -#define GAIM_HIG_CAT_SPACE PIDGIN_HIG_CAT_SPACE -#if !GTK_CHECK_VERSION(2,16,0) -#define GAIM_INVISIBLE_CHAR PIDGIN_INVISIBLE_CHAR -#endif /* Less than GTK+ 2.16 */ -#define GAIM_IS_GTK_CONVERSATION PIDGIN_IS_PIDGIN_CONVERSATION -#define GAIM_IS_GTK_PLUGIN PIDGIN_IS_PIDGIN_PLUGIN -#define gaim_new_check_item pidgin_new_check_item -#define gaim_new_item_from_stock pidgin_new_item_from_stock -#define gaim_new_item pidgin_new_item -#define gaim_pixbuf_button_from_stock pidgin_pixbuf_button_from_stock -#define gaim_pixbuf_toolbar_button_from_stock pidgin_pixbuf_toolbar_button_from_stock -#define GaimScrollBookClass PidginScrollBookClass -#define gaim_scroll_book_get_type pidgin_scroll_book_get_type -#define gaim_scroll_book_new pidgin_scroll_book_new -#define GaimScrollBook PidginScrollBook -#define gaim_separator pidgin_separator -#define gaim_set_accessible_label pidgin_set_accessible_label -#define gaim_set_gtkxfer_dialog pidgin_set_xfer_dialog -#define gaim_setup_imhtml pidgin_setup_imhtml -#define gaim_status_box_add pidgin_status_box_add -#define gaim_status_box_add_separator pidgin_status_box_add_separator -#define GaimStatusBoxClass PidginStatusBoxClass -#define gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon -#define gaim_status_box_get_message pidgin_status_box_get_message -#define gaim_status_box_get_type pidgin_status_box_get_type -#define GaimStatusBoxItemType PidginStatusBoxItemType -#define gaim_status_box_new pidgin_status_box_new -#define gaim_status_box_new_with_account pidgin_status_box_new_with_account -#define GaimStatusBox PidginStatusBox -#define gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting -#define gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon -#define gaim_status_box_set_connecting pidgin_status_box_set_connecting -#define gaim_status_box_set_network_available pidgin_status_box_set_network_available -#define GAIM_STATUS_ICON_LARGE PIDGIN_STATUS_ICON_LARGE -#define GaimStatusIconSize PidginStatusIconSize -#define GAIM_STATUS_ICON_SMALL PIDGIN_STATUS_ICON_SMALL -#define GAIM_STOCK_ABOUT PIDGIN_STOCK_ABOUT -#define GAIM_STOCK_ACTION PIDGIN_STOCK_ACTION -#define GAIM_STOCK_ALIAS PIDGIN_STOCK_ALIAS -#define GAIM_STOCK_AWAY PIDGIN_STOCK_AWAY -#define GAIM_STOCK_CHAT PIDGIN_STOCK_CHAT -#define GAIM_STOCK_CLEAR PIDGIN_STOCK_CLEAR -#define GAIM_STOCK_CLOSE_TABS PIDGIN_STOCK_CLOSE_TABS -#define GAIM_STOCK_DEBUG PIDGIN_STOCK_DEBUG -#define GAIM_STOCK_DIALOG_AUTH PIDGIN_STOCK_DIALOG_AUTH -#define GAIM_STOCK_DIALOG_COOL PIDGIN_STOCK_DIALOG_COOL -#define GAIM_STOCK_DIALOG_ERROR PIDGIN_STOCK_DIALOG_ERROR -#define GAIM_STOCK_DIALOG_INFO PIDGIN_STOCK_DIALOG_INFO -#define GAIM_STOCK_DIALOG_QUESTION PIDGIN_STOCK_DIALOG_QUESTION -#define GAIM_STOCK_DIALOG_WARNING PIDGIN_STOCK_DIALOG_WARNING -#define GAIM_STOCK_DISCONNECT PIDGIN_STOCK_DISCONNECT -#define GAIM_STOCK_DOWNLOAD PIDGIN_STOCK_DOWNLOAD -#define GAIM_STOCK_EDIT PIDGIN_STOCK_EDIT -#define GAIM_STOCK_FGCOLOR PIDGIN_STOCK_FGCOLOR -#define GAIM_STOCK_FILE_CANCELED PIDGIN_STOCK_FILE_CANCELED -#define GAIM_STOCK_FILE_DONE PIDGIN_STOCK_FILE_DONE -#define GAIM_STOCK_FILE_TRANSFER PIDGIN_STOCK_FILE_TRANSFER -#define GAIM_STOCK_IGNORE PIDGIN_STOCK_IGNORE -#define GAIM_STOCK_IM "gaim-im" /* foo... */ -#define GAIM_STOCK_INVITE PIDGIN_STOCK_INVITE -#define GAIM_STOCK_MODIFY PIDGIN_STOCK_MODIFY -#define GAIM_STOCK_OPEN_MAIL PIDGIN_STOCK_OPEN_MAIL -#define GAIM_STOCK_PAUSE PIDGIN_STOCK_PAUSE -#define GAIM_STOCK_POUNCE PIDGIN_STOCK_POUNCE -#define GAIM_STOCK_SIGN_OFF PIDGIN_STOCK_SIGN_OFF -#define GAIM_STOCK_SIGN_ON PIDGIN_STOCK_SIGN_ON -#define GAIM_STOCK_STATUS_OFFLINE PIDGIN_STOCK_STATUS_OFFLINE -#define GAIM_STOCK_TEXT_NORMAL PIDGIN_STOCK_TEXT_NORMAL -#define GAIM_STOCK_TYPED PIDGIN_STOCK_TYPED -#define GAIM_STOCK_UPLOAD PIDGIN_STOCK_UPLOAD -#define GAIM_TYPE_GTK_CELL_RENDERER_EXPANDER PIDGIN_TYPE_GTK_CELL_RENDERER_EXPANDER -#define GAIM_TYPE_GTK_CELL_RENDERER_PROGRESS PIDGIN_TYPE_GTK_CELL_RENDERER_PROGRESS -#define GAIM_UNSEEN_EVENT PIDGIN_UNSEEN_EVENT -#define GAIM_UNSEEN_NICK PIDGIN_UNSEEN_NICK -#define GAIM_UNSEEN_NO_LOG PIDGIN_UNSEEN_NO_LOG -#define GAIM_UNSEEN_NONE PIDGIN_UNSEEN_NONE -#define GaimUnseenState PidginUnseenState -#define GAIM_UNSEEN_TEXT PIDGIN_UNSEEN_TEXT -#define GAIM_WINDOW_ICONIFIED PIDGIN_WINDOW_ICONIFIED -#define GTK_GAIM_IS_SCROLL_BOOK_CLASS PIDGIN_IS_SCROLL_BOOK_CLASS -#define GTK_GAIM_IS_SCROLL_BOOK PIDGIN_IS_SCROLL_BOOK -#define GTK_GAIM_IS_STATUS_BOX_CLASS PIDGIN_IS_STATUS_BOX_CLASS -#define GTK_GAIM_IS_STATUS_BOX PIDGIN_IS_STATUS_BOX -#define GTK_GAIM_SCROLL_BOOK_CLASS PIDGIN_SCROLL_BOOK_CLASS -#define GTK_GAIM_SCROLL_BOOK_GET_CLASS PIDGIN_SCROLL_BOOK_GET_CLASS -#define gtk_gaim_scroll_book_get_type pidgin_scroll_book_get_type -#define gtk_gaim_scroll_book_new pidgin_scroll_book_new -#define GTK_GAIM_SCROLL_BOOK PIDGIN_SCROLL_BOOK -#define gtk_gaim_status_box_add pidgin_status_box_add -#define gtk_gaim_status_box_add_separator pidgin_status_box_add_separator -#define GTK_GAIM_STATUS_BOX_CLASS PIDGIN_STATUS_BOX_CLASS -#define gtk_gaim_status_box_get_buddy_icon pidgin_status_box_get_buddy_icon -#define GTK_GAIM_STATUS_BOX_GET_CLASS PIDGIN_STATUS_BOX_GET_CLASS -#define gtk_gaim_status_box_get_message pidgin_status_box_get_message -#define gtk_gaim_status_box_get_type pidgin_status_box_get_type -#define GtkGaimStatusBoxItemType PidginStatusBoxItemType -#define gtk_gaim_status_box_new pidgin_status_box_new -#define gtk_gaim_status_box_new_with_account pidgin_status_box_new_with_account -#define GTK_GAIM_STATUS_BOX_NUM_TYPES PIDGIN_STATUS_BOX_NUM_TYPES -#define GtkGaimStatusBox PidginStatusBox -#define GTK_GAIM_STATUS_BOX PIDGIN_STATUS_BOX -#define gtk_gaim_status_box_pulse_connecting pidgin_status_box_pulse_connecting -#define gtk_gaim_status_box_set_buddy_icon pidgin_status_box_set_buddy_icon -#define gtk_gaim_status_box_set_connecting pidgin_status_box_set_connecting -#define gtk_gaim_status_box_set_network_available pidgin_status_box_set_network_available -#define GTK_GAIM_STATUS_BOX_TYPE_CUSTOM PIDGIN_STATUS_BOX_TYPE_CUSTOM -#define GTK_GAIM_STATUS_BOX_TYPE_POPULAR PIDGIN_STATUS_BOX_TYPE_POPULAR -#define GTK_GAIM_STATUS_BOX_TYPE_PRIMITIVE PIDGIN_STATUS_BOX_TYPE_PRIMITIVE -#define GTK_GAIM_STATUS_BOX_TYPE_SAVED PIDGIN_STATUS_BOX_TYPE_SAVED -#define GTK_GAIM_STATUS_BOX_TYPE_SEPARATOR PIDGIN_STATUS_BOX_TYPE_SEPARATOR -#define GTK_GAIM_TYPE_SCROLL_BOOK PIDGIN_TYPE_SCROLL_BOOK -#define GTK_GAIM_TYPE_STATUS_BOX PIDGIN_TYPE_STATUS_BOX - -#endif /* _GTKGAIM_COMPAT_H */ diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkimhtml.c Mon Aug 22 16:00:57 2011 +0000 @@ -5367,9 +5367,9 @@ tag = sl->data; /** don't worry about non-printing tags ending */ if (tag_ends_here(tag, &iter, &next_iter) && - strlen(tag_to_html_end(tag)) > 0 && - strlen(tag_to_html_start(tag)) > 0) { - + *tag_to_html_end(tag) && + *tag_to_html_start(tag)) + { PidginTextTagData *tmp; GQueue *r = g_queue_new(); diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkimhtml.h --- a/pidgin/gtkimhtml.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkimhtml.h Mon Aug 22 16:00:57 2011 +0000 @@ -135,16 +135,6 @@ GtkTextTag *link; } edit; -#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKIMHTML_C_) - /** @deprecated */ - char *clipboard_text_string; - /** @deprecated */ - char *clipboard_html_string; -#else - char *depr1; - char *depr2; -#endif - GSList *im_images; GtkIMHtmlFuncs *funcs; GtkSourceUndoManager *undo_manager; @@ -164,20 +154,6 @@ GList *protocols; /* List of GtkIMHtmlProtocol's */ }; -#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_) -/** @deprecated as of 2.7.10 */ -struct _GtkIMHtmlFontDetail { - gushort size; - gchar *face; - gchar *fore; - gchar *back; - gchar *bg; - gchar *sml; - gboolean underline; - gshort bold; -}; -#endif - struct _GtkSmileyTree { GString *values; GtkSmileyTree **children; diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkmain.c --- a/pidgin/gtkmain.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkmain.c Mon Aug 22 16:00:57 2011 +0000 @@ -498,7 +498,6 @@ int opt; gboolean gui_check; gboolean debug_enabled; - gboolean migration_failed = FALSE; GList *active_accounts; struct stat st; @@ -730,16 +729,6 @@ purple_debug_set_enabled(debug_enabled); - /* If we're using a custom configuration directory, we - * do NOT want to migrate, or weird things will happen. */ - if (opt_config_dir_arg == NULL) - { - if (!purple_core_migrate()) - { - migration_failed = TRUE; - } - } - search_path = g_build_filename(purple_user_dir(), "gtkrc-2.0", NULL); gtk_rc_add_default_file(search_path); g_free(search_path); @@ -765,37 +754,6 @@ winpidgin_init(hint); #endif - if (migration_failed) - { - char *old = g_strconcat(purple_home_dir(), - G_DIR_SEPARATOR_S ".gaim", NULL); - const char *text = _( - "%s encountered errors migrating your settings " - "from %s to %s. Please investigate and complete the " - "migration by hand. Please report this error at http://developer.pidgin.im"); - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - text, PIDGIN_NAME, - old, purple_user_dir()); - g_free(old); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_main_quit), NULL); - - gtk_widget_show_all(dialog); - - gtk_main(); - -#ifdef HAVE_SIGNAL_H - g_free(segfault_message); -#endif - return 0; - } - purple_core_set_ui_ops(pidgin_core_get_ui_ops()); purple_eventloop_set_ui_ops(pidgin_eventloop_get_ui_ops()); diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtknotify.c --- a/pidgin/gtknotify.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtknotify.c Mon Aug 22 16:00:57 2011 +0000 @@ -1035,6 +1035,10 @@ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, column->title, renderer, "text", i, NULL); + + if (!purple_notify_searchresult_column_is_visible(column)) + gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), i), FALSE); + i++; } diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkprefs.c Mon Aug 22 16:00:57 2011 +0000 @@ -2882,8 +2882,6 @@ { const char *str = NULL; - purple_prefs_rename("/gaim/gtk", PIDGIN_PREFS_ROOT); - /* Rename some old prefs */ purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims"); purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats"); @@ -2907,12 +2905,6 @@ purple_prefs_remove(PIDGIN_PREFS_ROOT "/browsers/command"); } - /* this string pref moved into the core, try to be friendly */ - purple_prefs_rename(PIDGIN_PREFS_ROOT "/idle/reporting_method", "/purple/away/idle_reporting"); - if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) && - strcmp(str, "gaim") == 0) - purple_prefs_set_string("/purple/away/idle_reporting", "purple"); - /* Remove some no-longer-used prefs */ purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/auto_expand_contacts"); purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/button_style"); diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkrequest.c Mon Aug 22 16:00:57 2011 +0000 @@ -857,6 +857,10 @@ gtk_text_buffer_set_text(buffer, value, -1); } +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(textview, purple_request_field_get_tooltip(field)); +#endif + gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), purple_request_field_string_is_editable(field)); @@ -881,6 +885,10 @@ if (value != NULL) gtk_entry_set_text(GTK_ENTRY(widget), value); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + if (purple_request_field_string_is_masked(field)) { gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE); @@ -921,6 +929,10 @@ gtk_entry_set_text(GTK_ENTRY(widget), buf); } +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + g_signal_connect(G_OBJECT(widget), "focus-out-event", G_CALLBACK(field_int_focus_out_cb), field); @@ -935,6 +947,10 @@ widget = gtk_check_button_new_with_label( purple_request_field_get_label(field)); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), purple_request_field_bool_get_default_value(field)); @@ -965,6 +981,10 @@ gtk_combo_box_set_active(GTK_COMBO_BOX(widget), purple_request_field_choice_get_default_value(field)); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(field_choice_menu_cb), field); } @@ -982,6 +1002,10 @@ widget = box; +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + for (l = labels, i = 0; l != NULL; l = l->next, i++) { const char *text = l->data; @@ -1024,6 +1048,10 @@ g_object_unref(G_OBJECT(buf)); g_object_unref(G_OBJECT(scale)); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + return widget; } @@ -1039,6 +1067,10 @@ purple_request_field_account_get_filter(field), field); +#if GTK_CHECK_VERSION(2,12,0) + gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field)); +#endif + return widget; } diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkutils.c --- a/pidgin/gtkutils.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkutils.c Mon Aug 22 16:00:57 2011 +0000 @@ -922,24 +922,6 @@ return optmenu; } -gboolean -pidgin_check_if_dir(const char *path, GtkFileSelection *filesel) -{ - char *dirname = NULL; - - if (g_file_test(path, G_FILE_TEST_IS_DIR)) { - /* append a / if needed */ - if (path[strlen(path) - 1] != G_DIR_SEPARATOR) { - dirname = g_strconcat(path, G_DIR_SEPARATOR_S, NULL); - } - gtk_file_selection_set_filename(filesel, (dirname != NULL) ? dirname : path); - g_free(dirname); - return TRUE; - } - - return FALSE; -} - void pidgin_setup_gtkspell(GtkTextView *textview) { @@ -1002,7 +984,7 @@ show_retrieveing_info(PurpleConnection *conn, const char *name) { PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); + purple_notify_user_info_add_pair_plaintext(info, _("Information"), _("Retrieving...")); purple_notify_userinfo(conn, name, info, NULL, NULL); purple_notify_user_info_destroy(info); } @@ -2181,13 +2163,6 @@ } } -void -pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *accountopt, gboolean all) { - pidgin_setup_screenname_autocomplete_with_filter(entry, accountopt, pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(all)); -} - - - void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type) { GdkCursor *cursor; @@ -2533,21 +2508,6 @@ return NULL; } -void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename) -{ - PurpleBuddy *buddy; - PurpleContact *contact; - - buddy = purple_find_buddy(account, who); - if (!buddy) { - purple_debug_info("custom-icon", "You can only set custom icon for someone in your buddylist.\n"); - return; - } - - contact = purple_buddy_get_contact(buddy); - purple_buddy_icons_node_set_custom_icon_from_file((PurpleBlistNode*)contact, filename); -} - char *pidgin_make_pretty_arrows(const char *str) { char *ret; diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/gtkutils.h --- a/pidgin/gtkutils.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/gtkutils.h Mon Aug 22 16:00:57 2011 +0000 @@ -384,39 +384,6 @@ gboolean pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts); /** - * Add autocompletion of screenames to an entry. - * - * @deprecated - * For new code, use the equivalent: - * #pidgin_setup_screenname_autocomplete_with_filter(@a entry, @a optmenu, - * #pidgin_screenname_autocomplete_default_filter, GINT_TO_POINTER(@a - * all)) - * - * @param entry The GtkEntry on which to setup autocomplete. - * @param optmenu A menu for accounts, returned by - * pidgin_account_option_menu_new(). If @a optmenu is not @c - * NULL, it'll be updated when a username is chosen from the - * autocomplete list. - * @param all Whether to include usernames from disconnected accounts. - */ -void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all); - -/** - * Check if the given path is a directory or not. If it is, then modify - * the given GtkFileSelection dialog so that it displays the given path. - * If the given path is not a directory, then do nothing. - * - * @param path The path entered in the file selection window by the user. - * @param filesel The file selection window. - * - * @return TRUE if given path is a directory, FALSE otherwise. - * @deprecated Pidgin no longer uses GtkFileSelection internally. It has also - * been deprecated by GTK+. Use GtkFileChooser instead and ignore - * this function. - */ -gboolean pidgin_check_if_dir(const char *path, GtkFileSelection *filesel); - -/** * Sets up GtkSpell for the given GtkTextView, reporting errors * if encountered. * @@ -661,19 +628,6 @@ */ gpointer pidgin_convert_buddy_icon(PurplePlugin *plugin, const char *path, size_t *len); -#if !(defined PIDGIN_DISABLE_DEPRECATED) || (defined _PIDGIN_GTKUTILS_C_) -/** - * Set or unset a custom buddyicon for a user. - * - * @param account The account the user belongs to. - * @param who The name of the user. - * @param filename The path of the custom icon. If this is @c NULL, then any - * previously set custom buddy icon for the user is removed. - * @deprecated See purple_buddy_icons_node_set_custom_icon_from_file() - */ -void pidgin_set_custom_buddy_icon(PurpleAccount *account, const char *who, const char *filename); -#endif - /** * Converts "->" and "<-" in strings to Unicode arrow characters, for use in referencing * menu items. diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin-2-uninstalled.pc.in --- a/pidgin/pidgin-2-uninstalled.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -abs_srcdir=@abs_srcdir@ -abs_builddir=@abs_builddir@ - -abs_top_srcdir=@abs_top_srcdir@ -abs_top_builddir=@abs_top_builddir@ - -plugindir=${libdir}/pidgin - -Name: Pidgin -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: gtk+-2.0 purple -Cflags: -I${abs_top_srcdir} diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin-2.pc.in --- a/pidgin/pidgin-2.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -plugindir=${libdir}/pidgin - -Name: Pidgin -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: gtk+-2.0 purple -Cflags: -I${includedir} diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin-3-uninstalled.pc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidgin-3-uninstalled.pc.in Mon Aug 22 16:00:57 2011 +0000 @@ -0,0 +1,21 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ + +abs_srcdir=@abs_srcdir@ +abs_builddir=@abs_builddir@ + +abs_top_srcdir=@abs_top_srcdir@ +abs_top_builddir=@abs_top_builddir@ + +plugindir=${libdir}/pidgin + +Name: Pidgin +Description: Pidgin is a GTK2-based instant messenger application. +Version: @VERSION@ +Requires: gtk+-2.0 purple-3 +Cflags: -I${abs_top_srcdir} diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin-3.pc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidgin-3.pc.in Mon Aug 22 16:00:57 2011 +0000 @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir=@datarootdir@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ + +plugindir=${libdir}/pidgin + +Name: Pidgin +Description: Pidgin is a GTK2-based instant messenger application. +Version: @VERSION@ +Requires: gtk+-2.0 purple-3 +Cflags: -I${includedir} diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin-uninstalled.pc.in --- a/pidgin/pidgin-uninstalled.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -abs_srcdir=@abs_srcdir@ -abs_builddir=@abs_builddir@ - -plugindir=${libdir}/pidgin - -Name: Pidgin -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: gtk+-2.0 purple -Cflags: -I${abs_srcdir} diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/pidgin.pc.in --- a/pidgin/pidgin.pc.in Sun Aug 21 23:45:07 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -plugindir=${libdir}/pidgin - -Name: Pidgin -Description: Pidgin is a GTK2-based instant messenger application. -Version: @VERSION@ -Requires: gtk+-2.0 purple -Cflags: -I${includedir}/pidgin - diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/plugins/perl/common/GtkBlist.xs --- a/pidgin/plugins/perl/common/GtkBlist.xs Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/plugins/perl/common/GtkBlist.xs Mon Aug 22 16:00:57 2011 +0000 @@ -69,8 +69,3 @@ void pidgin_blist_joinchat_show() - -void -pidgin_blist_update_account_error_state(account, message) - Purple::Account account - const char * message diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/plugins/perl/common/GtkDialogs.xs --- a/pidgin/plugins/perl/common/GtkDialogs.xs Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/plugins/perl/common/GtkDialogs.xs Mon Aug 22 16:00:57 2011 +0000 @@ -24,10 +24,6 @@ pidgin_dialogs_log() void -pidgin_dialogs_alias_contact(contact) - Purple::BuddyList::Contact contact - -void pidgin_dialogs_alias_buddy(buddy) Purple::BuddyList::Buddy buddy diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/plugins/relnot.c --- a/pidgin/plugins/relnot.c Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/plugins/relnot.c Mon Aug 22 16:00:57 2011 +0000 @@ -152,7 +152,7 @@ url, host); - purple_util_fetch_url_request_len(url, TRUE, NULL, FALSE, + purple_util_fetch_url_request_len(NULL, url, TRUE, NULL, FALSE, request, TRUE, -1, version_fetch_cb, NULL); g_free(request); diff -r 8c6254c23e32 -r e44af4d2e01b pidgin/win32/untar.h --- a/pidgin/win32/untar.h Sun Aug 21 23:45:07 2011 +0000 +++ b/pidgin/win32/untar.h Mon Aug 22 16:00:57 2011 +0000 @@ -12,7 +12,7 @@ extern "C" { #endif /* __cplusplus */ -typedef enum _untar_opt { +typedef enum { UNTAR_LISTING = (1 << 0), UNTAR_QUIET = (1 << 1), UNTAR_VERBOSE = (1 << 2),