Changeset 1635 for branches/daemon


Ignore:
Timestamp:
Apr 2, 2007, 8:37:07 PM (15 years ago)
Author:
joshe
Message:

Make adding torrents work when using a proxy on another machine.
Add option to disable pex.
Miscellaneous cleanups and bug fixes.

Location:
branches/daemon/daemon
Files:
12 edited

Legend:

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

    r1631 r1635  
    6565    size_t             listlen;
    6666    int64_t          * numlist;
     67    uint8_t          * buf;
    6768    int                types;
    6869    SLIST_ENTRY( req ) next;
     
    108109static struct resptree     gl_resps  = RB_INITIALIZER( &gl_resps );
    109110static int64_t             gl_tag    = 0;
     111static int                 gl_proxy  = -1;
    110112
    111113int
     
    139141
    140142    assert( NULL != gl_base );
     143    assert( 0 > gl_proxy );
    141144    assert( NULL != path );
     145
     146    gl_proxy = 0;
    142147
    143148    bzero( &sun, sizeof sun );
     
    196201
    197202    assert( NULL != gl_base );
     203    assert( 0 > gl_proxy );
    198204    assert( NULL != cmd && NULL != cmd[0] );
     205
     206    gl_proxy = 1;
    199207
    200208    if( 0 > pipe( tocmd ) )
     
    329337client_addfiles( struct strlist * list )
    330338{
     339    struct stritem * ii;
     340    uint8_t        * buf;
     341    size_t           size;
     342    struct req     * req;
     343
     344    if( gl_proxy )
     345    {
     346        SLIST_FOREACH( ii, list, next )
     347        {
     348            buf = readfile( ii->str, &size );
     349            req = addreq( IPC_MSG_ADDONEFILE, -1, NULL );
     350            if( NULL == req )
     351            {
     352                free( buf );
     353                return -1;
     354            }
     355            req->buf     = buf;
     356            req->listlen = size;
     357        }
     358    }
     359    else
     360    {
     361        req = addreq( IPC_MSG_ADDMANYFILES, -1, NULL );
     362        if( NULL == req )
     363        {
     364            return -1;
     365        }
     366
     367        /* XXX need to move arg parsing back here or something */
     368        req->strs = list;
     369    }
     370
     371    return 0;
     372}
     373
     374int
     375client_automap( int automap )
     376{
    331377    struct req * req;
    332378
    333     req = addreq( IPC_MSG_ADDMANYFILES, -1, NULL );
    334     if( NULL == req )
    335     {
    336         return -1;
    337     }
    338 
    339     /* XXX need to move arg parsing back here or something */
    340     req->strs = list;
    341 
    342     return 0;
    343 }
    344 
    345 int
    346 client_automap( int automap )
     379    req = addreq( IPC_MSG_AUTOMAP, -1, NULL );
     380    if( NULL == req )
     381    {
     382        return -1;
     383    }
     384
     385    req->num = ( automap ? 1 : 0 );
     386
     387    return 0;
     388}
     389
     390int
     391client_pex( int pex )
    347392{
    348393    struct req * req;
    349394
    350     req = addreq( IPC_MSG_AUTOMAP, -1, NULL );
    351     if( NULL == req )
    352     {
    353         return -1;
    354     }
    355 
    356     req->num = ( automap ? 1 : 0 );
     395    req = addreq( IPC_MSG_PEX, -1, NULL );
     396    if( NULL == req )
     397    {
     398        return -1;
     399    }
     400
     401    req->num = ( pex ? 1 : 0 );
    357402
    358403    return 0;
     
    670715flushreqs( struct con * con )
    671716{
    672     struct req * req;
    673     uint8_t    * buf;
    674     size_t       buflen;
     717    struct req     * req;
     718    uint8_t        * buf;
     719    size_t           buflen, ii;
     720    benc_val_t       pk, * val;
     721    struct stritem * jj;
    675722
    676723    if( !HASVERS( &con->ipc ) )
     
    688735        req = SLIST_FIRST( &gl_reqs );
    689736        SLIST_REMOVE_HEAD( &gl_reqs, next );
     737        buf = NULL;
    690738        switch( req->id )
    691739        {
     
    697745                break;
    698746            case IPC_MSG_ADDMANYFILES:
    699                 buf = ipc_mkstrlist( &con->ipc, &buflen, req->id, -1,
    700                                      req->strs );
     747                ii = 0;
     748                SLIST_FOREACH( jj, req->strs, next )
     749                {
     750                    ii++;
     751                }
     752                val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST );
     753                if( NULL != val && !tr_bencListReserve( val, ii ) )
     754                {
     755                    SLIST_FOREACH( jj, req->strs, next )
     756                    {
     757                        tr_bencInitStr( tr_bencListAdd( val ),
     758                                        jj->str, -1, 1 );
     759                    }
     760                    buf = ipc_mkval( &pk, &buflen );
     761                    SAFEBENCFREE( &pk );
     762                }
    701763                SAFEFREESTRLIST( req->strs );
     764                break;
     765            case IPC_MSG_ADDONEFILE:
     766                val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_DICT );
     767                if( NULL != val && !tr_bencDictReserve( val, 1 ) )
     768                {
     769                    tr_bencInitStr( tr_bencDictAdd( val, "data" ),
     770                                    req->buf, req->listlen, 1 );
     771                    buf = ipc_mkval( &pk, &buflen );
     772                    SAFEBENCFREE( &pk );
     773                }
     774                SAFEFREE( req->buf );
    702775                break;
    703776            case IPC_MSG_AUTOMAP:
     
    714787            case IPC_MSG_STOP:
    715788            case IPC_MSG_REMOVE:
    716                 buf = ipc_mkints( &con->ipc, &buflen, req->id, req->tag,
    717                                   req->listlen, req->numlist );
     789                val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST );
     790                if( NULL != val && !tr_bencListReserve( val, req->listlen ) )
     791                {
     792                    for( ii = 0; ii < req->listlen; ii++ )
     793                    {
     794                        tr_bencInitInt( tr_bencListAdd( val ),
     795                                        req->numlist[ii] );
     796                    }
     797                    buf = ipc_mkval( &pk, &buflen );
     798                    SAFEBENCFREE( &pk );
     799                }
    718800                SAFEFREE( req->numlist );
    719801                break;
  • branches/daemon/daemon/client.h

    r1626 r1635  
    4242int  client_port     ( int );
    4343int  client_automap  ( int );
     44int  client_pex      ( int );
    4445int  client_downlimit( int );
    4546int  client_uplimit  ( int );
  • branches/daemon/daemon/ipc.c

    r1631 r1635  
    101101    { "noop",                2, IPC_MSG_NOOP,         RB_ENTRY_INITIALIZER() },
    102102    { "not-supported",       2, IPC_MSG_NOTSUP,       RB_ENTRY_INITIALIZER() },
    103     { "pex",                 2, IPC_MSG_PORT,         RB_ENTRY_INITIALIZER() },
     103    { "pex",                 2, IPC_MSG_PEX,          RB_ENTRY_INITIALIZER() },
    104104    { "port",                2, IPC_MSG_PORT,         RB_ENTRY_INITIALIZER() },
    105105    { "quit",                1, IPC_MSG_QUIT,         RB_ENTRY_INITIALIZER() },
     
    157157};
    158158
    159 static int          pkinit     ( struct ipc_info *, benc_val_t *, enum ipc_msg,
    160                                  benc_val_t **, int64_t );
    161 static uint8_t *    pkgenerate ( benc_val_t *, size_t * );
    162159static int          handlevers ( struct ipc_info *, benc_val_t * );
    163160static int          handlemsgs ( struct ipc_info *, benc_val_t *, void * );
     
    245242}
    246243
    247 int
    248 pkinit( struct ipc_info * info, benc_val_t * pk, enum ipc_msg id,
    249         benc_val_t ** val, int64_t tag )
    250 {
     244benc_val_t *
     245ipc_initval( struct ipc_info * info, enum ipc_msg id, int64_t tag,
     246             benc_val_t * pk, int type )
     247{
     248    benc_val_t * ret;
     249
    251250    assert( MSGVALID( id ) );
    252251
     
    254253    {
    255254        errno = EPERM;
    256         return -1;
     255        return NULL;
    257256    }
    258257
     
    262261        if( tr_bencDictReserve( pk, 1 ) )
    263262        {
    264             return -1;
    265         }
    266         *val = tr_bencDictAdd( pk, MSGNAME( id ) );
     263            return NULL;
     264        }
     265        ret = tr_bencDictAdd( pk, MSGNAME( id ) );
    267266    }
    268267    else
     
    271270        if( tr_bencListReserve( pk, ( 0 < tag ? 3 : 2 ) ) )
    272271        {
    273             return -1;
     272            return NULL;
    274273        }
    275274        tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( id ), -1, 1 );
    276         *val = tr_bencListAdd( pk );
     275        ret = tr_bencListAdd( pk );
    277276        if( 0 < tag )
    278277        {
     
    281280    }
    282281
    283     return 0;
     282    tr_bencInit( ret, type );
     283
     284    return ret;
    284285}
    285286
    286287uint8_t *
    287 pkgenerate( benc_val_t * pk, size_t * len )
     288ipc_mkval( benc_val_t * pk, size_t * len )
    288289{
    289290    char * buf, hex[IPC_MIN_MSG_LEN+1];
     
    322323
    323324uint8_t *
    324 ipc_mkstr( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag,
    325            const char * str )
    326 {
    327     benc_val_t pk, * strval;
    328     uint8_t  * ret;
    329 
    330     if( 0 > pkinit( info, &pk, id, &strval, tag ) )
    331     {
    332         return NULL;
    333     }
    334 
    335     tr_bencInitStr( strval, str, -1, 1 );
    336 
    337     ret = pkgenerate( &pk, len );
    338     SAFEBENCFREE( &pk );
    339 
    340     return ret;
    341 }
    342 
    343 uint8_t *
    344 ipc_mkstrlist( struct ipc_info * info, size_t * len, enum ipc_msg id,
    345                int64_t tag, struct strlist * strs )
    346 {
    347     benc_val_t       pk, * list;
    348     struct stritem * ii;
    349     uint8_t        * ret;
    350     int              count;
    351 
    352     if( 0 > pkinit( info, &pk, id, &list, tag ) )
    353     {
    354         return NULL;
    355     }
    356 
    357     count = 0;
    358     SLIST_FOREACH( ii, strs, next )
    359     {
    360         count++;
    361     }
    362 
    363     tr_bencInit( list, TYPE_LIST );
    364     if( tr_bencListReserve( list, count ) )
    365     {
    366         SAFEBENCFREE( &pk );
    367         return NULL;
    368     }
    369 
    370     SLIST_FOREACH( ii, strs, next )
    371     {
    372         if( tr_bencInitStrDup( tr_bencListAdd( list ), ii->str ) )
    373         {
    374             SAFEBENCFREE( &pk );
    375             return NULL;
    376         }
    377     }
    378 
    379     ret = pkgenerate( &pk, len );
    380     SAFEBENCFREE( &pk );
    381 
    382     return ret;
    383 }
    384 
    385 uint8_t *
    386325ipc_mkempty( struct ipc_info * info, size_t * len, enum ipc_msg id,
    387326             int64_t tag )
    388327{
    389     benc_val_t pk, * empty;
     328    benc_val_t pk;
    390329    uint8_t  * ret;
    391330
    392     if( 0 > pkinit( info, &pk, id, &empty, tag ) )
     331    if( NULL == ipc_initval( info, id, tag, &pk, TYPE_STR ) )
    393332    {
    394333        return NULL;
    395334    }
    396335
    397     tr_bencInitStr( empty, NULL, 0, 1 );
    398     ret = pkgenerate( &pk, len );
     336    ret = ipc_mkval( &pk, len );
    399337    SAFEBENCFREE( &pk );
    400338
     
    409347    uint8_t  * ret;
    410348
    411     if( 0 > pkinit( info, &pk, id, &val, tag ) )
     349    val = ipc_initval( info, id, tag, &pk, TYPE_INT );
     350    if( NULL == val )
    412351    {
    413352        return NULL;
    414353    }
    415354
    416     tr_bencInitInt( val, num );
    417     ret = pkgenerate( &pk, len );
     355    val->val.i = num;
     356    ret = ipc_mkval( &pk, len );
    418357    SAFEBENCFREE( &pk );
    419358
     
    422361
    423362uint8_t *
    424 ipc_mkints( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag,
    425             size_t count, const int64_t * nums )
    426 {
    427     benc_val_t pk, * list;
    428     size_t     ii;
     363ipc_mkstr( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag,
     364           const char * str )
     365{
     366    benc_val_t pk, * val;
    429367    uint8_t  * ret;
    430368
    431     if( 0 > pkinit( info, &pk, id, &list, tag ) )
     369    val = ipc_initval( info, id, tag, &pk, TYPE_STR );
     370    if( NULL == val )
    432371    {
    433372        return NULL;
    434373    }
    435374
    436     tr_bencInit( list, TYPE_LIST );
    437     if( tr_bencListReserve( list, count ) )
    438     {
    439         SAFEBENCFREE( &pk );
    440         return NULL;
    441     }
    442 
    443     for( ii = 0; count > ii; ii++ )
    444     {
    445         tr_bencInitInt( tr_bencListAdd( list ), nums[ii] );
    446     }
    447 
    448     ret = pkgenerate( &pk, len );
     375    tr_bencInitStr( val, str, -1, 1 );
     376    ret = ipc_mkval( &pk, len );
    449377    SAFEBENCFREE( &pk );
    450378
     
    474402    tr_bencInitInt( tr_bencDictAdd( dict, "max" ), PROTO_VERS_MAX );
    475403
    476     ret = pkgenerate( &pk, len );
     404    ret = ipc_mkval( &pk, len );
    477405    SAFEBENCFREE( &pk );
    478406
     
    489417    uint8_t    * ret;
    490418
    491     if( 0 > pkinit( info, &pk, id, &top, tag ) )
    492     {
    493         return NULL;
    494     }
    495 
    496419    /* no ID list, send an -all message */
    497420    if( NULL == ids )
    498421    {
    499         typelist = top;
     422        typelist = ipc_initval( info, id, tag, &pk, TYPE_LIST );
     423        if( NULL == typelist )
     424        {
     425            return NULL;
     426        }
    500427    }
    501428    else
    502429    {
     430        top = ipc_initval( info, id, tag, &pk, TYPE_DICT );
     431        if( NULL == top )
     432        {
     433            return NULL;
     434        }
    503435        /* add the requested IDs */
    504         tr_bencInit( top, TYPE_DICT );
    505436        if( tr_bencDictReserve( top, 2 ) )
    506437        {
     
    511442        typelist = tr_bencDictAdd( top, "type" );
    512443        tr_bencInit( idlist, TYPE_LIST );
     444        tr_bencInit( typelist, TYPE_LIST );
    513445        for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ )
    514446        {
     
    544476
    545477    /* add the type names */
    546     tr_bencInit( typelist, TYPE_LIST );
    547478    for( ii = used = 0; typecount > ii; ii++ )
    548479    {
     
    569500
    570501    /* generate packet */
    571     ret = pkgenerate( &pk, len );
     502    ret = ipc_mkval( &pk, len );
    572503    SAFEBENCFREE( &pk );
    573504
    574505    return ret;
    575 }
    576 
    577 int
    578 ipc_initinfo( struct ipc_info * info, enum ipc_msg id, int64_t tag,
    579               benc_val_t * pk, benc_val_t ** val )
    580 {
    581     assert( IPC_MSG_INFO == id || IPC_MSG_STAT == id );
    582 
    583     if( 0 > pkinit( info, pk, id, val, tag ) )
    584     {
    585         return -1;
    586     }
    587 
    588     tr_bencInit( *val, TYPE_LIST );
    589 
    590     return 0;
    591506}
    592507
     
    918833}
    919834
    920 uint8_t *
    921 ipc_mkinfo( benc_val_t * pk, size_t * len )
    922 {
    923     return pkgenerate( pk, len );
    924 }
    925 
    926835ssize_t
    927836ipc_parse( struct ipc_info * info, uint8_t * buf, ssize_t total, void * arg )
  • branches/daemon/daemon/ipc.h

    r1631 r1635  
    140140/* message creation */
    141141/* sets errno to EPERM if requested message not supported by protocol vers */
     142benc_val_t * ipc_initval  ( struct ipc_info *, enum ipc_msg, int64_t,
     143                            benc_val_t *, int );
     144uint8_t *    ipc_mkval    ( benc_val_t *, size_t * );
     145uint8_t *    ipc_mkempty  ( struct ipc_info *, size_t *, enum ipc_msg,
     146                            int64_t );
     147uint8_t *    ipc_mkint    ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
     148                            int64_t );
    142149uint8_t *    ipc_mkstr    ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
    143150                            const char * );
    144 uint8_t *    ipc_mkstrlist( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
    145                             struct strlist * );
    146 uint8_t *    ipc_mkempty  ( struct ipc_info *, size_t *, enum ipc_msg,
    147                             int64_t );
    148 uint8_t *    ipc_mkint    ( struct ipc_info *, size_t *, enum ipc_msg,
    149                             int64_t, int64_t );
    150 uint8_t *    ipc_mkints   ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
    151                             size_t, const int64_t * );
    152151uint8_t *    ipc_mkvers   ( size_t * );
    153152uint8_t *    ipc_mkgetinfo( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
    154153                            int, const int * );
    155 int          ipc_initinfo ( struct ipc_info *, enum ipc_msg, int64_t,
    156                             benc_val_t *, benc_val_t ** );
    157154int          ipc_addinfo  ( benc_val_t *, int, tr_info_t *, int );
    158155int          ipc_addstat  ( benc_val_t *, int, tr_info_t *, tr_stat_t *, int );
    159 uint8_t *    ipc_mkinfo   ( benc_val_t *, size_t * );
    160156
    161157/* sets errno to EINVAL on parse error or
  • branches/daemon/daemon/misc.c

    r1617 r1635  
    2424
    2525#include <sys/types.h>
     26#include <sys/stat.h>
    2627#include <assert.h>
     28#include <errno.h>
     29#include <fcntl.h>
     30#include <stdlib.h>
    2731#include <string.h>
    2832#include <unistd.h>
     
    116120    strlcat( buf, path, len );
    117121}
     122
     123int
     124writefile( const char * name, uint8_t * buf, ssize_t len )
     125{
     126    int     fd;
     127    ssize_t res;
     128
     129    fd = open( name, O_WRONLY | O_CREAT | O_TRUNC, 0666 );
     130    if( 0 > fd )
     131    {
     132        errnomsg( "failed to open %s for writing", name );
     133        return -1;
     134    }
     135
     136    res = write( fd, buf, len );
     137    if( 0 > res )
     138    {
     139        errnomsg( "failed to write to %s", name );
     140        return -1;
     141    }
     142    if( len > res )
     143    {
     144        errmsg( "failed to write all data to %s", name );
     145        return -1;
     146    }
     147
     148    close( fd );
     149
     150    return 0;
     151}
     152
     153uint8_t *
     154readfile( const char * name, size_t * len )
     155{
     156    struct stat sb;
     157    int         fd;
     158    uint8_t   * buf;
     159    ssize_t     res;
     160
     161    fd = open( name, O_RDONLY );
     162    if( 0 > fd )
     163    {
     164        if( ENOENT != errno )
     165        {
     166            errnomsg( "failed to open %s for reading", name );
     167        }
     168        return NULL;
     169    }
     170
     171    if( 0 > fstat( fd, &sb ) )
     172    {
     173        errnomsg( "failed to stat %s", name );
     174        return NULL;
     175    }
     176
     177    buf = malloc( sb.st_size );
     178    if( NULL == buf )
     179    {
     180        mallocmsg( sb.st_size );
     181        return NULL;
     182    }
     183
     184    res = read( fd, buf, sb.st_size );
     185    if( 0 > res )
     186    {
     187        errnomsg( "failed to read from %s", name );
     188        free( buf );
     189        return NULL;
     190    }
     191    if( res < sb.st_size )
     192    {
     193        errmsg( "failed to read all data from %s", name );
     194        free( buf );
     195        return NULL;
     196    }
     197
     198    close( fd );
     199    *len = res;
     200
     201    return buf;
     202}
  • branches/daemon/daemon/misc.h

    r1621 r1635  
    136136void         confpath  ( char *, size_t, const char *, enum confpathtype );
    137137void         absolutify( char *, size_t, const char * );
     138int          writefile ( const char *, uint8_t *, ssize_t );
     139uint8_t *    readfile  ( const char *, size_t * );
    138140
    139141#endif /* TR_DAEMON_MISC_H */
  • branches/daemon/daemon/proxy.c

    r1630 r1635  
    4040#include "transmission.h"
    4141
    42 #define TIMEOUT                 ( 60 )
    43 
    44 static void                 usage    ( const char *, ... );
    45 static enum confpathtype    readargs ( int, char ** );
    46 static int                  makesock ( enum confpathtype );
    47 static struct bufferevent * setupev  ( struct event_base *, int,
    48                                        void ( * )( struct bufferevent *, short,
    49                                                    void * ), void * );
    50 static void                 noop     ( struct bufferevent *, void * );
    51 static void                 relay    ( struct bufferevent *, void * );
    52 static void                 outerr   ( struct bufferevent *, short, void * );
    53 static void                 inerr    ( struct bufferevent *, short, void * );
    54 static void                 sockerr  ( struct bufferevent *, short, void * );
     42static void              usage    ( const char *, ... );
     43static enum confpathtype readargs ( int, char ** );
     44static int               makesock ( enum confpathtype );
     45static void              inread   ( struct bufferevent *, void * );
     46static void              noop     ( struct bufferevent *, void * );
     47static void              inerr    ( struct bufferevent *, short, void * );
     48static void              wtf      ( struct bufferevent *, void * );
     49static void              outerr   ( struct bufferevent *, short, void * );
     50static void              sockread ( struct bufferevent *, void * );
     51static void              sockwrite( struct bufferevent *, void * );
     52static void              sockerr  ( struct bufferevent *, short, void * );
     53
     54static struct bufferevent * gl_in   = NULL;
     55static struct bufferevent * gl_out  = NULL;
     56static struct bufferevent * gl_sock = NULL;
    5557
    5658int
     
    6062    enum confpathtype    type;
    6163    int                  sockfd;
    62     struct bufferevent * outev, * inev, * sockev;
    6364
    6465    setmyname( argv[0] );
     
    7273    }
    7374
    74     outev  = setupev( base, STDOUT_FILENO, outerr,  NULL );
    75     sockev = setupev( base, sockfd,        sockerr, outev );
    76     inev   = setupev( base, STDIN_FILENO,  inerr,   sockev );
    77 
    78     if( NULL == outev || NULL == inev || NULL == sockev )
    79     {
     75    gl_in = bufferevent_new( STDIN_FILENO, inread, noop, inerr, NULL );
     76    if( NULL == gl_in )
     77    {
     78        errnomsg( "failed to set up event buffer for stdin" );
    8079        return EXIT_FAILURE;
    8180    }
    82 
    83     bufferevent_disable( outev,  EV_READ );
    84     bufferevent_enable(  outev,  EV_WRITE );
    85     bufferevent_enable(  inev,   EV_READ );
    86     bufferevent_disable( inev,   EV_WRITE );
    87     bufferevent_enable(  sockev, EV_READ );
    88     bufferevent_enable(  sockev, EV_WRITE );
     81    bufferevent_base_set( base, gl_in );
     82    bufferevent_enable( gl_in, EV_READ );
     83    bufferevent_disable( gl_in, EV_WRITE );
     84
     85    gl_out  = bufferevent_new( STDOUT_FILENO, wtf, noop, outerr,  NULL );
     86    if( NULL == gl_in )
     87    {
     88        errnomsg( "failed to set up event buffer for stdin" );
     89        return EXIT_FAILURE;
     90    }
     91    bufferevent_base_set( base, gl_out );
     92    bufferevent_disable( gl_out, EV_READ );
     93    bufferevent_enable( gl_out, EV_WRITE );
     94
     95    gl_sock = bufferevent_new( sockfd, sockread, sockwrite, sockerr, NULL );
     96    if( NULL == gl_in )
     97    {
     98        errnomsg( "failed to set up event buffer for stdin" );
     99        return EXIT_FAILURE;
     100    }
     101    bufferevent_base_set( base, gl_sock );
     102    bufferevent_enable( gl_sock, EV_READ );
     103    bufferevent_enable( gl_sock, EV_WRITE );
    89104
    90105    event_base_dispatch( base );
     
    189204}
    190205
    191 struct bufferevent *
    192 setupev( struct event_base * base, int fd,
    193          void ( * efunc )( struct bufferevent *, short, void * ), void * arg )
    194 {
    195     struct bufferevent * ev;
    196 
    197     ev = bufferevent_new( fd, relay, noop, efunc, arg );
    198     if( NULL == ev )
    199     {
    200         mallocmsg( -1 );
    201         return NULL;
    202     }
    203 
    204     bufferevent_base_set( base, ev );
    205     bufferevent_settimeout( ev, TIMEOUT, TIMEOUT );
    206 
    207     return ev;
     206void
     207inread( struct bufferevent * ev UNUSED, void * arg UNUSED )
     208{
     209    bufferevent_write_buffer( gl_sock, EVBUFFER_INPUT( gl_in ) );
    208210}
    209211
     
    211213noop( struct bufferevent * ev UNUSED, void * arg UNUSED )
    212214{
    213     /* libevent prior to 1.2 couldn't handle a NULL write callback */
    214 }
    215 
    216 void
    217 relay( struct bufferevent * in, void * arg )
    218 {
    219     struct bufferevent * out = arg;
    220 
    221     if( NULL == arg )
    222     {
    223         /* this shouldn't happen, but let's drain the buffer anyway */
    224         evbuffer_drain( EVBUFFER_INPUT( in ),
    225                         EVBUFFER_LENGTH( EVBUFFER_INPUT( in ) ) );
     215}
     216
     217void
     218inerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED )
     219{
     220    if( EVBUFFER_EOF & what )
     221    {
     222        bufferevent_free( gl_in );
     223        gl_in = NULL;
     224        sockwrite( NULL, NULL );
     225        return;
     226    }
     227
     228    if( EVBUFFER_TIMEOUT & what )
     229    {
     230        errmsg( "timed out reading from stdin" );
     231    }
     232    else if( EVBUFFER_READ & what )
     233    {
     234        errmsg( "read error on stdin" );
     235    }
     236    else if( EVBUFFER_ERROR & what )
     237    {
     238        errmsg( "error on stdin" );
    226239    }
    227240    else
    228241    {
    229         bufferevent_write_buffer( out, EVBUFFER_INPUT( in ) );
    230     }
     242        errmsg( "unknown error on stdin: 0x%x", what );
     243    }
     244
     245    exit( EXIT_FAILURE );
     246}
     247
     248void
     249wtf( struct bufferevent * ev, void * arg UNUSED )
     250{
     251    /* this shouldn't happen, but let's drain the buffer anyway */
     252    evbuffer_drain( EVBUFFER_INPUT( ev ),
     253                    EVBUFFER_LENGTH( EVBUFFER_INPUT( ev ) ) );
    231254}
    232255
     
    255278
    256279void
    257 inerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED )
     280sockread( struct bufferevent * ev UNUSED, void * arg UNUSED )
     281{
     282    bufferevent_write_buffer( gl_out, EVBUFFER_INPUT( gl_sock ) );
     283}
     284
     285void
     286sockwrite( struct bufferevent * ev UNUSED, void * arg UNUSED )
     287{
     288    if( NULL == gl_in && 0 == EVBUFFER_LENGTH( EVBUFFER_OUTPUT( gl_sock ) ) )
     289    {
     290        exit( EXIT_SUCCESS );
     291    }
     292}
     293
     294void
     295sockerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED )
    258296{
    259297    if( EVBUFFER_EOF & what )
    260298    {
    261         exit( EXIT_SUCCESS );
     299        errmsg( "server closed connection" );
    262300    }
    263301    else if( EVBUFFER_TIMEOUT & what )
    264302    {
    265         errmsg( "timed out reading from stdin" );
     303        errmsg( "server connection timed out" );
    266304    }
    267305    else if( EVBUFFER_READ & what )
    268306    {
    269         errmsg( "read error on stdin" );
     307        errmsg( "read error on server connection" );
     308    }
     309    else if( EVBUFFER_WRITE & what )
     310    {
     311        errmsg( "write error on server connection" );
    270312    }
    271313    else if( EVBUFFER_ERROR & what )
    272314    {
    273         errmsg( "error on stdin" );
     315        errmsg( "error on server connection" );
    274316    }
    275317    else
    276318    {
    277         errmsg( "unknown error on stdin: 0x%x", what );
     319        errmsg( "unknown error on server connection: 0x%x", what );
    278320    }
    279321
    280322    exit( EXIT_FAILURE );
    281323}
    282 
    283 void
    284 sockerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED )
    285 {
    286     if( EVBUFFER_EOF & what )
    287     {
    288         errmsg( "server closed connection" );
    289     }
    290     else if( EVBUFFER_TIMEOUT & what )
    291     {
    292         errmsg( "server connection timed out" );
    293     }
    294     else if( EVBUFFER_READ & what )
    295     {
    296         errmsg( "read error on server connection" );
    297     }
    298     else if( EVBUFFER_WRITE & what )
    299     {
    300         errmsg( "write error on server connection" );
    301     }
    302     else if( EVBUFFER_ERROR & what )
    303     {
    304         errmsg( "error on server connection" );
    305     }
    306     else
    307     {
    308         errmsg( "unknown error on server connection: 0x%x", what );
    309     }
    310 
    311     exit( EXIT_FAILURE );
    312 }
  • branches/daemon/daemon/remote.c

    r1631 r1635  
    162162        ( o.port                    &&   0 > client_port     ( o.port    ) ) ||
    163163        ( 0 <= o.map                &&   0 > client_automap  ( o.map     ) ) ||
     164        ( 0 <= o.pex                &&   0 > client_pex      ( o.pex     ) ) ||
    164165        ( o.uplimit                 &&   0 > client_uplimit  ( o.up      ) ) ||
    165166        ( o.downlimit               &&   0 > client_downlimit( o.down    ) ) ||
     
    212213  "  -d --download-limit <int> Max download rate in KiB/s\n"
    213214  "  -D --download-unlimited   No download rate limit\n"
     215  "  -e --enable-pex           Enable peer exchange\n"
     216  "  -E --disable-pex          Disable peer exchange\n"
    214217  "  -f --folder <path>        Folder to set for new torrents\n"
    215218  "  -h --help                 Display this message and exit\n"
     
    238241readargs( int argc, char ** argv, struct opts * opts )
    239242{
    240     char optstr[] = "a:d:Df:hilmMp:qr:s:S:t:u:Ux";
     243    char optstr[] = "a:d:DeEf:hilmMp:qr:s:S:t:u:Ux";
    241244    struct option longopts[] =
    242245    {
     
    244247        { "download-limit",     required_argument, NULL, 'd' },
    245248        { "download-unlimited", no_argument,       NULL, 'D' },
     249        { "enable-pex",         no_argument,       NULL, 'e' },
     250        { "disable-pex",        no_argument,       NULL, 'E' },
    246251        { "folder",             required_argument, NULL, 'f' },
    247252        { "help",               no_argument,       NULL, 'h' },
     
    268273    SLIST_INIT( &opts->files );
    269274    opts->map = -1;
     275    opts->pex = -1;
    270276    SLIST_INIT( &opts->start );
    271277    SLIST_INIT( &opts->stop );
     
    289295                opts->downlimit = 1;
    290296                opts->down      = -1;
     297                break;
     298            case 'e':
     299                opts->pex       = 1;
     300                break;
     301            case 'E':
     302                opts->pex       = 0;
    291303                break;
    292304            case 'f':
     
    876888        downspeed = fmtsize( ii->down, &downunits );
    877889        name      = ( NULL == ii->name ? "???" : ii->name );
    878         progress  = ( float )ii->done / ( float )ii->size;
     890        progress  = ( float )ii->done / ( float )ii->size * 100.0;
    879891        progress  = MIN( 100.0, progress );
    880892        progress  = MAX( 0.0, progress );
  • branches/daemon/daemon/server.c

    r1631 r1635  
    409409    }
    410410
    411     if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &added ) )
     411    added = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
     412    if( NULL == added )
    412413    {
    413414        errnomsg( "failed to build message" );
     
    424425        }
    425426        /* XXX need to somehow inform client of skipped or failed files */
    426         tor = torrent_add( file->val.s.s, NULL, -1 );
     427        tor = torrent_add_file( file->val.s.s, NULL, -1 );
    427428        if( TORRENT_ID_VALID( tor ) )
    428429        {
     
    438439    }
    439440
    440     buf = ipc_mkinfo( &pk, &buflen );
     441    buf = ipc_mkval( &pk, &buflen );
    441442    tr_bencFree( &pk );
    442443    queuemsg( client, buf, buflen );
     
    469470    if( NULL != val && TYPE_STR == val->type )
    470471    {
    471         /* XXX not quite yet */
    472         msgresp( client, tag, IPC_MSG_NOTSUP );
    473         return;
     472        /* XXX detect duplicates and return a message indicating so */
     473        tor = torrent_add_data( val->val.s.s, val->val.s.i, dir, start );
    474474    }
    475475    else
     
    482482        }
    483483        /* XXX detect duplicates and return a message indicating so */
    484         tor = torrent_add( val->val.s.s, dir, start );
     484        tor = torrent_add_file( val->val.s.s, dir, start );
    485485    }
    486486
    487487    if( TORRENT_ID_VALID( tor ) )
    488488    {
    489         if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &val ) )
     489        val = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
     490        if( NULL == val )
    490491        {
    491492            errnomsg( "failed to build message" );
     
    501502            return;
    502503        }
    503         buf = ipc_mkinfo( &pk, &buflen );
     504        buf = ipc_mkval( &pk, &buflen );
    504505        tr_bencFree( &pk );
    505506        queuemsg( client, buf, buflen );
     
    628629
    629630    /* initialize packet */
    630     if( 0 > ipc_initinfo( &client->ipc, respid, tag, &pk, &pkinf ) )
     631    pkinf = ipc_initval( &client->ipc, respid, tag, &pk, TYPE_LIST );
     632    if( NULL == pkinf )
    631633    {
    632634        errnomsg( "failed to build message" );
     
    650652            if( 0 > addfunc( pkinf, tor, types ) )
    651653            {
     654                errnomsg( "failed to build message" );
    652655                tr_bencFree( &pk );
    653656                byebye( client->ev, EVBUFFER_EOF, NULL );
     
    685688            if( 0 > addfunc( pkinf, idval->val.i, types ) )
    686689            {
     690                errnomsg( "failed to build message" );
    687691                tr_bencFree( &pk );
    688692                byebye( client->ev, EVBUFFER_EOF, NULL );
     
    693697
    694698    /* generate packet data and send it */
    695     buf = ipc_mkinfo( &pk, &buflen );
     699    buf = ipc_mkval( &pk, &buflen );
     700    tr_bencFree( &pk );
    696701    queuemsg( client, buf, buflen );
    697702    free( buf );
    698     tr_bencFree( &pk );
    699703}
    700704
     
    813817    }
    814818
    815     if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &pkinf ) )
    816     {
     819    pkinf = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
     820    if( NULL == pkinf )
     821    {
     822        errnomsg( "failed to build message" );
    817823        byebye( client->ev, EVBUFFER_EOF, NULL );
    818824        return;
     
    838844        if( 0 > ipc_addinfo( pkinf, found, inf, IPC_INF_HASH ) )
    839845        {
     846            errnomsg( "failed to build message" );
    840847            tr_bencFree( &pk );
    841848            byebye( client->ev, EVBUFFER_EOF, NULL );
     
    844851    }
    845852
    846     buf = ipc_mkinfo( &pk, &buflen );
     853    buf = ipc_mkval( &pk, &buflen );
    847854    tr_bencFree( &pk );
    848855    queuemsg( client, buf, buflen );
     
    902909    uint8_t        * buf;
    903910    size_t           buflen;
    904     int              ii, used;
    905     benc_val_t     * name;
    906     struct stritem * strs;
    907     struct strlist   strlist;
     911    int              ii;
     912    benc_val_t       pk, *pkval, * name;
    908913    enum ipc_msg     found;
    909914
     
    914919    }
    915920
    916     strs = calloc( val->val.l.count, sizeof *strs );
    917     if( NULL == strs )
    918     {
     921    pkval = ipc_initval( &client->ipc, IPC_MSG_SUP, tag, &pk, TYPE_LIST );
     922    if( NULL == pkval )
     923    {
     924        errnomsg( "failed to build message" );
    919925        byebye( client->ev, EVBUFFER_EOF, NULL );
    920926        return;
    921927    }
    922     used = 0;
     928    /* XXX look at other initval to make sure we free pk */
     929    if( tr_bencListReserve( pkval, val->val.l.count ) )
     930    {
     931        errnomsg( "failed to build message" );
     932        tr_bencFree( &pk );
     933        byebye( client->ev, EVBUFFER_EOF, NULL );
     934        return;
     935    }
    923936
    924937    for( ii = 0; val->val.l.count > ii; ii++ )
     
    927940        if( NULL == name || TYPE_STR != name->type )
    928941        {
    929             free( strs );
     942            tr_bencFree( &pk );
    930943            msgresp( client, tag, IPC_MSG_NOTSUP );
    931944            return;
     
    936949            continue;
    937950        }
    938         strs[used].str = name->val.s.s;
    939         used++;
    940     }
    941 
    942     SLIST_INIT( &strlist );
    943     while( 0 < used )
    944     {
    945         SLIST_INSERT_HEAD( &strlist, &strs[used-1], next );
    946         used--;
    947     }
    948     buf = ipc_mkstrlist( &client->ipc, &buflen, IPC_MSG_SUP, tag, &strlist );
     951        tr_bencInitStr( tr_bencListAdd( pkval ),
     952                        name->val.s.s, name->val.s.i, 1 );
     953    }
     954
     955    buf = ipc_mkval( &pk, &buflen );
     956    tr_bencFree( &pk );
    949957    queuemsg( client, buf, buflen );
    950     free( strs );
    951 }
     958    free( buf );
     959}
  • branches/daemon/daemon/torrents.c

    r1631 r1635  
    6666RB_HEAD( hashtree, tor );
    6767
    68 static struct tor * opentorrent ( const char *, const char *, const char * );
    69 static void         closetorrent( struct tor *, int );
    70 static void         starttimer  ( int );
    71 static void         timerfunc   ( int, short, void * );
    72 static int          loadstate   ( void );
    73 static int          savestate   ( void );
    74 static int          toridcmp    ( struct tor *, struct tor * );
    75 static int          torhashcmp  ( struct tor *, struct tor * );
    76 static int          writefile   ( const char *, uint8_t *, ssize_t );
    77 static uint8_t    * readfile    ( const char *, size_t * );
    78 static struct tor * idlookup    ( int, int );
    79 static struct tor * hashlookup  ( const uint8_t *, int );
    80 static struct tor * iterate     ( struct tor * );
     68static struct tor * opentor    ( const char *, const char *, uint8_t *, size_t,
     69                                  const char * );
     70static void         closetor   ( struct tor *, int );
     71static void         starttimer ( int );
     72static void         timerfunc  ( int, short, void * );
     73static int          loadstate  ( void );
     74static int          savestate  ( void );
     75static int          toridcmp   ( struct tor *, struct tor * );
     76static int          torhashcmp ( struct tor *, struct tor * );
     77static struct tor * idlookup   ( int, int );
     78static struct tor * hashlookup ( const uint8_t *, int );
     79static struct tor * iterate    ( struct tor * );
    8180
    8281static struct event_base * gl_base      = NULL;
     
    120119
    121120int
    122 torrent_add( const char * path, const char * dir, int autostart )
    123 {
    124     struct tor * tor;
    125 
    126     assert( NULL != gl_handle );
    127     assert( !gl_exiting );
    128 
    129     tor = opentorrent( path, NULL, dir );
     121torrent_add_file( const char * path, const char * dir, int autostart )
     122{
     123    struct tor * tor;
     124
     125    assert( NULL != gl_handle );
     126    assert( !gl_exiting );
     127
     128    tor = opentor( path, NULL, NULL, 0, dir );
     129    if( NULL == tor )
     130    {
     131        return -1;
     132    }
     133
     134    if( 0 > autostart )
     135    {
     136        autostart = gl_autostart;
     137    }
     138    if( autostart )
     139    {
     140        tr_torrentStart( tor->tor );
     141    }
     142
     143    savestate();
     144
     145    return tor->id;
     146}
     147
     148int
     149torrent_add_data( uint8_t * data, size_t size, const char * dir, int autostart )
     150{
     151    struct tor * tor;
     152
     153    assert( NULL != gl_handle );
     154    assert( !gl_exiting );
     155
     156    tor = opentor( NULL, NULL, data, size, dir );
    130157    if( NULL == tor )
    131158    {
     
    207234    }
    208235
    209     closetorrent( tor, 1 );
     236    closetor( tor, 1 );
    210237    savestate();
    211238}
     
    306333    RB_FOREACH( tor, tortree, &gl_tree )
    307334    {
    308         closetorrent( tor, 0 );
     335        closetor( tor, 0 );
    309336    }
    310337
     
    444471
    445472struct tor *
    446 opentorrent( const char * path, const char * hash, const char * dir )
     473opentor( const char * path, const char * hash, uint8_t * data, size_t size,
     474         const char * dir )
    447475{
    448476    struct tor * tor, * found;
     
    450478    tr_info_t  * inf;
    451479
    452     assert( NULL == path || NULL == hash );
    453     assert( NULL != path || NULL != hash );
     480    assert( ( NULL != path && NULL == hash && NULL == data ) ||
     481            ( NULL == path && NULL != hash && NULL == data ) ||
     482            ( NULL == path && NULL == hash && NULL != data ) );
    454483
    455484    /* XXX should probably wrap around back to 1 and avoid duplicates */
     
    473502                                   TR_FLAG_SAVE, &errcode );
    474503    }
     504    else if( NULL != hash )
     505    {
     506        tor->tor = tr_torrentInitSaved( gl_handle, hash, 0, &errcode );
     507    }
    475508    else
    476509    {
    477         tor->tor = tr_torrentInitSaved( gl_handle, hash, 0, &errcode );
     510        tor->tor = tr_torrentInitData( gl_handle, data, size, tor->hash,
     511                                       TR_FLAG_SAVE, &errcode );
    478512    }
    479513
     
    484518        {
    485519            case TR_EINVALID:
    486                 errmsg( "invalid torrent file: %s", path );
     520                if( NULL == path )
     521                {
     522                    errmsg( "invalid torrent file" );
     523                }
     524                else
     525                {
     526                    errmsg( "invalid torrent file: %s", path );
     527                }
    487528                break;
    488529            case TR_EUNSUPPORTED:
    489                 errmsg( "unsupported torrent file: %s", path );
     530                if( NULL == path )
     531                {
     532                    errmsg( "unsupported torrent file" );
     533                }
     534                else
     535                {
     536                    errmsg( "unsupported torrent file: %s", path );
     537                }
    490538                break;
    491539            case TR_EDUPLICATE:
     
    495543                break;
    496544            default:
    497                 errmsg( "torrent file failed to load: %s", path );
     545                if( NULL == path )
     546                {
     547                    errmsg( "torrent file failed to load" );
     548                }
     549                else
     550                {
     551                    errmsg( "torrent file failed to load: %s", path );
     552                }
    498553                break;
    499554        }
     
    530585
    531586void
    532 closetorrent( struct tor * tor, int calltimer )
     587closetor( struct tor * tor, int calltimer )
    533588{
    534589    tr_stat_t  * st;
     
    729784        }
    730785
    731         tor = opentorrent( NULL, str->val.s.s, dir );
     786        tor = opentor( NULL, str->val.s.s, NULL, 0, dir );
    732787        if( NULL == tor )
    733788        {
     
    854909}
    855910
    856 int
    857 writefile( const char * name, uint8_t * buf, ssize_t len )
    858 {
    859     int     fd;
    860     ssize_t res;
    861 
    862     fd = open( name, O_WRONLY | O_CREAT | O_TRUNC, 0666 );
    863     if( 0 > fd )
    864     {
    865         errnomsg( "failed to open %s for writing", name );
    866         return -1;
    867     }
    868 
    869     res = write( fd, buf, len );
    870     if( 0 > res )
    871     {
    872         errnomsg( "failed to write to %s", name );
    873         return -1;
    874     }
    875     if( len > res )
    876     {
    877         errmsg( "failed to write all data to %s", name );
    878         return -1;
    879     }
    880 
    881     close( fd );
    882 
    883     return 0;
    884 }
    885 
    886 uint8_t *
    887 readfile( const char * name, size_t * len )
    888 {
    889     struct stat sb;
    890     int         fd;
    891     uint8_t   * buf;
    892     ssize_t     res;
    893 
    894     fd = open( name, O_RDONLY );
    895     if( 0 > fd )
    896     {
    897         if( ENOENT != errno )
    898         {
    899             errnomsg( "failed to open %s for reading", name );
    900         }
    901         return NULL;
    902     }
    903 
    904     if( 0 > fstat( fd, &sb ) )
    905     {
    906         errnomsg( "failed to stat %s", name );
    907         return NULL;
    908     }
    909 
    910     buf = malloc( sb.st_size );
    911     if( NULL == buf )
    912     {
    913         mallocmsg( sb.st_size );
    914         return NULL;
    915     }
    916 
    917     res = read( fd, buf, sb.st_size );
    918     if( 0 > res )
    919     {
    920         errnomsg( "failed to read from %s", name );
    921         free( buf );
    922         return NULL;
    923     }
    924     if( res < sb.st_size )
    925     {
    926         errmsg( "failed to read all data from %s", name );
    927         free( buf );
    928         return NULL;
    929     }
    930 
    931     close( fd );
    932     *len = res;
    933 
    934     return buf;
    935 }
    936 
    937911struct tor *
    938912idlookup( int id, int wantdel )
  • branches/daemon/daemon/torrents.h

    r1631 r1635  
    3434
    3535void         torrent_init                ( struct event_base * );
    36 int          torrent_add                 ( const char *, const char *, int );
     36int          torrent_add_file            ( const char *, const char *, int );
     37int          torrent_add_data            ( uint8_t *, size_t, const char *, int );
    3738void         torrent_start               ( int );
    3839void         torrent_stop                ( int );
  • branches/daemon/daemon/transmission-remote.1

    r1629 r1635  
    4141.Op Fl d Ar download-rate
    4242.Op Fl D
     43.Op Fl e
     44.Op Fl E
    4345.Op Fl f Ar directory
    4446.Op Fl i
     
    6567.Op Fl d Ar download-rate
    6668.Op Fl D
     69.Op Fl e
     70.Op Fl E
    6771.Op Fl f Ar directory
    6872.Op Fl i
     
    103107.It Fl D Fl -download-unlimited
    104108Remove the download limit.
     109.It Fl e
     110Enable peer exchange.
     111.It Fl E
     112Disable peer exchange.
    105113.It Fl f Fl -folder Ar directory
    106114Use
Note: See TracChangeset for help on using the changeset viewer.