1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-03 02:05:19 +00:00

Add client/server name to IPC version handshake.

This commit is contained in:
Josh Elsasser 2007-06-29 02:21:29 +00:00
parent 7d6137931f
commit a09a9c9157
7 changed files with 157 additions and 83 deletions

View file

@ -51,7 +51,7 @@ struct con
{
int infd;
int outfd;
struct ipc_info ipc;
struct ipc_info * ipc;
struct bufferevent * evin;
struct bufferevent * evout;
};
@ -168,13 +168,20 @@ client_new_sock( const char * path )
close( fd );
return -1;
}
ipc_newcon( &con->ipc, gl_tree );
con->ipc = ipc_newcon( gl_tree );
if( NULL == con->ipc )
{
mallocmsg( sizeof *con->ipc );
close( fd );
free( con );
}
con->infd = fd;
con->evin = bufferevent_new( fd, canread, didwrite, ohshit, con );
if( NULL == con->evin )
{
mallocmsg( -1 );
errnomsg( "failed to create bufferevent" );
close( fd );
ipc_freecon( con->ipc );
free( con );
return -1;
}
@ -274,6 +281,7 @@ client_new_cmd( char * const * cmd )
if( NULL == con->evout )
{
bufferevent_free( con->evin );
bufferevent_free( con->evout );
free( con );
close( tocmd[1] );
close( fromcmd[0] );
@ -283,7 +291,18 @@ client_new_cmd( char * const * cmd )
bufferevent_settimeout( con->evout, SERVER_TIMEOUT, SERVER_TIMEOUT );
bufferevent_enable( con->evout, EV_READ );
ipc_newcon( &con->ipc, gl_tree );
con->ipc = ipc_newcon( gl_tree );
if( NULL == con->ipc )
{
mallocmsg( sizeof *con->ipc );
bufferevent_free( con->evin );
bufferevent_free( con->evout );
free( con );
close( tocmd[1] );
close( fromcmd[0] );
return -1;
}
if( 0 > sendvers( con ) )
{
exit( 1 );
@ -686,7 +705,7 @@ canread( struct bufferevent * evin, void * arg )
return;
}
res = ipc_parse( &con->ipc, buf, len, con );
res = ipc_parse( con->ipc, buf, len, con );
if( 0 > res )
{
switch( errno )
@ -720,7 +739,7 @@ flushreqs( struct con * con )
benc_val_t pk, * val;
struct stritem * jj;
if( !HASVERS( &con->ipc ) )
if( !HASVERS( con->ipc ) )
{
return;
}
@ -741,7 +760,7 @@ flushreqs( struct con * con )
case IPC_MSG_STARTALL:
case IPC_MSG_STOPALL:
case IPC_MSG_REMOVEALL:
buf = ipc_mkempty( &con->ipc, &buflen, req->id, req->tag );
buf = ipc_mkempty( con->ipc, &buflen, req->id, req->tag );
break;
case IPC_MSG_ADDMANYFILES:
ii = 0;
@ -749,7 +768,7 @@ flushreqs( struct con * con )
{
ii++;
}
val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST );
val = ipc_initval( con->ipc, req->id, -1, &pk, TYPE_LIST );
if( NULL != val && !tr_bencListReserve( val, ii ) )
{
SLIST_FOREACH( jj, req->strs, next )
@ -763,7 +782,7 @@ flushreqs( struct con * con )
SAFEFREESTRLIST( req->strs );
break;
case IPC_MSG_ADDONEFILE:
val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_DICT );
val = ipc_initval( con->ipc, req->id, -1, &pk, TYPE_DICT );
if( NULL != val && !tr_bencDictReserve( val, 1 ) )
{
tr_bencInitStr( tr_bencDictAdd( val, "data" ),
@ -778,16 +797,16 @@ flushreqs( struct con * con )
case IPC_MSG_DOWNLIMIT:
case IPC_MSG_UPLIMIT:
case IPC_MSG_PEX:
buf = ipc_mkint( &con->ipc, &buflen, req->id, -1, req->num );
buf = ipc_mkint( con->ipc, &buflen, req->id, -1, req->num );
break;
case IPC_MSG_DIR:
buf = ipc_mkstr( &con->ipc, &buflen, req->id, -1, req->str );
buf = ipc_mkstr( con->ipc, &buflen, req->id, -1, req->str );
SAFEFREE( req->str );
break;
case IPC_MSG_START:
case IPC_MSG_STOP:
case IPC_MSG_REMOVE:
val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST );
val = ipc_initval( con->ipc, req->id, -1, &pk, TYPE_LIST );
if( NULL != val && !tr_bencListReserve( val, req->listlen ) )
{
for( ii = 0; ii < req->listlen; ii++ )
@ -802,7 +821,7 @@ flushreqs( struct con * con )
break;
case IPC_MSG_GETINFOALL:
case IPC_MSG_GETSTATALL:
buf = ipc_mkgetinfo( &con->ipc, &buflen, req->id, req->tag,
buf = ipc_mkgetinfo( con->ipc, &buflen, req->id, req->tag,
req->types, NULL );
break;
default:
@ -838,7 +857,7 @@ sendvers( struct con * con )
uint8_t * buf;
size_t len;
buf = ipc_mkvers( &len );
buf = ipc_mkvers( &len, "Transmission remote" VERSION_STRING );
if( NULL == buf )
{
if( EPERM == errno )

View file

@ -51,7 +51,7 @@ struct client
{
int fd;
struct bufferevent * ev;
struct ipc_info ipc;
struct ipc_info * ipc;
RB_ENTRY( client ) link;
};
@ -223,19 +223,28 @@ newclient( int fd, short event UNUSED, void * arg )
break;
}
client->ipc = ipc_newcon( gl_tree );
if( NULL == client->ipc )
{
mallocmsg( sizeof *client->ipc );
close( clfd );
free( client );
return;
}
clev = bufferevent_new( clfd, doread, noop, byebye, client );
if( NULL == clev )
{
errnomsg( "failed to create bufferevent" );
close( clfd );
ipc_freecon( client->ipc );
free( client );
mallocmsg( -1 );
return;
}
/* XXX bufferevent_base_set( gl_base, clev ); */
bufferevent_settimeout( clev, CLIENT_TIMEOUT, CLIENT_TIMEOUT );
client->fd = clfd;
ipc_newcon( &client->ipc, gl_tree );
client->ev = clev;
old = RB_INSERT( allclients, &gl_clients, client );
assert( NULL == old );
@ -246,7 +255,7 @@ newclient( int fd, short event UNUSED, void * arg )
}
bufferevent_enable( clev, EV_READ );
buf = ipc_mkvers( &buflen );
buf = ipc_mkvers( &buflen, "Transmission daemon " VERSION_STRING );
if( 0 > queuemsg( client, buf, buflen ) )
{
free( buf );
@ -298,6 +307,7 @@ byebye( struct bufferevent * ev, short what, void * arg UNUSED )
RB_REMOVE( allclients, &gl_clients, client );
bufferevent_free( ev );
close( client->fd );
ipc_freecon( client->ipc );
if( gl_debug )
{
printf( "*** client %i went bye-bye\n", client->fd );
@ -330,7 +340,7 @@ doread( struct bufferevent * ev, void * arg )
return;
}
res = ipc_parse( &client->ipc, buf, len, client );
res = ipc_parse( client->ipc, buf, len, client );
if( gl_exiting )
{
@ -400,7 +410,7 @@ msgresp( struct client * client, int64_t tag, enum ipc_msg id )
return 0;
}
buf = ipc_mkempty( &client->ipc, &buflen, id, tag );
buf = ipc_mkempty( client->ipc, &buflen, id, tag );
ret = queuemsg( client, buf, buflen );
free( buf );
@ -441,7 +451,7 @@ addmsg1( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
return;
}
added = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
added = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
if( NULL == added )
{
errnomsg( "failed to build message" );
@ -520,7 +530,7 @@ addmsg2( enum ipc_msg id UNUSED, benc_val_t * dict, int64_t tag, void * arg )
if( TORRENT_ID_VALID( tor ) )
{
val = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
val = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
if( NULL == val )
{
errnomsg( "failed to build message" );
@ -662,7 +672,7 @@ infomsg( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
}
/* initialize packet */
pkinf = ipc_initval( &client->ipc, respid, tag, &pk, TYPE_LIST );
pkinf = ipc_initval( client->ipc, respid, tag, &pk, TYPE_LIST );
if( NULL == pkinf )
{
errnomsg( "failed to build message" );
@ -847,7 +857,7 @@ lookmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
return;
}
pkinf = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
pkinf = ipc_initval( client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST );
if( NULL == pkinf )
{
errnomsg( "failed to build message" );
@ -897,31 +907,31 @@ prefmsg( enum ipc_msg id, benc_val_t * val UNUSED, int64_t tag, void * arg )
switch( id )
{
case IPC_MSG_GETAUTOMAP:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_AUTOMAP, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_AUTOMAP, tag,
torrent_get_port_mapping() );
break;
case IPC_MSG_GETAUTOSTART:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_AUTOSTART, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_AUTOSTART, tag,
torrent_get_autostart() );
break;
case IPC_MSG_GETDIR:
buf = ipc_mkstr( &client->ipc, &buflen, IPC_MSG_DIR, tag,
buf = ipc_mkstr( client->ipc, &buflen, IPC_MSG_DIR, tag,
torrent_get_directory() );
break;
case IPC_MSG_GETDOWNLIMIT:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_DOWNLIMIT, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_DOWNLIMIT, tag,
torrent_get_downlimit() );
break;
case IPC_MSG_GETPEX:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_PEX, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_PEX, tag,
torrent_get_pex() );
break;
case IPC_MSG_GETPORT:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_PORT, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_PORT, tag,
torrent_get_port() );
break;
case IPC_MSG_GETUPLIMIT:
buf = ipc_mkint( &client->ipc, &buflen, IPC_MSG_UPLIMIT, tag,
buf = ipc_mkint( client->ipc, &buflen, IPC_MSG_UPLIMIT, tag,
torrent_get_uplimit() );
break;
default:
@ -949,7 +959,7 @@ supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
return;
}
pkval = ipc_initval( &client->ipc, IPC_MSG_SUP, tag, &pk, TYPE_LIST );
pkval = ipc_initval( client->ipc, IPC_MSG_SUP, tag, &pk, TYPE_LIST );
if( NULL == pkval )
{
errnomsg( "failed to build message" );
@ -974,8 +984,8 @@ supmsg( enum ipc_msg id UNUSED, benc_val_t * val, int64_t tag, void * arg )
msgresp( client, tag, IPC_MSG_BAD );
return;
}
found = ipc_msgid( &client->ipc, name->val.s.s );
if( IPC__MSG_COUNT == found || !ipc_ishandled( &client->ipc, found ) )
found = ipc_msgid( client->ipc, name->val.s.s );
if( IPC__MSG_COUNT == found || !ipc_ishandled( client->ipc, found ) )
{
continue;
}

View file

@ -71,7 +71,7 @@ struct constate
int fd;
enum contype type;
struct ipc_funcs * msgs;
struct ipc_info ipc;
struct ipc_info * ipc;
union
{
struct constate_serv serv;
@ -221,8 +221,15 @@ blocking_client( enum ipc_msg msgid, GList * files )
return FALSE;
}
con->ipc = ipc_newcon( con->msgs );
if( NULL == con->ipc )
{
ipc_freemsgs( con->msgs );
g_free( con );
return FALSE;
}
ipc_setdefmsg( con->msgs, all_default );
ipc_newcon( &con->ipc, con->msgs );
con->u.client.loop = g_main_loop_new(NULL, TRUE);
con->u.client.msg = msgid;
@ -333,7 +340,7 @@ client_connect(char *path, struct constate *con) {
return FALSE;
}
buf = ipc_mkvers( &size );
buf = ipc_mkvers( &size, "Transmission GTK+ " VERSION_STRING );
if( NULL == buf )
{
close( con->fd );
@ -356,19 +363,28 @@ srv_io_accept(GSource *source SHUTUP, int fd, struct sockaddr *sa SHUTUP,
newcon = g_new(struct constate, 1);
memcpy(newcon, con, sizeof(*newcon));
newcon->fd = fd;
ipc_newcon( &newcon->ipc, con->msgs );
newcon->source = io_new(fd, NULL, srv_io_received, all_io_closed, newcon);
if( NULL == newcon->source )
newcon->ipc = ipc_newcon( con->msgs );
if( NULL == newcon->ipc )
{
g_free( newcon );
close( fd );
return;
}
buf = ipc_mkvers( &size );
newcon->source = io_new(fd, NULL, srv_io_received, all_io_closed, newcon);
if( NULL == newcon->source )
{
ipc_freecon( newcon->ipc );
g_free( newcon );
close( fd );
return;
}
buf = ipc_mkvers( &size, "Transmission GTK+ " VERSION_STRING );
if( NULL == buf )
{
ipc_freecon( newcon->ipc );
g_free( newcon );
close( fd );
return;
@ -395,7 +411,7 @@ srv_io_received( GSource * source SHUTUP, void * data, size_t len,
destroycon( con );
}
res = ipc_parse( &con->ipc, data, len, con );
res = ipc_parse( con->ipc, data, len, con );
if( 0 > res )
{
@ -431,7 +447,7 @@ cli_io_received( GSource * source SHUTUP, void * data, size_t len,
return 0;
}
res = ipc_parse( &con->ipc, data, len, con );
res = ipc_parse( con->ipc, data, len, con );
if( 0 > res )
{
@ -452,7 +468,7 @@ cli_io_received( GSource * source SHUTUP, void * data, size_t len,
return 0;
}
if( HASVERS( &con->ipc ) && 0 == cli->msgid )
if( HASVERS( con->ipc ) && 0 == cli->msgid )
{
client_sendmsg( con );
}
@ -473,7 +489,7 @@ client_sendmsg( struct constate * con )
switch( cli->msg )
{
case IPC_MSG_ADDMANYFILES:
val = ipc_initval( &con->ipc, cli->msg, -1, &packet, TYPE_LIST );
val = ipc_initval( con->ipc, cli->msg, -1, &packet, TYPE_LIST );
if( NULL == val ||
tr_bencListReserve( val, g_list_length( cli->files ) ) )
{
@ -492,7 +508,7 @@ client_sendmsg( struct constate * con )
cli->files = NULL;
break;
case IPC_MSG_QUIT:
buf = ipc_mkempty( &con->ipc, &size, cli->msg, -1 );
buf = ipc_mkempty( con->ipc, &size, cli->msg, -1 );
saved = errno;
break;
default:
@ -518,6 +534,7 @@ destroycon(struct constate *con) {
if(0 <= con->fd)
close(con->fd);
con->fd = -1;
ipc_freecon( con->ipc );
switch(con->type) {
case CON_SERV:
@ -689,7 +706,7 @@ smsg_info( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
}
typeflags = ipc_infotypes( respid, types );
pkval = ipc_initval( &con->ipc, respid, tag, &packet, TYPE_LIST );
pkval = ipc_initval( con->ipc, respid, tag, &packet, TYPE_LIST );
if( NULL == pkval )
{
simpleresp( con, tag, IPC_MSG_FAIL );
@ -747,7 +764,7 @@ smsg_infoall( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
respid = ( IPC_MSG_GETINFOALL == id ? IPC_MSG_INFO : IPC_MSG_STAT );
typeflags = ipc_infotypes( respid, val );
pkval = ipc_initval( &con->ipc, respid, tag, &packet, TYPE_LIST );
pkval = ipc_initval( con->ipc, respid, tag, &packet, TYPE_LIST );
if( NULL == pkval )
{
simpleresp( con, tag, IPC_MSG_FAIL );
@ -819,7 +836,7 @@ smsg_look( enum ipc_msg id SHUTUP, benc_val_t * val, int64_t tag,
return;
}
pkval = ipc_initval( &con->ipc, IPC_MSG_INFO, tag, &packet, TYPE_LIST );
pkval = ipc_initval( con->ipc, IPC_MSG_INFO, tag, &packet, TYPE_LIST );
if( NULL == pkval )
{
simpleresp( con, tag, IPC_MSG_FAIL );
@ -962,18 +979,18 @@ smsg_pref( enum ipc_msg id, benc_val_t * val SHUTUP, int64_t tag, void * arg )
{
case IPC_MSG_GETAUTOMAP:
hstat = tr_handleStatus( tr_core_handle( srv->core ) );
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_AUTOMAP, tag,
buf = ipc_mkint( con->ipc, &size, IPC_MSG_AUTOMAP, tag,
!TR_NAT_TRAVERSAL_IS_DISABLED(
hstat->natTraversalStatus ) );
break;
case IPC_MSG_GETAUTOSTART:
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_AUTOSTART, tag, 1 );
buf = ipc_mkint( con->ipc, &size, IPC_MSG_AUTOSTART, tag, 1 );
break;
case IPC_MSG_GETDIR:
pref = tr_prefs_get( PREF_ID_ASKDIR );
/* XXX sending back "" when we're prompting is kind of bogus */
pref = strbool( pref ) ? "" : getdownloaddir();
buf = ipc_mkstr( &con->ipc, &size, IPC_MSG_DIR, tag, pref );
buf = ipc_mkstr( con->ipc, &size, IPC_MSG_DIR, tag, pref );
break;
case IPC_MSG_GETDOWNLIMIT:
num = -1;
@ -981,14 +998,14 @@ smsg_pref( enum ipc_msg id, benc_val_t * val SHUTUP, int64_t tag, void * arg )
{
num = tr_prefs_get_int_with_default( PREF_ID_DOWNLIMIT );
}
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_DOWNLIMIT, tag, num );
buf = ipc_mkint( con->ipc, &size, IPC_MSG_DOWNLIMIT, tag, num );
break;
case IPC_MSG_GETPEX:
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_PEX, tag,
buf = ipc_mkint( con->ipc, &size, IPC_MSG_PEX, tag,
tr_prefs_get_bool_with_default( PREF_ID_PEX ) );
break;
case IPC_MSG_GETPORT:
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_PORT, tag,
buf = ipc_mkint( con->ipc, &size, IPC_MSG_PORT, tag,
tr_prefs_get_int_with_default( PREF_ID_PORT ) );
break;
case IPC_MSG_GETUPLIMIT:
@ -997,7 +1014,7 @@ smsg_pref( enum ipc_msg id, benc_val_t * val SHUTUP, int64_t tag, void * arg )
{
num = tr_prefs_get_int_with_default( PREF_ID_UPLIMIT );
}
buf = ipc_mkint( &con->ipc, &size, IPC_MSG_UPLIMIT, tag, num );
buf = ipc_mkint( con->ipc, &size, IPC_MSG_UPLIMIT, tag, num );
break;
default:
g_assert_not_reached();
@ -1107,7 +1124,7 @@ smsg_sup( enum ipc_msg id SHUTUP, benc_val_t * val, int64_t tag, void * arg )
return;
}
pkval = ipc_initval( &con->ipc, IPC_MSG_SUP, tag, &packet, TYPE_LIST );
pkval = ipc_initval( con->ipc, IPC_MSG_SUP, tag, &packet, TYPE_LIST );
if( NULL == pkval )
{
simpleresp( con, tag, IPC_MSG_FAIL );
@ -1127,8 +1144,8 @@ smsg_sup( enum ipc_msg id SHUTUP, benc_val_t * val, int64_t tag, void * arg )
{
continue;
}
found = ipc_msgid( &con->ipc, name->val.s.s );
if( IPC__MSG_COUNT == found || !ipc_ishandled( &con->ipc, found ) )
found = ipc_msgid( con->ipc, name->val.s.s );
if( IPC__MSG_COUNT == found || !ipc_ishandled( con->ipc, found ) )
{
continue;
}
@ -1170,7 +1187,7 @@ simpleresp( struct constate * con, int64_t tag, enum ipc_msg id )
uint8_t * buf;
size_t size;
buf = ipc_mkempty( &con->ipc, &size, id, tag );
buf = ipc_mkempty( con->ipc, &size, id, tag );
if( NULL == buf )
{
return FALSE;

View file

@ -292,12 +292,29 @@ ipc_freemsgs( struct ipc_funcs * tree )
free( tree );
}
void
ipc_newcon( struct ipc_info * info, struct ipc_funcs * funcs )
struct ipc_info *
ipc_newcon( struct ipc_funcs * funcs )
{
bzero( info, sizeof *info );
info->funcs = funcs;
info->vers = -1;
struct ipc_info * info;
info = calloc( 1, sizeof *info );
if( NULL != info )
{
info->funcs = funcs;
info->vers = -1;
}
return info;
}
void
ipc_freecon( struct ipc_info * info )
{
if( NULL != info )
{
free( info->label );
free( info );
}
}
benc_val_t *
@ -439,7 +456,7 @@ ipc_mkstr( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag,
}
uint8_t *
ipc_mkvers( size_t * len )
ipc_mkvers( size_t * len, const char * label )
{
benc_val_t pk, * dict;
uint8_t * ret;
@ -452,13 +469,15 @@ ipc_mkvers( size_t * len )
dict = tr_bencDictAdd( &pk, MSGNAME( IPC_MSG_VERSION ) );
tr_bencInit( dict, TYPE_DICT );
if( tr_bencDictReserve( dict, 2 ) )
if( tr_bencDictReserve( dict, ( NULL == label ? 2 : 3 ) ) )
{
SAFEBENCFREE( &pk );
return NULL;
}
tr_bencInitInt( tr_bencDictAdd( dict, "min" ), PROTO_VERS_MIN );
tr_bencInitInt( tr_bencDictAdd( dict, "max" ), PROTO_VERS_MAX );
if( NULL != label )
tr_bencInitStr( tr_bencDictAdd( dict, "label" ), label, -1, 1 );
ret = ipc_mkval( &pk, len );
SAFEBENCFREE( &pk );

View file

@ -123,9 +123,11 @@ struct ipc_info
{
struct ipc_funcs * funcs;
int vers;
char * label;
};
#define HASVERS( info ) ( 0 < (info)->vers )
#define VERSLABEL( info ) ( (info)->label )
#define TORRENT_ID_VALID( id ) ( 0 < (id) && INT_MAX > (id) )
@ -139,7 +141,8 @@ struct ipc_funcs * ipc_initmsgs ( void );
int ipc_addmsg ( struct ipc_funcs *, enum ipc_msg, trd_msgfunc );
void ipc_setdefmsg( struct ipc_funcs *, trd_msgfunc );
void ipc_freemsgs ( struct ipc_funcs * );
void ipc_newcon ( struct ipc_info *, struct ipc_funcs * );
struct ipc_info * ipc_newcon( struct ipc_funcs * );
void ipc_freecon ( struct ipc_info * );
/* message creation */
/* sets errno to EPERM if requested message not supported by protocol vers */
@ -152,7 +155,7 @@ uint8_t * ipc_mkint ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
int64_t );
uint8_t * ipc_mkstr ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
const char * );
uint8_t * ipc_mkvers ( size_t * );
uint8_t * ipc_mkvers ( size_t *, const char * );
uint8_t * ipc_mkgetinfo( struct ipc_info *, size_t *, enum ipc_msg, int64_t,
int, const int * );
int ipc_addinfo ( benc_val_t *, int, tr_info_t *, int );

View file

@ -76,10 +76,10 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
@interface IPCClient : NSObject
{
NSFileHandle * _handle;
struct ipc_info _ipc;
IPCController * _controller;
NSMutableData * _buf;
NSFileHandle * _handle;
struct ipc_info * _ipc;
IPCController * _controller;
NSMutableData * _buf;
}
- (id) initClient: (IPCController *) controller
@ -269,12 +269,13 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
return nil;
_handle = [handle retain];
ipc_newcon( &_ipc, funcs );
_ipc = ipc_newcon( funcs );
_controller = controller;
_buf = [[NSMutableData alloc] init];
buf = ipc_mkvers( &size );
if( nil == _buf || NULL == buf || ![self sendresp: buf size: size] )
buf = ipc_mkvers( &size, "Transmission MacOS X " VERSION_STRING );
if( NULL == _ipc || nil == _buf || NULL == buf ||
![self sendresp: buf size: size] )
{
[self release];
return nil;
@ -295,6 +296,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
[[NSNotificationCenter defaultCenter] removeObserver: self];
[_handle release];
[_buf release];
ipc_freecon( _ipc );
[super dealloc];
}
@ -305,7 +307,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
- (struct ipc_info *) ipc
{
return &_ipc;
return _ipc;
}
- (void) gotdata: (NSNotification *) notification
@ -338,7 +340,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
if( IPC_MIN_MSG_LEN > [_buf length] )
return;
res = ipc_parse( &_ipc, [_buf mutableBytes], [_buf length], self );
res = ipc_parse( _ipc, [_buf mutableBytes], [_buf length], self );
if( 0 > res )
{
@ -392,7 +394,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
uint8_t * buf;
size_t size;
buf = ipc_mkempty( &_ipc, &size, msgid, tag );
buf = ipc_mkempty( _ipc, &size, msgid, tag );
if( NULL == buf )
return FALSE;
@ -407,7 +409,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
uint8_t * buf;
size_t size;
buf = ipc_mkint( &_ipc, &size, msgid, tag, val );
buf = ipc_mkint( _ipc, &size, msgid, tag, val );
if( NULL == buf )
return FALSE;
@ -425,7 +427,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
NSMutableData * sucky;
if( [val canBeConvertedToEncoding: NSUTF8StringEncoding] )
buf = ipc_mkstr( &_ipc, &size, msgid, tag,
buf = ipc_mkstr( _ipc, &size, msgid, tag,
[val cStringUsingEncoding: NSUTF8StringEncoding] );
else
{
@ -434,7 +436,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
/* XXX this sucks, I should add a length argument to ipc_mkstr() */
sucky = [NSMutableData dataWithData: data];
[sucky appendBytes: "" length: 1];
buf = ipc_mkstr( &_ipc, &size, msgid, tag, [sucky bytes] );
buf = ipc_mkstr( _ipc, &size, msgid, tag, [sucky bytes] );
}
if( NULL == buf )
return FALSE;
@ -455,7 +457,7 @@ msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
size_t size;
int res;
pkinf = ipc_initval( &_ipc, respid, tag, &packet, TYPE_LIST );
pkinf = ipc_initval( _ipc, respid, tag, &packet, TYPE_LIST );
if( NULL == pkinf )
goto fail;
if( tr_bencListReserve( pkinf, [tors count] ) )

View file

@ -72,6 +72,10 @@ receive a version value that is an integer instead of a dictionary
with "min" and "max" keys. This deprecated version format indicates
the only version supported by the server.
The version dictionary may optionally contain a key "label". This is a
human-readable name for the software, it is not machine-readable and
neither servers nor clients should attempt to parse it.
An example message containing minimum and maximum versions 1 and 2:
0000001Dd7:versiond3:mini1e3:maxi2eee