1
/******************************************************************************
2
* $Id: IPCController.m 5715 2008-04-28 18:09:17Z charles $
4
* Copyright (c) 2007-2008 Transmission authors and contributors
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>
35
#include "transmission.h"
38
#import "IPCController.h"
40
#import "PrefsController.h"
43
getaddr( struct sockaddr_un * );
45
bencarray( benc_val_t * val, int type );
47
msg_lookup ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
49
msg_info ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
51
msg_infoall ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
53
msg_action ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
55
msg_actionall( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
57
msg_addold ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
59
msg_addnew ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
61
msg_getbool ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
63
msg_getint ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
65
msg_getstr ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
67
msg_setbool ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
69
msg_setint ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
71
msg_setstr ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
73
msg_empty ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
75
msg_sup ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
77
msg_default ( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg );
79
@interface IPCClient : NSObject
81
NSFileHandle * _handle;
82
struct ipc_info * _ipc;
83
IPCController * _controller;
87
- (id) initClient: (IPCController *) controller
88
funcs: (struct ipc_funcs *) funcs
89
handle: (NSFileHandle *) handle;
90
- (IPCController *) controller;
91
- (struct ipc_info *) ipc;
92
- (void) gotdata: (NSNotification *) notification;
93
- (BOOL) sendresp: (uint8_t *) buf
95
- (BOOL) sendrespEmpty: (enum ipc_msg) msgid
97
- (BOOL) sendrespInt: (enum ipc_msg) msgid
100
- (BOOL) sendrespStr: (enum ipc_msg) msgid
102
val: (NSString *) val;
103
- (void) sendrespInfo: (enum ipc_msg) respid
105
torrents: (NSArray *) tors
110
@interface IPCController (Private)
112
- (void) newclient: (NSNotification *) notification;
113
- (void) killclient: (IPCClient *) client;
115
NSUserDefaults * fDefaults;
116
PrefsController * fPrefsController;
121
@implementation IPCController
125
struct sockaddr_un sun;
132
unlink( sun.sun_path );
133
_sock = [[NSSocketPort alloc]
134
initWithProtocolFamily: PF_UNIX
135
socketType: SOCK_STREAM
137
address: [NSData dataWithBytes: &sun
138
length: sizeof(sun)]];
139
_listen = [[NSFileHandle alloc]
140
initWithFileDescriptor: [_sock socket]
141
closeOnDealloc: YES];
142
_funcs = ipc_initmsgs();
143
_clients = [[NSMutableArray alloc] init];
145
/* XXX is this error checking bogus? */
155
ipc_addmsg( _funcs, IPC_MSG_ADDMANYFILES, msg_addold );
156
ipc_addmsg( _funcs, IPC_MSG_ADDONEFILE, msg_addnew );
157
ipc_addmsg( _funcs, IPC_MSG_AUTOMAP, msg_setbool );
158
ipc_addmsg( _funcs, IPC_MSG_AUTOSTART, msg_setbool );
159
ipc_addmsg( _funcs, IPC_MSG_CRYPTO, msg_setstr );
160
ipc_addmsg( _funcs, IPC_MSG_DIR, msg_setstr );
161
ipc_addmsg( _funcs, IPC_MSG_DOWNLIMIT, msg_setint );
162
ipc_addmsg( _funcs, IPC_MSG_GETAUTOMAP, msg_getbool );
163
ipc_addmsg( _funcs, IPC_MSG_GETAUTOSTART, msg_getbool );
164
ipc_addmsg( _funcs, IPC_MSG_GETCRYPTO, msg_getstr );
165
ipc_addmsg( _funcs, IPC_MSG_GETDIR, msg_getstr );
166
ipc_addmsg( _funcs, IPC_MSG_GETDOWNLIMIT, msg_getint );
167
ipc_addmsg( _funcs, IPC_MSG_GETINFO, msg_info );
168
ipc_addmsg( _funcs, IPC_MSG_GETINFOALL, msg_infoall );
169
ipc_addmsg( _funcs, IPC_MSG_GETPEX, msg_getbool );
170
ipc_addmsg( _funcs, IPC_MSG_GETPORT, msg_getint );
171
ipc_addmsg( _funcs, IPC_MSG_GETSTAT, msg_info );
172
ipc_addmsg( _funcs, IPC_MSG_GETSTATALL, msg_infoall );
173
ipc_addmsg( _funcs, IPC_MSG_GETUPLIMIT, msg_getint );
174
ipc_addmsg( _funcs, IPC_MSG_LOOKUP, msg_lookup );
175
ipc_addmsg( _funcs, IPC_MSG_NOOP, msg_empty );
176
ipc_addmsg( _funcs, IPC_MSG_PEX, msg_setbool );
177
ipc_addmsg( _funcs, IPC_MSG_PORT, msg_setint );
178
ipc_addmsg( _funcs, IPC_MSG_QUIT, msg_empty );
179
ipc_addmsg( _funcs, IPC_MSG_REMOVE, msg_action );
180
ipc_addmsg( _funcs, IPC_MSG_REMOVEALL, msg_actionall );
181
ipc_addmsg( _funcs, IPC_MSG_START, msg_action );
182
ipc_addmsg( _funcs, IPC_MSG_STARTALL, msg_actionall );
183
ipc_addmsg( _funcs, IPC_MSG_STOP, msg_action );
184
ipc_addmsg( _funcs, IPC_MSG_STOPALL, msg_actionall );
185
ipc_addmsg( _funcs, IPC_MSG_SUP, msg_sup );
186
ipc_addmsg( _funcs, IPC_MSG_UPLIMIT, msg_setint );
187
ipc_addmsg( _funcs, IPC_MSG_VERIFY, msg_action );
188
ipc_setdefmsg( _funcs, msg_default );
190
[[NSNotificationCenter defaultCenter]
192
selector: @selector(newclient:)
193
name: NSFileHandleConnectionAcceptedNotification
195
[_listen acceptConnectionInBackgroundAndNotify];
202
struct sockaddr_un sun;
204
[[NSNotificationCenter defaultCenter] removeObserver: self];
208
ipc_freemsgs( _funcs );
210
unlink( sun.sun_path );
219
- (void) setDelegate: (id) newdelegate
221
_delegate = newdelegate;
224
- (void) setPrefsController: (id) thePrefsController
226
fPrefsController = thePrefsController;
231
@implementation IPCController (Private)
233
- (void) newclient: (NSNotification *) notification
236
NSFileHandle * handle;
241
info = [notification userInfo];
242
handle = [info objectForKey: NSFileHandleNotificationFileHandleItem];
243
error = [info objectForKey: @"NSFileHandleError"];
247
NSLog( @"Failed to accept IPC socket connection: %@", error );
251
[_listen acceptConnectionInBackgroundAndNotify];
256
client = [[IPCClient alloc]
263
[_clients addObject:client];
267
- (void) killclient: (IPCClient *) client
269
[_clients removeObject: client];
274
@implementation IPCClient
276
- (id) initClient: (IPCController *) controller
277
funcs: (struct ipc_funcs *) funcs
278
handle: (NSFileHandle *) handle
287
_handle = [handle retain];
288
_ipc = ipc_newcon( funcs );
289
_controller = controller;
290
_buf = [[NSMutableData alloc] init];
292
buf = ipc_mkvers( &size, "Transmission Mac OS X " LONG_VERSION_STRING );
293
if( NULL == _ipc || nil == _buf || NULL == buf ||
294
![self sendresp: buf size: size] )
300
[[NSNotificationCenter defaultCenter]
302
selector: @selector(gotdata:)
303
name: NSFileHandleReadCompletionNotification
305
[_handle readInBackgroundAndNotify];
312
[[NSNotificationCenter defaultCenter] removeObserver: self];
319
- (IPCController *) controller
324
- (struct ipc_info *) ipc
329
- (void) gotdata: (NSNotification *) notification
336
info = [notification userInfo];
337
data = [info objectForKey: NSFileHandleNotificationDataItem];
338
error = [info objectForKey: @"NSFileHandleError"];
342
NSLog( @"Failed to read from IPC socket connection: %@", error );
343
[_controller killclient: self];
347
if( nil == data || 0 == [data length] )
349
[_controller killclient: self];
353
[_handle readInBackgroundAndNotify];
354
[_buf appendData: data];
356
if( IPC_MIN_MSG_LEN > [_buf length] )
359
res = ipc_handleMessages( _ipc, [_buf mutableBytes], [_buf length], self );
366
NSLog( @"IPC client has unsupported protocol version" );
369
NSLog( @"IPC protocol parse error" );
372
NSLog( @"IPC parsing failed" );
375
[_controller killclient: self];
380
assert( res <= [_buf length]);
381
if( res < [_buf length])
383
memmove( [_buf mutableBytes], [_buf bytes] + res,
384
[_buf length] - res );
386
[_buf setLength: ([_buf length] - res)];
390
- (BOOL) sendresp: (uint8_t *) buf
395
[_handle writeData: [NSData dataWithBytesNoCopy: buf
400
@catch( NSException * ex )
402
NSLog( @"Failed to write to IPC socket connection" );
407
- (BOOL) sendrespEmpty: (enum ipc_msg) msgid
413
buf = ipc_mkempty( _ipc, &size, msgid, tag );
417
return [self sendresp: buf
421
- (BOOL) sendrespInt: (enum ipc_msg) msgid
428
buf = ipc_mkint( _ipc, &size, msgid, tag, val );
432
return [self sendresp: buf
436
- (BOOL) sendrespStr: (enum ipc_msg) msgid
438
val: (NSString *) val
443
NSMutableData * sucky;
445
if( [val canBeConvertedToEncoding: NSUTF8StringEncoding] )
446
buf = ipc_mkstr( _ipc, &size, msgid, tag,
447
[val cStringUsingEncoding: NSUTF8StringEncoding] );
450
data = [val dataUsingEncoding: NSUTF8StringEncoding
451
allowLossyConversion: YES];
452
/* XXX this sucks, I should add a length argument to ipc_mkstr() */
453
sucky = [NSMutableData dataWithData: data];
454
[sucky appendBytes: "" length: 1];
455
buf = ipc_mkstr( _ipc, &size, msgid, tag, [sucky bytes] );
460
return [self sendresp: buf
464
- (void) sendrespInfo: (enum ipc_msg) respid
466
torrents: (NSArray *) tors
469
benc_val_t packet, * pkinf;
470
NSEnumerator * enumerator;
476
pkinf = ipc_initval( _ipc, respid, tag, &packet, TYPE_LIST );
479
if( tr_bencListReserve( pkinf, [tors count] ) )
481
tr_bencFree( &packet );
485
enumerator = [tors objectEnumerator];
486
while( nil != ( tor = [enumerator nextObject] ) )
488
if( IPC_MSG_INFO == respid )
489
res = ipc_addinfo( pkinf, [tor torrentID], [tor torrentStruct], types );
491
res = ipc_addstat( pkinf, [tor torrentID], [tor torrentStruct], types );
494
tr_bencFree( &packet );
499
buf = ipc_serialize( &packet, &size );
500
tr_bencFree( &packet );
503
[self sendresp: buf size: size ];
507
NSLog( @"Failed to create IPC reply packet" );
508
[_controller killclient: self];
514
void getaddr( struct sockaddr_un * sun )
516
bzero( sun, sizeof *sun );
517
sun->sun_family = AF_LOCAL;
518
tr_buildPath( sun->sun_path, sizeof( sun->sun_path ), tr_getDefaultConfigDir(), "socket", NULL );
521
NSArray * bencarray( benc_val_t * val, int type )
524
NSMutableArray * ret;
527
assert( TYPE_STR == type || TYPE_INT == type );
529
if( NULL == val || TYPE_LIST != val->type )
532
ret = [NSMutableArray arrayWithCapacity: val->val.l.count];
533
for( ii = 0; ii < val->val.l.count; ii++ )
535
item = &val->val.l.vals[ii];
536
if( type != item->type )
538
if( TYPE_STR == type )
540
[ret addObject: [NSString stringWithCString: item->val.s.s
541
encoding: NSUTF8StringEncoding]];
545
[ret addObject: [NSNumber numberWithLongLong: (long long) item->val.i]];
552
void msg_lookup( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
554
IPCClient * client = arg;
555
NSArray * hashes, * tors;
557
hashes = bencarray( val, TYPE_STR );
560
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
564
tors = [[[client controller] delegate] ipcGetTorrentsByHash: hashes];
565
[client sendrespInfo: IPC_MSG_INFO
568
types: IPC_INF_HASH];
571
void msg_info( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
573
IPCClient * client = arg;
575
benc_val_t * typesval;
577
NSArray * ids, * tors;
579
if( NULL == val || TYPE_DICT != val->type )
582
typesval = tr_bencDictFind( val, "type" );
583
if( NULL == typesval || TYPE_LIST != typesval->type ||
584
nil == ( ids = bencarray( tr_bencDictFind( val, "id" ), TYPE_INT ) ) )
587
respid = ( IPC_MSG_GETINFO == msgid ? IPC_MSG_INFO : IPC_MSG_STAT );
588
tors = [[[client controller] delegate] ipcGetTorrentsByID: ids];
589
types = ipc_infotypes( respid, typesval );
590
[client sendrespInfo: respid tag: tag torrents: tors types: types];
594
NSLog( @"Got bad IPC packet" );
595
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
598
void msg_infoall( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
600
IPCClient * client = arg;
605
if( NULL == val || TYPE_LIST != val->type )
607
NSLog( @"Got bad IPC packet" );
608
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
612
respid = ( IPC_MSG_GETINFOALL == msgid ? IPC_MSG_INFO : IPC_MSG_STAT );
613
tors = [[[client controller] delegate] ipcGetTorrentsByID: nil];
614
types = ipc_infotypes( respid, val );
615
[client sendrespInfo: respid tag: tag torrents: tors types: types];
618
void msg_action( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
620
IPCClient * client = arg;
622
NSArray * ids, * tors;
625
ids = bencarray( val, TYPE_INT );
628
NSLog( @"Got bad IPC packet" );
629
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
633
delegate = [[client controller] delegate];
634
tors = [delegate ipcGetTorrentsByID: ids];
638
res = [delegate ipcRemoveTorrents: tors];
641
res = [delegate ipcStartTorrents: tors];
644
res = [delegate ipcStopTorrents: tors];
647
res = [delegate ipcVerifyTorrents: tors];
655
[client sendrespEmpty: IPC_MSG_OK tag: tag];
657
[client sendrespEmpty: IPC_MSG_FAIL tag: tag];
660
void msg_actionall( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
662
IPCClient * client = arg;
667
delegate = [[client controller] delegate];
668
tors = [delegate ipcGetTorrentsByID: nil];
671
case IPC_MSG_REMOVEALL:
672
res = [delegate ipcRemoveTorrents: tors];
674
case IPC_MSG_STARTALL:
675
res = [delegate ipcStartTorrents: tors];
677
case IPC_MSG_STOPALL:
678
res = [delegate ipcStopTorrents: tors];
686
[client sendrespEmpty: IPC_MSG_OK tag: tag];
688
[client sendrespEmpty: IPC_MSG_FAIL tag: tag];
691
void msg_addold( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
693
IPCClient * client = arg;
696
paths = bencarray( val, TYPE_STR );
699
NSLog( @"Got bad IPC packet" );
700
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
704
/* XXX should send back info message with torrent IDs */
705
if( [[[client controller] delegate] ipcAddTorrents: paths] )
706
[client sendrespEmpty: IPC_MSG_OK tag: tag];
708
[client sendrespEmpty: IPC_MSG_FAIL tag: tag];
711
void msg_addnew( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
713
IPCClient * client = arg;
714
benc_val_t * fileval, * dataval, * dirval, * autoval;
715
NSString * file, * dir;
719
if( NULL == val || TYPE_DICT != val->type )
722
fileval = tr_bencDictFind( val, "file" );
723
dataval = tr_bencDictFind( val, "data" );
724
dirval = tr_bencDictFind( val, "directory" );
725
autoval = tr_bencDictFind( val, "autostart" );
726
if( ( ( NULL == fileval || TYPE_STR != fileval->type ) &&
727
( NULL == dataval || TYPE_STR != dataval->type ) ) ||
728
( ( NULL != fileval && TYPE_STR == fileval->type ) &&
729
( NULL != dataval && TYPE_STR == dataval->type ) ) ||
730
( NULL != dirval && TYPE_STR != dirval->type ) ||
731
( NULL != autoval && TYPE_INT != autoval->type ) )
734
dir = ( NULL == dirval ? nil :
735
[NSString stringWithCString: dirval->val.s.s
736
encoding: NSUTF8StringEncoding] );
737
autobool = ( NULL == autoval || 0 == autoval->val.i ? NO : YES );
739
if( NULL != fileval )
741
file = [NSString stringWithCString: fileval->val.s.s
742
encoding: NSUTF8StringEncoding];
743
if( NULL == autoval )
744
res = [[[client controller] delegate]
745
ipcAddTorrentFile: file
748
res = [[[client controller] delegate]
749
ipcAddTorrentFileAutostart: file
751
autostart: autobool];
755
data = [NSData dataWithBytes: dataval->val.s.s
756
length: dataval->val.s.i];
757
if( NULL == autoval )
758
res = [[[client controller] delegate]
759
ipcAddTorrentData: data
762
res = [[[client controller] delegate]
763
ipcAddTorrentDataAutostart: data
765
autostart: autobool];
768
/* XXX should send back info message with torrent ID */
770
[client sendrespEmpty: IPC_MSG_OK tag: tag];
772
[client sendrespEmpty: IPC_MSG_FAIL tag: tag];
776
NSLog( @"Got bad IPC packet" );
777
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
780
void msg_getbool( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
782
IPCClient * client = arg;
784
fDefaults = [NSUserDefaults standardUserDefaults];
788
case IPC_MSG_GETAUTOMAP:
789
[client sendrespInt:IPC_MSG_AUTOMAP tag:tag val:[fDefaults boolForKey:@"NatTraversal"]];
791
case IPC_MSG_GETAUTOSTART:
792
[client sendrespInt:IPC_MSG_AUTOSTART tag:tag val:[fDefaults boolForKey:@"AutoStartDownload"]];
795
[client sendrespInt:IPC_MSG_PEX tag:tag val:[fDefaults boolForKey:@"PEXGlobal"]];
803
void msg_getint( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
805
IPCClient * client = arg;
807
fDefaults = [NSUserDefaults standardUserDefaults];
813
case IPC_MSG_GETDOWNLIMIT:
814
if ( [fDefaults boolForKey:@"CheckDownload"] )
815
theValue = [fDefaults integerForKey:@"DownloadLimit"];
818
[client sendrespInt:IPC_MSG_DOWNLIMIT tag:tag val:theValue];
820
case IPC_MSG_GETPORT:
821
[client sendrespInt:IPC_MSG_PORT tag:tag val:[fDefaults integerForKey:@"BindPort"]];
823
case IPC_MSG_GETUPLIMIT:
824
if ( [fDefaults boolForKey:@"CheckUpload"] )
825
theValue = [fDefaults integerForKey:@"UploadLimit"];
828
[client sendrespInt:IPC_MSG_UPLIMIT tag:tag val:theValue];
836
void msg_getstr( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
838
IPCClient * client = arg;
839
NSString * cryptoValue;
841
fDefaults = [NSUserDefaults standardUserDefaults];
847
[client sendrespStr:IPC_MSG_DIR tag:tag val:[fDefaults stringForKey:@"DownloadFolder"]];
850
case IPC_MSG_GETCRYPTO:
851
if ([fDefaults boolForKey: @"EncryptionPrefer"])
852
if ([fDefaults boolForKey: @"EncryptionRequire"])
853
cryptoValue = @"required";
855
cryptoValue = @"preferred";
857
cryptoValue = @"plaintext";
859
[client sendrespStr:IPC_MSG_CRYPTO tag:tag val:cryptoValue];
868
void msg_setbool( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
870
IPCClient * client = arg;
872
if( NULL == val || TYPE_INT != val->type )
874
NSLog( @"Got bad IPC packet" );
875
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
879
fDefaults = [NSUserDefaults standardUserDefaults];
883
case IPC_MSG_AUTOMAP:
884
[fDefaults setBool:(bool)val->val.i forKey:@"NatTraversal"];
885
[fPrefsController setNat:nil];
886
[client sendrespEmpty:IPC_MSG_OK tag:tag];
888
case IPC_MSG_AUTOSTART:
889
[fDefaults setBool:(bool)val->val.i forKey:@"AutoStartDownload"];
890
[client sendrespEmpty:IPC_MSG_OK tag:tag];
893
[fDefaults setBool:(bool)val->val.i forKey:@"PEXGlobal"];
894
[fPrefsController setPEX:nil];
895
[client sendrespEmpty: IPC_MSG_OK tag: tag];
903
void msg_setint( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
905
IPCClient * client = arg;
907
if( NULL == val || TYPE_INT != val->type )
909
NSLog( @"Got bad IPC packet" );
910
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
914
fDefaults = [NSUserDefaults standardUserDefaults];
917
case IPC_MSG_DOWNLIMIT:
918
if ( val->val.i < 0 )
919
[fDefaults setBool:NO forKey:@"CheckDownload"];
922
[fDefaults setBool:YES forKey:@"CheckDownload"];
923
[fDefaults setInteger:val->val.i forKey:@"DownloadLimit"];
925
[fPrefsController updateLimitFields];
926
[fPrefsController applySpeedSettings: nil];
929
[fPrefsController setPort:[NSNumber numberWithInt:val->val.i]];
930
[fPrefsController updatePortField];
932
case IPC_MSG_UPLIMIT:
933
if ( val->val.i < 0 )
934
[fDefaults setBool:NO forKey:@"CheckUpload"];
937
[fDefaults setBool:YES forKey:@"CheckUpload"];
938
[fDefaults setInteger:val->val.i forKey:@"UploadLimit"];
940
[fPrefsController updateLimitFields];
941
[fPrefsController applySpeedSettings: nil];
947
[client sendrespEmpty:IPC_MSG_OK tag:tag];
950
void msg_setstr( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
952
IPCClient * client = arg;
954
if( NULL == val || TYPE_STR != val->type )
956
NSLog( @"Got bad IPC packet" );
957
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
961
fDefaults = [NSUserDefaults standardUserDefaults];
966
[fDefaults setObject:[NSString stringWithCString: val->val.s.s] forKey:@"DownloadFolder"];
967
[fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
968
[client sendrespEmpty: IPC_MSG_OK tag: tag];
972
if(!strcasecmp(val->val.s.s, "required"))
974
[fDefaults setBool:YES forKey: @"EncryptionPrefer"];
975
[fDefaults setBool:YES forKey: @"EncryptionRequire"];
978
else if(!strcasecmp(val->val.s.s, "preferred"))
980
[fDefaults setBool:YES forKey: @"EncryptionPrefer"];
981
[fDefaults setBool:NO forKey: @"EncryptionRequire"];
984
else if(!strcasecmp(val->val.s.s, "plaintext"))
986
[fDefaults setBool:NO forKey: @"EncryptionPrefer"];
987
[fDefaults setBool:NO forKey: @"EncryptionRequire"];
989
[fPrefsController setEncryptionMode:nil];
990
[client sendrespEmpty: IPC_MSG_OK tag: tag];
999
void msg_empty( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
1001
IPCClient * client = arg;
1006
[client sendrespEmpty: IPC_MSG_OK tag: tag];
1009
[[[client controller] delegate] ipcQuit];
1010
[client sendrespEmpty: IPC_MSG_OK tag: tag];
1018
void msg_sup( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
1020
IPCClient * client = arg;
1021
benc_val_t packet, * pkval, * name;
1022
struct ipc_info * ipc;
1028
if( NULL == val || TYPE_LIST != val->type )
1032
pkval = ipc_initval( ipc, IPC_MSG_SUP, tag, &packet, TYPE_LIST );
1035
if( tr_bencListReserve( pkval, val->val.l.count ) )
1037
tr_bencFree( &packet );
1041
for( ii = 0; val->val.l.count > ii; ii++ )
1043
name = &val->val.l.vals[ii];
1044
if( NULL == name || TYPE_STR != name->type )
1046
found = ipc_msgid( ipc, name->val.s.s );
1047
if( IPC__MSG_COUNT == found || !ipc_ishandled( ipc, found ) )
1051
tr_bencInitStr( tr_bencListAdd( pkval ),
1052
name->val.s.s, name->val.s.i, 1 );
1055
buf = ipc_serialize( &packet, &size );
1056
tr_bencFree( &packet );
1059
[client sendresp: buf size: size ];
1063
NSLog( @"Got bad IPC packet" );
1064
[client sendrespEmpty: IPC_MSG_BAD tag: tag];
1068
NSLog( @"Failed to create IPC reply packet" );
1069
[[client controller] killclient: client];
1072
void msg_default( enum ipc_msg msgid, benc_val_t * val, int64_t tag, void * arg )
1074
IPCClient * client = arg;
1076
[client sendrespEmpty: IPC_MSG_NOTSUP tag: tag];