From: Charles Kerr Date: Fri, 4 Apr 2008 17:19:44 +0000 (+0000) Subject: ipc/daemon cleanup X-Git-Tag: 1.11~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0080f1abe8e8bb922445e8adb07fb2903e6739c0;p=transmission ipc/daemon cleanup --- diff --git a/daemon/client.c b/daemon/client.c index 64cc069b6..c57412cc4 100644 --- a/daemon/client.c +++ b/daemon/client.c @@ -723,7 +723,7 @@ canread( struct bufferevent * evin, void * arg ) return; } - res = ipc_parse( con->ipc, buf, len, con ); + res = ipc_handleMessages( con->ipc, buf, len, con ); if( 0 > res ) { switch( errno ) @@ -840,8 +840,8 @@ flushreqs( struct con * con ) break; case IPC_MSG_GETINFOALL: case IPC_MSG_GETSTATALL: - buf = ipc_mkgetinfo( con->ipc, &buflen, req->id, req->tag, - req->types, NULL ); + buf = ipc_createInfoRequest( con->ipc, &buflen, req->id, req->tag, + req->types, NULL ); break; default: assert( 0 ); @@ -906,7 +906,6 @@ void infomsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, void * arg UNUSED ) { - benc_val_t * dict; int ii; struct cl_info inf; int64_t id; @@ -914,10 +913,8 @@ infomsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, assert( IPC_MSG_INFO == msgid ); - if( TYPE_LIST != list->type ) - { + if( !tr_bencIsList( list ) ) return; - } memset( &key, 0, sizeof key ); key.tag = tag; @@ -930,11 +927,10 @@ infomsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, for( ii = 0; list->val.l.count > ii; ii++ ) { - dict = &list->val.l.vals[ii]; - if( TYPE_DICT != dict->type ) - { + tr_benc * dict = &list->val.l.vals[ii]; + + if( !tr_bencIsDict( dict ) ) continue; - } id = getinfoint( msgid, dict, IPC_INF_ID, -1 ); inf.name = getinfostr( msgid, dict, IPC_INF_NAME, NULL ); @@ -958,7 +954,6 @@ void statmsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, void * arg UNUSED ) { - benc_val_t * dict; int ii; int64_t id; struct cl_stat st; @@ -966,10 +961,8 @@ statmsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, assert( IPC_MSG_STAT == msgid ); - if( TYPE_LIST != list->type ) - { + if( !tr_bencIsList( list ) ) return; - } memset( &key, 0, sizeof key ); key.tag = tag; @@ -982,11 +975,10 @@ statmsg( enum ipc_msg msgid, benc_val_t * list, int64_t tag, for( ii = 0; list->val.l.count > ii; ii++ ) { - dict = &list->val.l.vals[ii]; - if( TYPE_DICT != dict->type ) - { + tr_benc * dict = &list->val.l.vals[ii]; + + if( !tr_bencIsDict( dict ) ) continue; - } id = getinfoint( msgid, dict, IPC_ST_ID, -1 ); st.state = getinfostr( msgid, dict, IPC_ST_STATE, NULL ); @@ -1052,11 +1044,11 @@ defmsg( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg UNUSED ) void cbdone( struct resp * resp ) { - if( NULL != resp->infocb ) + if( resp->infocb ) { resp->infocb( NULL ); } - else if( NULL != resp->statcb ) + else if( resp->statcb ) { resp->statcb( NULL ); } @@ -1065,29 +1057,15 @@ cbdone( struct resp * resp ) int64_t getinfoint( enum ipc_msg msgid, benc_val_t * dict, int type, int64_t defval ) { - benc_val_t * val; - - val = tr_bencDictFind( dict, ipc_infoname( msgid, type ) ); - - if( NULL != val && TYPE_INT == val->type ) - { - return val->val.i; - } - - return defval; + const char * key = ipc_infoname( msgid, type ); + benc_val_t * val = tr_bencDictFind( dict, key ); + return tr_bencIsInt( val ) ? val->val.i : defval; } char * getinfostr( enum ipc_msg msgid, benc_val_t * dict, int type, char * defval ) { - benc_val_t * val; - - val = tr_bencDictFind( dict, ipc_infoname( msgid, type ) ); - - if( NULL != val && TYPE_STR == val->type ) - { - return val->val.s.s ; - } - - return defval; + const char * key = ipc_infoname( msgid, type ); + benc_val_t * val = tr_bencDictFind( dict, key ); + return tr_bencIsString( val ) ? val->val.s.s : defval; } diff --git a/daemon/server.c b/daemon/server.c index 6cc7cec3d..13ea5e8e4 100644 --- a/daemon/server.c +++ b/daemon/server.c @@ -358,7 +358,7 @@ doread( struct bufferevent * ev, void * arg ) return; } - res = ipc_parse( client->ipc, buf, len, client ); + res = ipc_handleMessages( client->ipc, buf, len, client ); if( gl_exiting ) { @@ -457,12 +457,12 @@ void addmsg1( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) { struct client * client = arg; - benc_val_t pk, * added, * file; + benc_val_t pk, * added; int ii, tor; size_t buflen; uint8_t * buf; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -478,11 +478,10 @@ addmsg1( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) for( ii = 0; ii < val->val.l.count; ii++ ) { - file = &val->val.l.vals[ii]; - if( TYPE_STR != file->type ) - { + tr_benc * file = &val->val.l.vals[ii]; + if( !tr_bencIsString( file ) ) continue; - } + /* XXX need to somehow inform client of skipped or failed files */ tor = torrent_add_file( file->val.s.s, NULL, -1 ); if( TORRENT_ID_VALID( tor ) ) @@ -514,19 +513,18 @@ addmsg2( enum ipc_msg id UNUSED, benc_val_t * dict, int64_t tag, void * arg ) uint8_t * buf; const char * dir; - if( NULL == dict || TYPE_DICT != dict->type ) + if( !tr_bencIsDict( dict ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; } val = tr_bencDictFind( dict, "directory" ); - dir = ( NULL == val || TYPE_STR != val->type ? NULL : val->val.s.s ); + dir = tr_bencIsString( val ) ? val->val.s.s : NULL; val = tr_bencDictFind( dict, "autostart" ); - start = ( NULL == val || TYPE_INT != val->type ? -1 : - ( val->val.i ? 1 : 0 ) ); + start = tr_bencIsInt( val ) ? (val->val.i!=0) : -1; val = tr_bencDictFind( dict, "data" ); - if( NULL != val && TYPE_STR == val->type ) + if( tr_bencIsString( val ) ) { /* XXX detect duplicates and return a message indicating so */ tor = torrent_add_data( ( uint8_t * )val->val.s.s, val->val.s.i, @@ -535,7 +533,7 @@ addmsg2( enum ipc_msg id UNUSED, benc_val_t * dict, int64_t tag, void * arg ) else { val = tr_bencDictFind( dict, "file" ); - if( NULL == val || TYPE_STR != val->type ) + if( !tr_bencIsString( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -586,7 +584,7 @@ intmsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) struct client * client = arg; int num; - if( NULL == val || TYPE_INT != val->type ) + if( !tr_bencIsInt( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -626,7 +624,7 @@ strmsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) { struct client * client = arg; - if( NULL == val || TYPE_STR != val->type ) + if( !tr_bencIsString( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -704,7 +702,7 @@ infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) /* add info/status for all torrents */ if( all ) { - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); tr_bencFree( &pk ); @@ -726,7 +724,7 @@ infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) /* add info/status for the requested IDs */ else { - if( NULL == val || TYPE_DICT != val->type ) + if( !tr_bencIsDict( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); tr_bencFree( &pk ); @@ -734,8 +732,7 @@ infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) } typelist = tr_bencDictFind( val, "type" ); idlist = tr_bencDictFind( val, "id" ); - if( NULL == typelist || TYPE_LIST != typelist->type || - NULL == idlist || TYPE_LIST != idlist->type ) + if( !tr_bencIsList(typelist) || !tr_bencIsList(idlist) ) { msgresp( client, tag, IPC_MSG_BAD ); tr_bencFree( &pk ); @@ -836,7 +833,7 @@ tormsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg ) /* remove/start/stop requested list of torrents */ else { - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -865,7 +862,7 @@ lookmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) benc_val_t * hash, pk, * pkinf; int64_t found; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -883,8 +880,7 @@ lookmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) { const tr_info * inf; hash = &val->val.l.vals[ii]; - if( NULL == hash || TYPE_STR != hash->type || - SHA_DIGEST_LENGTH * 2 != hash->val.s.i ) + if( !tr_bencIsString(hash) || SHA_DIGEST_LENGTH * 2 != hash->val.s.i ) { tr_bencFree( &pk ); msgresp( client, tag, IPC_MSG_BAD ); @@ -984,10 +980,10 @@ supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) uint8_t * buf; size_t buflen; int ii; - benc_val_t pk, *pkval, * name; + benc_val_t pk, *pkval; enum ipc_msg found; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { msgresp( client, tag, IPC_MSG_BAD ); return; @@ -1011,8 +1007,8 @@ supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg ) for( ii = 0; val->val.l.count > ii; ii++ ) { - name = &val->val.l.vals[ii]; - if( NULL == name || TYPE_STR != name->type ) + tr_benc * name = &val->val.l.vals[ii]; + if( !tr_bencIsString( name ) ) { tr_bencFree( &pk ); msgresp( client, tag, IPC_MSG_BAD ); diff --git a/daemon/torrents.c b/daemon/torrents.c index 8fe71ab2c..d094311b5 100644 --- a/daemon/torrents.c +++ b/daemon/torrents.c @@ -655,7 +655,7 @@ loadstate( void ) { uint8_t * buf; size_t len; - benc_val_t top, * num, * str, * list, * dict; + benc_val_t top, * num, * str, * list; int ii; struct tor * tor; const char * dir; @@ -675,56 +675,43 @@ loadstate( void ) free( buf ); num = tr_bencDictFind( &top, "autostart" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) gl_autostart = ( num->val.i ? 1 : 0 ); - } num = tr_bencDictFind( &top, "port" ); - if( NULL != num && TYPE_INT == num->type && - 0 < num->val.i && 0xffff > num->val.i ) + if( tr_bencIsInt( num ) && 0 < num->val.i && 0xffff > num->val.i ) { gl_port = num->val.i; } tr_setBindPort( gl_handle, gl_port ); num = tr_bencDictFind( &top, "default-pex" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) gl_pex = ( num->val.i ? 1 : 0 ); - } num = tr_bencDictFind( &top, "port-mapping" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) gl_mapping = ( num->val.i ? 1 : 0 ); - } tr_natTraversalEnable( gl_handle, gl_mapping ); num = tr_bencDictFind( &top, "upload-limit" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) gl_uplimit = num->val.i; - } tr_setGlobalSpeedLimit( gl_handle, TR_UP, gl_uplimit ); tr_setUseGlobalSpeedLimit( gl_handle, TR_UP, gl_uplimit > 0 ); num = tr_bencDictFind( &top, "download-limit" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) gl_downlimit = num->val.i; - } tr_setGlobalSpeedLimit( gl_handle, TR_DOWN, gl_downlimit ); tr_setUseGlobalSpeedLimit( gl_handle, TR_DOWN, gl_downlimit > 0 ); str = tr_bencDictFind( &top, "default-directory" ); - if( NULL != str && TYPE_STR == str->type ) - { + if( tr_bencIsString( str ) ) strlcpy( gl_dir, str->val.s.s, sizeof gl_dir ); - } str = tr_bencDictFind( &top, "encryption-mode" ); - if( NULL != str && TYPE_STR == str->type ) + if( tr_bencIsString( str ) ) { if(!strcasecmp(str->val.s.s, "preferred")) gl_crypto = TR_ENCRYPTION_PREFERRED; @@ -735,46 +722,33 @@ loadstate( void ) tr_setEncryptionMode(gl_handle, gl_crypto); list = tr_bencDictFind( &top, "torrents" ); - if( NULL == list || TYPE_LIST != list->type ) - { + if( !tr_bencIsList( list ) ) return 0; - } for( ii = 0; ii < list->val.l.count; ii++ ) { - dict = &list->val.l.vals[ii]; - if( TYPE_DICT != dict->type ) - { + tr_benc * dict = &list->val.l.vals[ii]; + if( !tr_bencIsDict( dict ) ) continue; - } str = tr_bencDictFind( dict, "directory" ); - dir = ( NULL != str && TYPE_STR == str->type ? str->val.s.s : NULL ); + dir = tr_bencIsString( str ) ? str->val.s.s : NULL; str = tr_bencDictFind( dict, "hash" ); - if( NULL == str || TYPE_STR != str->type || - 2 * SHA_DIGEST_LENGTH != str->val.s.i ) - { + if( !tr_bencIsString( str ) || 2 * SHA_DIGEST_LENGTH != str->val.s.i ) continue; - } tor = opentor( NULL, str->val.s.s, NULL, 0, dir ); - if( NULL == tor ) - { + if( !tor ) continue; - } num = tr_bencDictFind( dict, "pex" ); - if( NULL != num && TYPE_INT == num->type ) - { + if( tr_bencIsInt( num ) ) fprintf( stderr, "warning: obsolete command 'pex'\n" ); - } num = tr_bencDictFind( dict, "paused" ); - if( NULL != num && TYPE_INT == num->type && !num->val.i ) - { + if( tr_bencIsInt( num ) && !num->val.i ) tr_torrentStart( tor->tor ); - } } return 0; diff --git a/gtk/ipc.c b/gtk/ipc.c index b7d6dbe3e..51bcbcb76 100644 --- a/gtk/ipc.c +++ b/gtk/ipc.c @@ -222,7 +222,7 @@ cli_io_received( GSource * source UNUSED, void * data, size_t len, return 0; } - res = ipc_parse( con->ipc, data, len, con ); + res = ipc_handleMessages( con->ipc, data, len, con ); if( 0 > res ) { @@ -381,7 +381,7 @@ srv_io_received( GSource * source UNUSED, void * data, size_t len, destroycon( con ); } - res = ipc_parse( con->ipc, data, len, con ); + res = ipc_handleMessages( con->ipc, data, len, con ); if( 0 > res ) { @@ -494,7 +494,7 @@ smsg_add( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg ) int ii; GSList * list = NULL; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -530,7 +530,7 @@ smsg_addone( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, tr_benc * file, * data, * dir, * start; tr_ctor * ctor; - if( !val || ( val->type != TYPE_DICT ) ) + if( !tr_bencIsDict( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -541,10 +541,10 @@ smsg_addone( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, dir = tr_bencDictFind( val, "directory" ); start = tr_bencDictFind( val, "autostart" ); - if( ( NULL != file && TYPE_STR != file->type ) || - ( NULL != data && TYPE_STR != data->type ) || - ( NULL != dir && TYPE_STR != dir->type ) || - ( NULL != start && TYPE_INT != start->type ) ) + if( ( file && !tr_bencIsString( file ) ) || + ( data && !tr_bencIsString( data ) ) || + ( dir && !tr_bencIsString( dir ) ) || + ( start && !tr_bencIsInt( start ) ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -645,7 +645,7 @@ smsg_info( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) uint8_t * buf; size_t size; - if( NULL == val || TYPE_DICT != val->type ) + if( !tr_bencIsDict( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -654,8 +654,7 @@ smsg_info( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) respid = ( IPC_MSG_GETINFO == id ? IPC_MSG_INFO : IPC_MSG_STAT ); ids = tr_bencDictFind( val, "id" ); types = tr_bencDictFind( val, "types" ); - if( NULL == ids || TYPE_LIST != ids->type || - NULL == types || TYPE_LIST != types->type ) + if( !tr_bencIsList(ids) || !tr_bencIsList(types) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -711,7 +710,7 @@ smsg_infoall( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) uint8_t * buf; size_t size; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -798,7 +797,7 @@ smsg_look( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, uint8_t * buf; size_t size; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -851,7 +850,7 @@ smsg_tor( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) GtkTreeIter iter; int ii; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -1000,7 +999,7 @@ smsg_int( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) struct constate * con = arg; struct constate_serv * srv = &con->u.serv; - if( NULL == val || TYPE_INT != val->type || INT_MAX < val->val.i ) + if( !tr_bencIsInt( val ) || INT_MAX < val->val.i ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -1054,7 +1053,7 @@ smsg_str( enum ipc_msg id, tr_benc * val, int64_t tag, void * arg ) struct constate * con = arg; struct constate_serv * srv = &con->u.serv; - if( NULL == val || TYPE_STR != val->type ) + if( !tr_bencIsString( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -1075,13 +1074,13 @@ static void smsg_sup( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg ) { struct constate * con = arg; - tr_benc packet, * pkval, * name; + tr_benc packet, * pkval; int ii; enum ipc_msg found; uint8_t * buf; size_t size; - if( NULL == val || TYPE_LIST != val->type ) + if( !tr_bencIsList( val ) ) { simpleresp( con, tag, IPC_MSG_BAD ); return; @@ -1102,30 +1101,26 @@ smsg_sup( enum ipc_msg id UNUSED, tr_benc * val, int64_t tag, void * arg ) for( ii = 0; val->val.l.count > ii; ii++ ) { - name = &val->val.l.vals[ii]; - if( NULL == name || TYPE_STR != name->type ) - { + tr_benc * name = &val->val.l.vals[ii]; + + if( !tr_bencIsString( name ) ) continue; - } + found = ipc_msgid( con->ipc, name->val.s.s ); if( IPC__MSG_COUNT == found || !ipc_ishandled( con->ipc, found ) ) - { continue; - } + tr_bencInitStr( tr_bencListAdd( pkval ), name->val.s.s, name->val.s.i, 1 ); } buf = ipc_serialize( &packet, &size ); tr_bencFree( &packet ); - if( NULL == buf ) - { + + if( !buf ) simpleresp( con, tag, IPC_MSG_FAIL ); - } else - { io_send_keepdata( con->source, buf, size ); - } } void diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index c355e2d72..e1ca9c7cc 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -41,26 +41,21 @@ *** **/ -static int -isType( const tr_benc * val, int type ) +int +tr_bencIsType( const tr_benc * val, int type ) { return ( ( val != NULL ) && ( val->type == type ) ); } -#define isInt(v) ( isType( ( v ), TYPE_INT ) ) -#define isString(v) ( isType( ( v ), TYPE_STR ) ) -#define isList(v) ( isType( ( v ), TYPE_LIST ) ) -#define isDict(v) ( isType( ( v ), TYPE_DICT ) ) - static int isContainer( const tr_benc * val ) { - return isList(val) || isDict(val); + return tr_bencIsList(val) || tr_bencIsDict(val); } static int isSomething( const tr_benc * val ) { - return isContainer(val) || isInt(val) || isString(val); + return isContainer(val) || tr_bencIsInt(val) || tr_bencIsString(val); } /*** @@ -272,7 +267,7 @@ tr_bencParse( const void * buf_in, return TR_ERROR; node = tr_ptrArrayBack( parentStack ); - if( isDict( node ) && ( node->val.l.count % 2 ) ) + if( tr_bencIsDict( node ) && ( node->val.l.count % 2 ) ) return TR_ERROR; /* odd # of children in dict */ tr_ptrArrayPop( parentStack ); @@ -338,7 +333,7 @@ tr_bencDictFind( tr_benc * val, const char * key ) { int len, ii; - if( !isDict( val ) ) + if( !tr_bencIsDict( val ) ) return NULL; len = strlen( key ); @@ -385,7 +380,7 @@ tr_benc* tr_bencListGetNthChild( tr_benc * val, int i ) { tr_benc * ret = NULL; - if( isList( val ) && ( i >= 0 ) && ( i < val->val.l.count ) ) + if( tr_bencIsList( val ) && ( i >= 0 ) && ( i < val->val.l.count ) ) ret = val->val.l.vals + i; return ret; } @@ -393,14 +388,14 @@ tr_bencListGetNthChild( tr_benc * val, int i ) int64_t tr_bencGetInt ( const tr_benc * val ) { - assert( isInt( val ) ); + assert( tr_bencIsInt( val ) ); return val->val.i; } char * tr_bencStealStr( tr_benc * val ) { - assert( isString( val ) ); + assert( tr_bencIsString( val ) ); val->val.s.nofree = 1; return val->val.s.s; } @@ -450,7 +445,7 @@ tr_bencInitList( tr_benc * val, int reserveCount ) int tr_bencListReserve( tr_benc * val, int count ) { - assert( isList( val ) ); + assert( tr_bencIsList( val ) ); return makeroom( val, count ); } @@ -464,7 +459,7 @@ tr_bencInitDict( tr_benc * val, int reserveCount ) int tr_bencDictReserve( tr_benc * val, int count ) { - assert( isDict( val ) ); + assert( tr_bencIsDict( val ) ); return makeroom( val, count * 2 ); } @@ -473,7 +468,7 @@ tr_bencListAdd( tr_benc * list ) { tr_benc * item; - assert( isList( list ) ); + assert( tr_bencIsList( list ) ); assert( list->val.l.count < list->val.l.alloc ); item = &list->val.l.vals[list->val.l.count]; @@ -488,7 +483,7 @@ tr_bencDictAdd( tr_benc * dict, const char * key ) { tr_benc * keyval, * itemval; - assert( isDict( dict ) ); + assert( tr_bencIsDict( dict ) ); assert( dict->val.l.count + 2 <= dict->val.l.alloc ); keyval = dict->val.l.vals + dict->val.l.count++; @@ -535,7 +530,7 @@ nodeNewDict( const tr_benc * val ) struct SaveNode * node; struct KeyIndex * indices; - assert( isDict( val ) ); + assert( tr_bencIsDict( val ) ); nKeys = val->val.l.count / 2; node = tr_new0( struct SaveNode, 1 ); @@ -566,7 +561,7 @@ nodeNewList( const tr_benc * val ) int i, n; struct SaveNode * node; - assert( isList( val ) ); + assert( tr_bencIsList( val ) ); n = val->val.l.count; node = tr_new0( struct SaveNode, 1 ); @@ -596,9 +591,9 @@ nodeNew( const tr_benc * val ) { struct SaveNode * node; - if( isList( val ) ) + if( tr_bencIsList( val ) ) node = nodeNewList( val ); - else if( isDict( val ) ) + else if( tr_bencIsDict( val ) ) node = nodeNewDict( val ); else node = nodeNewLeaf( val ); diff --git a/libtransmission/bencode.h b/libtransmission/bencode.h index 7b572794e..fc55612e5 100644 --- a/libtransmission/bencode.h +++ b/libtransmission/bencode.h @@ -103,6 +103,11 @@ char* tr_bencSaveAsSerializedPHP( const tr_benc * top, int * len ); int64_t tr_bencGetInt( const tr_benc * val ); +int tr_bencIsType( const tr_benc *, int type ); +#define tr_bencIsInt(b) (tr_bencIsType(b,TYPE_INT)) +#define tr_bencIsDict(b) (tr_bencIsType(b,TYPE_DICT)) +#define tr_bencIsList(b) (tr_bencIsType(b,TYPE_LIST)) +#define tr_bencIsString(b) (tr_bencIsType(b,TYPE_STR)) /** *** Treat these as private -- they're only made public here diff --git a/libtransmission/ipcparse.c b/libtransmission/ipcparse.c index 925a89090..59e1e0f12 100644 --- a/libtransmission/ipcparse.c +++ b/libtransmission/ipcparse.c @@ -63,6 +63,12 @@ #define MSGNAME( id ) ( gl_msgs[(id)].name ) #define DICTPAYLOAD( info ) ( 2 > (info)->vers ) +struct ipc_funcs +{ + trd_msgfunc msgs[IPC__MSG_COUNT]; + trd_msgfunc def; +}; + struct ipc_info { struct ipc_funcs * funcs; @@ -82,24 +88,6 @@ struct msg const enum ipc_msg id; }; -struct inf -{ - const char * name; - const int type; -}; - -struct msgfunc -{ - int id; - trd_msgfunc func; -}; - -struct ipc_funcs -{ - trd_msgfunc msgs[IPC__MSG_COUNT]; - trd_msgfunc def; -}; - /* these names must be sorted for strcmp() */ static const struct msg gl_msgs[] = { @@ -146,6 +134,12 @@ static const struct msg gl_msgs[] = { "version", 1, IPC_MSG_VERSION } }; +struct inf +{ + const char * name; + const int type; +}; + /* these names must be sorted for strcmp() */ static const struct inf gl_inf[] = { @@ -195,7 +189,9 @@ ipc_initmsgs( void ) } void -ipc_addmsg( struct ipc_funcs * funcs, enum ipc_msg msg_id, trd_msgfunc func ) +ipc_addmsg( struct ipc_funcs * funcs, + enum ipc_msg msg_id, + trd_msgfunc func ) { assert( MSGVALID( msg_id ) ); assert( IPC_MSG_VERSION != msg_id ); @@ -225,23 +221,23 @@ ipc_newcon( struct ipc_funcs * funcs ) } void -ipc_freecon( struct ipc_info * info ) +ipc_freecon( struct ipc_info * session ) { - tr_free( info ); + tr_free( session ); } int -ipc_ishandled( const struct ipc_info * info, enum ipc_msg id ) +ipc_ishandled( const struct ipc_info * session, enum ipc_msg msg_id ) { - assert( MSGVALID( id ) ); + assert( MSGVALID( msg_id ) ); - return info->funcs->msgs[id] != NULL; + return session->funcs->msgs[msg_id] != NULL; } int -ipc_havetags( const struct ipc_info * info ) +ipc_havetags( const struct ipc_info * session ) { - return !DICTPAYLOAD( info ); + return !DICTPAYLOAD( session ); } static int @@ -251,12 +247,12 @@ sessionSupportsTags( const struct ipc_info * session ) } static int -sessionSupportsMessage( const struct ipc_info * info, enum ipc_msg id ) +sessionSupportsMessage( const struct ipc_info * session, enum ipc_msg id ) { assert( MSGVALID( id ) ); - assert( ipc_hasvers( info ) ); + assert( ipc_hasvers( session ) ); - return gl_msgs[id].minvers <= info->vers; + return gl_msgs[id].minvers <= session->vers; } /** @@ -313,23 +309,23 @@ ipc_initval( const struct ipc_info * session, * gives the length of the string. */ uint8_t * -ipc_serialize( const tr_benc * pk, size_t * setmeSize ) +ipc_serialize( const tr_benc * benc, size_t * setmeSize ) { - int bencSize = 0; - char * benc = tr_bencSave( pk, &bencSize ); uint8_t * ret = NULL; + int len = 0; + char * str = tr_bencSave( benc, &len ); - if( bencSize > IPC_MAX_MSG_LEN ) + if( len > IPC_MAX_MSG_LEN ) errno = EFBIG; else { - const size_t size = IPC_MIN_MSG_LEN + bencSize; + const size_t size = IPC_MIN_MSG_LEN + len; ret = tr_new( uint8_t, size ); - snprintf( (char*)ret, size, "%0*X", IPC_MIN_MSG_LEN, bencSize ); - memcpy( ret + IPC_MIN_MSG_LEN, benc, bencSize ); + snprintf( (char*)ret, size, "%0*X", IPC_MIN_MSG_LEN, len ); + memcpy( ret + IPC_MIN_MSG_LEN, str, len ); *setmeSize = size; } - tr_free( benc ); + tr_free( str ); return ret; } @@ -398,6 +394,10 @@ ipc_mkstr( const struct ipc_info * session, * * Note that this message is just the dictionary payload. * It doesn't contain metainfo as the other ipc_mk*() functions do. + * That's because the metainfo is dependent on the protocol version, + * and this is a handshake message to negotiate protocol versions. + * + * @see handlevers() */ uint8_t * ipc_mkvers( size_t * len, const char * label ) @@ -447,12 +447,12 @@ ipc_mkvers( size_t * len, const char * label ) * a single list identical to the "type" list described above. */ uint8_t * -ipc_mkgetinfo( const struct ipc_info * session, - size_t * setmeSize, - enum ipc_msg msg_id, - int64_t tag, - int types, - const int * ids ) +ipc_createInfoRequest( const struct ipc_info * session, + size_t * setmeSize, + enum ipc_msg msg_id, + int64_t tag, + int types, + const int * ids ) { tr_benc pk; tr_benc * typelist; @@ -533,7 +533,7 @@ filltracker( tr_benc * val, const tr_tracker_info * tk ) 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 ) + if( tk->scrape ) tr_bencInitStr( tr_bencDictAdd( val, "scrape" ), tk->scrape, -1, 1 ); } @@ -552,7 +552,7 @@ ipc_addinfo( tr_benc * list, const tr_info * inf, int types ) { - tr_benc * dict, * item, * file, * tier; + tr_benc * dict; int ii, jj, kk; tr_file_index_t ff; @@ -579,6 +579,8 @@ ipc_addinfo( tr_benc * list, /* populate the dict with info key->value pairs */ for( ii = 0; IPC_INF__MAX > 1 << ii; ii++ ) { + tr_benc * item; + if( !( types & ( 1 << ii ) ) ) continue; @@ -598,7 +600,7 @@ ipc_addinfo( tr_benc * list, tr_bencInitList( item, inf->fileCount ); for( ff = 0; inf->fileCount > ff; ff++ ) { - file = tr_bencListAdd( item ); + tr_benc * file = tr_bencListAdd( item ); tr_bencInitDict( file, 2 ); tr_bencInitStr( tr_bencDictAdd( file, "name" ), inf->files[ff].name, -1, 1 ); @@ -628,7 +630,7 @@ ipc_addinfo( tr_benc * list, tr_bencInitList( item, inf->trackerTiers ); for( jj = 0; inf->trackerTiers > jj; jj++ ) { - tier = tr_bencListAdd( item ); + tr_benc * tier = tr_bencListAdd( item ); tr_bencInitList( tier, inf->trackerList[jj].count ); for( kk = 0; inf->trackerList[jj].count > kk; kk++ ) filltracker( tr_bencListAdd( tier ), @@ -845,13 +847,21 @@ ipc_addstat( tr_benc * list, return 0; } +/** + * This reads a handshake message from the client to decide + * which IPC protocol version to use. + * Returns 0 on success; otherwise, returns -1 and sets errno. + * + * @see ipc_handleMessages() + * @see ipc_mkvers() + */ static int handlevers( struct ipc_info * info, tr_benc * dict ) { - tr_benc * vers, * num; + tr_benc * vers; int64_t min, max; - if( TYPE_DICT != dict->type ) + if( !tr_bencIsDict( dict ) ) { errno = EINVAL; return -1; @@ -870,12 +880,13 @@ handlevers( struct ipc_info * info, tr_benc * dict ) min = vers->val.i; max = vers->val.i; break; - case TYPE_DICT: - num = tr_bencDictFind( vers, "min" ); - min = ( NULL == num || TYPE_INT != num->type ? -1 : num->val.i ); + case TYPE_DICT: { + tr_benc * num = tr_bencDictFind( vers, "min" ); + min = tr_bencIsInt( num ) ? num->val.i : -1; num = tr_bencDictFind( vers, "max" ); - max = ( NULL == num || TYPE_INT != num->type ? -1 : num->val.i ); + max = tr_bencIsInt( num ) ? num->val.i : -1; break; + } default: min = -1; max = -1; @@ -930,108 +941,113 @@ ipc_msgid( const struct ipc_info * info, const char * name ) : IPC__MSG_COUNT; } +/** + * Invokes the trd_msgfunc for the message passed in. + * Returns 0 on success; otherwise, returns -1 and sets errno. + */ static int -gotmsg( const struct ipc_info * info, tr_benc * name, tr_benc * val, - tr_benc * tagval, void * arg ) +callmsgfunc( const struct ipc_info * info, + tr_benc * name, + tr_benc * val, + tr_benc * tagval, + void * user_data ) { const struct msg * msg; int64_t tag; - if( TYPE_STR != name->type ) - { + /* extract tag from tagval */ + if( !tagval ) + tag = -1; + else if( tr_bencIsInt( tagval ) ) + tag = tagval->val.i; + else { errno = EINVAL; return -1; } - if( NULL == tagval ) - { - tag = -1; - } - else - { - if( TYPE_INT != tagval->type ) - { - errno = EINVAL; - return -1; - } - tag = tagval->val.i; + /* find the msg corresponding to `name' */ + if( !tr_bencIsString( name ) ) { + errno = EINVAL; + return -1; } - msg = msglookup( name->val.s.s ); + if( msg && msg->minvers <= info->vers ) { if( info->funcs->msgs[msg->id] != NULL ) { - (*info->funcs->msgs[msg->id])( msg->id, val, tag, arg ); + (*info->funcs->msgs[msg->id])( msg->id, val, tag, user_data ); } else if( info->funcs->def ) { - info->funcs->def( msg->id, val, tag, arg ); + info->funcs->def( msg->id, val, tag, user_data ); } } else if( NULL != info->funcs->def ) - info->funcs->def( IPC__MSG_UNKNOWN, NULL, tag, arg ); + info->funcs->def( IPC__MSG_UNKNOWN, NULL, tag, user_data ); return 0; } static int -handlemsgs( const struct ipc_info * info, tr_benc * pay, void * arg ) +handlemsgs( const struct ipc_info * session, + tr_benc * message, + void * user_data ) { tr_benc * name, * val, * tag; - int ii; - assert( ipc_hasvers( info ) ); + assert( ipc_hasvers( session ) ); - if( DICTPAYLOAD( info ) ) + if( DICTPAYLOAD( session ) ) { - if( TYPE_DICT != pay->type || pay->val.l.count % 2 ) + int ii; + + if( TYPE_DICT != message->type || message->val.l.count % 2 ) { errno = EINVAL; return -1; } - for( ii = 0; ii < pay->val.l.count; ii += 2 ) + for( ii = 0; ii < message->val.l.count; ii += 2 ) { - assert( ii + 1 < pay->val.l.count ); - name = &pay->val.l.vals[ii]; - val = &pay->val.l.vals[ii+1]; - if( 0 > gotmsg( info, name, val, NULL, arg ) ) - { + assert( ii + 1 < message->val.l.count ); + name = &message->val.l.vals[ii]; + val = &message->val.l.vals[ii+1]; + if( 0 > callmsgfunc( session, name, val, NULL, user_data ) ) return -1; - } } } else { - if( TYPE_LIST != pay->type || 2 > pay->val.l.count ) + if( TYPE_LIST != message->type || 2 > message->val.l.count ) { errno = EINVAL; return -1; } - name = &pay->val.l.vals[0]; - val = &pay->val.l.vals[1]; - tag = ( 2 == pay->val.l.count ? NULL : &pay->val.l.vals[2] ); - if( 0 > gotmsg( info, name, val, tag, arg ) ) - { + name = &message->val.l.vals[0]; + val = &message->val.l.vals[1]; + tag = ( 2 == message->val.l.count ? NULL : &message->val.l.vals[2] ); + if( 0 > callmsgfunc( session, name, val, tag, user_data ) ) return -1; - } } return 0; } ssize_t -ipc_parse( struct ipc_info * info, const uint8_t * buf, ssize_t total, void * arg ) +ipc_handleMessages( struct ipc_info * info, + const uint8_t * msgs, + ssize_t msgslen, + void * user_data ) { char hex[IPC_MIN_MSG_LEN+1], * end; ssize_t off, len; tr_benc benc; - for( off = 0; off + IPC_MIN_MSG_LEN < total; off += IPC_MIN_MSG_LEN + len ) + for( off = 0; off + IPC_MIN_MSG_LEN < msgslen; off += IPC_MIN_MSG_LEN + len ) { - memcpy( hex, buf + off, IPC_MIN_MSG_LEN ); + memcpy( hex, msgs + off, IPC_MIN_MSG_LEN ); hex[IPC_MIN_MSG_LEN] = '\0'; end = NULL; len = strtol( hex, &end, 16 ); @@ -1041,12 +1057,12 @@ ipc_parse( struct ipc_info * info, const uint8_t * buf, ssize_t total, void * ar errno = EINVAL; return -1; } - if( off + IPC_MIN_MSG_LEN + len > total ) + if( off + IPC_MIN_MSG_LEN + len > msgslen ) { break; } errno = 0; - if( tr_bencLoad( buf + off + IPC_MIN_MSG_LEN, len, &benc, NULL ) ) + if( tr_bencLoad( msgs + off + IPC_MIN_MSG_LEN, len, &benc, NULL ) ) { if( 0 == errno ) { @@ -1054,7 +1070,7 @@ ipc_parse( struct ipc_info * info, const uint8_t * buf, ssize_t total, void * ar } return -1; } - if( 0 > ( ipc_hasvers( info ) ? handlemsgs( info, &benc, arg ) : + if( 0 > ( ipc_hasvers( info ) ? handlemsgs( info, &benc, user_data ) : handlevers( info, &benc ) ) ) { SAFEBENCFREE( &benc ); @@ -1073,6 +1089,12 @@ compareNameToInf( const void * a, const void * b ) return strcmp( a, inf->name ); } +/** + * Convert a benc list of string keys from gl_inf or gl_stat + * into a bitwise-or'ed int representation. + * msg_id must be either IPC_MSG_INFO or IPC_MSG_STAT. + * @see ipc_infoname() + */ int ipc_infotypes( enum ipc_msg id, const tr_benc * list ) { @@ -1098,17 +1120,15 @@ ipc_infotypes( enum ipc_msg id, const tr_benc * list ) ret = IPC_INF_ID; - if( NULL == list || TYPE_LIST != list->type ) - { + if( !tr_bencIsList( list ) ) return ret; - } for( i=0; ival.l.count; ++i ) { const tr_benc * name = &list->val.l.vals[i]; const struct inf * inf; - if( TYPE_STR != name->type ) + if( !tr_bencIsString( name ) ) continue; inf = bsearch( name->val.s.s, @@ -1121,6 +1141,13 @@ ipc_infotypes( enum ipc_msg id, const tr_benc * list ) return ret; } +/** + * This function is the reverse of ipc_infotypes: + * it returns the string key that corresponds to the type passed in. + * Type is one of the IPC_INF_* or IPC_ST_* enums from ipcparse.h. + * msg_id must be either IPC_MSG_INFO or IPC_MSG_STAT. + * @see ipc_infotypes() + */ const char * ipc_infoname( enum ipc_msg id, int type ) { diff --git a/libtransmission/ipcparse.h b/libtransmission/ipcparse.h index a9e7c6c2e..2ffd598b3 100644 --- a/libtransmission/ipcparse.h +++ b/libtransmission/ipcparse.h @@ -160,8 +160,14 @@ uint8_t * ipc_mkint ( const struct ipc_info *, size_t *, enum ipc_msg, 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 * ); + +uint8_t * ipc_createInfoRequest( const struct ipc_info * session, + size_t * setme_len, + enum ipc_msg msg_id, + int64_t tag, + int types, + const int * ids ); + int ipc_addinfo ( struct tr_benc *, int, const struct tr_info *, int ); int ipc_addstat ( struct tr_benc *, int, @@ -169,8 +175,10 @@ int ipc_addstat ( struct tr_benc *, int, /* sets errno to EINVAL on parse error or EPERM for unsupported protocol version */ -ssize_t ipc_parse ( struct ipc_info *, const uint8_t *, - ssize_t, void * ); +ssize_t ipc_handleMessages( struct ipc_info * session, + const uint8_t * serializedMessages , + ssize_t serializedLength, + void * user_data ); /* misc info functions, these will always succeed */ enum ipc_msg ipc_msgid ( const struct ipc_info *, const char * ); diff --git a/libtransmission/metainfo.c b/libtransmission/metainfo.c index b54651277..6b85cb8a4 100644 --- a/libtransmission/metainfo.c +++ b/libtransmission/metainfo.c @@ -174,7 +174,7 @@ tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag ) /* comment */ memset( buf, '\0', sizeof( buf ) ); val = tr_bencDictFindFirst( meta, "comment.utf-8", "comment", NULL ); - if( val && val->type == TYPE_STR ) + if( tr_bencIsString( val ) ) strlcat_utf8( buf, val->val.s.s, sizeof( buf ), 0 ); tr_free( inf->comment ); inf->comment = tr_strdup( buf ); @@ -182,7 +182,7 @@ tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag ) /* creator */ memset( buf, '\0', sizeof( buf ) ); val = tr_bencDictFindFirst( meta, "created by.utf-8", "created by", NULL ); - if( val && val->type == TYPE_STR ) + if( tr_bencIsString( val ) ) strlcat_utf8( buf, val->val.s.s, sizeof( buf ), 0 ); tr_free( inf->creator ); inf->creator = tr_strdup( buf ); @@ -190,23 +190,21 @@ tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag ) /* Date created */ inf->dateCreated = 0; val = tr_bencDictFind( meta, "creation date" ); - if( NULL != val && TYPE_INT == val->type ) - { + if( tr_bencIsInt( val ) ) inf->dateCreated = val->val.i; - } /* Private torrent */ val = tr_bencDictFind( beInfo, "private" ); val2 = tr_bencDictFind( meta, "private" ); - if( ( NULL != val && ( TYPE_INT != val->type || 0 != val->val.i ) ) || - ( NULL != val2 && ( TYPE_INT != val2->type || 0 != val2->val.i ) ) ) + if( ( tr_bencIsInt(val) && val->val.i ) || + ( tr_bencIsInt(val2) && val2->val.i ) ) { inf->isPrivate = 1; } /* Piece length */ val = tr_bencDictFind( beInfo, "piece length" ); - if( NULL == val || TYPE_INT != val->type ) + if( !tr_bencIsInt( val ) ) { if( val ) tr_err( _( "Invalid metadata entry \"%s\"" ), "piece length" ); @@ -218,7 +216,7 @@ tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag ) /* Hashes */ val = tr_bencDictFind( beInfo, "pieces" ); - if( NULL == val || TYPE_STR != val->type ) + if( !tr_bencIsString( val ) ) { if( val ) tr_err( _( "Invalid metadata entry \"%s\"" ), "pieces" ); @@ -307,29 +305,24 @@ void tr_metainfoFree( tr_info * inf ) static int getfile( char ** setme, const char * prefix, tr_benc * name ) { - tr_benc * dir; const char ** list; int ii, jj; char buf[4096]; - if( TYPE_LIST != name->type ) - { + if( !tr_bencIsList( name ) ) return TR_EINVALID; - } list = calloc( name->val.l.count, sizeof( list[0] ) ); - if( NULL == list ) - { + if( !list ) return TR_EINVALID; - } for( ii = jj = 0; name->val.l.count > ii; ii++ ) { - dir = &name->val.l.vals[ii]; - if( TYPE_STR != dir->type ) - { + tr_benc * dir = &name->val.l.vals[ii]; + + if( !tr_bencIsString( dir ) ) continue; - } + if( 0 == strcmp( "..", dir->val.s.s ) ) { if( 0 < jj ) @@ -367,15 +360,15 @@ getfile( char ** setme, const char * prefix, tr_benc * name ) static int getannounce( tr_info * inf, tr_benc * meta ) { - tr_benc * val, * subval, * urlval; + tr_benc * val, * urlval; char * address, * announce; - int ii, jj, port, random, subcount; + int ii, jj, port, random; tr_tracker_info * sublist; void * swapping; /* Announce-list */ val = tr_bencDictFind( meta, "announce-list" ); - if( NULL != val && TYPE_LIST == val->type && 0 < val->val.l.count ) + if( tr_bencIsList(val) && 0 < val->val.l.count ) { inf->trackerTiers = 0; inf->trackerList = calloc( val->val.l.count, @@ -384,12 +377,12 @@ static int getannounce( tr_info * inf, tr_benc * meta ) /* iterate through the announce-list's tiers */ for( ii = 0; ii < val->val.l.count; ii++ ) { - subval = &val->val.l.vals[ii]; - if( TYPE_LIST != subval->type || 0 >= subval->val.l.count ) - { + int subcount = 0; + tr_benc * subval = &val->val.l.vals[ii]; + + if( !tr_bencIsList(subval) || 0 >= subval->val.l.count ) continue; - } - subcount = 0; + sublist = calloc( subval->val.l.count, sizeof( sublist[0] ) ); /* iterate through the tier's items */ @@ -463,7 +456,7 @@ static int getannounce( tr_info * inf, tr_benc * meta ) /* Regular announce value */ val = tr_bencDictFind( meta, "announce" ); - if( NULL == val || TYPE_STR != val->type ) + if( !tr_bencIsString( val ) ) { tr_err( _( "Missing metadata entry \"%s\"" ), "announce" ); return TR_EINVALID; @@ -611,7 +604,7 @@ parseFiles( tr_info * inf, tr_benc * name, tr_benc * item, * path; int ii; - if( NULL == name || TYPE_STR != name->type ) + if( !tr_bencIsString( name ) ) { if( name ) tr_err( _( "Invalid metadata entry \"%s\"" ), "name" ); @@ -629,7 +622,7 @@ parseFiles( tr_info * inf, tr_benc * name, } inf->totalSize = 0; - if( files && TYPE_LIST == files->type ) + if( tr_bencIsList( files ) ) { /* Multi-file mode */ inf->isMultifile = 1; @@ -652,7 +645,7 @@ parseFiles( tr_info * inf, tr_benc * name, return TR_EINVALID; } length = tr_bencDictFind( item, "length" ); - if( NULL == length || TYPE_INT != length->type ) + if( !tr_bencIsInt( length ) ) { if( length ) tr_err( _( "Invalid metadata entry \"%s\"" ), "length" ); @@ -664,7 +657,7 @@ parseFiles( tr_info * inf, tr_benc * name, inf->totalSize += length->val.i; } } - else if( NULL != length && TYPE_INT == length->type ) + else if( tr_bencIsInt( length ) ) { char buf[4096]; diff --git a/macosx/IPCController.m b/macosx/IPCController.m index 6794ce9bd..c84265b0f 100644 --- a/macosx/IPCController.m +++ b/macosx/IPCController.m @@ -355,7 +355,7 @@ PrefsController * fPrefsController; if( IPC_MIN_MSG_LEN > [_buf length] ) return; - res = ipc_parse( _ipc, [_buf mutableBytes], [_buf length], self ); + res = ipc_handleMessages( _ipc, [_buf mutableBytes], [_buf length], self ); if( 0 > res ) {