Changeset 6036


Ignore:
Timestamp:
Jun 4, 2008, 7:46:37 PM (14 years ago)
Author:
charles
Message:

(gtk) more work on the RPC preferences tab: the ACL editor works now & is wired up...

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/NEWS

    r6009 r6036  
    1414   + Add preferences options to inhibit hibernation and to toggle the tray icon
    1515- Daemon
    16    + Redesigned & rewritten to use json over http
     16   + Redesigned & rewritten to use JSON over http
    1717
    18181.21 (2008/05/21)
  • trunk/gtk/main.c

    r5996 r6036  
    942942        tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) );
    943943    }
     944    else if( !strcmp( key, PREF_KEY_RPC_ACL ) )
     945    {
     946        char * err = NULL;
     947        char * s = pref_string_get( key );
     948        tr_sessionSetRPCACL( tr, s, &err );
     949        g_free( s );
     950    }
     951    else if( !strcmp( key, PREF_KEY_RPC_PASSWORD ) )
     952    {
     953        char * s = pref_string_get( key );
     954        /*FIXMEtr_sessionSetRPCACL( tr, s );*/
     955        g_free( s );
     956    }
     957    else if( !strcmp( key, PREF_KEY_RPC_PASSWORD_ENABLED ) )
     958    {
     959        const gboolean enabled = pref_flag_get( key );
     960        /*FIXME tr_sessionSetRPCEnabled( tr, enabled );*/
     961    }
    944962}
    945963
  • trunk/gtk/tr-prefs.c

    r6022 r6036  
    1111 */
    1212
     13#include <ctype.h> /* isspace */
    1314#include <errno.h>
     15#include <stdarg.h>
    1416#include <stdlib.h> /* free() */
    1517#include <unistd.h>
     
    215217    const gboolean b = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( tb ) );
    216218    gtk_widget_set_sensitive( GTK_WIDGET(target), b );
    217 }
    218 
    219 static void
    220 toggle_sets_sensitivity( GtkWidget * t, GtkWidget * w)
    221 {
    222     target_cb( t, w );
    223     g_signal_connect( t, "toggled", G_CALLBACK( target_cb ), w );
    224219}
    225220
     
    581576enum
    582577{
    583     COL_ALLOW, COL_IP_1, COL_IP_2, COL_IP_3, COL_IP_4,
    584     COL_MASK, COL_DOT, N_COLS
     578    COL_ADDRESS,
     579    COL_PERMISSION,
     580    N_COLS
    585581};
    586582
    587583static GtkTreeModel*
    588 acl_tree_model_new( const char * str UNUSED )
    589 {
    590     GtkTreeIter iter;
     584acl_tree_model_new( const char * acl )
     585{
     586    int i;
     587    char ** rules;
    591588    GtkListStore * store = gtk_list_store_new( N_COLS,
    592589                                               G_TYPE_STRING,
    593                                                G_TYPE_INT, G_TYPE_INT,
    594                                                G_TYPE_INT, G_TYPE_INT,
    595                                                G_TYPE_INT,
    596590                                               G_TYPE_STRING );
    597     gtk_list_store_append( store, &iter );
    598     gtk_list_store_set( store, &iter, COL_ALLOW, _( "Allow" ),
    599                                       COL_IP_1, 127, COL_IP_2, 0, COL_IP_3, 0, COL_IP_4, 1,
    600                                       COL_MASK, 32, COL_DOT, ".",
    601                                       -1 );
    602     gtk_list_store_append( store, &iter );
    603     gtk_list_store_set( store, &iter, COL_ALLOW, _( "Deny" ),
    604                                       COL_IP_1, 192, COL_IP_2, 168, COL_IP_3, 1, COL_IP_4, 666,
    605                                       COL_MASK, 32, COL_DOT, ".",
    606                                       -1 );
    607     gtk_list_store_append( store, &iter );
    608     gtk_list_store_set( store, &iter, COL_ALLOW, _( "Allow" ),
    609                                       COL_IP_1, 255, COL_IP_2, 255, COL_IP_3, 255, COL_IP_4, 255,
    610                                       COL_MASK, 32, COL_DOT, ".",
    611                                       -1 );
     591    rules = g_strsplit( acl, ",", 0 );
     592
     593    for( i=0; rules && rules[i]; ++i )
     594    {
     595        const char * s = rules[i];
     596        while( isspace( *s ) ) ++s;
     597        if( *s=='+' || *s=='-' )
     598        {
     599            GtkTreeIter iter;
     600            gtk_list_store_append( store, &iter );
     601            gtk_list_store_set( store, &iter,
     602                COL_PERMISSION, *s=='+' ? _( "Allow" ) : _( "Deny" ) ,
     603                COL_ADDRESS, s+1,
     604                -1 );
     605        }
     606    }
     607
     608    g_strfreev( rules );
    612609    return GTK_TREE_MODEL( store );
    613610}
     
    615612struct remote_page
    616613{
     614    TrCore * core;
    617615    GtkTreeView * view;
    618616    GtkListStore * store;
    619617    GtkWidget * remove_button;
     618    GtkWidget * pw_entry;
     619    GSList * widgets;
     620    GtkToggleButton * rpc_tb;
     621    GtkToggleButton * pw_tb;
    620622};
    621623
    622624static void
    623 onACLSelectionChanged( GtkTreeSelection  * sel,
    624                        gpointer            gpage )
    625 {
    626     struct remote_page * page = gpage;
    627     gboolean has_selection = gtk_tree_selection_get_selected( sel, NULL, NULL );
    628     gtk_widget_set_sensitive( page->remove_button, has_selection );
    629 }
    630 
    631 static void
    632 onAllowEdited( GtkCellRendererText  * renderer UNUSED,
    633                gchar                * path_string,
    634                gchar                * new_text,
    635                gpointer               gpage )
     625refreshACL( struct remote_page * page )
     626{
     627    GtkTreeIter iter;
     628    GtkTreeModel * model = GTK_TREE_MODEL( page->store );
     629    GString * gstr = g_string_new( NULL );
     630
     631    if( gtk_tree_model_get_iter_first( model, &iter ) ) do
     632    {
     633        char * permission;
     634        char * address;
     635        gtk_tree_model_get( model, &iter, COL_PERMISSION, &permission,
     636                                          COL_ADDRESS, &address,
     637                                          -1 );
     638        g_string_append_c( gstr, strcmp(permission,_("Allow")) ? '-' : '+' );
     639        g_string_append( gstr, address );
     640        g_string_append( gstr, ", " );
     641        g_free( address );
     642        g_free( permission );
     643    }
     644    while( gtk_tree_model_iter_next( model, &iter ) );
     645
     646    g_string_truncate( gstr, gstr->len-2 ); /* remove the trailing ", " */
     647
     648    tr_core_set_pref( page->core, PREF_KEY_RPC_ACL, gstr->str );
     649
     650    g_string_free( gstr, TRUE );
     651}
     652
     653static void
     654onPermissionEdited( GtkCellRendererText  * renderer UNUSED,
     655                    gchar                * path_string,
     656                    gchar                * new_text,
     657                    gpointer               gpage )
    636658{
    637659    GtkTreeIter iter;
     
    640662    GtkTreeModel * model = GTK_TREE_MODEL( page->store );
    641663    if( gtk_tree_model_get_iter( model, &iter, path ) )
    642         gtk_list_store_set( page->store, &iter, COL_ALLOW, new_text, -1 );
     664        gtk_list_store_set( page->store, &iter, COL_PERMISSION, new_text, -1 );
    643665    gtk_tree_path_free( path );
    644 }
    645 
    646 #define IP_OFFSET "ip-offset"
    647 
    648 static void
    649 onNumberEdited( GtkCellRendererText  * r,
    650                 gchar                * path_string,
    651                 gchar                * new_text,
    652                 gpointer               gpage )
    653 {
     666    refreshACL( page );
     667}
     668
     669static void
     670onAddressEdited( GtkCellRendererText  * r UNUSED,
     671                 gchar                * path_string,
     672                 gchar                * new_text,
     673                 gpointer               gpage )
     674{
     675    char * acl;
    654676    GtkTreeIter iter;
    655     GtkTreePath * path = gtk_tree_path_new_from_string( path_string );
    656677    struct remote_page * page = gpage;
    657678    GtkTreeModel * model = GTK_TREE_MODEL( page->store );
    658     char * end;
    659     int i;
    660     int ip_offset = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( r ), IP_OFFSET ) );
    661 
    662     /* only allow [0...255] */
    663     errno = 0;
    664     i = strtol( new_text, &end, 10 );
    665     if( i<0 || i>255 || *end || errno )
    666         return;
    667 
    668     if( gtk_tree_model_get_iter( model, &iter, path ) )
    669         gtk_list_store_set( page->store, &iter, COL_IP_1+ip_offset, i, -1 );
    670 
     679    tr_handle * session = tr_core_handle( page->core );
     680    GtkTreePath * path = gtk_tree_path_new_from_string( path_string );
     681
     682    acl = g_strdup_printf( "+%s", new_text );
     683    if( !tr_sessionTestRPCACL( session, acl, NULL ) )
     684        if( gtk_tree_model_get_iter( model, &iter, path ) )
     685            gtk_list_store_set( page->store, &iter, COL_ADDRESS, new_text, -1 );
     686
     687    g_free( acl );
    671688    gtk_tree_path_free( path );
     689    refreshACL( page );
    672690}
    673691
     
    680698    gtk_list_store_append( page->store, &iter );
    681699    gtk_list_store_set( page->store, &iter,
    682                         COL_ALLOW, _( "Allow" ),
    683                         COL_IP_1, 0, COL_IP_2, 0,
    684                         COL_IP_3, 0, COL_IP_4, 0,
     700                        COL_PERMISSION, _( "Allow" ),
     701                        COL_ADDRESS, _( "0.0.0.0" ),
    685702                        -1 );
    686703
    687704    path = gtk_tree_model_get_path( GTK_TREE_MODEL( page->store ), &iter );
    688     gtk_tree_view_set_cursor( page->view, path,
    689                               gtk_tree_view_get_column( page->view, COL_IP_1 ),
    690                               TRUE );
     705    gtk_tree_view_set_cursor(
     706        page->view, path,
     707        gtk_tree_view_get_column( page->view, COL_ADDRESS ),
     708        TRUE );
    691709    gtk_tree_path_free( path );
    692710}
     
    699717    GtkTreeIter iter;
    700718    if( gtk_tree_selection_get_selected( sel, NULL, &iter ) )
     719    {
    701720        gtk_list_store_remove( page->store, &iter );
     721        refreshACL( page );
     722    }
     723}
     724
     725static void
     726refreshRPCSensitivity( struct remote_page * page )
     727{
     728    GSList * l;
     729    const int rpc_active = gtk_toggle_button_get_active( page->rpc_tb );
     730    const int pw_active = gtk_toggle_button_get_active( page->pw_tb );
     731    GtkTreeSelection * sel = gtk_tree_view_get_selection( page->view );
     732    const int have_addr = gtk_tree_selection_get_selected( sel, NULL, NULL );
     733    const int n_rules = gtk_tree_model_iter_n_children(
     734                                       GTK_TREE_MODEL( page->store ), NULL );
     735
     736    for( l=page->widgets; l!=NULL; l=l->next )
     737        gtk_widget_set_sensitive( GTK_WIDGET( l->data ), rpc_active );
     738
     739    gtk_widget_set_sensitive( page->pw_entry, rpc_active && pw_active );
     740
     741    gtk_widget_set_sensitive( page->remove_button,
     742                              rpc_active && have_addr && n_rules>1 );
     743}
     744
     745static void
     746onRPCToggled( GtkToggleButton * tb UNUSED, gpointer page )
     747{
     748    refreshRPCSensitivity( page );
     749}
     750static void
     751onRPCPassToggled( GtkToggleButton * tb UNUSED, gpointer page )
     752{
     753    refreshRPCSensitivity( page );
     754}
     755static void
     756onACLSelectionChanged( GtkTreeSelection * sel UNUSED, gpointer page )
     757{
     758    refreshRPCSensitivity( page );
    702759}
    703760
     
    711768    GtkWidget * w2;
    712769    GtkWidget * enabled_toggle;
    713     const gboolean rpc_enabled = pref_flag_get( PREF_KEY_RPC_ENABLED );
    714     const gboolean pw_enabled = pref_flag_get( PREF_KEY_RPC_PASSWORD_ENABLED );
    715770    struct remote_page * page = g_new0( struct remote_page, 1 );
     771
     772    page->core = TR_CORE( core );
    716773
    717774    t = hig_workarea_create( );
     
    725782        hig_workarea_add_wide_control( t, &row, w );
    726783        enabled_toggle = w;
     784        page->rpc_tb = GTK_TOGGLE_BUTTON( w );
     785        g_signal_connect( w, "clicked", G_CALLBACK(onRPCToggled), page );
    727786
    728787        /* password protection */
    729788        s = _( "Require _password:" );
    730789        w = new_check_button( s, PREF_KEY_RPC_PASSWORD_ENABLED, core );
    731         toggle_sets_sensitivity( enabled_toggle, w );
    732         w2 = new_entry( PREF_KEY_RPC_PASSWORD, core );
     790        g_signal_connect( w, "clicked", G_CALLBACK(onRPCPassToggled), page );
     791        page->pw_tb = GTK_TOGGLE_BUTTON( w );
     792        page->widgets = g_slist_append( page->widgets, w );
     793        //toggles_set_sensitivity( w, enabled_toggle, NULL );
     794        w2 = page->pw_entry = new_entry( PREF_KEY_RPC_PASSWORD, core );
     795        //toggles_set_sensitivity( w2, enabled_toggle, w, NULL );
    733796        gtk_entry_set_visibility( GTK_ENTRY( w2 ), FALSE );
    734 
    735         gtk_widget_set_sensitive( GTK_WIDGET( w2 ), rpc_enabled && pw_enabled );
    736         g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 );
    737         g_signal_connect( enabled_toggle, "toggled", G_CALLBACK( target_cb ), w );
    738797        hig_workarea_add_row_w( t, &row, w, w2, NULL );
    739798
    740799        /* port */
    741800        w = new_spin_button( PREF_KEY_RPC_PORT, core, 0, 65535, 1 );
    742         toggle_sets_sensitivity( enabled_toggle, w );
    743         w = hig_workarea_add_row( t, &row, _( "Listen for requests on _port:" ), w, NULL );
    744         toggle_sets_sensitivity( enabled_toggle, w );
    745 
    746 #if 1
     801        page->widgets = g_slist_append( page->widgets, w );
     802        //toggles_set_sensitivity( w, enabled_toggle, NULL );
     803        w = hig_workarea_add_row( t, &row, _( "Listening _port:" ), w, NULL );
     804        page->widgets = g_slist_append( page->widgets, w );
     805        //toggles_set_sensitivity( w, enabled_toggle, NULL );
     806
    747807        /* access control list */
    748808        {
    749         int i;
    750809        char * val = pref_string_get( PREF_KEY_RPC_ACL );
    751810        GtkTreeModel * m = acl_tree_model_new( val );
     
    756815        GtkWidget * w;
    757816        GtkWidget * h;
     817        GtkTooltips * tips = gtk_tooltips_new( );
    758818
    759819        s = _( "Access control list:" );
    760820        page->store = GTK_LIST_STORE( m );
    761821        w = gtk_tree_view_new_with_model( m );
     822
     823        page->widgets = g_slist_append( page->widgets, w );
     824        //toggles_set_sensitivity( w, enabled_toggle, NULL );
    762825        v = page->view = GTK_TREE_VIEW( w );
     826        gtk_tooltips_set_tip( tips, w,
     827            _( "IP addresses may use wildcards, such as 192.168.*.*" ),
     828            NULL );
    763829        sel = gtk_tree_view_get_selection( v );
    764830        g_signal_connect( sel, "changed",
    765831                          G_CALLBACK( onACLSelectionChanged ), page );
    766832        g_object_unref( G_OBJECT( m ) );
    767         gtk_tree_view_set_headers_visible( v, FALSE );
     833        gtk_tree_view_set_headers_visible( v, TRUE );
    768834        w = gtk_frame_new( NULL );
    769835        gtk_frame_set_shadow_type( GTK_FRAME( w ), GTK_SHADOW_IN );
    770836        gtk_container_add( GTK_CONTAINER( w ), GTK_WIDGET( v ) );
    771837
     838        /* ip address column */
     839        r = gtk_cell_renderer_text_new( );
     840        g_signal_connect( r, "edited",
     841                          G_CALLBACK( onAddressEdited ), page );
     842        g_object_set( G_OBJECT( r ), "editable", TRUE, NULL );
     843        c = gtk_tree_view_column_new_with_attributes( _( "IP Address" ), r,
     844                "text", COL_ADDRESS,
     845                NULL );
     846        gtk_tree_view_column_set_expand( c, TRUE );
     847        gtk_tree_view_append_column( v, c );
     848
     849        w = hig_workarea_add_row( t, &row, s, w, NULL );
     850        gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.1f );
     851        page->widgets = g_slist_append( page->widgets, w );
     852        //toggles_set_sensitivity( w, enabled_toggle, NULL );
     853        g_free( val );
     854
     855        /* permission column */
    772856        m = allow_deny_model_new( );
    773         c = gtk_tree_view_column_new( );
    774857        r = gtk_cell_renderer_combo_new( );
    775         g_signal_connect( r, "edited",
    776                           G_CALLBACK( onAllowEdited ), page );
    777         gtk_tree_view_column_pack_start( c, r, TRUE );
    778         g_object_set (G_OBJECT( r ), "model", m,
     858        g_object_set( G_OBJECT( r ), "model", m,
    779859                                     "editable", TRUE,
    780860                                     "has-entry", FALSE,
    781861                                     "text-column", 0,
    782862                                     NULL );
    783         gtk_tree_view_column_add_attribute( c, r, "text", COL_ALLOW );
     863        c = gtk_tree_view_column_new_with_attributes( _( "Permission" ), r,
     864                "text", COL_PERMISSION,
     865                NULL );
     866        g_signal_connect( r, "edited",
     867                          G_CALLBACK( onPermissionEdited ), page );
    784868        gtk_tree_view_append_column( v, c );
    785 
    786         for( i=0; i<4; ++i )
    787         {
    788             r = gtk_cell_renderer_text_new( );
    789             g_signal_connect( r, "edited",
    790                               G_CALLBACK( onNumberEdited ), page );
    791             g_object_set( G_OBJECT( r ), "editable", TRUE, NULL );
    792             g_object_set_data( G_OBJECT( r ), IP_OFFSET, GINT_TO_POINTER( i ) );
    793             c = gtk_tree_view_column_new_with_attributes( NULL, r, "text", COL_IP_1+i, NULL );
    794             gtk_tree_view_append_column( v, c );
    795 
    796             if( i<3 )
    797             {
    798                 r = gtk_cell_renderer_text_new( );
    799                 c = gtk_tree_view_column_new_with_attributes( NULL, r, "text", COL_DOT, NULL );
    800                 gtk_tree_view_column_set_clickable( c, FALSE );
    801                 gtk_tree_view_append_column( v, c );
    802             }
    803         }
    804 
    805         w = hig_workarea_add_row( t, &row, s, w, NULL );
    806         gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.1f );
    807         g_free( val );
    808869
    809870        h = gtk_hbox_new( TRUE, GUI_PAD );
     
    814875        gtk_box_pack_start_defaults( GTK_BOX( h ), w );
    815876        w = gtk_button_new_from_stock( GTK_STOCK_ADD );
     877        page->widgets = g_slist_append( page->widgets, w );
     878        //toggles_set_sensitivity( w, enabled_toggle, NULL );
    816879        g_signal_connect( w, "clicked", G_CALLBACK(onAddACLClicked), page );
    817880        gtk_box_pack_start_defaults( GTK_BOX( h ), w );
     
    821884        hig_workarea_add_wide_control( t, &row, w );
    822885        }
    823 #endif
    824886
    825887    hig_workarea_finish( t, &row );
     
    864926        gtk_misc_set_alignment( GTK_MISC(l), 0.0f, 0.5f );
    865927        gtk_box_pack_start( GTK_BOX(h), l, FALSE, FALSE, 0 );
    866         hig_workarea_add_row( t, &row, _("Listen for _peers on port:"), h, w );
     928        hig_workarea_add_row( t, &row, _("Listening _port:"), h, w );
    867929
    868930        g_object_set_data( G_OBJECT(l), "tr-port-spin", w2 );
  • trunk/libtransmission/rpc-server.c

    r6031 r6036  
    274274               char                ** setme_errmsg )
    275275{
    276     int ret = 0;
     276    int err = 0;
    277277    char * cidr = cidrize( acl );
    278278    char * errmsg = testACL( cidr );
     
    283283        else
    284284            tr_free( errmsg );
    285         ret = -1;
     285        err = -1;
    286286    }
    287287    tr_free( cidr );
    288     return ret;
     288    return err;
    289289}
    290290
     
    295295{
    296296    char * cidr = cidrize( acl );
    297     const int ret = tr_rpcTestACL( server, cidr, setme_errmsg );
    298 
    299     if( ret )
     297    const int err = tr_rpcTestACL( server, cidr, setme_errmsg );
     298
     299    if( err )
    300300    {
    301301        const int isRunning = server->ctx != NULL;
     
    311311    }
    312312
    313     return ret;
     313    return err;
    314314}
    315315
Note: See TracChangeset for help on using the changeset viewer.