hack on IPC a bit because it's been too long since I broke it

This commit is contained in:
Charles Kerr 2008-04-03 21:38:32 +00:00
parent 918f8f4936
commit fd0e71c00a
12 changed files with 305 additions and 299 deletions

View File

@ -794,7 +794,7 @@ flushreqs( struct con * con )
tr_bencInitStr( tr_bencListAdd( val ),
jj->str, -1, 1 );
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
SAFEBENCFREE( &pk );
}
SAFEFREESTRLIST( req->strs );
@ -805,7 +805,7 @@ flushreqs( struct con * con )
{
tr_bencInitStr( tr_bencDictAdd( val, "data" ),
req->buf, req->listlen, 1 );
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
SAFEBENCFREE( &pk );
}
SAFEFREE( req->buf );
@ -833,7 +833,7 @@ flushreqs( struct con * con )
tr_bencInitInt( tr_bencListAdd( val ),
req->numlist[ii] );
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
SAFEBENCFREE( &pk );
}
SAFEFREE( req->numlist );

View File

@ -498,7 +498,7 @@ addmsg1( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
}
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
tr_bencFree( &pk );
queuemsg( client, buf, buflen );
free( buf );
@ -562,7 +562,7 @@ addmsg2( enum ipc_msg id UNUSED, benc_val_t * dict, int64_t tag, void * arg )
byebye( client->ev, EVBUFFER_EOF, NULL );
return;
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
tr_bencFree( &pk );
queuemsg( client, buf, buflen );
free( buf );
@ -761,7 +761,7 @@ infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
}
/* generate packet data and send it */
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
tr_bencFree( &pk );
queuemsg( client, buf, buflen );
free( buf );
@ -906,7 +906,7 @@ lookmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
}
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
tr_bencFree( &pk );
queuemsg( client, buf, buflen );
free( buf );
@ -1027,7 +1027,7 @@ supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
name->val.s.s, name->val.s.i, 1 );
}
buf = ipc_mkval( &pk, &buflen );
buf = ipc_serialize( &pk, &buflen );
tr_bencFree( &pk );
queuemsg( client, buf, buflen );
free( buf );

View File

@ -183,7 +183,7 @@ client_sendmsg( struct constate * con )
{
tr_bencInitStr( tr_bencListAdd( val ), ii->data, -1, 0 );
}
buf = ipc_mkval( &packet, &size );
buf = ipc_serialize( &packet, &size );
saved = errno;
tr_bencFree( &packet );
g_slist_free( cli->files );
@ -684,7 +684,7 @@ smsg_info( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg )
}
}
buf = ipc_mkval( &packet, &size );
buf = ipc_serialize( &packet, &size );
tr_bencFree( &packet );
if( NULL == buf )
{
@ -745,7 +745,7 @@ smsg_infoall( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg )
while( gtk_tree_model_iter_next( model, &iter ) );
}
buf = ipc_mkval( &packet, &size );
buf = ipc_serialize( &packet, &size );
tr_bencFree( &packet );
if( NULL == buf )
{
@ -829,7 +829,7 @@ smsg_look( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag,
}
}
buf = ipc_mkval( &packet, &size );
buf = ipc_serialize( &packet, &size );
tr_bencFree( &packet );
if( NULL == buf )
{
@ -1116,7 +1116,7 @@ smsg_sup( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg )
name->val.s.s, name->val.s.i, 1 );
}
buf = ipc_mkval( &packet, &size );
buf = ipc_serialize( &packet, &size );
tr_bencFree( &packet );
if( NULL == buf )
{

View File

@ -440,19 +440,31 @@ tr_bencInitInt( tr_benc * val, int64_t num )
val->val.i = num;
}
int
tr_bencInitList( tr_benc * val, int reserveCount )
{
tr_bencInit( val, TYPE_LIST );
return tr_bencListReserve( val, reserveCount );
}
int
tr_bencListReserve( tr_benc * val, int count )
{
assert( isList( val ) );
return makeroom( val, count );
}
int
tr_bencInitDict( tr_benc * val, int reserveCount )
{
tr_bencInit( val, TYPE_DICT );
return tr_bencDictReserve( val, reserveCount );
}
int
tr_bencDictReserve( tr_benc * val, int count )
{
assert( isDict( val ) );
return makeroom( val, count * 2 );
}

View File

@ -88,6 +88,8 @@ static inline void tr_bencInit( tr_benc * val, int type )
void _tr_bencInitStr( tr_benc * val, char * str, int len, int nofree );
int tr_bencInitStrDup( tr_benc * val, const char * str );
void tr_bencInitInt( tr_benc * val, int64_t num );
int tr_bencInitDict( tr_benc * val, int reserveCount );
int tr_bencInitList( tr_benc * val, int reserveCount );
int tr_bencListReserve( tr_benc * list, int count );
/* note that for one key-value pair, count should be 1, not 2 */
int tr_bencDictReserve( tr_benc * dict, int count );

View File

@ -94,40 +94,41 @@ void tr_cpClose( tr_completion * cp )
static void
tr_cpEnsureDoneValid( const tr_completion * ccp )
{
const tr_torrent * tor = ccp->tor;
const tr_info * info = &tor->info;
uint64_t have=0, total=0;
tr_piece_index_t i;
tr_completion * cp ;
if( ccp->doneDirty )
{
const tr_torrent * tor = ccp->tor;
const tr_info * info = &tor->info;
uint64_t have = 0;
uint64_t total = 0;
tr_piece_index_t i;
tr_completion * cp ;
if( !ccp->doneDirty )
return;
/* too bad C doesn't have 'mutable' */
cp = (tr_completion*) ccp;
cp->doneDirty = FALSE;
/* too bad C doesn't have 'mutable' */
cp = (tr_completion*) ccp;
cp->doneDirty = FALSE;
for( i=0; i<info->pieceCount; ++i ) {
if( !info->pieces[i].dnd ) {
total += info->pieceSize;
have += cp->completeBlocks[ i ];
for( i=0; i<info->pieceCount; ++i ) {
if( !info->pieces[i].dnd ) {
total += info->pieceSize;
have += cp->completeBlocks[ i ];
}
}
have *= tor->blockSize;
/* the last piece/block is probably smaller than the others */
if( !info->pieces[info->pieceCount-1].dnd ) {
total -= ( info->pieceSize - tr_torPieceCountBytes(tor,info->pieceCount-1) );
if( tr_cpBlockIsComplete( cp, tor->blockCount-1 ) )
have -= ( tor->blockSize - tr_torBlockCountBytes(tor,tor->blockCount-1) );
}
assert( have <= total );
assert( total <= info->totalSize );
cp->doneHave = have;
cp->doneTotal = total;
}
have *= tor->blockSize;
/* the last piece/block is probably smaller than the others */
if( !info->pieces[info->pieceCount-1].dnd ) {
total -= ( info->pieceSize - tr_torPieceCountBytes(tor,info->pieceCount-1) );
if( tr_cpBlockIsComplete( cp, tor->blockCount-1 ) )
have -= ( tor->blockSize - tr_torBlockCountBytes(tor,tor->blockCount-1) );
}
assert( have <= total );
assert( total <= info->totalSize );
cp->doneHave = have;
cp->doneTotal = total;
}
void
@ -311,10 +312,8 @@ tr_cpGetStatus ( const tr_completion * cp )
tr_cpEnsureDoneValid( cp );
if( cp->doneHave >= cp->doneTotal )
return TR_CP_DONE;
return TR_CP_INCOMPLETE;
return cp->doneHave >= cp->doneTotal ? TR_CP_DONE
: TR_CP_INCOMPLETE;
}
uint64_t

View File

@ -195,24 +195,24 @@ ipc_initmsgs( void )
}
void
ipc_addmsg( struct ipc_funcs * tree, enum ipc_msg id, trd_msgfunc func )
ipc_addmsg( struct ipc_funcs * funcs, enum ipc_msg msg_id, trd_msgfunc func )
{
assert( MSGVALID( id ) );
assert( IPC_MSG_VERSION != id );
assert( MSGVALID( msg_id ) );
assert( IPC_MSG_VERSION != msg_id );
tree->msgs[id] = func;
funcs->msgs[msg_id] = func;
}
void
ipc_setdefmsg( struct ipc_funcs * tree, trd_msgfunc func )
ipc_setdefmsg( struct ipc_funcs * funcs, trd_msgfunc func )
{
tree->def = func;
funcs->def = func;
}
void
ipc_freemsgs( struct ipc_funcs * tree )
ipc_freemsgs( struct ipc_funcs * funcs )
{
tr_free( tree );
tr_free( funcs );
}
struct ipc_info *
@ -230,8 +230,28 @@ ipc_freecon( struct ipc_info * info )
tr_free( info );
}
int
ipc_ishandled( const struct ipc_info * info, enum ipc_msg id )
{
assert( MSGVALID( id ) );
return info->funcs->msgs[id] != NULL;
}
int
ipc_havetags( const struct ipc_info * info )
{
return !DICTPAYLOAD( info );
}
static int
ipc_havemsg( const struct ipc_info * info, enum ipc_msg id )
sessionSupportsTags( const struct ipc_info * session )
{
return session->vers >= 2;
}
static int
sessionSupportsMessage( const struct ipc_info * info, enum ipc_msg id )
{
assert( MSGVALID( id ) );
assert( ipc_hasvers( info ) );
@ -239,51 +259,61 @@ ipc_havemsg( const struct ipc_info * info, enum ipc_msg id )
return gl_msgs[id].minvers <= info->vers;
}
/**
* Creates the benc metainfo structure for a message
* and returns its child where payload should be set.
*
* In protocol version 1, the metainfo is a single-entry
* dictionary with a string from gl_msgs as the key
* and the return tr_benc pointer as the value.
*
* In protocol version 2, the metainfo is a list
* holding a string from gl_msgs, the return benc pointer,
* and (optionally) the integer tag.
*/
tr_benc *
ipc_initval( const struct ipc_info * info, enum ipc_msg id, int64_t tag,
tr_benc * pk, int type )
ipc_initval( const struct ipc_info * session,
enum ipc_msg msg_id,
int64_t tag,
tr_benc * pk,
int benc_type )
{
tr_benc * ret;
assert( MSGVALID( id ) );
assert( MSGVALID( msg_id ) );
if( !ipc_havemsg( info, id ) || ( 0 < tag && !ipc_havetags( info ) ) )
if( !sessionSupportsMessage( session, msg_id )
|| ( (tag>0) && !sessionSupportsTags( session ) ) )
{
errno = EPERM;
return NULL;
}
if( DICTPAYLOAD( info ) )
if( DICTPAYLOAD( session ) )
{
tr_bencInit( pk, TYPE_DICT );
if( tr_bencDictReserve( pk, 1 ) )
{
return NULL;
}
ret = tr_bencDictAdd( pk, MSGNAME( id ) );
tr_bencInitDict( pk, 1 );
ret = tr_bencDictAdd( pk, MSGNAME( msg_id ) );
}
else
{
tr_bencInit( pk, TYPE_LIST );
if( tr_bencListReserve( pk, ( 0 < tag ? 3 : 2 ) ) )
{
return NULL;
}
tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( id ), -1, 1 );
tr_bencInitList( pk, 3 );
tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( msg_id ), -1, 1 );
ret = tr_bencListAdd( pk );
if( 0 < tag )
{
tr_bencInitInt( tr_bencListAdd( pk ), tag );
}
}
tr_bencInit( ret, type );
tr_bencInit( ret, benc_type );
return ret;
}
/**
* Serialize a benc message into a string appended to a
* printf()'ed string IPC_MIN_MSG_LEN bytes long that
* gives the length of the string.
*/
uint8_t *
ipc_mkval( const tr_benc * pk, size_t * setmeSize )
ipc_serialize( const tr_benc * pk, size_t * setmeSize )
{
int bencSize = 0;
char * benc = tr_bencSave( pk, &bencSize );
@ -303,137 +333,161 @@ ipc_mkval( const tr_benc * pk, size_t * setmeSize )
return ret;
}
/**
* Create a serialized message whose payload is a NULL string
*/
uint8_t *
ipc_mkempty( const struct ipc_info * info, size_t * len, enum ipc_msg id,
int64_t tag )
ipc_mkempty( const struct ipc_info * session,
size_t * setmeSize,
enum ipc_msg msg_id,
int64_t tag )
{
tr_benc pk;
uint8_t * ret = NULL;
if( ipc_initval( info, id, tag, &pk, TYPE_STR ) )
{
ret = ipc_mkval( &pk, len );
SAFEBENCFREE( &pk );
}
return ret;
return ipc_mkstr( session, setmeSize, msg_id, tag, NULL );
}
/**
* Create a serialized message whose payload is an integer
*/
uint8_t *
ipc_mkint( const struct ipc_info * info, size_t * len, enum ipc_msg id,
int64_t tag, int64_t num )
ipc_mkint( const struct ipc_info * session,
size_t * setmeSize,
enum ipc_msg msg_id,
int64_t tag,
int64_t num )
{
tr_benc pk, * val;
uint8_t * ret = NULL;
if(( val = ipc_initval( info, id, tag, &pk, TYPE_INT )))
if(( val = ipc_initval( session, msg_id, tag, &pk, TYPE_INT )))
{
val->val.i = num;
ret = ipc_mkval( &pk, len );
ret = ipc_serialize( &pk, setmeSize );
SAFEBENCFREE( &pk );
}
return ret;
}
/**
* Create a serialized message whose payload is a string
*/
uint8_t *
ipc_mkstr( const struct ipc_info * info, size_t * len, enum ipc_msg id,
int64_t tag, const char * str )
ipc_mkstr( const struct ipc_info * session,
size_t * setmeSize,
enum ipc_msg msg_id,
int64_t tag,
const char * str )
{
tr_benc pk, * val;
uint8_t * ret = NULL;
if(( val = ipc_initval( info, id, tag, &pk, TYPE_STR )))
if(( val = ipc_initval( session, msg_id, tag, &pk, TYPE_STR )))
{
tr_bencInitStr( val, str, -1, 1 );
ret = ipc_mkval( &pk, len );
ret = ipc_serialize( &pk, setmeSize );
SAFEBENCFREE( &pk );
}
return ret;
}
/**
* Create a serialized message whose payload is a dictionary
* giving the minimum and maximum protocol version we support,
* and (optionally) the label passed in.
*
* Note that this message is just the dictionary payload.
* It doesn't contain metainfo as the other ipc_mk*() functions do.
*/
uint8_t *
ipc_mkvers( size_t * len, const char * label )
{
tr_benc pk, * dict;
uint8_t * ret;
tr_bencInit( &pk, TYPE_DICT );
if( tr_bencDictReserve( &pk, 1 ) )
{
return NULL;
}
tr_bencInitDict( &pk, 1 );
dict = tr_bencDictAdd( &pk, MSGNAME( IPC_MSG_VERSION ) );
tr_bencInit( dict, TYPE_DICT );
if( tr_bencDictReserve( dict, ( NULL == label ? 2 : 3 ) ) )
{
SAFEBENCFREE( &pk );
return NULL;
}
tr_bencInitDict( dict, 3 );
tr_bencInitInt( tr_bencDictAdd( dict, "min" ), PROTO_VERS_MIN );
tr_bencInitInt( tr_bencDictAdd( dict, "max" ), PROTO_VERS_MAX );
if( NULL != label )
if( label )
tr_bencInitStr( tr_bencDictAdd( dict, "label" ), label, -1, 1 );
ret = ipc_mkval( &pk, len );
ret = ipc_serialize( &pk, len );
SAFEBENCFREE( &pk );
return ret;
}
/**
* Create a serialized message that is used to request
* torrent information or statistics.
*
* msg_id must be one of:
* IPC_MSG_GETINFO
* IPC_MSG_GETINFOALL
* IPC_MSG_GETSTAT
* IPC_MSG_GETSTATALL
*
* "ids" is an optional array of torrent IDs.
* The array, if included, must be terminated by a 0 torrent id.
*
* "types" is a bitwise-and'ed set of fields from either
* the IPC_INF_* or IPC_ST_* enums in ipc-parse.h.
* Which enums are used is dependent on the value of msg_id.
*
* If torrent ids are specified in the "ids" array,
* the payload is a dictionary of two lists, "id" and "type".
* The "id" list holds the torrent IDs, and
* the "type" list holds string keys from either
* gl_inf or gl_stat, depending on the value of msg_id
*
* If no torrent ids are specified, the payload is
* a single list identical to the "type" list described above.
*/
uint8_t *
ipc_mkgetinfo( const struct ipc_info * info, size_t * len, enum ipc_msg id,
int64_t tag, int types, const int * ids )
ipc_mkgetinfo( const struct ipc_info * session,
size_t * setmeSize,
enum ipc_msg msg_id,
int64_t tag,
int types,
const int * ids )
{
tr_benc pk, * top, * idlist, * typelist;
tr_benc pk;
tr_benc * typelist;
size_t ii, typecount, used;
const struct inf * typearray;
uint8_t * ret;
/* no ID list, send an -all message */
if( NULL == ids )
{
typelist = ipc_initval( info, id, tag, &pk, TYPE_LIST );
if( NULL == typelist )
{
if( !ids ) {
typelist = ipc_initval( session, msg_id, tag, &pk, TYPE_LIST );
if( !typelist )
return NULL;
}
}
else
{
top = ipc_initval( info, id, tag, &pk, TYPE_DICT );
if( NULL == top )
{
tr_benc * top;
tr_benc * idlist;
top = ipc_initval( session, msg_id, tag, &pk, TYPE_DICT );
if( !top )
return NULL;
}
/* add the requested IDs */
if( tr_bencDictReserve( top, 2 ) )
{
SAFEBENCFREE( &pk );
return NULL;
}
tr_bencDictReserve( top, 2 );
idlist = tr_bencDictAdd( top, "id" );
typelist = tr_bencDictAdd( top, "type" );
tr_bencInit( idlist, TYPE_LIST );
tr_bencInit( typelist, TYPE_LIST );
for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ ) { }
tr_bencInitList( idlist, ii );
for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ )
{
}
if( tr_bencListReserve( idlist, ii ) )
{
SAFEBENCFREE( &pk );
return NULL;
}
for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ )
{
tr_bencInitInt( tr_bencListAdd( idlist ), ids[ii] );
}
}
/* get the type name array */
switch( id )
switch( msg_id )
{
case IPC_MSG_GETINFO:
case IPC_MSG_GETINFOALL:
@ -452,53 +506,51 @@ ipc_mkgetinfo( const struct ipc_info * info, size_t * len, enum ipc_msg id,
/* add the type names */
for( ii = used = 0; typecount > ii; ii++ )
{
if( types & ( 1 << ii ) )
{
used++;
}
}
if( tr_bencListReserve( typelist, used ) )
{
SAFEBENCFREE( &pk );
return NULL;
}
tr_bencListReserve( typelist, used );
for( ii = 0; typecount > ii; ii++ )
{
if( !( types & ( 1 << ii ) ) )
{
continue;
}
assert( typearray[ii].type == ( 1 << ii ) );
tr_bencInitStr( tr_bencListAdd( typelist ),
typearray[ii].name, -1, 1 );
}
/* generate packet */
ret = ipc_mkval( &pk, len );
ret = ipc_serialize( &pk, setmeSize );
SAFEBENCFREE( &pk );
return ret;
}
static int
static void
filltracker( tr_benc * val, const tr_tracker_info * tk )
{
tr_bencInit( val, TYPE_DICT );
if( tr_bencDictReserve( val, ( NULL == tk->scrape ? 3 : 4 ) ) )
return -1;
tr_bencInitDict( val, 4 );
tr_bencInitStr( tr_bencDictAdd( val, "address" ), tk->address, -1, 1 );
tr_bencInitInt( tr_bencDictAdd( val, "port" ), tk->port );
tr_bencInitStr( tr_bencDictAdd( val, "announce" ), tk->announce, -1, 1 );
if( NULL != tk->scrape )
tr_bencInitStr( tr_bencDictAdd( val, "scrape" ), tk->scrape, -1, 1 );
return 0;
}
/**
* append to "list" a dictionary whose keys are
* the string keys from gl_inf and whose values are
* torrent info set from "torrent_id" and "inf".
*
* "types" is a bitwise-and'ed set of fields
* from the IPC_INF_* enum in ipcparse.h.
* It specifies what to put in the dictionary.
*/
int
ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
ipc_addinfo( tr_benc * list,
int torrent_id,
const tr_info * inf,
int types )
{
tr_benc * dict, * item, * file, * tier;
int ii, jj, kk;
@ -507,75 +559,47 @@ ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
/* always send torrent id */
types |= IPC_INF_ID;
if( tr_bencListReserve( list, 1 ) )
{
return -1;
}
tr_bencListReserve( list, 1 );
dict = tr_bencListAdd( list );
tr_bencInit( dict, TYPE_DICT );
/* count the number of info keys and allocate a dict for them */
for( ii = jj = 0; IPC_INF__MAX > 1 << ii; ii++ )
{
if( !( types & ( 1 << ii ) ) )
{
continue;
}
assert( TR_N_ELEMENTS( gl_inf ) > ( unsigned )ii );
assert( gl_inf[ii].type == ( 1 << ii ) );
/* check for missing optional info */
if( ( IPC_INF_COMMENT == ( 1 << ii ) && !*inf->comment ) ||
( IPC_INF_CREATOR == ( 1 << ii ) && !*inf->creator ) ||
( IPC_INF_DATE == ( 1 << ii ) && 0 >= inf->dateCreated ) )
{
continue;
}
jj++;
}
if( tr_bencDictReserve( dict, jj ) )
{
return -1;
}
tr_bencInitDict( dict, jj );
/* populate the dict with info key->value pairs */
for( ii = 0; IPC_INF__MAX > 1 << ii; ii++ )
{
if( !( types & ( 1 << ii ) ) )
{
continue;
}
/* check for missing optional info */
if( ( IPC_INF_COMMENT == ( 1 << ii ) && !*inf->comment ) ||
( IPC_INF_CREATOR == ( 1 << ii ) && !*inf->creator ) ||
( IPC_INF_DATE == ( 1 << ii ) && 0 >= inf->dateCreated ) )
{
continue;
}
item = tr_bencDictAdd( dict, gl_inf[ii].name );
switch( 1 << ii )
{
case IPC_INF_COMMENT:
tr_bencInitStr( item, inf->comment, -1, 1 );
tr_bencInitStr( item, inf->comment ? inf->comment : "", -1, 1 );
break;
case IPC_INF_CREATOR:
tr_bencInitStr( item, inf->creator, -1, 1 );
tr_bencInitStr( item, inf->creator ? inf->creator : "", -1, 1 );
break;
case IPC_INF_DATE:
tr_bencInitInt( item, inf->dateCreated );
break;
case IPC_INF_FILES:
tr_bencInit( item, TYPE_LIST );
if( tr_bencListReserve( item, inf->fileCount ) )
{
return -1;
}
tr_bencInitList( item, inf->fileCount );
for( ff = 0; inf->fileCount > ff; ff++ )
{
file = tr_bencListAdd( item );
tr_bencInit( file, TYPE_DICT );
if( tr_bencDictReserve( file, 2 ) )
{
return -1;
}
tr_bencInitDict( file, 2 );
tr_bencInitStr( tr_bencDictAdd( file, "name" ),
inf->files[ff].name, -1, 1 );
tr_bencInitInt( tr_bencDictAdd( file, "size" ),
@ -586,7 +610,7 @@ ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
tr_bencInitStr( item, inf->hashString, -1, 1 );
break;
case IPC_INF_ID:
tr_bencInitInt( item, tor );
tr_bencInitInt( item, torrent_id );
break;
case IPC_INF_NAME:
tr_bencInitStr( item, inf->name, -1, 1 );
@ -601,28 +625,14 @@ ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
tr_bencInitInt( item, inf->totalSize );
break;
case IPC_INF_TRACKERS:
tr_bencInit( item, TYPE_LIST );
if( tr_bencListReserve( item, inf->trackerTiers ) )
{
return -1;
}
tr_bencInitList( item, inf->trackerTiers );
for( jj = 0; inf->trackerTiers > jj; jj++ )
{
tier = tr_bencListAdd( item );
tr_bencInit( tier, TYPE_LIST );
if( tr_bencListReserve( tier,
inf->trackerList[jj].count ) )
{
return -1;
}
tr_bencInitList( tier, inf->trackerList[jj].count );
for( kk = 0; inf->trackerList[jj].count > kk; kk++ )
{
if( 0 > filltracker( tr_bencListAdd( tier ),
&inf->trackerList[jj].list[kk] ) )
{
return -1;
}
}
filltracker( tr_bencListAdd( tier ),
&inf->trackerList[jj].list[kk] );
}
break;
default:
@ -634,32 +644,42 @@ ipc_addinfo( tr_benc * list, int tor, const tr_info * inf, int types )
return 0;
}
/**
* append to "list" a dictionary whose keys are
* the string keys from gl_stat and whose values
* are torrent statistics set from "st".
*
* "types" is a bitwise-and'ed set of fields
* from the IPC_INF_* enum in ipcparse.h.
* It specifies what to put in the dictionary.
*/
int
ipc_addstat( tr_benc * list, int tor,
const tr_stat * st, int types )
ipc_addstat( tr_benc * list,
int torrent_id,
const tr_stat * st,
int types )
{
tr_benc * dict, * item;
int ii, used;
tr_errno error;
tr_benc * dict;
int ii, used;
/* add the dictionary child */
tr_bencListReserve( list, 1 );
dict = tr_bencListAdd( list );
/* always send torrent id */
types |= IPC_ST_ID;
if( tr_bencListReserve( list, 1 ) )
return -1;
dict = tr_bencListAdd( list );
/* count the number of stat keys and allocate a dict for them */
for( ii = used = 0; IPC_ST__MAX > 1 << ii; ii++ )
if( types & ( 1 << ii ) )
used++;
tr_bencInitDict( dict, used );
tr_bencInit( dict, TYPE_DICT );
if( tr_bencDictReserve( dict, used ) )
return -1;
/* populate the dict */
for( ii = 0; IPC_ST__MAX > 1 << ii; ii++ )
{
tr_benc * item;
if( !( types & ( 1 << ii ) ) )
continue;
@ -678,8 +698,8 @@ ipc_addstat( tr_benc * list, int tor,
case IPC_ST_DOWNTOTAL:
tr_bencInitInt( item, st->downloadedEver );
break;
case IPC_ST_ERROR:
error = st->error;
case IPC_ST_ERROR: {
const tr_errno error = st->error;
if( TR_OK == error )
{
tr_bencInitStr( item, "", -1, 1 );
@ -725,6 +745,7 @@ ipc_addstat( tr_benc * list, int tor,
tr_bencInitStr( item, "other", -1, 1 );
}
break;
}
case IPC_ST_ERRMSG:
if( TR_OK == st->error )
{
@ -743,17 +764,13 @@ ipc_addstat( tr_benc * list, int tor,
tr_bencInitInt( item, st->eta );
break;
case IPC_ST_ID:
tr_bencInitInt( item, tor );
tr_bencInitInt( item, torrent_id );
break;
case IPC_ST_PEERDOWN:
tr_bencInitInt( item, st->peersSendingToUs );
break;
case IPC_ST_PEERFROM:
tr_bencInit( item, TYPE_DICT );
if( tr_bencDictReserve( item, 4 ) )
{
return -1;
}
tr_bencInitDict( item, 4 );
tr_bencInitInt( tr_bencDictAdd( item, "incoming" ),
st->peersFrom[TR_PEER_FROM_INCOMING] );
tr_bencInitInt( tr_bencDictAdd( item, "tracker" ),
@ -802,10 +819,7 @@ ipc_addstat( tr_benc * list, int tor,
tr_bencInitInt( item, st->swarmspeed * 1024 );
break;
case IPC_ST_TRACKER:
if( 0 > filltracker( item, st->tracker ) )
{
return -1;
}
filltracker( item, st->tracker );
break;
case IPC_ST_TKDONE:
tr_bencInitInt( item, st->completedFromTracker );
@ -906,6 +920,16 @@ msglookup( const char * name )
compareNameToMsg );
}
enum ipc_msg
ipc_msgid( const struct ipc_info * info, const char * name )
{
const struct msg * msg = msglookup( name );
return msg && sessionSupportsMessage( info, msg->id )
? msg->id
: IPC__MSG_COUNT;
}
static int
gotmsg( const struct ipc_info * info, tr_benc * name, tr_benc * val,
tr_benc * tagval, void * arg )
@ -1042,30 +1066,6 @@ ipc_parse( struct ipc_info * info, const uint8_t * buf, ssize_t total, void * ar
return off;
}
enum ipc_msg
ipc_msgid( const struct ipc_info * info, const char * name )
{
const struct msg * msg = msglookup( name );
return msg && ipc_havemsg( info, msg->id )
? msg->id
: IPC__MSG_COUNT;
}
int
ipc_ishandled( const struct ipc_info * info, enum ipc_msg id )
{
assert( MSGVALID( id ) );
return info->funcs->msgs[id] != NULL;
}
int
ipc_havetags( const struct ipc_info * info )
{
return !DICTPAYLOAD( info );
}
static int
compareNameToInf( const void * a, const void * b )
{

View File

@ -152,20 +152,20 @@ int ipc_hasvers ( const struct ipc_info * );
/* sets errno to EPERM if requested message not supported by protocol vers */
struct tr_benc * ipc_initval ( const struct ipc_info *, enum ipc_msg,
int64_t tag, struct tr_benc *, int );
uint8_t * ipc_mkval ( const struct tr_benc *, size_t * );
uint8_t * ipc_mkempty ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t );
uint8_t * ipc_mkint ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t tag, int64_t val );
uint8_t * ipc_mkstr ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t tag, const char * val );
uint8_t * ipc_mkvers ( size_t *, const char * );
uint8_t * ipc_mkgetinfo( const struct ipc_info *, size_t *, enum ipc_msg,
uint8_t * ipc_serialize ( const struct tr_benc *, size_t * );
uint8_t * ipc_mkempty ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t );
uint8_t * ipc_mkint ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t tag, int64_t val );
uint8_t * ipc_mkstr ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t tag, const char * val );
uint8_t * ipc_mkvers ( size_t *, const char * );
uint8_t * ipc_mkgetinfo ( const struct ipc_info *, size_t *, enum ipc_msg,
int64_t, int, const int * );
int ipc_addinfo ( struct tr_benc *, int,
const struct tr_info *, int );
int ipc_addstat ( struct tr_benc *, int,
const struct tr_stat *, int );
int ipc_addinfo ( struct tr_benc *, int,
const struct tr_info *, int );
int ipc_addstat ( struct tr_benc *, int,
const struct tr_stat *, int );
/* sets errno to EINVAL on parse error or
EPERM for unsupported protocol version */

View File

@ -288,8 +288,7 @@ getFileInfo( const char * topFile,
for( pch=file->filename+topLen; *pch; ++pch )
if (*pch == TR_PATH_DELIMITER)
++n;
tr_bencInit( uninitialized_path, TYPE_LIST );
tr_bencListReserve( uninitialized_path, n );
tr_bencInitList( uninitialized_path, n );
for( prev=pch=file->filename+topLen; ; ++pch )
{
char buf[MAX_PATH_LENGTH];
@ -322,8 +321,7 @@ makeFilesList( tr_benc * list,
tr_benc * dict = tr_bencListAdd( list );
tr_benc *length, *pathVal;
tr_bencInit( dict, TYPE_DICT );
tr_bencDictReserve( dict, 2 );
tr_bencInitDict( dict, 2 );
length = tr_bencDictAdd( dict, "length" );
pathVal = tr_bencDictAdd( dict, "path" );
getFileInfo( builder->top, &builder->files[i], length, pathVal );
@ -374,9 +372,8 @@ tr_realMakeMetaInfo ( tr_metainfo_builder * builder )
int n = 5;
tr_benc top, *val;
tr_bencInit ( &top, TYPE_DICT );
if ( builder->comment && *builder->comment ) ++n;
tr_bencDictReserve( &top, n );
tr_bencInitDict( &top, n );
val = tr_bencDictAdd( &top, "announce" );
tr_bencInitStrDup( val, builder->announce );
@ -402,8 +399,7 @@ tr_realMakeMetaInfo ( tr_metainfo_builder * builder )
tr_bencInitStrDup( val, "UTF-8" );
val = tr_bencDictAdd( &top, "info" );
tr_bencInit( val, TYPE_DICT );
tr_bencDictReserve( val, 666 );
tr_bencInitDict( val, 666 );
makeInfoDict( val, builder );
}

View File

@ -871,8 +871,7 @@ sendLtepHandshake( tr_peermsgs * msgs )
else
pex = 1;
tr_bencInit( &val, TYPE_DICT );
tr_bencDictReserve( &val, 4 );
tr_bencInitDict( &val, 4 );
tr_bencInitInt( tr_bencDictAdd( &val, "e" ), 1 );
m = tr_bencDictAdd( &val, "m" );
tr_bencInit( m, TYPE_DICT );
@ -1840,8 +1839,7 @@ sendPex( tr_peermsgs * msgs )
msgs->pexCount = diffs.elementCount;
/* build the pex payload */
tr_bencInit( &val, TYPE_DICT );
tr_bencDictReserve( &val, 3 );
tr_bencInitDict( &val, 3 );
/* "added" */
added = tr_bencDictAdd( &val, "added" );

View File

@ -89,8 +89,7 @@ saveCumulativeStats( const tr_session_stats * stats )
int len;
tr_benc top;
tr_bencInit( &top, TYPE_DICT );
tr_bencDictReserve( &top, 5 );
tr_bencInitDict( &top, 5 );
tr_bencInitInt( tr_bencDictAdd( &top, "uploaded-bytes" ), stats->uploadedBytes );
tr_bencInitInt( tr_bencDictAdd( &top, "downloaded-bytes" ), stats->downloadedBytes );
tr_bencInitInt( tr_bencDictAdd( &top, "files-added" ), stats->filesAdded );

View File

@ -723,7 +723,7 @@ struct tr_info
/* Torrent info */
char * comment;
char * creator;
int dateCreated;
time_t dateCreated;
/* Pieces info */
uint32_t pieceSize;