]> granicus.if.org Git - transmission/commitdiff
hack on IPC a bit because it's been too long since I broke it
authorCharles Kerr <charles@transmissionbt.com>
Thu, 3 Apr 2008 21:38:32 +0000 (21:38 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Thu, 3 Apr 2008 21:38:32 +0000 (21:38 +0000)
12 files changed:
daemon/client.c
daemon/server.c
gtk/ipc.c
libtransmission/bencode.c
libtransmission/bencode.h
libtransmission/completion.c
libtransmission/ipcparse.c
libtransmission/ipcparse.h
libtransmission/makemeta.c
libtransmission/peer-msgs.c
libtransmission/stats.c
libtransmission/transmission.h

index 3eb32c9e3c264ac3ba6b36a61871436312ef6301..64cc069b67ddf3d0a30d987450e727da750eee13 100644 (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 );
index e14d82509c0fb919cd6ef543d241b1e5058ed9e1..6cc7cec3d163127c2fd1d98b5888df327b77ff39 100644 (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 );
index 582a366d28b94e11e25e5505353fab21ba7afe1b..b7d6dbe3e29fbf33a1932e7fa5c646a522d3dbff 100644 (file)
--- a/gtk/ipc.c
+++ b/gtk/ipc.c
@@ -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 )
     {
index 3c661df6780591f2fa45532af4a4f10b8bf4b948..c355e2d72c89eae42ea10a8c60c206f2c49803fa 100644 (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 );
 }
 
index 6f78d55b62b3773bbfe7de0378eeee9ba5755dc2..7b572794e082e4036ad68081c94009541826936f 100644 (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 );
index 045cda5948e517c3e3355fe33a05f2a66eb50b06..b462385d1cafebb9fe6ac4871ad4dbd36707142a 100644 (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 )
-        return;
+    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 ;
+
+        /* 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 ];
+            }
+        }
 
-    /* too bad C doesn't have 'mutable' */
-    cp = (tr_completion*) ccp;
-    cp->doneDirty = FALSE;
+        have *= tor->blockSize;
 
-    for( i=0; i<info->pieceCount; ++i ) {
-        if( !info->pieces[i].dnd ) {
-            total += info->pieceSize;
-            have += cp->completeBlocks[ i ];
+        /* 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) );
         }
-    }
 
-    have *= tor->blockSize;
+        assert( have <= total );
+        assert( total <= info->totalSize );
 
-    /* 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) );
+        cp->doneHave = have;
+        cp->doneTotal = total;
     }
-
-    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
index 9434ea9074384a8c1062090289e4f36ca04b1fd7..925a890901ec300e7b152ab105c7d537ed201030 100644 (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
+sessionSupportsTags( const struct ipc_info * session )
+{
+    return session->vers >= 2;
+}
+
 static int
-ipc_havemsg( const struct ipc_info * info, enum ipc_msg id )
+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 )
 {
index 4c2a2782f3a101f70e0d2a450b3df31ce755d81c..a9e7c6c2ec312ea47cf0169a3e9aa66eb41fdb5c 100644 (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 */
index 9009b563708448da9757e01e426378f1bd7bcff1..f7a4d53a1bbbf58fadf475277a67567e92061556 100644 (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 );
     }
 
index 570e51f795ff8fc9a5cc5ba4026a02722f5da7d8..0f9df11682f1ba4aec0d21dfcb9ea5225effa040 100644 (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" );
index 14226f48966cb762adb8d8f172b9778259b98327..4c97c3c71c7d39d9b8627dae8917ce819d8da498 100644 (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 );
index fcd8b1e20315cfa316a2afee897a5f6df36a2bfd..7cbb090e5d19c9454a4c12906420c49164cd99c9 100644 (file)
@@ -723,7 +723,7 @@ struct tr_info
     /* Torrent info */
     char               * comment;
     char               * creator;
-    int                  dateCreated;
+    time_t               dateCreated;
 
     /* Pieces info */
     uint32_t             pieceSize;