Eliminate an error-prone varargs function.
This commit is contained in:
parent
b8530669e6
commit
0c1c57a62a
|
@ -318,40 +318,7 @@ void tr_bencInitInt( benc_val_t * val, int64_t num )
|
||||||
val->val.i = num;
|
val->val.i = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tr_bencListAppend( benc_val_t * val, ... )
|
int tr_bencListReserve( benc_val_t * val, int count )
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int len;
|
|
||||||
benc_val_t ** ptr;
|
|
||||||
|
|
||||||
assert( TYPE_LIST == val->type );
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
va_start( ap, val );
|
|
||||||
while( NULL != va_arg( ap, benc_val_t ** ) )
|
|
||||||
{
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
if( makeroom( val, len ) )
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start( ap, val );
|
|
||||||
while( NULL != ( ptr = va_arg( ap, benc_val_t ** ) ) )
|
|
||||||
{
|
|
||||||
*ptr = &val->val.l.vals[val->val.l.count];
|
|
||||||
tr_bencInit( *ptr, TYPE_INT );
|
|
||||||
val->val.l.count++;
|
|
||||||
}
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tr_bencListExtend( benc_val_t * val, int count )
|
|
||||||
{
|
{
|
||||||
assert( TYPE_LIST == val->type );
|
assert( TYPE_LIST == val->type );
|
||||||
|
|
||||||
|
@ -363,75 +330,48 @@ int tr_bencListExtend( benc_val_t * val, int count )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int _tr_bencDictAppend( benc_val_t * val, va_list ap,
|
int tr_bencDictReserve( benc_val_t * val, int count )
|
||||||
va_list ap2, int nofree )
|
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
char * key;
|
|
||||||
benc_val_t ** ptr;
|
|
||||||
|
|
||||||
assert( TYPE_DICT == val->type );
|
assert( TYPE_DICT == val->type );
|
||||||
|
|
||||||
len = 0;
|
if( makeroom( val, count * 2 ) )
|
||||||
while( NULL != va_arg( ap, char * ) )
|
|
||||||
{
|
|
||||||
ptr = va_arg( ap, benc_val_t ** );
|
|
||||||
assert( NULL != ptr );
|
|
||||||
len += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( makeroom( val, len ) )
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( NULL != ( key = va_arg( ap2, char * ) ) )
|
|
||||||
{
|
|
||||||
if( !nofree )
|
|
||||||
{
|
|
||||||
key = strdup( key );
|
|
||||||
if( NULL == key )
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr = va_arg( ap2, benc_val_t ** );
|
|
||||||
tr_bencInitStr( &val->val.l.vals[val->val.l.count], key, 0, nofree );
|
|
||||||
val->val.l.count++;
|
|
||||||
*ptr = &val->val.l.vals[val->val.l.count];
|
|
||||||
tr_bencInit( *ptr, TYPE_INT );
|
|
||||||
val->val.l.count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tr_bencDictAppend( benc_val_t * val, ... )
|
benc_val_t * tr_bencListAdd( benc_val_t * list )
|
||||||
{
|
{
|
||||||
va_list ap, ap2;
|
benc_val_t * item;
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start( ap, val );
|
assert( TYPE_LIST == list->type );
|
||||||
va_start( ap2, val );
|
assert( list->val.l.count < list->val.l.alloc );
|
||||||
ret = _tr_bencDictAppend( val, ap, ap2, 0 );
|
|
||||||
va_end( ap2 );
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
return ret;
|
item = &list->val.l.vals[list->val.l.count];
|
||||||
|
list->val.l.count++;
|
||||||
|
tr_bencInit( item, TYPE_INT );
|
||||||
|
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tr_bencDictAppendNofree( benc_val_t * val, ... )
|
benc_val_t * tr_bencDictAdd( benc_val_t * dict, const char * key )
|
||||||
{
|
{
|
||||||
va_list ap, ap2;
|
benc_val_t * keyval, * itemval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start( ap, val );
|
assert( TYPE_DICT == dict->type );
|
||||||
va_start( ap2, val );
|
assert( dict->val.l.count + 2 <= dict->val.l.alloc );
|
||||||
ret = _tr_bencDictAppend( val, ap, ap2, 1 );
|
|
||||||
va_end( ap2 );
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
return ret;
|
keyval = &dict->val.l.vals[dict->val.l.count];
|
||||||
|
dict->val.l.count++;
|
||||||
|
itemval = &dict->val.l.vals[dict->val.l.count];
|
||||||
|
dict->val.l.count++;
|
||||||
|
|
||||||
|
tr_bencInitStr( keyval, key, -1, 1 );
|
||||||
|
tr_bencInit( itemval, TYPE_INT );
|
||||||
|
|
||||||
|
return itemval;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * tr_bencSaveMalloc( benc_val_t * val, int * len )
|
char * tr_bencSaveMalloc( benc_val_t * val, int * len )
|
||||||
|
|
|
@ -76,15 +76,12 @@ static inline void tr_bencInit( benc_val_t * val, int type )
|
||||||
void _tr_bencInitStr( benc_val_t * val, char * str, int len, int nofree );
|
void _tr_bencInitStr( benc_val_t * val, char * str, int len, int nofree );
|
||||||
int tr_bencInitStrDup( benc_val_t * val, const char * str );
|
int tr_bencInitStrDup( benc_val_t * val, const char * str );
|
||||||
void tr_bencInitInt( benc_val_t * val, int64_t num );
|
void tr_bencInitInt( benc_val_t * val, int64_t num );
|
||||||
/* args are a NULL terminated list of benc_val_t** */
|
int tr_bencListReserve( benc_val_t * list, int count );
|
||||||
int tr_bencListAppend( benc_val_t * val, ... );
|
/* note that for one key-value pair, count should be 1, not 2 */
|
||||||
/* args are a NULL terminated list of pairs of char * key, benc_val_t ** val */
|
int tr_bencDictReserve( benc_val_t * dict, int count );
|
||||||
int tr_bencDictAppend( benc_val_t * val, ... );
|
benc_val_t * tr_bencListAdd( benc_val_t * list );
|
||||||
/* like tr_bencDictAppend but char * key args are marked nofree */
|
/* note: key must not be freed or modified while val is in use */
|
||||||
int tr_bencDictAppendNofree( benc_val_t * val, ... );
|
benc_val_t * tr_bencDictAdd( benc_val_t * dict, const char * key );
|
||||||
|
|
||||||
/* insure val has room for at least count more items */
|
|
||||||
int tr_bencListExtend( benc_val_t * val, int count );
|
|
||||||
|
|
||||||
char * tr_bencSaveMalloc( benc_val_t * val, int * len );
|
char * tr_bencSaveMalloc( benc_val_t * val, int * len );
|
||||||
int tr_bencSave( benc_val_t * val, char ** buf,
|
int tr_bencSave( benc_val_t * val, char ** buf,
|
||||||
|
|
|
@ -100,8 +100,7 @@ static uint8_t *
|
||||||
makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
||||||
{
|
{
|
||||||
char * buf;
|
char * buf;
|
||||||
benc_val_t val, * idval, * clientval, * versval;
|
benc_val_t val, * msgsval, * msgdictval;
|
||||||
benc_val_t * tcpval, * msgsval, * msgdictval, * msgidval, * msgversval;
|
|
||||||
int len, max, idx;
|
int len, max, idx;
|
||||||
uint8_t vers;
|
uint8_t vers;
|
||||||
|
|
||||||
|
@ -123,13 +122,7 @@ makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
||||||
|
|
||||||
/* start building a dictionary for handshake data */
|
/* start building a dictionary for handshake data */
|
||||||
tr_bencInit( &val, TYPE_DICT );
|
tr_bencInit( &val, TYPE_DICT );
|
||||||
if( tr_bencDictAppendNofree( &val,
|
if( tr_bencDictReserve( &val, 5 ) )
|
||||||
"identity", &idval,
|
|
||||||
"client", &clientval,
|
|
||||||
"version", &versval,
|
|
||||||
"tcp_port", &tcpval,
|
|
||||||
"messages", &msgsval,
|
|
||||||
NULL ) )
|
|
||||||
{
|
{
|
||||||
free( buf );
|
free( buf );
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
|
@ -137,13 +130,23 @@ makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in the dictionary values */
|
/* fill in the dictionary values */
|
||||||
tr_bencInitStr( idval, tor->azId, TR_AZ_ID_LEN, 1 );
|
tr_bencInitStr( tr_bencDictAdd( &val, "identity" ),
|
||||||
tr_bencInitStr( clientval, TR_NAME, 0, 1 );
|
tor->azId, TR_AZ_ID_LEN, 1 );
|
||||||
tr_bencInitStr( versval, VERSION_STRING, 0, 1 );
|
tr_bencInitStr( tr_bencDictAdd( &val, "client" ), TR_NAME, 0, 1 );
|
||||||
tr_bencInitInt( tcpval, tor->publicPort );
|
tr_bencInitStr( tr_bencDictAdd( &val, "version" ), VERSION_STRING, 0, 1 );
|
||||||
tr_bencInit( msgsval, TYPE_LIST );
|
tr_bencInitInt( tr_bencDictAdd( &val, "tcp_port" ), tor->publicPort );
|
||||||
|
|
||||||
/* fill in the supported message list */
|
/* initialize supported message list */
|
||||||
|
msgsval = tr_bencDictAdd( &val, "messages" );
|
||||||
|
tr_bencInit( msgsval, TYPE_LIST );
|
||||||
|
if( tr_bencListReserve( msgsval, azmsgCount() ) )
|
||||||
|
{
|
||||||
|
tr_bencFree( &val );
|
||||||
|
free( buf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill in the message list */
|
||||||
vers = AZ_EXT_VERSION;
|
vers = AZ_EXT_VERSION;
|
||||||
for( idx = 0; azmsgCount() > idx; idx++ )
|
for( idx = 0; azmsgCount() > idx; idx++ )
|
||||||
{
|
{
|
||||||
|
@ -156,25 +159,18 @@ makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
||||||
/* no point in saying we can do pex if the torrent is private */
|
/* no point in saying we can do pex if the torrent is private */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( tr_bencListAppend( msgsval, &msgdictval, NULL ) )
|
|
||||||
{
|
|
||||||
tr_bencFree( &val );
|
|
||||||
free( buf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* each item in the list is a dict with id and ver keys */
|
/* each item in the list is a dict with id and ver keys */
|
||||||
|
msgdictval = tr_bencListAdd( msgsval );
|
||||||
tr_bencInit( msgdictval, TYPE_DICT );
|
tr_bencInit( msgdictval, TYPE_DICT );
|
||||||
if( tr_bencDictAppendNofree( msgdictval,
|
if( tr_bencDictReserve( msgdictval, 2 ) )
|
||||||
"id", &msgidval,
|
|
||||||
"ver", &msgversval,
|
|
||||||
NULL ) )
|
|
||||||
{
|
{
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
free( buf );
|
free( buf );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tr_bencInitStr( msgidval, azmsgStr( idx ), azmsgLen( idx ), 1 );
|
tr_bencInitStr( tr_bencDictAdd( msgdictval, "id" ),
|
||||||
tr_bencInitStr( msgversval, &vers, 1, 1 );
|
azmsgStr( idx ), azmsgLen( idx ), 1 );
|
||||||
|
tr_bencInitStr( tr_bencDictAdd( msgdictval, "ver" ), &vers, 1, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bencode the dictionary and append it to the buffer */
|
/* bencode the dictionary and append it to the buffer */
|
||||||
|
@ -200,7 +196,7 @@ makeAZHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * buflen )
|
||||||
static int
|
static int
|
||||||
peertreeToBencAZ( tr_peertree_t * tree, benc_val_t * val )
|
peertreeToBencAZ( tr_peertree_t * tree, benc_val_t * val )
|
||||||
{
|
{
|
||||||
int count, jj;
|
int count;
|
||||||
tr_peertree_entry_t * ii;
|
tr_peertree_entry_t * ii;
|
||||||
|
|
||||||
tr_bencInit( val, TYPE_LIST );
|
tr_bencInit( val, TYPE_LIST );
|
||||||
|
@ -209,20 +205,16 @@ peertreeToBencAZ( tr_peertree_t * tree, benc_val_t * val )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( tr_bencListExtend( val, count ) )
|
if( tr_bencListReserve( val, count ) )
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ii = peertreeFirst( tree );
|
ii = peertreeFirst( tree );
|
||||||
jj = val->val.l.count;
|
|
||||||
while( NULL != ii )
|
while( NULL != ii )
|
||||||
{
|
{
|
||||||
assert( jj < val->val.l.alloc );
|
tr_bencInitStr( tr_bencListAdd( val ), ii->peer, 6, 1 );
|
||||||
tr_bencInitStr( &val->val.l.vals[jj], ii->peer, 6, 1 );
|
|
||||||
val->val.l.count++;
|
|
||||||
ii = peertreeNext( tree, ii );
|
ii = peertreeNext( tree, ii );
|
||||||
jj++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -67,10 +67,19 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len,
|
||||||
/* build the dictionaries */
|
/* build the dictionaries */
|
||||||
tr_bencInit( &val, TYPE_DICT );
|
tr_bencInit( &val, TYPE_DICT );
|
||||||
if( ( peertreeEmpty( &added ) && peertreeEmpty( sent ) ) ||
|
if( ( peertreeEmpty( &added ) && peertreeEmpty( sent ) ) ||
|
||||||
tr_bencDictAppendNofree( &val, extrakey, &extra, "added", &addval,
|
tr_bencDictReserve( &val, 3 ) )
|
||||||
"dropped", &delval, NULL ) ||
|
{
|
||||||
(*peerfunc)( &added, addval ) ||
|
tr_bencFree( &val );
|
||||||
(*peerfunc)( sent, delval ) )
|
peertreeMerge( sent, &common );
|
||||||
|
peertreeFree( &added );
|
||||||
|
tr_bencFree( extraval );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
extra = tr_bencDictAdd( &val, extrakey );
|
||||||
|
addval = tr_bencDictAdd( &val, "added" );
|
||||||
|
delval = tr_bencDictAdd( &val, "dropped" );
|
||||||
|
assert( NULL != extra && NULL != addval && NULL != delval );
|
||||||
|
if( (*peerfunc)( &added, addval ) || (*peerfunc)( sent, delval ) )
|
||||||
{
|
{
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
peertreeMerge( sent, &common );
|
peertreeMerge( sent, &common );
|
||||||
|
@ -101,12 +110,9 @@ makeCommonPex( tr_torrent_t * tor, tr_peer_t * peer, int * len,
|
||||||
static char *
|
static char *
|
||||||
makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
|
makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
|
||||||
{
|
{
|
||||||
benc_val_t val, * msgsval, * portval, * versval, * pexval;
|
benc_val_t val, * msgsval;
|
||||||
char * buf, * vers;
|
char * buf, * vers;
|
||||||
|
|
||||||
peer_dbg( "SEND extended-handshake, %s pex",
|
|
||||||
( peer->private ? "without" : "with" ) );
|
|
||||||
|
|
||||||
/* get human-readable version string */
|
/* get human-readable version string */
|
||||||
vers = NULL;
|
vers = NULL;
|
||||||
asprintf( &vers, "%s %s", TR_NAME, VERSION_STRING );
|
asprintf( &vers, "%s %s", TR_NAME, VERSION_STRING );
|
||||||
|
@ -115,10 +121,9 @@ makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reserve space in toplevel dictionary for v, m, and possibly p */
|
||||||
tr_bencInit( &val, TYPE_DICT );
|
tr_bencInit( &val, TYPE_DICT );
|
||||||
|
if( tr_bencDictReserve( &val, ( 0 < tor->publicPort ? 3 : 2 ) ) )
|
||||||
/* append v str and m dict to toplevel dictionary */
|
|
||||||
if( tr_bencDictAppendNofree( &val, "v", &versval, "m", &msgsval, NULL ) )
|
|
||||||
{
|
{
|
||||||
free( vers );
|
free( vers );
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
|
@ -126,41 +131,41 @@ makeExtendedHandshake( tr_torrent_t * tor, tr_peer_t * peer, int * len )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* human readable version string */
|
/* human readable version string */
|
||||||
tr_bencInitStr( versval, vers, 0, 0 );
|
tr_bencInitStr( tr_bencDictAdd( &val, "v" ), vers, 0, 0 );
|
||||||
|
|
||||||
/* create dict of supported extended messages */
|
/* create dict of supported extended messages */
|
||||||
|
msgsval = tr_bencDictAdd( &val, "m" );
|
||||||
tr_bencInit( msgsval, TYPE_DICT );
|
tr_bencInit( msgsval, TYPE_DICT );
|
||||||
if( !peer->private )
|
if( !peer->private )
|
||||||
{
|
{
|
||||||
/* for public torrents advertise utorrent pex message */
|
/* for public torrents, advertise utorrent pex message */
|
||||||
if( tr_bencDictAppendNofree( msgsval, "ut_pex", &pexval, NULL ) )
|
if( tr_bencDictReserve( msgsval, 1 ) )
|
||||||
{
|
{
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tr_bencInitInt( pexval, EXTENDED_PEX_ID );
|
tr_bencInitInt( tr_bencDictAdd( msgsval, "ut_pex" ), EXTENDED_PEX_ID );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* our listening port */
|
/* our listening port */
|
||||||
if( 0 < tor->publicPort )
|
if( 0 < tor->publicPort )
|
||||||
{
|
{
|
||||||
if( tr_bencDictAppendNofree( &val, "p", &portval, NULL ) )
|
tr_bencInitInt( tr_bencDictAdd( &val, "p" ), tor->publicPort );
|
||||||
{
|
|
||||||
tr_bencFree( &val );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
tr_bencInitInt( portval, tor->publicPort );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bencode it */
|
/* bencode it */
|
||||||
buf = tr_bencSaveMalloc( &val, len );
|
buf = tr_bencSaveMalloc( &val, len );
|
||||||
tr_bencFree( &val );
|
tr_bencFree( &val );
|
||||||
|
if( NULL == buf )
|
||||||
if( NULL != buf )
|
|
||||||
{
|
{
|
||||||
peer->advertisedPort = tor->publicPort;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer->advertisedPort = tor->publicPort;
|
||||||
|
|
||||||
|
peer_dbg( "SEND extended-handshake, %s pex",
|
||||||
|
( peer->private ? "without" : "with" ) );
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue