mirror of
https://github.com/transmission/transmission
synced 2024-12-24 08:43:27 +00:00
Use a new, more flexible version message in ipc.
Don't actually have the server send it yet, old clients can't handle it.
This commit is contained in:
parent
5a62e83689
commit
36c7c9d7d2
1 changed files with 135 additions and 13 deletions
142
gtk/ipc.c
142
gtk/ipc.c
|
@ -43,7 +43,9 @@
|
|||
#include "tr_prefs.h"
|
||||
#include "util.h"
|
||||
|
||||
#define PROTOVERS 1 /* IPC protocol version */
|
||||
/* IPC protocol version */
|
||||
#define PROTO_VERS_MIN ( 1 )
|
||||
#define PROTO_VERS_MAX ( 1 )
|
||||
|
||||
/* int, IPC protocol version */
|
||||
#define MSG_VERSION ("version")
|
||||
|
@ -78,6 +80,7 @@ struct handlerdef {char *name; handler_func_t func;};
|
|||
struct constate {
|
||||
GSource *source;
|
||||
int fd;
|
||||
int vers;
|
||||
const struct handlerdef *funcs;
|
||||
enum contype type;
|
||||
union {
|
||||
|
@ -98,7 +101,9 @@ srv_io_accept(GSource *source, int fd, struct sockaddr *sa, socklen_t len,
|
|||
static int
|
||||
send_msg(struct constate *con, const char *name, benc_val_t *val);
|
||||
static int
|
||||
send_msg_int(struct constate *con, const char *name, int num);
|
||||
send_msg_vers_new(struct constate *con);
|
||||
static int
|
||||
send_msg_vers_old(struct constate *con);
|
||||
static unsigned int
|
||||
all_io_received(GSource *source, char *data, unsigned int len, void *vdata);
|
||||
static void
|
||||
|
@ -106,6 +111,8 @@ destroycon(struct constate *con);
|
|||
static void
|
||||
all_io_closed(GSource *source, void *vdata);
|
||||
static void
|
||||
srv_vers(struct constate *con, const char *name, benc_val_t *val);
|
||||
static void
|
||||
srv_addfile(struct constate *con, const char *name, benc_val_t *val);
|
||||
static void
|
||||
srv_quit( struct constate * con, const char * name, benc_val_t * val );
|
||||
|
@ -113,8 +120,13 @@ static void
|
|||
afc_version(struct constate *con, const char *name, benc_val_t *val);
|
||||
static void
|
||||
afc_io_sent(GSource *source, unsigned int id, void *vdata);
|
||||
static int
|
||||
ipc_checkversion( benc_val_t * vers );
|
||||
static int
|
||||
getvers( benc_val_t * dict, const char * key );
|
||||
|
||||
static const struct handlerdef gl_funcs_serv[] = {
|
||||
{MSG_VERSION, srv_vers},
|
||||
{MSG_ADDFILES, srv_addfile},
|
||||
{MSG_QUIT, srv_quit},
|
||||
{NULL, NULL}
|
||||
|
@ -137,6 +149,7 @@ ipc_socket_setup( void * parent, add_torrents_func_t addfunc,
|
|||
con = g_new0(struct constate, 1);
|
||||
con->source = NULL;
|
||||
con->fd = -1;
|
||||
con->vers = -1;
|
||||
con->funcs = gl_funcs_serv;
|
||||
con->type = CON_SERV;
|
||||
con->u.serv.wind = parent;
|
||||
|
@ -158,6 +171,7 @@ blocking_client( enum client_cmd cmd, GList * files )
|
|||
con = g_new0(struct constate, 1);
|
||||
con->source = NULL;
|
||||
con->fd = -1;
|
||||
con->vers = -1;
|
||||
con->funcs = gl_funcs_client;
|
||||
con->type = CON_CLIENT;
|
||||
con->u.client.loop = g_main_loop_new(NULL, TRUE);
|
||||
|
@ -262,6 +276,11 @@ client_connect(char *path, struct constate *con) {
|
|||
con->source = io_new(con->fd, afc_io_sent, all_io_received,
|
||||
all_io_closed, con);
|
||||
|
||||
if( NULL != con->source )
|
||||
{
|
||||
send_msg_vers_new( con );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -276,8 +295,11 @@ srv_io_accept(GSource *source SHUTUP, int fd, struct sockaddr *sa SHUTUP,
|
|||
newcon->fd = fd;
|
||||
newcon->source = io_new(fd, NULL, all_io_received, all_io_closed, newcon);
|
||||
|
||||
/* XXX need to check for incoming version from client */
|
||||
|
||||
if(NULL != newcon->source)
|
||||
send_msg_int(newcon, MSG_VERSION, PROTOVERS);
|
||||
/* XXX need to switch to new version scheme after the next release */
|
||||
send_msg_vers_old( newcon );
|
||||
else {
|
||||
g_free(newcon);
|
||||
close(fd);
|
||||
|
@ -323,14 +345,40 @@ send_msg(struct constate *con, const char *name, benc_val_t *val) {
|
|||
}
|
||||
|
||||
static int
|
||||
send_msg_int(struct constate *con, const char *name, int num) {
|
||||
send_msg_vers_new( struct constate * con )
|
||||
{
|
||||
benc_val_t dict;
|
||||
|
||||
/* XXX ugh, I need to merge the pex branch and use it's benc funcs */
|
||||
bzero( &dict, sizeof dict );
|
||||
dict.type = TYPE_DICT;
|
||||
dict.val.l.alloc = 4;
|
||||
dict.val.l.count = 4;
|
||||
dict.val.l.vals = g_new0( benc_val_t, 4 );
|
||||
dict.val.l.vals[0].type = TYPE_STR;
|
||||
dict.val.l.vals[0].val.s.i = 3;
|
||||
dict.val.l.vals[0].val.s.s = "min";
|
||||
dict.val.l.vals[1].type = TYPE_INT;
|
||||
dict.val.l.vals[1].val.i = PROTO_VERS_MIN;
|
||||
dict.val.l.vals[2].type = TYPE_STR;
|
||||
dict.val.l.vals[2].val.s.i = 3;
|
||||
dict.val.l.vals[2].val.s.s = "max";
|
||||
dict.val.l.vals[3].type = TYPE_INT;
|
||||
dict.val.l.vals[3].val.i = PROTO_VERS_MAX;
|
||||
|
||||
return send_msg( con, MSG_VERSION, &dict );
|
||||
}
|
||||
|
||||
static int
|
||||
send_msg_vers_old( struct constate * con )
|
||||
{
|
||||
benc_val_t val;
|
||||
|
||||
bzero(&val, sizeof(val));
|
||||
bzero( &val, sizeof val );
|
||||
val.type = TYPE_INT;
|
||||
val.val.i = num;
|
||||
val.val.i = PROTO_VERS_MIN;
|
||||
|
||||
return send_msg(con, name, &val);
|
||||
return send_msg( con, MSG_VERSION, &val );
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
@ -394,6 +442,21 @@ all_io_closed(GSource *source SHUTUP, void *vdata) {
|
|||
destroycon(con);
|
||||
}
|
||||
|
||||
static void
|
||||
srv_vers( struct constate * con, const char * name SHUTUP, benc_val_t * val )
|
||||
{
|
||||
if( 0 > con->vers )
|
||||
{
|
||||
con->vers = ipc_checkversion( val );
|
||||
if( 0 > con->vers )
|
||||
{
|
||||
fprintf( stderr, _("bad IPC protocol version\n") );
|
||||
destroycon( con );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
srv_addfile(struct constate *con, const char *name SHUTUP, benc_val_t *val) {
|
||||
struct constate_serv *srv = &con->u.serv;
|
||||
|
@ -430,9 +493,18 @@ afc_version(struct constate *con, const char *name SHUTUP, benc_val_t *val) {
|
|||
GList *file;
|
||||
benc_val_t list, *str;
|
||||
|
||||
if(TYPE_INT != val->type || PROTOVERS != val->val.i) {
|
||||
fprintf(stderr, _("bad IPC protocol version\n"));
|
||||
destroycon(con);
|
||||
if( 0 > con->vers )
|
||||
{
|
||||
con->vers = ipc_checkversion( val );
|
||||
if( 0 > con->vers )
|
||||
{
|
||||
fprintf( stderr, _("bad IPC protocol version\n") );
|
||||
destroycon( con );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -474,3 +546,53 @@ afc_io_sent(GSource *source SHUTUP, unsigned int id, void *vdata) {
|
|||
destroycon(vdata);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ipc_checkversion( benc_val_t * vers )
|
||||
{
|
||||
int min, max;
|
||||
|
||||
if( TYPE_INT == vers->type )
|
||||
{
|
||||
if( 0 > vers->val.i )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
min = max = vers->val.i;
|
||||
}
|
||||
else if( TYPE_DICT == vers->type )
|
||||
{
|
||||
min = getvers( vers, "min" );
|
||||
max = getvers( vers, "max" );
|
||||
if( 0 > min || 0 > max )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_assert( PROTO_VERS_MIN <= PROTO_VERS_MAX );
|
||||
if( min > max || PROTO_VERS_MAX < min || PROTO_VERS_MIN > max )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return MIN( PROTO_VERS_MAX, max );
|
||||
}
|
||||
|
||||
int
|
||||
getvers( benc_val_t * dict, const char * key )
|
||||
{
|
||||
benc_val_t * val;
|
||||
|
||||
val = tr_bencDictFind( dict, key );
|
||||
if( NULL == val || TYPE_INT != val->type || 0 > val->val.i )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return val->val.i;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue