Skip to content

Commit 70d749d

Browse files
committed
Add LaunchDaemon for turbo boost switcher.
1 parent 4b2e923 commit 70d749d

File tree

10 files changed

+219
-132
lines changed

10 files changed

+219
-132
lines changed

Classes/FanControl.m

Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#import "FanControl.h"
2626
#import <Sparkle/SUUpdater.h>
2727
#import "Privilege.h"
28+
#import "tb-switcher.h"
2829

2930
@interface FanControl ()
3031
+ (void)copyMachinesIfNecessary;
@@ -39,9 +40,6 @@ @implementation FanControl
3940
// Number of fans reported by the hardware.
4041
int g_numFans = 0;
4142

42-
NSString *moduleDstPath =
43-
@"/Library/Application Support/smcFanControl2/DisableTurboBoost.64bits.kext";
44-
4543
NSUserDefaults *defaults;
4644

4745
#pragma mark **Init-Methods**
@@ -242,23 +240,14 @@ - (void)displayDonationMessage {
242240
}
243241
}
244242

245-
- (void)enableTurboBoost {
246-
[Privilege runTaskAsAdmin:@"/sbin/kextunload" andArgs:@[moduleDstPath]];
247-
}
248-
249-
- (void)disableTurboBoost {
250-
NSArray *argsArrayLoadKext = @[@"-v", moduleDstPath];
251-
[Privilege runTaskAsAdmin:@"/usr/bin/kextutil" andArgs:argsArrayLoadKext];
252-
}
253-
254243
- (void)applyTurboBoost:(id)sender {
255244
NSControlStateValue state = [sender state];
256245
if (state == NSOffState) {
257246
[sender setState:NSOnState];
258-
[self enableTurboBoost];
247+
enable_tb();
259248
} else {
260249
[sender setState:NSOffState];
261-
[self disableTurboBoost];
250+
disable_tb();
262251
}
263252
}
264253

@@ -278,7 +267,7 @@ - (void)init_statusitem {
278267
[theMenu insertItem:s_menus[i] atIndex:i];
279268
};
280269

281-
[self disableTurboBoost];
270+
disable_tb();
282271
NSMenuItem *fan1Item = [theMenu itemWithTitle:@"Fan: 1"];
283272
int fan1ItemIdx = [theMenu indexOfItem:fan1Item];
284273
NSMenuItem *turboBoostItem = [[NSMenuItem alloc]
@@ -296,7 +285,6 @@ - (void)init_statusitem {
296285
[theMenu setDelegate:self];
297286
}
298287

299-
300288
#pragma mark **Action-Methods**
301289

302290
- (IBAction)loginItem:(id)sender {
@@ -617,7 +605,7 @@ - (void)terminate:(id)sender {
617605
[_readTimer invalidate];
618606
[pw deregisterForSleepWakeNotification];
619607
[pw deregisterForPowerChange];
620-
[self enableTurboBoost];
608+
enable_tb();
621609
[[NSApplication sharedApplication] terminate:self];
622610
}
623611

@@ -750,9 +738,9 @@ - (void)systemDidWakeFromSleep:(id)sender {
750738
[self apply_settings:nil controllerindex:[[defaults objectForKey:PREF_SELECTION_DEFAULT] intValue]];
751739

752740
if ([[theMenu itemWithTitle:@"Turbo Boost"] state] == NSOnState) {
753-
[self enableTurboBoost];
741+
enable_tb();
754742
} else {
755-
[self disableTurboBoost];
743+
disable_tb();
756744
}
757745
}
758746

@@ -866,46 +854,85 @@ - (void)setStartAtLogin:(BOOL)enabled {
866854

867855
#pragma mark **SMC-Binary Owner/Right Check**
868856

857+
+ (void) ensureService {
858+
NSString *tool = @"/bin/launchctl";
859+
NSArray *argsArray = @[@"load", @LAUNCH_DAEMON_PLIST_PATH];
860+
NSString *output;
861+
NSString *error;
862+
863+
if([Privilege runProcessAsAdministrator:tool withArguments:argsArray output:&output errorDescription:&error]){
864+
NSLog(@"output: %@", output);
865+
}else{
866+
NSLog(@"error: %@", error);
867+
}
868+
}
869+
869870
//TODO: It looks like this function is called inefficiently.
870871
//call smc binary with sudo rights and apply
871872
+ (void)setRights {
872-
NSString *smcpath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
873-
NSFileManager *fmanage = [NSFileManager defaultManager];
874-
NSDictionary *fdic = [fmanage attributesOfItemAtPath:smcpath error:nil];
875-
if ([[fdic valueForKey:@"NSFileOwnerAccountName"] isEqualToString:@"root"] && [[fdic valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:@"admin"] && ([[fdic valueForKey:@"NSFilePosixPermissions"] intValue] == 3437)) {
873+
NSString *smcPath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
874+
NSFileManager *fManger = [NSFileManager defaultManager];
875+
NSDictionary *fdic = [fManger attributesOfItemAtPath:smcPath error:nil];
876+
if ([[fdic valueForKey:@"NSFileOwnerAccountName"] isEqualToString:@"root"] &&
877+
[[fdic valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:@"admin"] &&
878+
([[fdic valueForKey:@"NSFilePosixPermissions"] intValue] == 3437)) {
876879
// If the SMC binary has already been modified to run as root, then do nothing.
877880

878881
} else {
879882
NSString *tool = @"/usr/sbin/chown";
880-
NSArray *argsArray = @[@"root:admin", smcpath];
883+
NSArray *argsArray = @[@"root:admin", smcPath];
881884
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
882885

883886
//second call for suid-bit
884887
tool = @"/bin/chmod";
885-
argsArray = @[@"6555", smcpath];
888+
argsArray = @[@"6555", smcPath];
886889
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
887890
}
888891

889-
890892
NSString *modulePath = [[NSBundle mainBundle] pathForResource:@"DisableTurboBoost.64bits" ofType:@"kext"];
891-
NSFileManager *fileManager = [NSFileManager defaultManager];
892-
if (![fileManager fileExistsAtPath:moduleDstPath]) {
893+
if (![fManger fileExistsAtPath:@MODULE_PATH]) {
893894
NSString *tool = @"/bin/sh";
894-
NSArray *argsArray = @[@"-c", [NSString stringWithFormat:@"mkdir -p \"%@\" && cp -Rf \"%@/\" \"%@\"", moduleDstPath, modulePath, moduleDstPath]];
895+
NSArray *argsArray = @[@"-c", [NSString stringWithFormat:@"mkdir -p \"%@\" && cp -Rf \"%@/\" \"%@\"",
896+
@MODULE_PATH, modulePath, @MODULE_PATH]];
895897
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
898+
[self setOwnAndMod:@MODULE_PATH user:@"root" group:@"wheel" mod:@"755"];
896899
}
897-
NSDictionary *fdicKext = [fmanage attributesOfItemAtPath:moduleDstPath error:nil];
898-
if ([[fdicKext valueForKey:@"NSFileOwnerAccountName"] isEqualToString:@"root"] && [[fdicKext valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:@"wheel"]) {
899-
// If the SMC binary has already been modified to run as root, then do nothing.
900+
901+
NSString *binPath = [[NSBundle mainBundle] pathForResource:@"tb-switcher" ofType:@""];
902+
if (![fManger fileExistsAtPath:@TB_SWITCHER_BIN_PATH]) {
903+
NSString *tool = @"/bin/sh";
904+
NSArray *argsArray = @[@"-c", [NSString stringWithFormat:@"cp -f \"%@\" \"%@\"",
905+
binPath, @TB_SWITCHER_BIN_PATH]];
906+
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
907+
[self setOwnAndMod:@TB_SWITCHER_BIN_PATH user:@"root" group:@"wheel" mod:@"755"];
908+
}
909+
910+
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"com.tinkernels.tb-switcher" ofType:@"plist"];
911+
if (![fManger fileExistsAtPath:@LAUNCH_DAEMON_PLIST_PATH]) {
912+
NSString *tool = @"/bin/sh";
913+
NSArray *argsArray = @[@"-c", [NSString stringWithFormat:@"cp -f \"%@\" \"%@\"",
914+
plistPath, @LAUNCH_DAEMON_PLIST_PATH]];
915+
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
916+
917+
[self setOwnAndMod:@LAUNCH_DAEMON_PLIST_PATH user:@"root" group:@"wheel" mod:@"644"];
918+
[self ensureService];
919+
}
920+
}
921+
922+
+ (void)setOwnAndMod:(NSString *)path user:(NSString *)user group:(NSString *)group mod:(NSString *)mod {
923+
NSFileManager *fManger = [NSFileManager defaultManager];
924+
NSDictionary *fdict = [fManger attributesOfItemAtPath:path error:nil];
925+
if ([[fdict valueForKey:@"NSFileOwnerAccountName"] isEqualToString:user] &&
926+
[[fdict valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:group]) {
900927

901928
} else {
902929
NSString *tool = @"/usr/sbin/chown";
903-
NSArray *argsArray = @[@"-R", @"root:wheel", moduleDstPath];
930+
NSArray *argsArray = @[@"-R", [NSString stringWithFormat:@"%@:%@", user, group], path];
904931

905932
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
906933

907934
tool = @"/bin/chmod";
908-
argsArray = @[@"-Rf", @"755", moduleDstPath];
935+
argsArray = @[@"-Rf", mod, path];
909936
[Privilege runTaskAsAdmin:tool andArgs:argsArray];
910937
}
911938
}

Classes/Privilege.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
+ (AuthorizationRef)Get;
1515

1616
+ (BOOL)runTaskAsAdmin:(NSString *)path andArgs:(NSArray *)args;
17+
18+
+ (BOOL) runProcessAsAdministrator:(NSString*)binPath
19+
withArguments:(NSArray *)arguments
20+
output:(NSString **)output
21+
errorDescription:(NSString **)errorDescription;
1722
@end
1823

1924
#endif /* Privilege_h */

Classes/Privilege.m

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ + (AuthorizationRef)Get {
1717
AuthorizationItem gencitem = {"system.privilege.admin", 0, NULL, 0};
1818
AuthorizationRights gencright = {1, &gencitem};
1919
int flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;
20-
OSStatus status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
20+
OSStatus status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, (AuthorizationFlags) flags, &authorizationRef);
2121

2222
if (status != errAuthorizationSuccess) {
2323
NSLog(@"Copy Rights Unsuccessful: %d", status);
@@ -27,6 +27,50 @@ + (AuthorizationRef)Get {
2727
return authorizationRef;
2828
}
2929

30+
+ (BOOL) runProcessAsAdministrator:(NSString*)binPath
31+
withArguments:(NSArray *)arguments
32+
output:(NSString **)output
33+
errorDescription:(NSString **)errorDescription {
34+
35+
NSString * allArgs = [arguments componentsJoinedByString:@" "];
36+
NSString * fullScript = [NSString stringWithFormat:@"%@ %@", binPath, allArgs];
37+
38+
NSDictionary *errorInfo = [NSDictionary new];
39+
NSString *script = [NSString stringWithFormat:@"do shell script \"%@\" with administrator privileges", fullScript];
40+
41+
NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:script];
42+
NSAppleEventDescriptor * eventResult = [appleScript executeAndReturnError:&errorInfo];
43+
44+
// Check errorInfo
45+
if (! eventResult)
46+
{
47+
// Describe common errors
48+
*errorDescription = nil;
49+
if ([errorInfo valueForKey:NSAppleScriptErrorNumber])
50+
{
51+
NSNumber * errorNumber = (NSNumber *)[errorInfo valueForKey:NSAppleScriptErrorNumber];
52+
if ([errorNumber intValue] == -128)
53+
*errorDescription = @"The administrator password is required to do this.";
54+
}
55+
56+
// Set error message from provided message
57+
if (*errorDescription == nil)
58+
{
59+
if ([errorInfo valueForKey:NSAppleScriptErrorMessage])
60+
*errorDescription = (NSString *)[errorInfo valueForKey:NSAppleScriptErrorMessage];
61+
}
62+
63+
return NO;
64+
}
65+
else
66+
{
67+
// Set output to the AppleScript's output
68+
*output = [eventResult stringValue];
69+
70+
return YES;
71+
}
72+
}
73+
3074
+ (BOOL)runTaskAsAdmin:(NSString *)path andArgs:(NSArray *)args {
3175

3276
if ([self Get] == nil) {
Binary file not shown.
Binary file not shown.

Ressources/com.tinkernels.tb-switcher.plist

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
<plist version="1.0">
44
<dict>
55
<key>Label</key>
6-
<string>com.github.tinkernels.tb-switcher.plist</string>
6+
<string>com.tinkernels.tb-switcher.plist</string>
77
<key>ProgramArguments</key>
88
<array>
9-
<string>/Library/Application Support/smcFanControl2/tb-switcher</string>
10-
<string>-l</string>
11-
<string>/var/run/tb-switcher.socket=</string>
9+
<string>/bin/sh</string>
10+
<string>-c</string>
11+
<string>"/Library/Application Support/smcFanControl2/tb-switcher"</string>
1212
</array>
1313
<key>RunAtLoad</key>
1414
<true/>

smcFanControl.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
8985F1590ADD0B5500F9EC46 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8985F1580ADD0B5500F9EC46 /* Security.framework */; };
2626
8987FBD20B878B3900A5ED8E /* smc.png in Resources */ = {isa = PBXBuildFile; fileRef = 8987FBD00B878B3900A5ED8E /* smc.png */; };
2727
89949E8D0AEEA37700077E93 /* Power.m in Sources */ = {isa = PBXBuildFile; fileRef = 89949E8C0AEEA37700077E93 /* Power.m */; };
28-
899D59DC15E1CF60003E322D /* smc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8924ECEE15AC96E70031730C /* smc */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
2928
899D59DD15E1CFFF003E322D /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 895BDA390B8F8F42003CD894 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
3029
89B243200B7E351000CAD103 /* smcfancontrol_v2.icns in Resources */ = {isa = PBXBuildFile; fileRef = 89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */; };
3130
89E7D3650ADE819B000F67AB /* Machines.plist in Resources */ = {isa = PBXBuildFile; fileRef = 89E7D3640ADE819B000F67AB /* Machines.plist */; };
@@ -37,8 +36,9 @@
3736
AFD3F221247B41B30086D29E /* DisableTurboBoost.32bits.kext in Resources */ = {isa = PBXBuildFile; fileRef = AFD3F220247B41B30086D29E /* DisableTurboBoost.32bits.kext */; };
3837
AFD3F223247B41BC0086D29E /* DisableTurboBoost.64bits.kext in Resources */ = {isa = PBXBuildFile; fileRef = AFD3F222247B41BB0086D29E /* DisableTurboBoost.64bits.kext */; };
3938
AFD3F22C247B58CB0086D29E /* Privilege.m in Sources */ = {isa = PBXBuildFile; fileRef = AFD3F22B247B58CB0086D29E /* Privilege.m */; };
39+
AFED6518247E2E4800BEDCB5 /* smc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8924ECEE15AC96E70031730C /* smc */; };
40+
AFED6519247E2E4B00BEDCB5 /* tb-switcher in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFF28EC8247D987C00B47C72 /* tb-switcher */; };
4041
AFF28ECB247D987C00B47C72 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF28ECA247D987C00B47C72 /* main.c */; };
41-
AFF28ECF247D9A3B00B47C72 /* tb-switcher in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFF28EC8247D987C00B47C72 /* tb-switcher */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
4242
AFF28ED2247D9B0600B47C72 /* com.tinkernels.tb-switcher.plist in Resources */ = {isa = PBXBuildFile; fileRef = AFF28ED0247D9A9500B47C72 /* com.tinkernels.tb-switcher.plist */; };
4343
AFF28ED5247DAE4F00B47C72 /* tb-switcher_s.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF28ED4247DAE4F00B47C72 /* tb-switcher_s.c */; };
4444
AFF28ED7247DAE7A00B47C72 /* tb-switcher_c.c in Sources */ = {isa = PBXBuildFile; fileRef = AFF28ED6247DAE7A00B47C72 /* tb-switcher_c.c */; };
@@ -61,8 +61,8 @@
6161
dstPath = "";
6262
dstSubfolderSpec = 7;
6363
files = (
64-
AFF28ECF247D9A3B00B47C72 /* tb-switcher in CopyFiles */,
65-
899D59DC15E1CF60003E322D /* smc in CopyFiles */,
64+
AFED6519247E2E4B00BEDCB5 /* tb-switcher in CopyFiles */,
65+
AFED6518247E2E4800BEDCB5 /* smc in CopyFiles */,
6666
);
6767
runOnlyForDeploymentPostprocessing = 0;
6868
};

tb-switcher/tb-switcher.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010

1111
#define ENABLE_TB_CMD "ENABLE_TB"
1212
#define DISABLE_TB_CMD "DISABLE_TB"
13-
#define SOCK_PATH "/var/run/tb-switcher.socket"
13+
#define MODULE_PATH "/Library/Application Support/smcFanControl2/DisableTurboBoost.64bits.kext"
14+
#define LAUNCH_DAEMON_PLIST_PATH "/Library/LaunchDaemons/com.tinkernels.tb-switcher.plist"
15+
#define TB_SWITCHER_BIN_PATH "/Library/Application Support/smcFanControl2/tb-switcher"
16+
#define SOCK_ADDR "127.0.0.1"
17+
#define SOCK_PORT 11532
18+
#define MAX_LEN 1024
1419

1520
int start_server(void);
1621

0 commit comments

Comments
 (0)