Ejemplo n.º 1
0
static void _elim_connect_progress        ( PurpleConnection *gc ,
                                            const char     *text ,
                                            size_t          step ,
                                            size_t    step_count )
{
    PurpleAccount *acct = purple_connection_get_account( gc );
    fprintf( stderr, "(_elim_connect_progress)\n" );

    if( acct )
    {
        char       *ID    = new_elim_id();
        xmlnode    *alist = xnode_new( "alist" );
        xmlnode    *mcall = func_call( "elim-connection-progress", ID, alist );
        const char *aname = purple_account_get_username   ( acct );
        const char *proto = purple_account_get_protocol_id( acct );
        int         state = purple_connection_get_state   ( gc   );
        g_free( ID );

        AL_PTR ( alist, "account-uid" , acct       );
        AL_STR ( alist, "account-name", aname      );
        AL_STR ( alist, "im-protocol" , proto      );
        AL_INT ( alist, "step"        , step       );
        AL_INT ( alist, "step-count"  , step_count );        
        AL_STR ( alist, "message"     , text       );
        AL_ENUM( alist, "state"       , state      , ":connection-state" );

        add_outbound_sexp( mcall );
    }

}
Ejemplo n.º 2
0
static void _elim_report_disconnect_reason( PurpleConnection     *conn   ,
                                            PurpleConnectionError reason ,
                                            const char           *text   )
{
    PurpleAccount *acct = purple_connection_get_account( conn );
    if( acct )
    {
        char       *ID    = new_elim_id();
        xmlnode    *alist = xnode_new( "alist" );
        fprintf( stderr, "(_elim_report_disconnect_reason)\n" );

        xmlnode    *mcall = func_call( "elim-disconnect-reason", ID, alist );
        const char *aname = purple_account_get_username   ( acct );
        const char *proto = purple_account_get_protocol_id( acct );
        int         state = purple_connection_get_state   ( conn );
        g_free( ID );

        AL_PTR ( alist, "account-uid" , acct  );
        AL_STR ( alist, "account-name", aname );
        AL_STR ( alist, "im-protocol" , proto );
        AL_STR ( alist, "message"     , text  );
        AL_ENUM( alist, "reason-code" , reason, ":connection-error" );
        AL_ENUM( alist, "state"       , state , ":connection-state" );

        add_outbound_sexp( mcall );
    }
}
Ejemplo n.º 3
0
xmlnode * _h_elim_image ( const char *name ,
                          const char *id   ,
                          SEXP_VALUE *args ,
                          gpointer data    )
{
    ASSERT_ALISTP( args, id, name );
    xmlnode *rval = xnode_new( "alist" );
    int image_id  = (int)ALIST_VAL_INT( args, "image-id" );

    if( image_id <= 0 )
    {
        sexp_val_free( args );
        return response_error( EINVAL, id, name, "bad image ID" );
    }

    fprintf( stderr, "searching for image id %d\n", image_id );
    PurpleStoredImage *image = purple_imgstore_find_by_id( image_id );
    
    if( !image )
    {
        sexp_val_free( args );
        return response_error( ENOENT, id, name, "image ID not found" );
    }

    size_t size = IGET( image , size );

    AL_INT ( rval, "image-id"  , image_id );
    AL_INT ( rval, "image-size", size     );
    AL_STR ( rval, "image-file", IGET( image, filename  ) );
    AL_STR ( rval, "image-type", IGET( image, extension ) );
    AL_DATA( rval, "image-data", IGET( image, data      ) , size );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 4
0
static void _elim_chat_add_users       ( PurpleConversation *conv         ,
                                         GList              *cbuddies     ,
                                         gboolean            new_arrivals )
{
    char    *ID    = new_elim_id();
    xmlnode *args  = xnode_new( "alist" );
    xmlnode *list  = xnode_new( "list"  );
    xmlnode *mcall = func_call( "elim-chat-add-users", ID, args );
    g_free( ID );
    fprintf( stderr, "(_elim_chat_add_users)\n" );

    _elim_conv_args( args, conv );
    AL_BOOL( args, "new-arrivals" , new_arrivals );
    AL_NODE( args, "participants" , list         );

    fprintf( stderr, "(_elim_chat_add_users)\n" );

    for( ; cbuddies; cbuddies = cbuddies->next )
    {
        xmlnode             *cbuddy = xnode_new( "alist" );
        PurpleConvChatBuddy *pccb   = cbuddies->data;

        AL_STR ( cbuddy, "name"     , pccb->name      ? pccb->name      : "" );
        AL_STR ( cbuddy, "alias"    , pccb->alias     ? pccb->alias     : "" );
        AL_STR ( cbuddy, "alias-key", pccb->alias_key ? pccb->alias_key : "" );
        AL_ENUM( cbuddy, "flags"    , pccb->flags , ":conv-chat-buddy-flags" );
        AL_BOOL( cbuddy, "on-blist" , pccb->buddy );

        xnode_insert_child( list, cbuddy );
    }

    add_outbound_sexp( mcall );
    fprintf( stderr, "(_elim_chat_add_users:DONE)\n" );
}
Ejemplo n.º 5
0
static void _elim_write_conv ( PurpleConversation *conv    ,
                               const char         *name    ,
                               const char         *alias   ,
                               const char         *message ,
                               PurpleMessageFlags  flags   ,
                               time_t mtime                )
{
    char    *msg   = NULL;
    char    *ID    = new_elim_id();
    xmlnode *args  = xnode_new( "alist" );
    xmlnode *mcall = func_call( "elim-conv-write-sys", ID, args );
    g_free( ID );
    fprintf( stderr, "(_elim_write_conv)\n" );

    if( _elim_strippable( conv, flags ) )
        msg = purple_markup_strip_html( message );

    _elim_conv_args( args, conv );
    AL_STR ( args, "who"  , (name  ? name  : (alias ? alias : "")) );
    AL_STR ( args, "alias", (alias ? alias : (name  ? name  : "")) );
    AL_STR ( args, "text" , msg ? msg : message );
    AL_ENUM( args, "flags", flags , ":message-flags" );
    AL_INT ( args, "time" , mtime );

    if( msg ) g_free( msg );
    fprintf( stderr, "(elim-debug _elim_write_conv:DONE)\n" );
    add_outbound_sexp( mcall );
}
Ejemplo n.º 6
0
void __roomlist_insert_account( PurpleAccount *account, xmlnode *node )
{
    g_return_if_fail( account && node );

    const char *aname = purple_account_get_username    ( account );
    const char *proto = purple_account_get_protocol_id ( account );

    AL_PTR ( node, "account-uid"  , account );
    AL_STR ( node, "account-name" , aname   );
    AL_STR ( node, "im-protocol"  , proto   );
}
Ejemplo n.º 7
0
xmlnode * _h_elim_status ( const char *name ,
                           const char *id   ,
                           SEXP_VALUE *args ,
                           gpointer    data )
{
    fprintf(stderr, "(elim-debug entered _h_elim_status)");
    ASSERT_ALISTP( args, id, name );
    
    elim_ping();

    const char *sid   = ALIST_VAL_STR( args, "status-id"      );
    const char *mesg  = ALIST_VAL_STR( args, "status-message" );
    signed int _stype = ALIST_VAL_INT( args, "status-type"    );

    PurpleSavedStatus   *status = purple_savedstatus_find( sid );
    PurpleStatusPrimitive stype = PURPLE_STATUS_UNSET;

    // create a new status:
    if( !status )
    {
        CHECK_STATUS ( args, id, name, stype, _stype );
        status = purple_savedstatus_new( sid, stype );
        if( status )
        {
            if     ( mesg ) purple_savedstatus_set_message( status, mesg );
            else if( sid  ) purple_savedstatus_set_message( status, sid  );
        }
    }
    else
    {
        if( mesg ) purple_savedstatus_set_message( status, mesg );
    }

    if( !status )
    {
        sexp_val_free( args );
        return response_error( EINVAL, id, name, "Could not create status" );
    }

    purple_savedstatus_activate( status );

    xmlnode *rval = xnode_new( "alist" );
    AL_STR ( rval, "status-id"     , purple_savedstatus_get_title  (status) );
    AL_STR ( rval, "status-message", purple_savedstatus_get_message(status) );
    AL_ENUM( rval, "status-type"   , purple_savedstatus_get_type   (status) , 
             ":status-primitive"   );
    
    sexp_val_free( args );
    fprintf(stderr, "(elim-debug leaving _h_elim_status)");
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 8
0
static void _elim_roomlist_add ( PurpleRoomlist     *list ,
                                 PurpleRoomlistRoom *room )
{
    g_return_if_fail( list && room );

    xmlnode *alist  = xnode_new( "alist" );
    char    *ID     = new_elim_id();

    __roomlist_insert_account( list->account, alist );
    AL_PTR ( alist , "roomlist-id" , list          );
    AL_STR ( alist , "room-name"   , room->name    );
    AL_ENUM( alist , "room-type"   , room->type    , ":roomlist-room-type" );
    AL_PTR ( alist , "room-parent" , room->parent  );
    AL_BOOL( alist , "room-expanded-once", room->expanded_once );

    xmlnode *fields = xnode_new_child( alist, "alist" );
    xnode_set_attrib( fields, "name", "fields" );

    GList *listf = g_list_first( list->fields );
    GList *roomf = g_list_first( room->fields );

#define NNEXTT( a, b ) a = g_list_next( a ), b = g_list_next( b )
#define PTR_TO_BOOL(_p) (_p != NULL)

    for( ; listf && roomf ; NNEXTT( listf, roomf ) )
    {
        PurpleRoomlistField *f = (PurpleRoomlistField*) listf->data;
        switch( f->type )
        {
          case PURPLE_ROOMLIST_FIELD_BOOL:
            AL_BOOL( fields, f->name, PTR_TO_BOOL( roomf->data ) );
            break;

          case PURPLE_ROOMLIST_FIELD_INT:
            AL_INT ( fields, f->name, roomf->data );
            break;

          case PURPLE_ROOMLIST_FIELD_STRING:
            AL_STR ( fields, f->name, roomf->data );
            break;

          default:
            fprintf( stderr, "unsupported room list field type.\n" );
            break;
        }
    }

    xmlnode *mcall = func_call( "elim-roomlist-add", ID, alist );
    g_free( ID );
    add_outbound_sexp( mcall );
}
Ejemplo n.º 9
0
void __roomlist_add_list_field( gpointer _field, gpointer _parent )
{
    g_return_if_fail( _field && _parent );

    PurpleRoomlistField *field  = _field;
    xmlnode             *parent = _parent;
    xmlnode             *node   = xnode_new( "alist" );

    AL_ENUM( node , "field-type"  , field->type   , ":roomlist-field-type" );
    AL_STR ( node , "field-label" , field->label  );
    AL_STR ( node , "field-name"  , field->name   );
    AL_BOOL( node , "field-hidden", field->hidden );

    xnode_insert_child( parent, node );
}
Ejemplo n.º 10
0
xmlnode * _h_elim_set_icon ( const char *name , 
                             const char *id   ,
                             SEXP_VALUE *args , 
                             gpointer    data )
{
    ASSERT_ALISTP( args, id, name );

    elim_ping();
    
    const char *aname = ALIST_VAL_STR ( args, "account-name" );
    const char *proto = ALIST_VAL_STR ( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR ( args, "account-uid"  );
    const char *file  = ALIST_VAL_STR ( args, "icon-file"    );
    GString    *img   = ALIST_VAL_DATA( args, "icon-data"    );
    gchar      *bytes = NULL;
    gsize       len   = 0;
    gpointer    set   = NULL;
    PurpleAccount *acct =
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    if( !img && file && *file )
    {
        g_file_get_contents( file, &bytes, &len, NULL );
    }
    else if( img )
    {
        bytes = g_memdup( img->str, img->len );
        len   = img->len;
    }

    // the imgstore owns `bytes' after this, don't free it:
    set = purple_buddy_icons_set_account_icon( acct, (guchar *)bytes, len );

    xmlnode *rval = xnode_new( "alist" );
    AL_PTR ( rval, "account-uid" , acct );
    AL_STR ( rval, "account-name", purple_account_get_username   ( acct ) );
    AL_STR ( rval, "im-protocol" , purple_account_get_protocol_id( acct ) );
    AL_BOOL( rval, "has-icon"    , set ? TRUE : FALSE );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 11
0
xmlnode * _h_elim_init ( const char *name ,
                         const char *id   ,
                         SEXP_VALUE *args ,
                         gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    char    *dir = ALIST_VAL_STRING( args, "dot-dir" );
    char    *ui  = ALIST_VAL_STRING( args, "ui-id"   );
    gboolean dbg = ALIST_VAL_BOOL  ( args, "debug"   );

    if( !ui ) { ui = "elim"; }

    // libpurple initialisation:
    purple_util_set_user_dir       ( dir  );
    purple_util_init               ();
    purple_core_set_ui_ops         ( &elim_core_ui_ops         );
    purple_eventloop_set_ui_ops    ( &elim_eventloop_ui_ops    );
    purple_blist_set_ui_ops        ( &elim_blist_ui_ops        );
    purple_accounts_set_ui_ops     ( &elim_account_ui_ops      );
    purple_request_set_ui_ops      ( &elim_request_ui_ops      );
    purple_idle_set_ui_ops         ( &elim_idle_ui_ops         );
    purple_connections_set_ui_ops  ( &elim_connections_ui_ops  );
    purple_conversations_set_ui_ops( &elim_conversation_ui_ops );
    purple_notify_set_ui_ops       ( &elim_notify_ui_ops       );

    // load any data for init:    
    if( purple_get_core() == NULL )
    {
        // purple debug goes to stdout if we don't divert it here:
        g_set_print_handler( (GPrintFunc)_h_elim_warning );
        // look for plugins in user specified directory tree:
        char *ppath = g_build_filename( purple_user_dir(), "plugins", NULL );
        purple_plugins_add_search_path ( ppath );
        purple_debug_set_enabled( dbg );
        purple_core_init ( ui );
        purple_set_blist ( purple_blist_new() );
        purple_prefs_load();
        purple_blist_load();
        // glib signal initialisation:
        elim_ft_signals_init();
        // tidy up:
        g_free( ppath );
    }
    else
    {
        const char *cur_ui = purple_core_get_ui();
        if( strcmp( cur_ui, name ) )
        {
            sexp_val_free( args );
            return response_error( EINVAL, id, name, 
                                   "purple has already been initialised" );
        }
    }

    sexp_val_free( args );
    xmlnode *rval = xnode_new( "alist" );
    AL_STR( rval, "ui-id", purple_core_get_ui() );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 12
0
xmlnode * _h_elim_buddy_info ( const char *name ,
                               const char *id   ,
                               SEXP_VALUE *args ,
                               gpointer data    )
{
    ASSERT_ALISTP( args, id, name );
    
    PurpleAccount    *acct  = NULL;
    PurpleConnection *conn  = NULL;
    gpointer          a_uid = NULL;
    gpointer          b_uid = ALIST_VAL_PTR( args, "bnode-uid" );
    PurpleBlistNode  *bnode = find_blist_node_by_uid( b_uid, TRUE );
    PurpleBlistNodeType  bt = PURPLE_BLIST_OTHER_NODE;

    if( !bnode )
        HANDLER_FAIL( args, id, name, ENOENT, "no such buddy" );

    bt = purple_blist_node_get_type( bnode );
    switch( bt )
    {
      case PURPLE_BLIST_BUDDY_NODE:
        a_uid = purple_buddy_get_account( (PurpleBuddy *)bnode );
        break;
      default:
        HANDLER_FAIL( args, id, name, EINVAL, "unsupported buddy type" );
        break;
    }

    FETCH_ACCOUNT( args, id, name, acct, a_uid );
    
    conn = purple_account_get_connection( acct  );

    if( !conn )
        HANDLER_FAIL( args, id, name, ENXIO, "account disconnected" );

    xmlnode *rval = xnode_new( "alist" );
    AL_PTR ( rval, "bnode-uid"   , bnode );
    AL_PTR ( rval, "account-uid" , acct  );
    AL_STR ( rval, "account-name", purple_account_get_username   ( acct ) );
    AL_STR ( rval, "im-protocol" , purple_account_get_protocol_id( acct ) );

    serv_get_info( conn, purple_buddy_get_name( (PurpleBuddy *)bnode ) );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 13
0
static void _elim_chat_rename_user     ( PurpleConversation *conv      , 
                                         const char         *old_name  ,
                                         const char         *new_name  , 
                                         const char         *new_alias )
{
    char    *ID    = new_elim_id();
    xmlnode *args  = xnode_new( "alist" );
    xmlnode *mcall = func_call( "elim-chat-rename-user", ID, args );
    g_free( ID );
    fprintf( stderr, "(_elim_chat_rename_user)\n" );

    _elim_conv_args( args, conv );
    AL_STR( args, "old-name" , old_name  );
    AL_STR( args, "new-name" , new_name  );
    AL_STR( args, "new-alias", new_alias );
    
    add_outbound_sexp( mcall );
}
Ejemplo n.º 14
0
static void _elim_notify_added ( PurpleAccount *account    ,
                                 const char    *remote_user,
                                 const char    *id         ,
                                 const char    *alias      ,
                                 const char    *message    )
{
    xmlnode *alist = xnode_new( "alist" );
    char    *ID    = new_elim_id();
    fprintf( stderr, "(_elim_notify_added)\n" );

    AL_STR( alist, "user"         , remote_user  );
    AL_STR( alist, "alias"        , alias        );
    AL_STR( alist, "message"      , message      );
    AL_PTR( alist, "account-uid"  , account      );
    AL_STR( alist, "account-name" , purple_account_get_username   ( account ) );
    AL_STR( alist, "im-protocol"  , purple_account_get_protocol_id( account ) );
    xmlnode *mcall = func_call( "elim-account-notify-added", ID, alist );
    g_free( ID );
    add_outbound_sexp( mcall );
}
Ejemplo n.º 15
0
static void _elim_conv_args ( xmlnode *alist, PurpleConversation *conv )
{
    PurpleAccount *acct  = purple_conversation_get_account( conv );
    const char    *aname = purple_account_get_username    ( acct );
    const char    *proto = purple_account_get_protocol_id ( acct );
    const char    *title = purple_conversation_get_title  ( conv );
    const char    *cname = purple_conversation_get_name   ( conv );
    PurpleConnectionFlags  cflag = purple_conversation_get_features( conv );
    PurpleConversationType ctype = purple_conversation_get_type    ( conv );

    fprintf( stderr, "(_elim_conv_args)\n" );
    
    AL_STR ( alist, "account-name" , aname );
    AL_STR ( alist, "im-protocol"  , proto );
    AL_PTR ( alist, "account-uid"  , acct  );
    AL_PTR ( alist, "conv-uid"     , conv  );
    AL_STR ( alist, "conv-name"    , cname );
    AL_STR ( alist, "conv-title"   , title ? title : cname );
    AL_ENUM( alist, "conv-type"    , ctype , ":conversation-type" );
    AL_ENUM( alist, "conv-features", cflag , ":connection-flags"  );    
}
Ejemplo n.º 16
0
static void *_elim_request_authorise ( PurpleAccount *account      ,
                                       const char    *remote_user  ,
                                       const char    *id           ,
                                       const char    *alias        ,
                                       const char    *message      ,
                                       gboolean       on_list      ,
                                       PARA_CB        authorize_cb ,
                                       PARA_CB        deny_cb      ,
                                       void          *user_data    )
{
    CB_HANDLER *cbh   = g_new0( CB_HANDLER, 1 );
    AUI_RESP   *resp  = g_new0( AUI_RESP  , 1 );
    xmlnode    *alist = xnode_new( "alist" );
    char       *ID    = new_elim_id();
    fprintf( stderr, "(_elim_request_authorise)\n" );

    AL_STR ( alist, "user"        , remote_user  );
    AL_STR ( alist, "id"          , id           );
    AL_STR ( alist, "alias"       , alias        );
    AL_BOOL( alist, "on-list"     , on_list      );
    AL_STR ( alist, "message"     , message      );
    AL_PTR ( alist, "account-uid" , account      );
    AL_STR ( alist, "account-name", purple_account_get_username   ( account ) );
    AL_STR ( alist, "im-protocol" , purple_account_get_protocol_id( account ) );
    resp->ok   = authorize_cb;
    resp->nok  = deny_cb;
    resp->id   = ID;
    resp->data = user_data;
    cbh ->func = _elim_request_authorise_cb;
    cbh ->data = resp;
    store_cb_data( ID, cbh );
    xmlnode *mcall = func_call( "elim-account-request-auth", ID, alist );
    add_outbound_sexp( mcall );
    return cbh;
}
Ejemplo n.º 17
0
static void _elim_status_changed ( PurpleAccount *account ,
                                   PurpleStatus  *status  )
{
    xmlnode              *alist = xnode_new( "alist" );
    char                 *ID    = new_elim_id();
    fprintf( stderr, "(_elim_status_changed)\n" );

    PurpleStatusType     *type  = purple_status_get_type( status );
    PurpleStatusPrimitive statp = purple_status_type_get_primitive( type ); 

    AL_PTR ( alist, "account-uid" , account );
    AL_STR ( alist, "account-name", purple_account_get_username   ( account ) );
    AL_STR ( alist, "im-protocol" , purple_account_get_protocol_id( account ) );
    AL_STR ( alist, "status-name" , purple_status_get_name        ( status  ) );
    AL_ENUM( alist, "status-type" , statp, ":status-primitive" );
    AL_BOOL( alist, "connected"   , purple_account_is_connected   ( account ) );

    xmlnode *mcall = func_call( "elim-account-status-changed", ID, alist );

    g_free( ID );
    add_outbound_sexp( mcall );
}
Ejemplo n.º 18
0
static void _elim_notice ( PurpleConnection *conn, const char *msg )
{
    PurpleAccount *acct = purple_connection_get_account( conn );
    if( acct )
    {
        char       *ID    = new_elim_id();
        xmlnode    *alist = xnode_new( "alist" );
        xmlnode    *mcall = func_call( "elim-connection-state", ID, alist );
        const char *aname = purple_account_get_username   ( acct );
        const char *proto = purple_account_get_protocol_id( acct );
        int         state = purple_connection_get_state   ( conn );
        g_free( ID );

        AL_PTR ( alist, "account-uid" , acct  );
        AL_STR ( alist, "account-name", aname );
        AL_STR ( alist, "im-protocol" , proto );
        AL_STR ( alist, "message"     , msg   );
        AL_ENUM( alist, "state"       , state , ":connection-state" );

        add_outbound_sexp( mcall );
    }
}
Ejemplo n.º 19
0
xmlnode * _h_elim_send_file ( const char *name ,
                              const char *id   ,
                              SEXP_VALUE *args ,
                              gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    elim_ping();
    
    const char *aname = ALIST_VAL_STR( args, "account-name" );
    const char *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR( args, "account-uid"  );
    
    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    PurpleConnection *conn = purple_account_get_connection( acct );

    if( !conn )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "account not online" );
    }

    // file can be NULL, but that's Ok, it just triggers a req to the user:
    const char *b_arg = ALIST_VAL_STRING( args, "recipient" );
    const char *file  = ALIST_VAL_STRING( args, "filename"  );

    serv_send_file( conn, b_arg, file );

    // bname is a static buf allocated in purple_normalize: don't free it!
    // also, this means that bname is volatile, so use it immediately after
    // acquiring it, if you make any calls into libpurple they might invalidate
    // its state:
    const char *bname = purple_normalize( acct, b_arg );
    xmlnode    *rval  = xnode_new( "alist" );
    AL_PTR( rval, "account-uid" , acct  );
    AL_STR( rval, "recipient"   , bname );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 20
0
xmlnode * _h_elim_add_buddy ( const char *name ,
                              const char *id   ,
                              SEXP_VALUE *args ,
                              gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    elim_ping();
    
    int         loopc = 0;
    const char *aname = ALIST_VAL_STR( args, "account-name" );
    const char *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR( args, "account-uid"  );

    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    const char *b_arg = ALIST_VAL_STRING( args, "bnode-name" );
    const char *bname = purple_normalize( acct, b_arg        );
    const char *gname = ALIST_VAL_STRING( args, "group"      );
    if( !gname || !*gname ) gname = "Buddies";

    PurpleGroup *group = purple_group_new( gname );
    PurpleBuddy *buddy = purple_buddy_new( acct, bname, b_arg );
    PurpleBuddy *clone = NULL;
    //fprintf( stderr, "add-buddy( b: %p, g: %p )\n", buddy, group );
    // remove other references to this buddy
    purple_blist_add_buddy  ( buddy, NULL, group, NULL );
    purple_account_add_buddy( acct , buddy );
    while( ( clone = (PurpleBuddy*)find_blist_node_clone( buddy ) ) )
    {
        if( loopc++ > 99   ) 
        {
            fprintf( stderr, "ARGH! clone reaping looped: %d\n", loopc );
            break;
        }
        if( clone == buddy ) 
        { 
            fprintf( stderr, "ARGH! %p not a clone of %p\n", buddy, clone );
            break;
        }
        fprintf( stderr, "(removing clone %p %ld (of buddy: %p)\n", 
                 clone, (long)clone, buddy );
        fprintf( stderr, "   name : %s\n", purple_buddy_get_name(clone) );
        fprintf( stderr, "   group: %s)\n", 
                 purple_group_get_name( purple_buddy_get_group(clone) ) );
        purple_blist_remove_buddy( clone );
    }

    xmlnode *rval = xnode_new( "alist" );
    AL_PTR( rval, "account-uid" , acct  );
    AL_PTR( rval, "bnode-uid"   , buddy );
    AL_PTR( rval, "group-uid"   , group );
    AL_STR( rval, "bnode-name"  , purple_buddy_get_name         ( buddy ) );
    AL_STR( rval, "bnode-alias" , purple_buddy_get_alias        ( buddy ) );
    AL_STR( rval, "account-name", purple_account_get_username   ( acct  ) );
    AL_STR( rval, "im-protocol" , purple_account_get_protocol_id( acct  ) );
    AL_STR( rval, "group-name"  , purple_group_get_name         ( group ) );

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 21
0
xmlnode * _h_elim_message ( const char *name ,
                            const char *id   ,
                            SEXP_VALUE *args ,
                            gpointer data    )
{
    fprintf(stderr, "(elim-debug entered _h_elim_message)");
    ASSERT_ALISTP( args, id, name );
    
    elim_ping();

    const char *aname = ALIST_VAL_STR( args, "account-name" );
    const char *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR( args, "account-uid"  );

    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    PurpleConversationType pt = PURPLE_CONV_TYPE_UNKNOWN;
    gpointer             cuid = ALIST_VAL_PTR( args, "conv-uid"  );
    const char         *cname = ALIST_VAL_STR( args, "conv-name" );
    PurpleConversation    *pc = find_conv_by_acct_uid( acct, cuid );

    if  ( pc ) pt = purple_conversation_get_type( pc );
    else
    {
        pt = PURPLE_CONV_TYPE_ANY;
        pc = purple_find_conversation_with_account( pt, cname, acct );
        if( !pc )
        {
            pt = PURPLE_CONV_TYPE_IM;
            pc = purple_conversation_new( pt, acct, cname );
        }
        else { pt = purple_conversation_get_type( pc ); }
    }

    if( !pc )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "new conversation failed" );
    }

    PurpleConvIm   *pci = NULL;
    PurpleConvChat *pcc = NULL;
    const char     *msg = ALIST_VAL_STRING( args, "text" );
    char           *esc = g_markup_escape_text( msg, -1 );
    int             len = strlen( esc );

    switch( pt )
    {
      case PURPLE_CONV_TYPE_IM:
        pci = purple_conversation_get_im_data( pc );
        purple_conv_im_send( pci, esc );
        break;
      case PURPLE_CONV_TYPE_CHAT:
        pcc = purple_conversation_get_chat_data( pc );
        purple_conv_chat_send( pcc, esc );
        break;
      default:
        g_free       ( esc  );
        sexp_val_free( args );
        return response_error( EINVAL, id, name, "unknown conversation type" );
    }

    xmlnode *rval = xnode_new( "alist" );
    AL_INT( rval, "bytes"    , len     );
    AL_PTR( rval, "conv-uid" , pc      );
    AL_STR( rval, "conv-name", purple_conversation_get_name(pc) );

    g_free       ( esc  );
    sexp_val_free( args );
    fprintf(stderr, "(elim-debug leaving _h_elim_message)");
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 22
0
xmlnode * _h_elim_remove_buddy ( const char *name ,
                                 const char *id   ,
                                 SEXP_VALUE *args ,
                                 gpointer data    )
{
    ASSERT_ALISTP( args, id, name );

    fprintf( stderr, "(elim-remove-buddy)\n" );

    elim_ping();
    
    const char    *aname = ALIST_VAL_STR( args, "account-name" );
    const char    *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer       auid  = ALIST_VAL_PTR( args, "account-uid"  );
    PurpleAccount *acct  = NULL;

    gpointer       b_uid = ALIST_VAL_PTR( args, "bnode-uid" );
    const char    *b_arg = NULL;
    const char    *bname = NULL;
    const char    *gname = NULL; 
    PurpleGroup   *group = NULL; 
    PurpleBuddy   *buddy = NULL;
    gboolean       gone  = FALSE;

    if( b_uid )
    {
        PurpleBlistNodeType type = PURPLE_BLIST_OTHER_NODE;
        PurpleBlistNode    *node = find_blist_node_by_uid( b_uid , TRUE );

        if( !node )
        {
            sexp_val_free( args );
            return response_error( EINVAL, id, name, "rogue buddy pointer" );
        }
        type = purple_blist_node_get_type( node );

        // ===========================================================
        // groups, contacts and chats can safely be removed here:
        // buddies should instead be noted for removal in the next
        // block of code as they require client<->server interaction:
        switch( type )
        {
          case PURPLE_BLIST_GROUP_NODE  :
            purple_blist_remove_group  ( (PurpleGroup   *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_CONTACT_NODE:
            purple_blist_remove_contact( (PurpleContact *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_CHAT_NODE   :
            FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );
            BNODE_ACCOUNT_CHECK(chat,(PurpleChat *)node, acct, args, id, name);
            purple_blist_remove_chat   ( (PurpleChat    *)node );
            gone = TRUE;
            break;
          case PURPLE_BLIST_BUDDY_NODE  :
            buddy = (PurpleBuddy *)node;
            FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );
            BNODE_ACCOUNT_CHECK( buddy, buddy, acct, args, id, name );
            b_arg = purple_buddy_get_name( buddy );
            bname = purple_normalize( acct, b_arg );
            break;
          default:
            sexp_val_free( args );
            return response_error( EINVAL, id, name, 
                                   "Unknown buddy list node type" );
        }

        if( gone )
        {
            xmlnode *rval = xnode_new( "alist" );
            if( acct )
            {
                AL_STR( rval, "account-name", aname );
                AL_STR( rval, "im-protocol" , proto );
                AL_PTR( rval, "account-uid" , acct  );
            }
            AL_PTR ( rval, "bnode-uid" , buddy );
            AL_ENUM( rval, "bnode-type", type  , ":blist-node-type" );

            sexp_val_free( args );
            return response_value( 0, id, name, rval );
        }
    }
    else
    {
        b_arg = ALIST_VAL_STRING( args, "bnode-name" );
        FIND_ACCOUNT( args, id, name, acct, auid, aname, proto );

        if( b_arg )
        {
            bname = purple_normalize( acct, b_arg   );
            gname = ALIST_VAL_STRING( args, "group" );
            group = ( gname && *gname ) ? purple_find_group( gname ) : NULL;
            buddy = ( group ?
                      purple_find_buddy_in_group( acct, bname, group ) :
                      purple_find_buddy         ( acct, bname        ) );
        }
    }

    if( !b_arg || !*b_arg )
    {
        sexp_val_free( args );
        return response_error( EINVAL, id, name, "buddy not specified" );
    }

    // buddy must be in our local list or libpurple won't remove it from the
    // server list ( determined empirically, confirmed by inspecting code ):
    if( !buddy )
    {
        buddy = purple_buddy_new( acct, bname, bname );
        purple_blist_add_buddy  ( buddy, NULL, NULL, NULL );
    }

    if( buddy )
    {
        // the order of the remove operations is important: it has to be
        // this way round, as noted above: account buddy removal won't 
        // happen if the buddy is not in the blist when we try:
        if( !group ) group = purple_buddy_get_group( buddy );
        // is this correct? what if we have more than one copy of said buddy?
        // potentially confusing. dunno what the right thing to do is here.
        purple_account_remove_buddy( acct, buddy, group );
        purple_blist_remove_buddy( buddy );
    }
    else 
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "no such buddy" );
    }
    
    xmlnode *rval = xnode_new( "alist" );
    AL_STR ( rval, "account-name", purple_account_get_username   ( acct ) );
    AL_STR ( rval, "im-protocol" , purple_account_get_protocol_id( acct ) );
    AL_PTR ( rval, "account-uid" , acct  );
    AL_PTR ( rval, "bnode-uid"   , buddy );
    AL_ENUM( rval, "bnode-type", PURPLE_BLIST_BUDDY_NODE, ":blist-node-type" );
    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 23
0
xmlnode * _h_elim_command ( const char *name ,
                            const char *id   ,
                            SEXP_VALUE *args ,
                            gpointer data    )
{
    fprintf(stderr, "(elim-debug entered _h_elim_command)");
    ASSERT_ALISTP( args, id, name );
    
    elim_ping();

    const char *aname = ALIST_VAL_STR( args, "account-name" );
    const char *proto = ALIST_VAL_STR( args, "im-protocol"  );
    gpointer    auid  = ALIST_VAL_PTR( args, "account-uid"  );

    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    PurpleConversationType pt = PURPLE_CONV_TYPE_UNKNOWN;
    gpointer             cuid = ALIST_VAL_PTR( args, "conv-uid"  );
    const char         *cname = ALIST_VAL_STR( args, "conv-name" );
    PurpleConversation    *pc = find_conv_by_acct_uid( acct, cuid );

    if  ( pc ) pt = purple_conversation_get_type( pc );
    else
    {
        pt = PURPLE_CONV_TYPE_ANY;
        pc = purple_find_conversation_with_account( pt, cname, acct );
        if( !pc )
        {
            sexp_val_free( args );
            return response_error( ENOENT, id, name, "conversation not found" );
        }
        else { pt = purple_conversation_get_type( pc ); }
    }

    PurpleCmdStatus c_s = PURPLE_CMD_STATUS_FAILED;
    const char     *cmd = ALIST_VAL_STRING( args, "command" );
    char           *esc = g_markup_escape_text( cmd, -1 );
    char           *err = NULL;
    const char   *error = NULL;
    c_s = purple_cmd_do_command( pc, cmd, esc, &err );

    if( c_s != PURPLE_CMD_STATUS_OK && (!err || !*err) )
        switch( c_s )
        {
          case PURPLE_CMD_STATUS_FAILED    :
            error = "Command failed";
            break;
          case PURPLE_CMD_STATUS_NOT_FOUND :
            error = "Command not found";
            break;
          case PURPLE_CMD_STATUS_WRONG_ARGS:
            error = "Bad command arguments";
            break;
          case PURPLE_CMD_STATUS_WRONG_PRPL:
            error = "Command not valid for this IM protocol";
            break;
          case PURPLE_CMD_STATUS_WRONG_TYPE:
            error = "Command not valid in this conversation";
            break;
          default:
            error = "Unknown command error";
        }

    xmlnode *rval = xnode_new( "alist" );
    AL_PTR ( rval, "conv-uid"      , pc  );
    AL_STR ( rval, "conv-name"     , purple_conversation_get_name(pc) );

    AL_ENUM( rval, "command-status", c_s , ":cmd-status" );
    AL_STR ( rval, "command-error" , err ? err : error   );
    AL_STR ( rval, "command-line"  , cmd );

    g_free       ( err  );
    g_free       ( esc  );
    sexp_val_free( args );

    fprintf(stderr, "(elim-debug leaving _h_elim_command)");
    return response_value( 0, id, name, rval );
}
Ejemplo n.º 24
0
xmlnode * _h_elim_add_chat( const char *name , 
                            const char *id   ,
                            SEXP_VALUE *args , 
                            gpointer    data )
{
    ASSERT_ALISTP( args, id, name );

    elim_ping();

    const char *aname   = ALIST_VAL_STR  ( args, "account-name" );
    const char *proto   = ALIST_VAL_STR  ( args, "im-protocol"  );
    const char *alias   = ALIST_VAL_STR  ( args, "chat-alias"   );
    gpointer    auid    = ALIST_VAL_PTR  ( args, "account-uid"  );
    GHashTable *opts    = ALIST_VAL_ALIST( args, "chat-options" );
    GHashTable *options = __ghash_str_sexp__str_str( opts );
    PurpleAccount *acct = 
      auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto );

    if( !acct )
    {
        sexp_val_free( args );
        return response_error( ENXIO, id, name, "unknown account" );
    }

    // cook up a chat node. if it's already on our buddy list, uncook it
    // and use the old one instead (name should be unique per account
    // so the operation is reasonable - we cannot supply a name as this
    // parameter can be delegated to the plugin to generate automatically):
    // this will trigger a new_node call, and possibly a remove call 
    PurpleChat *chat = purple_chat_new( acct, alias, options );
    const char *chn  = purple_chat_get_name( chat );
    PurpleChat *ch_2 = purple_blist_find_chat( acct, chn );
    if( ch_2 )
    {
        fprintf( stderr, "(elim-debug chat already exists)\n" );
        purple_blist_remove_chat( chat );
        chat = ch_2;
        chn  = purple_chat_get_name( chat );
        purple_blist_alias_chat( chat, alias );
    }

    fprintf( stderr, "(elim-debug adding chat to blist)\n" );
    purple_blist_add_chat( chat, NULL, NULL );

    // if we have a conversation already, prod the client to show it
    fprintf( stderr, "(elim-debug looking for conversation)\n" );
    PurpleConversation *conv =
      purple_find_conversation_with_account( PURPLE_CONV_TYPE_CHAT, chn, acct );
    if( conv )
        purple_conversation_present( conv );

    xmlnode *rval = xnode_new( "alist" );

    AL_STR( rval, "account-name", purple_account_get_username   (acct) );
    AL_STR( rval, "im-protocol" , purple_account_get_protocol_id(acct) );
    AL_PTR( rval, "account-uid" , acct );
    AL_STR( rval, "chat-name"   , chn  );

    if( conv )
    {
        PurpleConversationType pct = purple_conversation_get_type    ( conv );
        PurpleConnectionFlags  pcf = purple_conversation_get_features( conv );

        AL_PTR ( rval, "conv-uid"     , conv );
        AL_STR ( rval, "conv-name"    , purple_conversation_get_name (conv) );
        AL_STR ( rval, "conv-title"   , purple_conversation_get_title(conv) );
        AL_ENUM( rval, "conv-type"    , pct, ":conversation-type" );
        AL_ENUM( rval, "conv-features", pcf, ":connection-flags"  );
    }

    sexp_val_free( args );
    return response_value( 0, id, name, rval );
}