mirror of
https://github.com/objective-see/KnockKnock.git
synced 2026-03-22 06:52:25 +00:00
v2.0.1
-try/catch around JSON output -switched to 'UUIDString' for <10.10 compatibility -update check!
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#import "ItemTableController.h"
|
||||
#import "AboutWindowController.h"
|
||||
#import "PrefsWindowController.h"
|
||||
#import "UpdateWindowController.h"
|
||||
#import "CategoryTableController.h"
|
||||
#import "ResultsWindowController.h"
|
||||
|
||||
@@ -107,6 +108,9 @@ extern Filter* itemFilter;
|
||||
//constraint for status text
|
||||
@property (weak) IBOutlet NSLayoutConstraint *statusTextConstraint;
|
||||
|
||||
//update window controller
|
||||
@property(nonatomic, retain)UpdateWindowController* updateWindowController;
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
|
||||
+85
-5
@@ -4,6 +4,7 @@
|
||||
//
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Update.h"
|
||||
#import "Utilities.h"
|
||||
#import "PluginBase.h"
|
||||
#import "AppDelegate.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
@synthesize aboutWindowController;
|
||||
@synthesize prefsWindowController;
|
||||
@synthesize showPreferencesButton;
|
||||
@synthesize updateWindowController;
|
||||
@synthesize categoryTableController;
|
||||
@synthesize resultsWindowController;
|
||||
|
||||
@@ -83,13 +85,9 @@
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//kick off thread to begin enumerating shared objects
|
||||
// ->this takes awhile, so do it now/first!
|
||||
[sharedItemEnumerator start];
|
||||
|
||||
//load defaults
|
||||
defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
|
||||
//first time run?
|
||||
// show thanks to friends window!
|
||||
if(YES != [defaults boolForKey:NOT_FIRST_TIME])
|
||||
@@ -107,7 +105,19 @@
|
||||
[self.friends close];
|
||||
});
|
||||
}
|
||||
|
||||
//check for update
|
||||
// unless user has turn off via prefs
|
||||
if(YES != [defaults boolForKey:PREF_DISABLE_UPDATE_CHECK])
|
||||
{
|
||||
//check
|
||||
[self check4Update];
|
||||
}
|
||||
|
||||
//kick off thread to begin enumerating shared objects
|
||||
// ->this takes awhile, so do it now/first!
|
||||
[sharedItemEnumerator start];
|
||||
|
||||
//instantiate all plugins objects
|
||||
self.plugins = [self instantiatePlugins];
|
||||
|
||||
@@ -1291,4 +1301,74 @@
|
||||
return bEnabled;
|
||||
}
|
||||
|
||||
//call into Update obj
|
||||
// check to see if there an update?
|
||||
-(void)check4Update
|
||||
{
|
||||
//update obj
|
||||
Update* update = nil;
|
||||
|
||||
//init update obj
|
||||
update = [[Update alloc] init];
|
||||
|
||||
//check for update
|
||||
// ->'updateResponse newVersion:' method will be called when check is done
|
||||
[update checkForUpdate:^(NSUInteger result, NSString* newVersion) {
|
||||
|
||||
//process response
|
||||
[self updateResponse:result newVersion:newVersion];
|
||||
|
||||
}];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//process update response
|
||||
// error, no update, update/new version
|
||||
-(void)updateResponse:(NSInteger)result newVersion:(NSString*)newVersion
|
||||
{
|
||||
//handle response
|
||||
// new version, show popup
|
||||
switch (result)
|
||||
{
|
||||
//error
|
||||
case -1:
|
||||
|
||||
break;
|
||||
|
||||
//no updates
|
||||
case 0:
|
||||
|
||||
break;
|
||||
|
||||
//new version
|
||||
case 1:
|
||||
|
||||
//alloc update window
|
||||
updateWindowController = [[UpdateWindowController alloc] initWithWindowNibName:@"UpdateWindow"];
|
||||
|
||||
//configure
|
||||
[self.updateWindowController configure:[NSString stringWithFormat:@"a new version (%@) is available!", newVersion] buttonTitle:@"Update"];
|
||||
|
||||
//center window
|
||||
[[self.updateWindowController window] center];
|
||||
|
||||
//show it
|
||||
[self.updateWindowController showWindow:self];
|
||||
|
||||
//invoke function in background that will make window modal
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
//make modal
|
||||
makeModal(self.updateWindowController);
|
||||
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -42,6 +42,10 @@ static NSString * const SUPPORTED_PLUGINS[] = {@"AuthorizationPlugins", @"Browse
|
||||
// ->save output
|
||||
#define PREF_SAVE_OUTPUT @"saveOutput"
|
||||
|
||||
//prefs
|
||||
// ->no updates
|
||||
#define PREF_DISABLE_UPDATE_CHECK @"noUpdateCheck"
|
||||
|
||||
//disabled state
|
||||
#define STATE_DISABLED 0
|
||||
|
||||
@@ -279,4 +283,7 @@ enum Signer{None, Apple, AppStore, DevID, AdHoc};
|
||||
//product url
|
||||
#define PRODUCT_URL @"https://objective-see.com/products/knockknock.html"
|
||||
|
||||
//product version url
|
||||
#define PRODUCT_VERSIONS_URL @"https://objective-see.com/products.json"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
CD24F077219DF3DB0081B0E5 /* Signing.m in Sources */ = {isa = PBXBuildFile; fileRef = CD24F075219DF3DA0081B0E5 /* Signing.m */; };
|
||||
CD2B613320675EEC00BF72E9 /* EventRules.m in Sources */ = {isa = PBXBuildFile; fileRef = CD2B611220675EEB00BF72E9 /* EventRules.m */; };
|
||||
CD2B61442067656200BF72E9 /* eventRulesIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD2B61432067656200BF72E9 /* eventRulesIcon.png */; };
|
||||
CD2F219F21A8A73100F67A83 /* Update.m in Sources */ = {isa = PBXBuildFile; fileRef = CD2F219E21A8A73100F67A83 /* Update.m */; };
|
||||
CD2F21A121A8A7D100F67A83 /* UpdateWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD2F21A021A8A7D000F67A83 /* UpdateWindow.xib */; };
|
||||
CD2F21A421A8A7E300F67A83 /* UpdateWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD2F21A321A8A7E300F67A83 /* UpdateWindowController.m */; };
|
||||
CD585494219FE61D00A438B0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD585493219FE61D00A438B0 /* Assets.xcassets */; };
|
||||
CD5854D321A5FADD00A438B0 /* patrons.txt in Resources */ = {isa = PBXBuildFile; fileRef = CD5854D221A5FADD00A438B0 /* patrons.txt */; };
|
||||
CD5854D521A60B1000A438B0 /* PlistWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD5854D421A60B0F00A438B0 /* PlistWindow.xib */; };
|
||||
@@ -172,6 +175,11 @@
|
||||
CD2B611220675EEB00BF72E9 /* EventRules.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EventRules.m; path = Plugins/EventRules.m; sourceTree = "<group>"; };
|
||||
CD2B611320675EEB00BF72E9 /* EventRules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EventRules.h; path = Plugins/EventRules.h; sourceTree = "<group>"; };
|
||||
CD2B61432067656200BF72E9 /* eventRulesIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = eventRulesIcon.png; path = images/eventRulesIcon.png; sourceTree = SOURCE_ROOT; };
|
||||
CD2F219D21A8A73000F67A83 /* Update.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Update.h; sourceTree = SOURCE_ROOT; };
|
||||
CD2F219E21A8A73100F67A83 /* Update.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Update.m; sourceTree = SOURCE_ROOT; };
|
||||
CD2F21A021A8A7D000F67A83 /* UpdateWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = UpdateWindow.xib; path = UI/UpdateWindow.xib; sourceTree = "<group>"; };
|
||||
CD2F21A221A8A7E300F67A83 /* UpdateWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateWindowController.h; sourceTree = "<group>"; };
|
||||
CD2F21A321A8A7E300F67A83 /* UpdateWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateWindowController.m; sourceTree = "<group>"; };
|
||||
CD585493219FE61D00A438B0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = SOURCE_ROOT; };
|
||||
CD5854D221A5FADD00A438B0 /* patrons.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = patrons.txt; sourceTree = SOURCE_ROOT; };
|
||||
CD5854D421A60B0F00A438B0 /* PlistWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = PlistWindow.xib; path = UI/PlistWindow.xib; sourceTree = "<group>"; };
|
||||
@@ -376,6 +384,8 @@
|
||||
1D21BC54172AF43D009D1CFD /* KnockKnock */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD2F219D21A8A73000F67A83 /* Update.h */,
|
||||
CD2F219E21A8A73100F67A83 /* Update.m */,
|
||||
CDF08CC71AC4C678009B3423 /* PrefsWindowController.h */,
|
||||
CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */,
|
||||
CD5854D621A60B2000A438B0 /* PlistWindowController.h */,
|
||||
@@ -469,6 +479,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD02195F1AD39A83005148A2 /* ResultsWindowController.h */,
|
||||
CD2F21A221A8A7E300F67A83 /* UpdateWindowController.h */,
|
||||
CD2F21A321A8A7E300F67A83 /* UpdateWindowController.m */,
|
||||
CD0219601AD39A83005148A2 /* ResultsWindowController.m */,
|
||||
CD0219511AD34D9A005148A2 /* AboutWindowController.h */,
|
||||
CD0219521AD34D9A005148A2 /* AboutWindowController.m */,
|
||||
@@ -550,6 +562,7 @@
|
||||
CDA81E621AA020E8009790E2 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD2F21A021A8A7D000F67A83 /* UpdateWindow.xib */,
|
||||
CD5854D421A60B0F00A438B0 /* PlistWindow.xib */,
|
||||
CD02195D1AD39A74005148A2 /* ResultsWindow.xib */,
|
||||
CD02194D1AD34D8B005148A2 /* AboutWindow.xib */,
|
||||
@@ -616,6 +629,11 @@
|
||||
1D21BC4A172AF43D009D1CFD = {
|
||||
DevelopmentTeam = VBG97UB4TA;
|
||||
ProvisioningStyle = Manual;
|
||||
SystemCapabilities = {
|
||||
com.apple.HardenedRuntime = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -695,6 +713,7 @@
|
||||
CDBE491F1B5B46040031FC22 /* logInOutIcon.png in Resources */,
|
||||
CDA81D721A95B4E9009790E2 /* virus.png in Resources */,
|
||||
CDA81DC91A9960A3009790E2 /* info.png in Resources */,
|
||||
CD2F21A121A8A7D100F67A83 /* UpdateWindow.xib in Resources */,
|
||||
CDA81D6E1A95B4E9009790E2 /* startScan.png in Resources */,
|
||||
CD02194F1AD34D8B005148A2 /* AboutWindow.xib in Resources */,
|
||||
CDA81DCA1A9960A3009790E2 /* infoBG.png in Resources */,
|
||||
@@ -732,8 +751,10 @@
|
||||
CDA81E001A9A7D26009790E2 /* File.m in Sources */,
|
||||
CD6BBBF01B52032D00506D0D /* NSApplicationKeyEvents.m in Sources */,
|
||||
CDA81D4F1A95B492009790E2 /* AppDelegate.m in Sources */,
|
||||
CD2F219F21A8A73100F67A83 /* Update.m in Sources */,
|
||||
CDA81D5E1A95B4B4009790E2 /* main.m in Sources */,
|
||||
CD5854D821A60B2100A438B0 /* PlistWindowController.m in Sources */,
|
||||
CD2F21A421A8A7E300F67A83 /* UpdateWindowController.m in Sources */,
|
||||
7DE2FE2E1D3F30BE006C1438 /* Extensions.m in Sources */,
|
||||
7DE29CA41CA7BC5600DFA6A6 /* StartupScripts.m in Sources */,
|
||||
CD6975061B02F60400CE819B /* RFOverlayScroller.m in Sources */,
|
||||
@@ -879,6 +900,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = VBG97UB4TA;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -892,6 +914,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = KnockKnock;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -902,6 +925,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = VBG97UB4TA;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -915,6 +939,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = KnockKnock;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
scope = "0"
|
||||
stopOnStyle = "0">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Plugins/DylibProxies.m"
|
||||
timestampString = "564556800.5881079"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "189"
|
||||
endingLineNumber = "189"
|
||||
landmarkName = "-enumLoadedDylibs"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ItemTableController.m"
|
||||
timestampString = "564556800.588191"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "136"
|
||||
endingLineNumber = "136"
|
||||
landmarkName = "-tableView:viewForTableColumn:row:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ItemTableController.m"
|
||||
timestampString = "564556800.588248"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "251"
|
||||
endingLineNumber = "251"
|
||||
landmarkName = "-tableView:viewForTableColumn:row:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ItemTableController.m"
|
||||
timestampString = "564556800.588299"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "254"
|
||||
endingLineNumber = "254"
|
||||
landmarkName = "-tableView:viewForTableColumn:row:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ItemTableController.m"
|
||||
timestampString = "564556800.5883451"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "886"
|
||||
endingLineNumber = "886"
|
||||
landmarkName = "getCodeSigningIcon"
|
||||
landmarkType = "9">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "kkRowCell.m"
|
||||
timestampString = "564208966.188289"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "22"
|
||||
endingLineNumber = "22"
|
||||
landmarkName = "-setBackgroundStyle:"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ResultsWindowController.m"
|
||||
timestampString = "564298058.888056"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "32"
|
||||
endingLineNumber = "32"
|
||||
landmarkName = "-windowDidLoad"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "main.m"
|
||||
timestampString = "564556800.588663"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "222"
|
||||
endingLineNumber = "222"
|
||||
landmarkName = "cmdlineScan"
|
||||
landmarkType = "9">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
@@ -66,10 +66,6 @@
|
||||
argument = "-whosthere"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-pretty"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
//button for filtering out OS componets
|
||||
@property (weak) IBOutlet NSButton* showTrustedItemsBtn;
|
||||
|
||||
//button disabling update check
|
||||
@property (weak) IBOutlet NSButton *disableUpdateCheckBtn;
|
||||
|
||||
//button for disabling talking to VT
|
||||
@property (weak) IBOutlet NSButton* disableVTQueriesBtn;
|
||||
|
||||
@@ -39,6 +42,9 @@
|
||||
//filter out OS/known items
|
||||
@property BOOL showTrustedItems;
|
||||
|
||||
//no update checks
|
||||
@property BOOL disableUpdateCheck;
|
||||
|
||||
//disable talking to VT
|
||||
@property BOOL disableVTQueries;
|
||||
|
||||
|
||||
+27
-2
@@ -19,6 +19,7 @@
|
||||
@synthesize shouldSaveNow;
|
||||
@synthesize disableVTQueries;
|
||||
@synthesize showTrustedItems;
|
||||
@synthesize disableUpdateCheck;
|
||||
|
||||
|
||||
//automatically called when nib is loaded
|
||||
@@ -54,6 +55,13 @@
|
||||
self.showTrustedItemsBtn.state = STATE_ENABLED;
|
||||
}
|
||||
|
||||
//check if 'disable update check' button should be selected
|
||||
if(YES == self.disableUpdateCheck)
|
||||
{
|
||||
//set
|
||||
self.disableUpdateCheckBtn.state = STATE_ENABLED;
|
||||
}
|
||||
|
||||
//check if 'disable vt queries' button should be selected
|
||||
if(YES == self.disableVTQueries)
|
||||
{
|
||||
@@ -76,11 +84,11 @@
|
||||
}
|
||||
|
||||
//register default prefs
|
||||
// ->only used if user hasn't set any
|
||||
// only used if user hasn't set any
|
||||
-(void)registerDefaults
|
||||
{
|
||||
//set defaults
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:@{PREF_SHOW_TRUSTED_ITEMS:@NO, PREF_DISABLE_VT_QUERIRES:@NO, PREF_SAVE_OUTPUT:@NO}];
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:@{PREF_SHOW_TRUSTED_ITEMS:@NO, PREF_DISABLE_UPDATE_CHECK:@NO, PREF_DISABLE_VT_QUERIRES:@NO, PREF_SAVE_OUTPUT:@NO}];
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -105,6 +113,13 @@
|
||||
self.showTrustedItems = [defaults boolForKey:PREF_SHOW_TRUSTED_ITEMS];
|
||||
}
|
||||
|
||||
//load 'disable update check'
|
||||
if(nil != [defaults objectForKey:PREF_DISABLE_UPDATE_CHECK])
|
||||
{
|
||||
//save
|
||||
self.disableUpdateCheck = [defaults boolForKey:PREF_DISABLE_UPDATE_CHECK];
|
||||
}
|
||||
|
||||
//load 'disable vt queries'
|
||||
if(nil != [defaults objectForKey:PREF_DISABLE_VT_QUERIRES])
|
||||
{
|
||||
@@ -129,6 +144,9 @@
|
||||
//save current state of 'include os/trusted' components
|
||||
self.showTrustedItems = self.showTrustedItemsBtn.state;
|
||||
|
||||
//save current state of 'disable update checks'
|
||||
self.disableUpdateCheck = self.disableUpdateCheckBtn.state;
|
||||
|
||||
//save current state of 'disable VT'
|
||||
self.disableVTQueries = self.disableVTQueriesBtn.state;
|
||||
|
||||
@@ -163,6 +181,7 @@
|
||||
//first, any prefs changed, a 'save' set
|
||||
// ->set 'save now' flag
|
||||
if( ((self.showTrustedItems != self.showTrustedItemsBtn.state) ||
|
||||
(self.disableUpdateCheck != self.disableUpdateCheckBtn.state) ||
|
||||
(self.disableVTQueries != self.disableVTQueriesBtn.state) ||
|
||||
(self.saveOutput != self.saveOutputBtn.state) ) &&
|
||||
(YES == self.saveOutputBtn.state) )
|
||||
@@ -180,6 +199,9 @@
|
||||
//save hiding OS components flag
|
||||
self.showTrustedItems = self.showTrustedItemsBtn.state;
|
||||
|
||||
//save current state of 'disable update checks'
|
||||
self.disableUpdateCheck = self.disableUpdateCheckBtn.state;
|
||||
|
||||
//save disabling VT flag
|
||||
self.disableVTQueries = self.disableVTQueriesBtn.state;
|
||||
|
||||
@@ -189,6 +211,9 @@
|
||||
//save 'show trusted items'
|
||||
[defaults setBool:self.showTrustedItems forKey:PREF_SHOW_TRUSTED_ITEMS];
|
||||
|
||||
//save 'disable update checks'
|
||||
[defaults setBool:self.disableUpdateCheck forKey:PREF_DISABLE_UPDATE_CHECK];
|
||||
|
||||
//save 'disable vt queries'
|
||||
[defaults setBool:self.disableVTQueries forKey:PREF_DISABLE_VT_QUERIRES];
|
||||
|
||||
|
||||
+3
-3
@@ -30,7 +30,7 @@
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkIcon" id="xKf-GK-m0k"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
|
||||
<rect key="frame" x="153" y="330" width="180" height="50"/>
|
||||
<rect key="frame" x="153" y="351" width="180" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="Ws8-bD-j2R"/>
|
||||
</imageView>
|
||||
@@ -71,7 +71,7 @@
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fZJ-sG-ZuJ">
|
||||
<rect key="frame" x="20" y="265" width="153" height="19"/>
|
||||
<rect key="frame" x="20" y="250" width="153" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Supporters/Patrons:" id="fJg-qw-wDf">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
@@ -80,7 +80,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
|
||||
<rect key="frame" x="153" y="309" width="182" height="19"/>
|
||||
<rect key="frame" x="153" y="334" width="182" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Version:" id="bBK-v0-ypq">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
|
||||
+33
-18
@@ -1,12 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="PrefsWindowController">
|
||||
<connections>
|
||||
<outlet property="disableUpdateCheckBtn" destination="dJU-Ok-N6U" id="Q9b-gF-V3d"/>
|
||||
<outlet property="disableVTQueriesBtn" destination="d54-mZ-jqy" id="Xx6-E1-yv0"/>
|
||||
<outlet property="okButton" destination="HZZ-Es-mpy" id="GKU-Jc-ENB"/>
|
||||
<outlet property="saveOutputBtn" destination="6la-v6-zBD" id="m3d-J9-MZg"/>
|
||||
@@ -16,41 +18,49 @@
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
|
||||
<window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="422" height="177"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="422" height="177"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
|
||||
<rect key="frame" x="25" y="37" width="48" height="48"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="settings" id="xKf-GK-m0k"/>
|
||||
</imageView>
|
||||
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4xV-kQ-iaT">
|
||||
<rect key="frame" x="101" y="85" width="264" height="18"/>
|
||||
<rect key="frame" x="101" y="139" width="264" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="include os/known items" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="WN8-cQ-8xh">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d54-mZ-jqy">
|
||||
<rect key="frame" x="101" y="52" width="303" height="19"/>
|
||||
<rect key="frame" x="101" y="81" width="303" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="disable virustotal integration" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="gXW-vY-Aj1">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dJU-Ok-N6U">
|
||||
<rect key="frame" x="101" y="110" width="303" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="disable update check" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="idJ-pd-k6U">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6la-v6-zBD">
|
||||
<rect key="frame" x="101" y="19" width="160" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="save results" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="8A7-6z-flS">
|
||||
<rect key="frame" x="101" y="51" width="160" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="save scan results" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="8A7-6z-flS">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
|
||||
<rect key="frame" x="326" y="10" width="82" height="32"/>
|
||||
<rect key="frame" x="326" y="13" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
@@ -59,12 +69,17 @@
|
||||
<action selector="closeWindow:" target="-2" id="eFa-k0-zTM"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
|
||||
<rect key="frame" x="20" y="79" width="48" height="48"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="settings" id="xKf-GK-m0k"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="318" y="246.5"/>
|
||||
<point key="canvasLocation" x="318" y="273.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="InfoWindowController">
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="tDD-5C-L8e" id="VA6-H5-ZZO"/>
|
||||
<outlet property="infoLabel" destination="OSm-xS-Dmd" id="Ffv-9q-5a6"/>
|
||||
<outlet property="overlayView" destination="afp-ji-No6" id="qDV-BW-3l3"/>
|
||||
<outlet property="progressIndicator" destination="1oq-WT-B5T" id="f6G-ch-c3m"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
|
||||
<rect key="frame" x="10" y="8" width="110" height="106"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkIcon" id="xKf-GK-m0k"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
|
||||
<rect key="frame" x="122" y="69" width="198" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="Ws8-bD-j2R"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
|
||||
<rect key="frame" x="124" y="48" width="279" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="bBK-v0-ypq">
|
||||
<font key="font" size="12" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button wantsLayer="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tDD-5C-L8e">
|
||||
<rect key="frame" x="272" y="13" width="136" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nMV-1f-RyK">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="buttonHandler:" target="-2" id="tap-If-b45"/>
|
||||
</connections>
|
||||
</button>
|
||||
<customView hidden="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="afp-ji-No6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="1oq-WT-B5T">
|
||||
<rect key="frame" x="195" y="45" width="32" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</progressIndicator>
|
||||
</subviews>
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="318" y="246.5"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="kkIcon" width="512" height="512"/>
|
||||
<image name="kkText" width="426.48001098632812" height="85.919998168945312"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// file: Update.h
|
||||
// project: lulu (shared)
|
||||
// description: checks for new versions of LuLu (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2017 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Update_h
|
||||
#define Update_h
|
||||
|
||||
@import Cocoa;
|
||||
@import Foundation;
|
||||
|
||||
@interface Update : NSObject
|
||||
|
||||
//check for an update
|
||||
// will invoke app delegate method to update UI when check completes
|
||||
-(void)checkForUpdate:(void (^)(NSUInteger result, NSString* latestVersion))completionHandler;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif /* Update_h */
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// file: Update.m
|
||||
// project: lulu (shared)
|
||||
// description: checks for new versions of LuLu
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2017 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Update.h"
|
||||
#import "Utilities.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
|
||||
@implementation Update
|
||||
|
||||
//check for an update
|
||||
// ->will invoke app delegate method to update UI when check completes
|
||||
-(void)checkForUpdate:(void (^)(NSUInteger result, NSString* latestVersion))completionHandler
|
||||
{
|
||||
//latest version
|
||||
__block NSString* latestVersion = nil;
|
||||
|
||||
//result
|
||||
__block NSInteger result = -1;
|
||||
|
||||
//get latest version in background
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
//grab latest version
|
||||
latestVersion = [self getLatestVersion];
|
||||
if(nil != latestVersion)
|
||||
{
|
||||
//check
|
||||
result = (NSOrderedAscending == [getAppVersion() compare:latestVersion options:NSNumericSearch]);
|
||||
}
|
||||
|
||||
//invoke app delegate method
|
||||
// ->will update UI/show popup if necessart
|
||||
dispatch_async(dispatch_get_main_queue(),
|
||||
^{
|
||||
completionHandler(result, latestVersion);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//query interwebz to get latest version
|
||||
-(NSString*)getLatestVersion
|
||||
{
|
||||
//product version(s) data
|
||||
NSData* productsVersionData = nil;
|
||||
|
||||
//version dictionary
|
||||
NSDictionary* productsVersionDictionary = nil;
|
||||
|
||||
//latest version
|
||||
NSString* latestVersion = nil;
|
||||
|
||||
//get version from remote URL
|
||||
productsVersionData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:PRODUCT_VERSIONS_URL]];
|
||||
if(nil == productsVersionData)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//convert JSON to dictionary
|
||||
// ->wrap as may throw exception
|
||||
@try
|
||||
{
|
||||
//convert
|
||||
productsVersionDictionary = [NSJSONSerialization JSONObjectWithData:productsVersionData options:0 error:nil];
|
||||
if(nil == productsVersionDictionary)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@catch(NSException* exception)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//extract latest version
|
||||
latestVersion = [[productsVersionDictionary objectForKey:@"KnockKnock"] objectForKey:@"version"];
|
||||
|
||||
bail:
|
||||
|
||||
return latestVersion;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// file: UpdateWindowController.m
|
||||
// project: KnockKnock
|
||||
// description: window handler for update window/popup (header)
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2017 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
@import Cocoa;
|
||||
|
||||
@interface UpdateWindowController : NSWindowController <NSWindowDelegate>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
//version label/string
|
||||
@property(weak)IBOutlet NSTextField *infoLabel;
|
||||
|
||||
//action button
|
||||
@property(weak)IBOutlet NSButton *actionButton;
|
||||
|
||||
//label string
|
||||
@property(nonatomic, retain)NSString* infoLabelString;
|
||||
|
||||
//first button ('update check')
|
||||
@property(weak)IBOutlet NSView *firstButton;
|
||||
|
||||
//button title
|
||||
@property(nonatomic, retain)NSString* actionButtonTitle;
|
||||
|
||||
//overlay view
|
||||
@property(weak)IBOutlet NSView *overlayView;
|
||||
|
||||
//spinner
|
||||
@property(weak)IBOutlet NSProgressIndicator *progressIndicator;
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//save the main label's & button title's text
|
||||
-(void)configure:(NSString*)label buttonTitle:(NSString*)buttonTitle;
|
||||
|
||||
//invoked when user clicks button
|
||||
// ->trigger action such as opening product website, updating, etc
|
||||
-(IBAction)buttonHandler:(id)sender;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// file: UpdateWindowController.m
|
||||
// project: KnockKnock
|
||||
// description: window handler for update window/popup
|
||||
//
|
||||
// created by Patrick Wardle
|
||||
// copyright (c) 2017 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Consts.h"
|
||||
#import "Utilities.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "UpdateWindowController.h"
|
||||
|
||||
|
||||
@implementation UpdateWindowController
|
||||
|
||||
@synthesize infoLabel;
|
||||
@synthesize overlayView;
|
||||
@synthesize firstButton;
|
||||
@synthesize actionButton;
|
||||
@synthesize infoLabelString;
|
||||
@synthesize actionButtonTitle;
|
||||
@synthesize progressIndicator;
|
||||
|
||||
//automatically called when nib is loaded
|
||||
// ->center window
|
||||
-(void)awakeFromNib
|
||||
{
|
||||
//center
|
||||
[self.window center];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//automatically invoked when window is loaded
|
||||
// ->set to white
|
||||
-(void)windowDidLoad
|
||||
{
|
||||
//super
|
||||
[super windowDidLoad];
|
||||
|
||||
//not in dark mode?
|
||||
// make window white
|
||||
if(YES != isDarkMode())
|
||||
{
|
||||
//make white
|
||||
self.window.backgroundColor = NSColor.whiteColor;
|
||||
}
|
||||
|
||||
//indicated title bar is tranparent (too)
|
||||
self.window.titlebarAppearsTransparent = YES;
|
||||
|
||||
//set main label
|
||||
[self.infoLabel setStringValue:self.infoLabelString];
|
||||
|
||||
//set button text
|
||||
self.actionButton.title = self.actionButtonTitle;
|
||||
|
||||
//hide first button when action is 'update'
|
||||
// ->don't need update check button ;)
|
||||
if(YES == [self.actionButton.title isEqualToString:@"Update"])
|
||||
{
|
||||
//hide
|
||||
self.firstButton.hidden = YES;
|
||||
|
||||
//then make action button first responder
|
||||
[self.window makeFirstResponder:self.actionButton];
|
||||
}
|
||||
|
||||
//make it key window
|
||||
[self.window makeKeyAndOrderFront:self];
|
||||
|
||||
//make window front
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//automatically invoked when window is closing
|
||||
// ->make ourselves unmodal
|
||||
-(void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
//make un-modal
|
||||
[[NSApplication sharedApplication] stopModal];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//save the main label's & button title's text
|
||||
// ->invoked before window is loaded (and thus buttons, etc are nil)
|
||||
-(void)configure:(NSString*)label buttonTitle:(NSString*)buttonTitle
|
||||
{
|
||||
//save label's string
|
||||
self.infoLabelString = label;
|
||||
|
||||
//save button's title
|
||||
self.actionButtonTitle = buttonTitle;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//invoked when user clicks button
|
||||
// trigger action such as opening product website, updating, etc
|
||||
-(IBAction)buttonHandler:(id)sender
|
||||
{
|
||||
//handle 'update' / 'more info', etc
|
||||
// ->open LuLu's webpage, if they *didn't* click 'close'
|
||||
if(YES != [((NSButton*)sender).title isEqualToString:@"close"])
|
||||
{
|
||||
//open URL
|
||||
// ->invokes user's default browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:PRODUCT_URL]];
|
||||
}
|
||||
|
||||
//always close window
|
||||
[[self window] close];
|
||||
|
||||
return;
|
||||
}
|
||||
@end
|
||||
+2
-2
@@ -108,9 +108,9 @@ NSMutableDictionary* allUsers()
|
||||
{
|
||||
//grab identity
|
||||
identity = [CBIdentity identityWithCSIdentity:(CSIdentityRef)CFArrayGetValueAtIndex(results, i)];
|
||||
|
||||
|
||||
//add user
|
||||
users[identity.uniqueIdentifier] = @{USER_NAME:identity.posixName, USER_DIRECTORY:NSHomeDirectoryForUser(identity.posixName)};
|
||||
users[identity.UUIDString] = @{USER_NAME:identity.posixName, USER_DIRECTORY:NSHomeDirectoryForUser(identity.posixName)};
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
@@ -251,14 +251,32 @@ void prettyPrintJSON(NSString* output)
|
||||
//covert to data
|
||||
data = [output dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
//serialize
|
||||
object = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
||||
|
||||
//covert to pretty data
|
||||
prettyData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil];
|
||||
//convert to JSON
|
||||
// wrap since we are serializing JSON
|
||||
@try
|
||||
{
|
||||
//serialize
|
||||
object = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
|
||||
|
||||
//covert to pretty data
|
||||
prettyData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil];
|
||||
}
|
||||
@catch(NSException *exception)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
//covert to pretty string
|
||||
prettyString = [[NSString alloc] initWithData:prettyData encoding:NSUTF8StringEncoding];
|
||||
if(nil != prettyData)
|
||||
{
|
||||
//convert to string
|
||||
prettyString = [[NSString alloc] initWithData:prettyData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
else
|
||||
{
|
||||
//error
|
||||
prettyString = @"{\"ERROR\" : \"failed to covert output to JSON\"}";
|
||||
}
|
||||
|
||||
//output
|
||||
printf("%s\n", prettyString.UTF8String);
|
||||
|
||||
Reference in New Issue
Block a user