1
/******************************************************************************
2
* $Id: server.c 5766 2008-05-07 11:57:23Z charles $
4
* Copyright (c) 2007 Joshua Elsasser
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
* DEALINGS IN THE SOFTWARE.
23
*****************************************************************************/
25
#include <sys/types.h>
26
#include <sys/socket.h>
39
#include <libtransmission/bencode.h>
40
#include <libtransmission/ipcparse.h>
41
#include <libtransmission/utils.h> /* tr_free */
49
/* time out clients after this many seconds */
50
#define CLIENT_TIMEOUT ( 60 )
55
struct bufferevent * ev;
56
struct ipc_info * ipc;
57
RB_ENTRY( client ) link;
60
RB_HEAD( allclients, client );
62
static void newclient( int, short, void * );
63
static void noop ( struct bufferevent *, void * );
64
static void byebye ( struct bufferevent *, short, void * );
65
static void doread ( struct bufferevent *, void * );
66
static int queuemsg ( struct client *, uint8_t *, size_t );
67
static int msgresp ( struct client *, int64_t, enum ipc_msg );
68
static void defmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
69
static void noopmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
70
static void addmsg1 ( enum ipc_msg, benc_val_t *, int64_t, void * );
71
static void addmsg2 ( enum ipc_msg, benc_val_t *, int64_t, void * );
72
static void quitmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
73
static void intmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
74
static void strmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
75
static void infomsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
76
static int addinfo ( benc_val_t *, int, int );
77
static int addstat ( benc_val_t *, int, int );
78
static void tormsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
79
static void lookmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
80
static void prefmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
81
static void supmsg ( enum ipc_msg, benc_val_t *, int64_t, void * );
82
static int clientcmp( struct client *, struct client * );
84
RB_GENERATE_STATIC( allclients, client, link, clientcmp )
85
INTCMP_FUNC( clientcmp, client, ev )
87
static struct event_base * gl_base = NULL;
88
static struct ipc_funcs * gl_tree = NULL;
89
static int gl_debug = 0;
90
static int gl_exiting = 0;
91
static struct allclients gl_clients = RB_INITIALIZER( &gl_clients );
94
server_init( struct event_base * base )
96
assert( NULL == gl_base && NULL == gl_tree );
98
gl_tree = ipc_initmsgs();
104
ipc_addmsg( gl_tree, IPC_MSG_ADDMANYFILES, addmsg1 );
105
ipc_addmsg( gl_tree, IPC_MSG_ADDONEFILE, addmsg2 );
106
ipc_addmsg( gl_tree, IPC_MSG_AUTOMAP, intmsg );
107
ipc_addmsg( gl_tree, IPC_MSG_AUTOSTART, intmsg );
108
ipc_addmsg( gl_tree, IPC_MSG_CRYPTO, strmsg );
109
ipc_addmsg( gl_tree, IPC_MSG_DOWNLIMIT, intmsg );
110
ipc_addmsg( gl_tree, IPC_MSG_DIR, strmsg );
111
ipc_addmsg( gl_tree, IPC_MSG_GETAUTOMAP, prefmsg );
112
ipc_addmsg( gl_tree, IPC_MSG_GETAUTOSTART, prefmsg );
113
ipc_addmsg( gl_tree, IPC_MSG_GETCRYPTO, prefmsg );
114
ipc_addmsg( gl_tree, IPC_MSG_GETDOWNLIMIT, prefmsg );
115
ipc_addmsg( gl_tree, IPC_MSG_GETDIR, prefmsg );
116
ipc_addmsg( gl_tree, IPC_MSG_GETINFO, infomsg );
117
ipc_addmsg( gl_tree, IPC_MSG_GETINFOALL, infomsg );
118
ipc_addmsg( gl_tree, IPC_MSG_GETPEX, prefmsg );
119
ipc_addmsg( gl_tree, IPC_MSG_GETPORT, prefmsg );
120
ipc_addmsg( gl_tree, IPC_MSG_GETSTAT, infomsg );
121
ipc_addmsg( gl_tree, IPC_MSG_GETSTATALL, infomsg );
122
ipc_addmsg( gl_tree, IPC_MSG_GETUPLIMIT, prefmsg );
123
ipc_addmsg( gl_tree, IPC_MSG_GETSUP, supmsg );
124
ipc_addmsg( gl_tree, IPC_MSG_LOOKUP, lookmsg );
125
ipc_addmsg( gl_tree, IPC_MSG_NOOP, noopmsg );
126
ipc_addmsg( gl_tree, IPC_MSG_PEX, intmsg );
127
ipc_addmsg( gl_tree, IPC_MSG_PORT, intmsg );
128
ipc_addmsg( gl_tree, IPC_MSG_QUIT, quitmsg );
129
ipc_addmsg( gl_tree, IPC_MSG_REMOVE, tormsg );
130
ipc_addmsg( gl_tree, IPC_MSG_REMOVEALL, tormsg );
131
ipc_addmsg( gl_tree, IPC_MSG_START, tormsg );
132
ipc_addmsg( gl_tree, IPC_MSG_STARTALL, tormsg );
133
ipc_addmsg( gl_tree, IPC_MSG_STOP, tormsg );
134
ipc_addmsg( gl_tree, IPC_MSG_STOPALL, tormsg );
135
ipc_addmsg( gl_tree, IPC_MSG_UPLIMIT, intmsg );
136
ipc_addmsg( gl_tree, IPC_MSG_VERIFY, tormsg );
138
ipc_setdefmsg( gl_tree, defmsg );
144
server_debug( int enable )
150
server_listen( int fd )
155
assert( NULL != gl_base );
157
flags = fcntl( fd, F_GETFL );
160
errnomsg( "failed to get flags on socket" );
163
if( 0 > fcntl( fd, F_SETFL, flags | O_NONBLOCK ) )
165
errnomsg( "failed to set flags on socket" );
169
if( 0 > listen( fd, 5 ) )
171
errnomsg( "failed to listen on socket" );
175
ev = malloc( sizeof *ev );
178
mallocmsg( sizeof *ev );
182
event_set( ev, fd, EV_READ | EV_PERSIST, newclient, ev );
183
event_base_set( gl_base, ev );
184
event_add( ev, NULL );
192
struct client * ii, * next;
200
for( ii = RB_MIN( allclients, &gl_clients ); NULL != ii; ii = next )
202
next = RB_NEXT( allclients, &gl_clients, ii );
203
byebye( ii->ev, EVBUFFER_EOF, NULL );
208
newclient( int fd, short event UNUSED, void * arg )
210
struct sockaddr_un sa;
211
struct client * client, * old;
213
struct bufferevent * clev;
226
client = calloc( 1, sizeof *client );
229
mallocmsg( sizeof *client );
234
clfd = accept( fd, ( struct sockaddr * )&sa, &socklen );
237
if( EWOULDBLOCK != errno && EAGAIN != errno &&
238
ECONNABORTED != errno )
240
errnomsg( "failed to accept ipc connection" );
246
client->ipc = ipc_newcon( gl_tree );
247
if( NULL == client->ipc )
254
clev = bufferevent_new( clfd, doread, noop, byebye, client );
257
errnomsg( "failed to create bufferevent" );
259
ipc_freecon( client->ipc );
263
bufferevent_base_set( gl_base, clev );
264
bufferevent_settimeout( clev, CLIENT_TIMEOUT, CLIENT_TIMEOUT );
268
old = RB_INSERT( allclients, &gl_clients, client );
269
assert( NULL == old );
273
printf( "*** new client %i\n", clfd );
276
bufferevent_enable( clev, EV_READ );
277
buf = ipc_mkvers( &buflen, "Transmission daemon " LONG_VERSION_STRING );
278
if( 0 > queuemsg( client, buf, buflen ) )
288
noop( struct bufferevent * ev UNUSED, void * arg UNUSED )
290
/* libevent prior to 1.2 couldn't handle a NULL write callback */
294
byebye( struct bufferevent * ev, short what, void * arg UNUSED )
296
struct client * client, key;
298
if( !( EVBUFFER_EOF & what ) )
300
if( EVBUFFER_TIMEOUT & what )
302
errmsg( "client connection timed out" );
304
else if( EVBUFFER_READ & what )
306
errmsg( "read error on client connection" );
308
else if( EVBUFFER_WRITE & what )
310
errmsg( "write error on client connection" );
312
else if( EVBUFFER_ERROR & what )
314
errmsg( "error on client connection" );
318
errmsg( "unknown error on client connection: 0x%x", what );
322
memset( &key, 0, sizeof key );
324
client = RB_FIND( allclients, &gl_clients, &key );
325
assert( NULL != client );
326
RB_REMOVE( allclients, &gl_clients, client );
327
bufferevent_free( ev );
329
ipc_freecon( client->ipc );
332
printf( "*** client %i went bye-bye\n", client->fd );
338
doread( struct bufferevent * ev, void * arg )
340
struct client * client = arg;
345
assert( !gl_exiting );
347
buf = EVBUFFER_DATA( EVBUFFER_INPUT( ev ) );
348
len = EVBUFFER_LENGTH( EVBUFFER_INPUT( ev ) );
352
printf( "<<< %zu bytes from client %i: ", len, client->fd );
353
fwrite( buf, 1, len, stdout );
354
putc( '\n', stdout );
357
if( IPC_MIN_MSG_LEN > len )
362
res = ipc_handleMessages( client->ipc, buf, len, client );
374
errmsg( "unsupported protocol version" );
377
errmsg( "protocol parse error" );
380
errnomsg( "parsing failed" );
383
byebye( ev, EVBUFFER_ERROR, NULL );
387
evbuffer_drain( EVBUFFER_INPUT( ev ), res );
392
queuemsg( struct client * client, uint8_t * buf, size_t buflen )
398
errnomsg( "failed to build message" );
399
byebye( client->ev, EVBUFFER_EOF, NULL );
406
printf( ">>> %zu bytes to client %i: ", buflen, client->fd );
407
fwrite( buf, 1, buflen, stdout );
408
putc( '\n', stdout );
411
if( 0 > bufferevent_write( client->ev, buf, buflen ) )
413
errnomsg( "failed to buffer %zd bytes of data for write", buflen );
421
queuepkmsg( struct client * client, tr_benc * pk )
424
uint8_t * buf = ipc_serialize( pk, &buflen );
425
int ret = queuemsg( client, buf, buflen );
431
msgresp( struct client * client, int64_t tag, enum ipc_msg id )
442
buf = ipc_mkempty( client->ipc, &buflen, id, tag );
443
ret = queuemsg( client, buf, buflen );
450
defmsg( enum ipc_msg id UNUSED, benc_val_t * val UNUSED, int64_t tag,
453
struct client * client = arg;
455
msgresp( client, tag, IPC_MSG_NOTSUP );
459
noopmsg( enum ipc_msg id UNUSED, benc_val_t * val UNUSED, int64_t tag,
462
struct client * client = arg;
464
msgresp( client, tag, IPC_MSG_OK );
468
addmsg1( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
470
struct client * client = arg;
471
benc_val_t pk, * added;
474
if( !tr_bencIsList( val ) )
476
msgresp( client, tag, IPC_MSG_BAD );
480
added = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
483
errnomsg( "failed to build message" );
484
byebye( client->ev, EVBUFFER_EOF, NULL );
488
for( ii = 0; ii < val->val.l.count; ii++ )
490
tr_benc * file = &val->val.l.vals[ii];
491
if( !tr_bencIsString( file ) )
494
/* XXX need to somehow inform client of skipped or failed files */
495
tor = torrent_add_file( file->val.s.s, NULL, -1 );
496
if( TORRENT_ID_VALID( tor ) )
498
if( 0 > ipc_addinfo( added, tor, torrent_handle( tor ), 0 ) )
500
errnomsg( "failed to build message" );
502
byebye( client->ev, EVBUFFER_EOF, NULL );
508
queuepkmsg( client, &pk );
513
addmsg2( enum ipc_msg id UNUSED, benc_val_t * dict, int64_t tag, void * arg )
515
struct client * client = arg;
516
benc_val_t * val, pk;
520
if( !tr_bencIsDict( dict ) )
522
msgresp( client, tag, IPC_MSG_BAD );
526
val = tr_bencDictFind( dict, "directory" );
527
dir = tr_bencIsString( val ) ? val->val.s.s : NULL;
528
val = tr_bencDictFind( dict, "autostart" );
529
start = tr_bencIsInt( val ) ? (val->val.i!=0) : -1;
530
val = tr_bencDictFind( dict, "data" );
531
if( tr_bencIsString( val ) )
533
/* XXX detect duplicates and return a message indicating so */
534
tor = torrent_add_data( ( uint8_t * )val->val.s.s, val->val.s.i,
539
val = tr_bencDictFind( dict, "file" );
540
if( !tr_bencIsString( val ) )
542
msgresp( client, tag, IPC_MSG_BAD );
545
/* XXX detect duplicates and return a message indicating so */
546
tor = torrent_add_file( val->val.s.s, dir, start );
549
if( TORRENT_ID_VALID( tor ) )
551
val = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
554
errnomsg( "failed to build message" );
555
byebye( client->ev, EVBUFFER_EOF, NULL );
558
if( 0 > ipc_addinfo( val, tor, torrent_handle( tor ), 0 ) )
560
errnomsg( "failed to build message" );
562
byebye( client->ev, EVBUFFER_EOF, NULL );
566
queuepkmsg( client, &pk );
571
msgresp( client, tag, IPC_MSG_FAIL );
576
quitmsg( enum ipc_msg id UNUSED, benc_val_t * val UNUSED, int64_t tag UNUSED,
583
intmsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
585
struct client * client = arg;
588
if( !tr_bencIsInt( val ) )
590
msgresp( client, tag, IPC_MSG_BAD );
594
num = MAX( INT_MIN, MIN( INT_MAX, val->val.i ) );
597
case IPC_MSG_AUTOMAP:
598
torrent_enable_port_mapping( num ? 1 : 0 );
600
case IPC_MSG_AUTOSTART:
601
torrent_set_autostart( num ? 1 : 0 );
603
case IPC_MSG_DOWNLIMIT:
604
torrent_set_downlimit( num );
607
torrent_set_pex( num ? 1 : 0 );
610
torrent_set_port( num );
612
case IPC_MSG_UPLIMIT:
613
torrent_set_uplimit( num );
620
msgresp( client, tag, IPC_MSG_OK );
624
strmsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
626
struct client * client = arg;
628
if( !tr_bencIsString( val ) )
630
msgresp( client, tag, IPC_MSG_BAD );
637
if( !strcasecmp( val->val.s.s, "required" ) )
638
torrent_set_encryption( TR_ENCRYPTION_REQUIRED );
639
else if( !strcasecmp( val->val.s.s, "preferred" ) )
640
torrent_set_encryption( TR_ENCRYPTION_PREFERRED );
641
else if( !strcasecmp( val->val.s.s, "tolerated" ) )
642
torrent_set_encryption( TR_PLAINTEXT_PREFERRED );
644
msgresp(client, tag, IPC_MSG_BAD);
650
torrent_set_directory( val->val.s.s );
657
msgresp( client, tag, IPC_MSG_OK );
661
infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
663
struct client * client = arg;
664
benc_val_t pk, * pkinf, * typelist, * idlist, * idval;
665
int all, types, ii, tor;
668
int ( * addfunc )( benc_val_t *, int, int );
673
case IPC_MSG_GETINFOALL:
676
case IPC_MSG_GETINFO:
677
respid = IPC_MSG_INFO;
680
case IPC_MSG_GETSTATALL:
683
case IPC_MSG_GETSTAT:
684
respid = IPC_MSG_STAT;
692
/* initialize packet */
693
pkinf = ipc_initval( client->ipc, respid, tag, &pk, TYPE_LIST );
696
errnomsg( "failed to build message" );
697
byebye( client->ev, EVBUFFER_EOF, NULL );
701
/* add info/status for all torrents */
704
if( !tr_bencIsList( val ) )
706
msgresp( client, tag, IPC_MSG_BAD );
710
types = ipc_infotypes( respid, val );
712
while( NULL != ( iter = torrent_iter( iter, &tor ) ) )
714
if( 0 > addfunc( pkinf, tor, types ) )
716
errnomsg( "failed to build message" );
718
byebye( client->ev, EVBUFFER_EOF, NULL );
723
/* add info/status for the requested IDs */
726
if( !tr_bencIsDict( val ) )
728
msgresp( client, tag, IPC_MSG_BAD );
732
typelist = tr_bencDictFind( val, "type" );
733
idlist = tr_bencDictFind( val, "id" );
734
if( !tr_bencIsList(typelist) || !tr_bencIsList(idlist) )
736
msgresp( client, tag, IPC_MSG_BAD );
740
types = ipc_infotypes( respid, typelist );
741
for( ii = 0; idlist->val.l.count > ii; ii++ )
743
idval = &idlist->val.l.vals[ii];
744
if( TYPE_INT != idval->type || !TORRENT_ID_VALID( idval->val.i ) )
749
if( 0 > addfunc( pkinf, idval->val.i, types ) )
751
errnomsg( "failed to build message" );
753
byebye( client->ev, EVBUFFER_EOF, NULL );
759
queuepkmsg( client, &pk );
764
addinfo( benc_val_t * list, int id, int types )
766
tr_torrent * tor = torrent_handle( id );
767
return tor ? ipc_addinfo( list, id, tor, types ) : 0;
771
addstat( benc_val_t * list, int id, int types )
773
tr_torrent * tor = torrent_handle( id );
774
return tor ? ipc_addstat( list, id, tor, types ) : 0;
778
tormsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
780
struct client * client = arg;
784
void ( * func )( int );
789
case IPC_MSG_REMOVEALL:
793
func = torrent_remove;
795
case IPC_MSG_STARTALL:
799
func = torrent_start;
801
case IPC_MSG_STOPALL:
809
func = torrent_verify;
816
/* remove/start/stop all torrents */
820
while( NULL != ( iter = torrent_iter( iter, &ii ) ) )
823
if( torrent_remove == func )
829
/* remove/start/stop requested list of torrents */
832
if( !tr_bencIsList( val ) )
834
msgresp( client, tag, IPC_MSG_BAD );
837
for( ii = 0; val->val.l.count > ii; ii++ )
839
idval = &val->val.l.vals[ii];
840
if( TYPE_INT != idval->type || !TORRENT_ID_VALID( idval->val.i ) )
844
func( idval->val.i );
848
msgresp( client, tag, IPC_MSG_OK );
852
lookmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
854
struct client * client = arg;
856
benc_val_t * hash, pk, * pkinf;
859
if( !tr_bencIsList( val ) )
861
msgresp( client, tag, IPC_MSG_BAD );
865
pkinf = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
868
errnomsg( "failed to build message" );
869
byebye( client->ev, EVBUFFER_EOF, NULL );
873
for( ii = 0; val->val.l.count > ii; ii++ )
875
hash = &val->val.l.vals[ii];
876
if( !tr_bencIsString(hash) || SHA_DIGEST_LENGTH * 2 != hash->val.s.i )
879
msgresp( client, tag, IPC_MSG_BAD );
882
found = torrent_lookup( ( uint8_t * )hash->val.s.s );
883
if( !TORRENT_ID_VALID( found ) )
887
if( 0 > ipc_addinfo( pkinf, found, torrent_handle( found ), IPC_INF_HASH ) )
889
errnomsg( "failed to build message" );
891
byebye( client->ev, EVBUFFER_EOF, NULL );
896
queuepkmsg( client, &pk );
901
prefmsg( enum ipc_msg id, benc_val_t * val UNUSED, int64_t tag, void * arg )
903
struct client * client = arg;
910
case IPC_MSG_GETAUTOMAP:
911
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_AUTOMAP, tag,
912
torrent_get_port_mapping() );
914
case IPC_MSG_GETAUTOSTART:
915
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_AUTOSTART, tag,
916
torrent_get_autostart() );
918
case IPC_MSG_GETCRYPTO:
919
switch(torrent_get_encryption()) {
920
case TR_ENCRYPTION_REQUIRED: strval = "required"; break;
921
case TR_ENCRYPTION_PREFERRED: strval = "preferred"; break;
922
case TR_PLAINTEXT_PREFERRED: strval = "tolerated"; break;
923
default: assert(0); return;
925
buf = ipc_mkstr(client->ipc, &buflen, IPC_MSG_CRYPTO, tag, strval);
928
buf = ipc_mkstr( client->ipc, &buflen, IPC_MSG_DIR, tag,
929
torrent_get_directory() );
931
case IPC_MSG_GETDOWNLIMIT:
932
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_DOWNLIMIT, tag,
933
torrent_get_downlimit() );
936
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_PEX, tag,
939
case IPC_MSG_GETPORT:
940
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_PORT, tag,
941
torrent_get_port() );
943
case IPC_MSG_GETUPLIMIT:
944
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_UPLIMIT, tag,
945
torrent_get_uplimit() );
952
queuemsg( client, buf, buflen );
957
supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
959
struct client * client = arg;
961
benc_val_t pk, *pkval;
964
if( !tr_bencIsList( val ) )
966
msgresp( client, tag, IPC_MSG_BAD );
970
pkval = ipc_initval( client->ipc, IPC_MSG_SUP, tag, &pk, TYPE_LIST );
973
errnomsg( "failed to build message" );
974
byebye( client->ev, EVBUFFER_EOF, NULL );
977
/* XXX look at other initval to make sure we free pk */
978
if( tr_bencListReserve( pkval, val->val.l.count ) )
980
errnomsg( "failed to build message" );
982
byebye( client->ev, EVBUFFER_EOF, NULL );
986
for( ii = 0; val->val.l.count > ii; ii++ )
988
tr_benc * name = &val->val.l.vals[ii];
989
if( !tr_bencIsString( name ) )
992
msgresp( client, tag, IPC_MSG_BAD );
995
found = ipc_msgid( client->ipc, name->val.s.s );
996
if( IPC__MSG_COUNT == found || !ipc_ishandled( client->ipc, found ) )
1000
tr_bencInitStr( tr_bencListAdd( pkval ),
1001
name->val.s.s, name->val.s.i, 1 );
1004
queuepkmsg( client, &pk );