Changeset 1626 for branches/daemon


Ignore:
Timestamp:
Apr 1, 2007, 2:19:09 AM (15 years ago)
Author:
joshe
Message:

Add option to proxy socket connection through a command.

Location:
branches/daemon/daemon
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/daemon/daemon/client.c

    r1617 r1626  
    4949struct con
    5050{
    51     int                  fd;
     51    int                  infd;
     52    int                  outfd;
    5253    struct ipc_info      ipc;
    53     struct bufferevent * ev;
     54    struct bufferevent * evin;
     55    struct bufferevent * evout;
    5456};
    5557
     
    8385static struct req * addreq   ( enum ipc_msg, int64_t, struct resp ** );
    8486static int     addintlistreq ( enum ipc_msg, size_t, const int * );
     87static void    noop          ( struct bufferevent *, void * );
     88static void    noway         ( struct bufferevent *, void * );
    8589static void    didwrite      ( struct bufferevent *, void * );
    8690static void    ohshit        ( struct bufferevent *, short, void * );
    8791static void    canread       ( struct bufferevent *, void * );
    8892static void    flushreqs     ( struct con * );
    89 static int     sendvers      ( struct bufferevent * );
     93static int     sendvers      ( struct con * );
    9094static void    infomsg       ( enum ipc_msg, benc_val_t *, int64_t, void * );
    9195static void    statmsg       ( enum ipc_msg, benc_val_t *, int64_t, void * );
     
    128132
    129133int
    130 client_connect( const char * path )
     134client_new_sock( const char * path )
    131135{
    132136    struct sockaddr_un sun;
     
    162166    }
    163167    ipc_newcon( &con->ipc, gl_tree );
    164     con->fd  = fd;
    165     con->ev  = bufferevent_new( fd, canread, didwrite, ohshit, con );
    166     if( NULL == con->ev )
     168    con->infd = fd;
     169    con->evin = bufferevent_new( fd, canread, didwrite, ohshit, con );
     170    if( NULL == con->evin )
    167171    {
    168172        mallocmsg( -1 );
     
    171175        return -1;
    172176    }
    173     bufferevent_base_set( gl_base, con->ev );
    174     bufferevent_settimeout( con->ev, SERVER_TIMEOUT, SERVER_TIMEOUT );
    175     bufferevent_enable( con->ev, EV_READ );
    176     if( 0 > sendvers( con->ev ) )
     177    con->outfd = con->infd;
     178    con->evout = con->evin;
     179    bufferevent_base_set( gl_base, con->evin );
     180    bufferevent_settimeout( con->evin, SERVER_TIMEOUT, SERVER_TIMEOUT );
     181    bufferevent_enable( con->evin, EV_READ );
     182    if( 0 > sendvers( con ) )
     183    {
     184        exit( 1 );
     185    }
     186
     187    return 0;
     188}
     189
     190int
     191client_new_cmd( char * const * cmd )
     192{
     193    struct con * con;
     194    int          tocmd[2], fromcmd[2];
     195    pid_t        kid;
     196
     197    assert( NULL != gl_base );
     198    assert( NULL != cmd && NULL != cmd[0] );
     199
     200    if( 0 > pipe( tocmd ) )
     201    {
     202        errnomsg( "failed to create pipe" );
     203        return -1;
     204    }
     205
     206    if( 0 > pipe( fromcmd ) )
     207    {
     208        errnomsg( "failed to create pipe" );
     209        close( tocmd[0] );
     210        close( tocmd[1] );
     211        return -1;
     212    }
     213
     214    kid = fork();
     215    if( 0 > kid )
     216    {
     217        close( tocmd[0] );
     218        close( tocmd[1] );
     219        close( fromcmd[0] );
     220        close( fromcmd[1] );
     221        return -1;
     222    }
     223    else if( 0 == kid )
     224    {
     225        if( 0 > dup2( tocmd[0], STDIN_FILENO ) ||
     226            0 > dup2( fromcmd[1], STDOUT_FILENO ) )
     227        {
     228            errnomsg( "failed to duplicate descriptors" );
     229            _exit( 1 );
     230        }
     231        close( tocmd[0] );
     232        close( tocmd[1] );
     233        close( fromcmd[0] );
     234        close( fromcmd[1] );
     235        execvp( cmd[0], cmd );
     236        errnomsg( "failed to execute: %s", cmd[0] );
     237        _exit( 1 );
     238    }
     239
     240    close( tocmd[0] );
     241    close( fromcmd[1] );
     242
     243    con = calloc( 1, sizeof *con );
     244    if( NULL == con )
     245    {
     246        mallocmsg( sizeof *con );
     247        close( tocmd[1] );
     248        close( fromcmd[0] );
     249        return -1;
     250    }
     251
     252    con->infd = fromcmd[0];
     253    con->evin = bufferevent_new( con->infd, canread, noop, ohshit, con );
     254    if( NULL == con->evin )
     255    {
     256        free( con );
     257        close( tocmd[1] );
     258        close( fromcmd[0] );
     259        return -1;
     260    }
     261    bufferevent_base_set( gl_base, con->evin );
     262    bufferevent_settimeout( con->evin, SERVER_TIMEOUT, SERVER_TIMEOUT );
     263    bufferevent_enable( con->evin, EV_READ );
     264
     265    con->outfd = tocmd[1];
     266    con->evout = bufferevent_new( con->outfd, noway, didwrite, ohshit, con );
     267    if( NULL == con->evout )
     268    {
     269        bufferevent_free( con->evin );
     270        free( con );
     271        close( tocmd[1] );
     272        close( fromcmd[0] );
     273        return -1;
     274    }
     275    bufferevent_base_set( gl_base, con->evout );
     276    bufferevent_settimeout( con->evout, SERVER_TIMEOUT, SERVER_TIMEOUT );
     277    bufferevent_enable( con->evout, EV_READ );
     278
     279    ipc_newcon( &con->ipc, gl_tree );
     280    if( 0 > sendvers( con ) )
    177281    {
    178282        exit( 1 );
     
    469573
    470574void
    471 didwrite( struct bufferevent * ev, void * arg )
     575noop( struct bufferevent * ev UNUSED, void * arg UNUSED )
     576{
     577    /* libevent prior to 1.2 couldn't handle a NULL write callback */
     578}
     579
     580void
     581noway( struct bufferevent * evin, void * arg UNUSED )
     582{
     583    /* this shouldn't happen, but let's drain the buffer anyway */
     584    evbuffer_drain( EVBUFFER_INPUT( evin ),
     585                    EVBUFFER_LENGTH( EVBUFFER_INPUT( evin ) ) );
     586}
     587
     588void
     589didwrite( struct bufferevent * evout, void * arg )
    472590{
    473591    struct con * con = arg;
    474592
    475     assert( ev == con->ev );
     593    assert( evout == con->evout );
    476594    flushreqs( con );
    477595}
     
    508626
    509627void
    510 canread( struct bufferevent * ev, void * arg )
     628canread( struct bufferevent * evin, void * arg )
    511629{
    512630    struct con * con = arg;
     
    515633    ssize_t      res;
    516634
    517     buf = EVBUFFER_DATA( EVBUFFER_INPUT( ev ) );
    518     len = EVBUFFER_LENGTH( EVBUFFER_INPUT( ev ) );
     635    assert( evin == con->evin );
     636    buf = EVBUFFER_DATA( EVBUFFER_INPUT( evin ) );
     637    len = EVBUFFER_LENGTH( EVBUFFER_INPUT( evin ) );
    519638
    520639    if( IPC_MIN_MSG_LEN > len )
     
    543662    if( 0 < res )
    544663    {
    545         evbuffer_drain( EVBUFFER_INPUT( ev ), res );
     664        evbuffer_drain( EVBUFFER_INPUT( evin ), res );
    546665        flushreqs( con );
    547666    }
     
    622741            exit( 1 );
    623742        }
    624         if( 0 > bufferevent_write( con->ev, buf, buflen ) )
     743        if( 0 > bufferevent_write( con->evout, buf, buflen ) )
    625744        {
    626745            errmsg( "failed to buffer %zd bytes of data for write", buflen );
     
    632751
    633752int
    634 sendvers( struct bufferevent * ev )
     753sendvers( struct con * con )
    635754{
    636755    uint8_t   * buf;
     
    651770    }
    652771
    653     if( 0 > bufferevent_write( ev, buf, len ) )
     772    if( 0 > bufferevent_write( con->evout, buf, len ) )
    654773    {
    655774        free( buf );
  • branches/daemon/daemon/client.h

    r1617 r1626  
    3636
    3737int  client_init     ( struct event_base * );
    38 int  client_connect  ( const char * );
     38int  client_new_sock ( const char * );
     39int  client_new_cmd  ( char * const * );
    3940int  client_quit     ( void );
    4041int  client_addfiles ( struct strlist * );
  • branches/daemon/daemon/remote.c

    r1623 r1626  
    4646struct opts
    4747{
     48    int               proxy;
     49    char           ** proxycmd;
    4850    enum confpathtype type;
    4951    struct strlist    files;
     
    139141
    140142    evbase = event_init();
    141 
    142     confpath( sockpath, sizeof sockpath, CONF_FILE_SOCKET, o.type );
    143143    client_init( evbase );
    144     client_connect( sockpath );
     144
     145    if( o.proxy )
     146    {
     147        client_new_cmd( o.proxycmd );
     148    }
     149    else
     150    {
     151        confpath( sockpath, sizeof sockpath, CONF_FILE_SOCKET, o.type );
     152        client_new_sock( sockpath );
     153    }
    145154
    146155    if( ( o.sendquit                &&   0 > client_quit     (           ) ) ||
     
    194203
    195204    printf(
    196   "usage: %s [options] [files]...\n"
     205  "usage: %s [options]\n"
    197206  "\n"
    198207  "Transmission %s (r%d) http://transmission.m0k.org/\n"
     
    219228  "  -t --type gtk             Use the GTK+ frontend, transmission-gtk\n"
    220229  "  -u --upload-limit <int>   Max upload rate in KiB/s\n"
    221   "  -U --upload-unlimited     No upload rate limit\n",
     230  "  -U --upload-unlimited     No upload rate limit\n"
     231  "  -x --proxy                Use proxy command to connect to frontend\n",
    222232            getmyname(), VERSION_STRING, VERSION_REVISION );
    223233    exit( 0 );
     
    227237readargs( int argc, char ** argv, struct opts * opts )
    228238{
    229     char optstr[] = "a:d:Df:hilmMp:qr:s:S:t:u:U";
     239    char optstr[] = "a:d:Df:hilmMp:qr:s:S:t:u:Ux";
    230240    struct option longopts[] =
    231241    {
     
    247257        { "upload-limit",       required_argument, NULL, 'u' },
    248258        { "upload-unlimited",   no_argument,       NULL, 'U' },
     259        { "proxy",              no_argument,       NULL, 'U' },
    249260        { NULL, 0, NULL, 0 }
    250261    };
     
    343354                opts->up        = -1;
    344355                break;
     356            case 'x':
     357                opts->proxy     = 1;
     358                break;
    345359            default:
    346360                usage( NULL );
     
    355369    }
    356370
    357     if( 0 > fileargs( &opts->files, argc - optind, argv + optind ) )
     371    if( opts->proxy )
     372    {
     373        opts->proxycmd = argv + optind;
     374    }
     375    else if( 0 > fileargs( &opts->files, argc - optind, argv + optind ) )
    358376    {
    359377        return -1;
Note: See TracChangeset for help on using the changeset viewer.