Fwd: a user requests to add me as a friend,im robot exit and crash

hqlong houqinglong at gmail.com
Sat May 8 07:35:08 EDT 2010


---------- 已转发邮件 ----------
发件人: hqlong <houqinglong at gmail.com>
日期: 2010年5月7日 下午12:46
主题: Re: a user requests to add me as a friend,im robot exit and crash
收件人: Daniel Atallah <datallah at pidgin.im>


thank you for you reponse.

my use code below.
#include "purple.h"
#include <glib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include "defines.h"
#include "util.h"

/**
 * The following eventloop functions are used in both pidgin and
purple-text. If your
 * application uses glib mainloop, you can safely use this verbatim.
 */
#define PURPLE_GLIB_READ_COND  (G_IO_IN | G_IO_HUP | G_IO_ERR)
#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
char *callback_url;
static char *botim_debug;

typedef struct _PurpleGLibIOClosure {
       PurpleInputFunction function;
       guint result;
       gpointer data;
} PurpleGLibIOClosure;

static void purple_glib_io_destroy(gpointer data)
{
       g_free(data);
}

static gboolean purple_glib_io_invoke(GIOChannel *source, GIOCondition
condition, gpointer data)
{
       PurpleGLibIOClosure *closure = data;
       PurpleInputCondition purple_cond = 0;

       if (condition & PURPLE_GLIB_READ_COND)
               purple_cond |= PURPLE_INPUT_READ;
       if (condition & PURPLE_GLIB_WRITE_COND)
               purple_cond |= PURPLE_INPUT_WRITE;

       closure->function(closure->data, g_io_channel_unix_get_fd(source),
                         purple_cond);
       return TRUE;
}
static guint glib_input_add(gint fd, PurpleInputCondition condition,
PurpleInputFunction function,
                                                          gpointer data)
{
       PurpleGLibIOClosure *closure = g_new0(PurpleGLibIOClosure, 1);
       GIOChannel *channel;
       GIOCondition cond = 0;
       closure->function = function;
       closure->data = data;

       if (condition & PURPLE_INPUT_READ)
               cond |= PURPLE_GLIB_READ_COND;
       if (condition & PURPLE_INPUT_WRITE)
               cond |= PURPLE_GLIB_WRITE_COND;
       channel = g_io_channel_unix_new(fd);
       closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
                                             purple_glib_io_invoke,
closure, purple_glib_io_destroy);
       g_io_channel_unref(channel);

       return closure->result;
}

static PurpleEventLoopUiOps glib_eventloops =
{
       g_timeout_add,
       g_source_remove,
       glib_input_add,
       g_source_remove,
       NULL,
#if GLIB_CHECK_VERSION(2,14,0)
       g_timeout_add_seconds,
#else
       NULL,
#endif

       /* padding */
       NULL,
       NULL,
       NULL
};
/*** End of the eventloop functions. ***/
/*** Conversation uiops ***/
static void null_write_conv(PurpleConversation *conv, const char *who,
const char *alias,
                       const char *message, PurpleMessageFlags flags,
time_t mtime)
{
       const char *name;
       if (alias && *alias)
               name = alias;
       else if (who && *who)
               name = who;
       else
               name = NULL;

       /*printf("(%s) %s %s: %s\n", purple_conversation_get_name(conv),
                       purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)),
                       name, message);*/

   PurpleConversationType type;
   PurpleAccount *account;
   PurpleConnection *gc;

   account = purple_conversation_get_account(conv);
   gc = purple_conversation_get_gc(conv);
   g_return_if_fail(account != NULL);
   g_return_if_fail(gc != NULL);
   type = purple_conversation_get_type(conv);
   flags |= PURPLE_MESSAGE_SEND;

   //需要post的数据
   GString *data = g_string_new("publishContent=");
   g_string_append(data, url_encode(message));
   g_string_append(data, "&type=");
   g_string_append(data, url_encode(account->protocol_id));
   g_string_append(data, "&account=");
   g_string_append(data, url_encode(purple_conversation_get_name(conv)));


   char* rps_txt = http_post(callback_url, data->str);
   if (strlen(rps_txt) == 0) return;
   serv_send_im(gc, purple_conversation_get_name(conv),rps_txt, flags);
}

//会话创建时调用
static void null_create_conv(PurpleConversation *conv) {
   purple_debug_info("IMBOT","create conv");
}

//好友添加请求
static void *bot_purple_request_authorize(PurpleAccount *account,
                            const char *remote_user,
                            const char *id,
                            const char *alias,
                            const char *message,
                            gboolean on_list,
                            PurpleAccountRequestAuthorizationCb auth_cb,
                            PurpleAccountRequestAuthorizationCb deny_cb,
                            void *user_data)
{
   if (message != NULL && *message == '\0')
       message = NULL;

   //没在列表中,添加好友,并通过验证
   if (!on_list) {
       auth_cb(user_data);
       purple_blist_request_add_buddy(account,g_strdup(remote_user),NULL,g_strdup(alias));
   } else {
       auth_cb(user_data);
   }

}

static PurpleAccountUiOps bot_account_uiops =
{
   NULL,               /* notify added */
   NULL,               /* status changed */
   NULL,               /* request add */
   bot_purple_request_authorize,               /* request authorize */
   NULL,               /* close account request */
   NULL,
   NULL,
   NULL,
   NULL
};

static PurpleConversationUiOps null_conv_uiops =
{
       null_create_conv,          /* create_conversation  */
       NULL,                      /* destroy_conversation */
       NULL,                      /* write_chat           */
       NULL,                      /* write_im             */
       null_write_conv,           /* write_conv           */
       NULL,                      /* chat_add_users       */
       NULL,                      /* chat_rename_user     */
       NULL,                      /* chat_remove_users    */
       NULL,                      /* chat_update_user     */
       NULL,                      /* present              */
       NULL,                      /* has_focus            */
       NULL,                      /* custom_smiley_add    */
       NULL,                      /* custom_smiley_write  */
       NULL,                      /* custom_smiley_close  */
       NULL,                      /* send_confirm         */
       NULL,
       NULL,
       NULL,
       NULL
};

void show_buddies(PurpleBuddyList *list) {
   purple_debug_info("IMBOT","sssss");
}

static void
null_ui_init(void)
{
       /**
        * This should initialize the UI components for all the modules. Here we
        * just initialize the UI for conversations.
        */
       purple_conversations_set_ui_ops(&null_conv_uiops);
   //purple_blist_set_ui_ops(&bot_blist_ui_ops);
  // purple_request_set_ui_ops(&bot_req_ops);
}

static PurpleCoreUiOps null_core_uiops =
{
       NULL,
       NULL,
       null_ui_init,
       NULL,

       /* padding */
       NULL,
       NULL,
       NULL,
       NULL
};

static void
init_libpurple(void)
{
       /* Set a custom user directory (optional) */
       purple_util_set_user_dir(CUSTOM_USER_DIRECTORY);

       /* We do not want any debugging for now to keep the noise to a
minimum. */
       //purple_debug_set_enabled(FALSE);
   //
   if (strcmp("true",botim_debug) == 0) purple_debug_set_enabled(TRUE);
   else purple_debug_set_enabled(FALSE);


       /* Set the core-uiops, which is used to
        *      - initialize the ui specific preferences.
        *      - initialize the debug ui.
        *      - initialize the ui components for all the modules.
        *      - uninitialize the ui components for all the modules when the
core terminates.
        */
       purple_core_set_ui_ops(&null_core_uiops);
   purple_accounts_set_ui_ops(&bot_account_uiops);
       /* Set the uiops for the eventloop. If your client is glib-based, you
can safely
        * copy this verbatim. */
       purple_eventloop_set_ui_ops(&glib_eventloops);

       /* Set path to search for plugins. The core (libpurple) takes care of
loading the
        * core-plugins, which includes the protocol-plugins. So it is not
essential to add
        * any path here, but it might be desired, especially for ui-specific
plugins. */
       purple_plugins_add_search_path(CUSTOM_PLUGIN_PATH);

       /* Now that all the essential stuff has been set, let's try to init
the core. It's
        * necessary to provide a non-NULL name for the current ui to the
core. This name
        * is used by stuff that depends on this ui, for example the
ui-specific plugins. */
       if (!purple_core_init(UI_ID)) {
               /* Initializing the core failed. Terminate. */
               fprintf(stderr,
                               "libpurple initialization failed.
Dumping core.\n"
                               "Please report this!\n");
               abort();
       }

       /* Create and load the buddylist. */
       purple_set_blist(purple_blist_new());
       purple_blist_load();

       /* Load the preferences. */
       purple_prefs_load();

       /* Load the desired plugins. The client should save the list of
loaded plugins in
        * the preferences using purple_plugins_save_loaded(PLUGIN_SAVE_PREF) */
       purple_plugins_load_saved(PLUGIN_SAVE_PREF);

       /* Load the pounces. */
       purple_pounces_load();
}



static void
signed_on(PurpleConnection *gc, gpointer null)
{
       PurpleAccount *account = purple_connection_get_account(gc);
       printf("Account connected: %s %s\n", account->username,
account->protocol_id);
}

static void
connect_to_signals_for_demonstration_purposes_only(void)
{
       static int handle;
   //PurpleConnection *gc = purple_connections_get_handle();
   //printf("DDDD%s\n",gc->proto_data->client_version);
       purple_signal_connect(purple_connections_get_handle(),
"signed-on", &handle,
                               PURPLE_CALLBACK(signed_on), NULL);
}

int main(int argc, char *argv[])
{
   //username password prpl callback_url
   if (argc < 6) {
       fprintf(stderr, "Usage: %s <username> <password> <prpl>
<callback_url> [<debug>]\n", argv[0]);
       return 1;
   }

       const char *prpl;
   const char *username;
       char *password;
       GMainLoop *loop = g_main_loop_new(NULL, FALSE);
       PurpleAccount *account;
       PurpleSavedStatus *status;

   username = argv[1];
   password = argv[2];
   prpl = argv[3];
   callback_url = argv[4];
   botim_debug = argv[5];
       /* libpurple's built-in DNS resolution forks processes to perform
        * blocking lookups without blocking the main process.  It does not
        * handle SIGCHLD itself, so if the UI does not you quickly get an army
        * of zombie subprocesses marching around.
        */
       signal(SIGCHLD, SIG_IGN);

       init_libpurple();

       /* Create the account */
       account = purple_account_new(username, prpl);

       /* Get the password for the account */
   purple_account_set_password(account, password);

   //qq使用2008版协议,并自动选择验证服务器
   if (strcmp("prpl-qq",account->protocol_id) == 0) {
       purple_account_set_string(account, "server", "auto");
       purple_account_set_string(account, "client_version", "qq2008");
   }
       /* It's necessary to enable the account first. */
       purple_account_set_enabled(account, UI_ID, TRUE);

       /* Now, to connect the account(s), create a status and activate it. */
       status = purple_savedstatus_new("NULL", PURPLE_STATUS_AVAILABLE);
       purple_savedstatus_activate(status);
   connect_to_signals_for_demonstration_purposes_only();
   g_main_loop_run(loop);

       return 0;
}

run log.


im robot run log below.

(12:34:22) msn: C: NS 000: PNG
(12:34:22) msn: S: NS 000: QNG 42
(12:34:23) msn: S: NS 000: ADL 0 87
(12:34:23) msn: Parsing received ADL XML data
(12:34:23) msn: Getting Contact List.
(12:34:23) soap: POST //abservice/SharingService.asmx HTTP/1.1
SOAPAction: http://www.msn.com/webservices/AddressBook/FindMembership
Content-Type:text/xml; charset=utf-8
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Accept: */*
Host: omega.contacts.msn.com
Content-Length: 2366
Connection: Keep-Alive
Cache-Control: no-cache

<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Header
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><ABApplicationHeader
xmlns='http://www.msn.com/webservices/AddressBook'><ApplicationId
xmlns='http://www.msn.com/webservices/AddressBook'>CFE80F9D-180F-4399-82AB-413F33A1FA11</ApplicationId><IsMigration
xmlns='http://www.msn.com/webservices/AddressBook'>false</IsMigration><PartnerScenario
xmlns='http://www.msn.com/webservices/AddressBook'>MessengerPendingList</PartnerScenario><CacheKey>14r2;RNZonVtw3nhs2PPlKXjQQek1F3dv87SZizToqwKYQfmVuhKxE85Ux+wzMCVrFK9QhkLNANzz4ZrKRKDYdXnCh8tJs5iSLkGCuO883b4qtT/ImOrFjro7YUa0ncB5EiTjQGDBa+4ReZ1BotI66R6soXUwLYr0Pzo62FKVU73D18Q=</CacheKey></ABApplicationHeader><ABAuthHeader
xmlns='http://www.msn.com/webservices/AddressBook'><ManagedGroupRequest
xmlns='http://www.msn.com/webservices/AddressBook'>false</ManagedGroupRequest><TicketToken>t=EwDgAcBdAAAURnMnP0xNtZi9ugdf902M4Br/7wKAAJrKsWloBfxQz80M1ak5YBgpAV1PVdSfcRt1/ghS9kBnmcuT5rBHqomO0rEFbIZOdPr0xY5VPbc5Dd52raQJ2Yi50qksqOl5nCSZRWdYudtGU+sAZjCn7DhW5/I2VtP2niL8xyk33OXPNengi0wNeMbCVC2VEImcUiunR+7ufekbA2YAAAhgIu4SCoKC/jAB6FeHb0A2/HH4TK6cc4ktVtmDvaRgN9H34X6bdaFix27VpdDY792XI+9JcwXIZAhprRCjXXk0VZqMEXiwtPJS6olCF38sUDf8sR27vBuEpElQ675JkW8tHVUcPfzzhP+v7l0w7qHTypQf8ARxepSvYx1w6WTk6v+Hq6XjUL7YqZjciMAxozZ74lZ2G1h3hKesfaaPJ0nbILxZ+A+Rgb0V/WDhvDEZnb+/SWtDgx5XTtBAh5I09MKZB3iSJP/sNcHZlmePvbmv1AgKM+5D/MxInj+z22kIUgmg0Zkhr5osr37VlGmz/Nt8/aQ+zTaNxzczgfDLIN9aFuxhbfGoCz8I+Ebv/au0wj7KbAC9kyIrplyutJkKc4QcV++MYLpvF2tGGTI0De8lU0ho27lMa6QVIVoB&p=</TicketToken></ABAuthHeader></soap:Header><soap:Body
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><FindMembership
xmlns='http://www.msn.com/webservices/AddressBook'><serviceFilter
xmlns='http://www.msn.com/webservices/AddressBook'><Types
xmlns='http://www.msn.com/webservices/AddressBook'><ServiceType
xmlns='http://www.msn.com/webservices/AddressBook'>Messenger</ServiceType><ServiceType
xmlns='http://www.msn.com/webservices/AddressBook'>Invitation</ServiceType><ServiceType
xmlns='http://www.msn.com/webservices/AddressBook'>SocialNetwork</ServiceType><ServiceType
xmlns='http://www.msn.com/webservices/AddressBook'>Space</ServiceType><ServiceType
xmlns='http://www.msn.com/webservices/AddressBook'>Profile</ServiceType></Types></serviceFilter></FindMembership></soap:Body></soap:Envelope>
(12:34:23) gnutls: send failed: Error in the push function.


Hope this information will help you to solve my problem!!  Thanks again.

2010/5/7 Daniel Atallah <datallah at pidgin.im>:
> 2010/5/7 hqlong <houqinglong at gmail.com>:
>> Hello all!
>>  I based on libpurple of pidgin2.6.6  development  an im robot, the
>> robot supports msn qq so on  protocol, login, post messages、 receiving
>> messages and have no problems, but when a user requests to add me as a
>> friend, this will automatically exit and crash, What is the reason for
>> this? Hope your can help me. Thank you.
>
> The most likely reason is a bug in your code.
>
> You are going to have to provide a lot more information for us to to
> be able to help you.
>
> -D
>
> _______________________________________________
> Devel mailing list
> Devel at pidgin.im
> http://pidgin.im/cgi-bin/mailman/listinfo/devel
>



--
祝好!
hqlong



-- 
祝好!
hqlong




More information about the Devel mailing list