Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
# WakeWatcher

Waits for system to wake from sleep and executes ~/.onwake
Only works on OS X.
Waits for system to wake from sleep and executes any executables in /opt/wake
Only works on macOS.


# Building

Build in Xcode or run `xcodebuild`. There are no dependencies.


# Using WakeWatcher
Create a LaunchDaemon to run the items you need.

Launch WakeWatcher.app. Until WakeWatcher supports launchd, consider
making WakeWatcher.app a login item.

On wake from sleep, if `~/.onwake` exists and is executable,
WakeWatcher will `chdir` to the current user's home directory and
execute `.onwake`
On wake from sleep, WakeWatcher will attempt to run anything under
/opt/wake (*.sh, *.py, *.rb, etc). An example LD is included.


# Bugs
Expand All @@ -25,14 +20,10 @@ WakeWatcher is not configurable.

WakeWatcher calls NSLog a lot.

WakeWatcher does not check to see if `~/.onwake` is already executing
before attempting to launch it.

WakeWatcher does not support launchd. Patches welcome.

WakeWatcher does not check to see if processes under `/opt/wake` are already executing
before attempting to launch them.

# Authorship/Licence

Created by Eric Kobrin.
Released under CC0 1.0 (Public Domain)
https://creativecommons.org/publicdomain/zero/1.0/
12 changes: 7 additions & 5 deletions WakeWatcher/WakeWatcher.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//
// WakeWatcher.h
// WakeWatcher.m
// WakeWatcher
//
// Created by Eric Kobrin on 7/23/16.
// Updated by John Peterson on 5/1/20
// Released under CC0 1.0 (Public Domain)
// https://creativecommons.org/publicdomain/zero/1.0/
//


#import <Foundation/Foundation.h>

@interface WakeWatcher : NSObject
@property (nonatomic, retain) NSString *home;
@property (nonatomic, retain) NSString *path;
@property (nonatomic, retain) NSString *executable;
@property (nonatomic, copy) NSString *home;
@property (nonatomic, copy) NSString *path;
@property (nonatomic, copy) NSString *executable;


- (void) registerNotifications;

@end

52 changes: 29 additions & 23 deletions WakeWatcher/WakeWatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,53 @@
// WakeWatcher
//
// Created by Eric Kobrin on 7/23/16.
// Updated by John Peterson on 5/1/20
// Released under CC0 1.0 (Public Domain)
// https://creativecommons.org/publicdomain/zero/1.0/
//

#import "WakeWatcher.h"
#import "wakeWatcher.h"
@import AppKit;

@implementation WakeWatcher


- (void) receiveWakeNote: (NSNotification*) note
{
NSFileManager *filemgr;
NSArray *filelist;

filemgr = [NSFileManager defaultManager];
filelist = [filemgr contentsOfDirectoryAtPath: @"/opt/wake" error: nil];

NSLog(@"receiveWakeNote: %@", [note name]);
if([[NSFileManager defaultManager] isExecutableFileAtPath:self.path]){
NSLog(@"Attempting to execute: '%@'", self.path);
NSTask *task;
@try {
[[NSFileManager defaultManager]
changeCurrentDirectoryPath:self.home];
task = [NSTask launchedTaskWithLaunchPath:self.path arguments:[NSArray arrayWithObject:self.executable]];
}
@catch (NSException *exception) {
NSLog(@"Error executing: '%@': %@", self.path, exception.reason);

for (id object in filelist) {

self.executable = object;
self.home = @"/opt/wake";
self.path = [self.home stringByAppendingPathComponent:self.executable];

if([[NSFileManager defaultManager] isExecutableFileAtPath:self.path]){
NSLog(@"Attempting to execute: '%@'", self.path);
NSTask *task;
@try {
[[NSFileManager defaultManager]
changeCurrentDirectoryPath:self.home];
task = [NSTask launchedTaskWithLaunchPath:self.path arguments:[NSArray arrayWithObject:self.executable]];
}
@catch (NSException *exception) {
NSLog(@"Error executing: '%@': %@", self.path, exception.reason);
}
} else {
NSLog(@"No executable file at: '%@'", self.path);
}
} else {
NSLog(@"No executable file at: '%@'", self.path);
}

}

- (void) registerNotifications
{
if(self.executable == nil){
self.executable = @".onwake";
}
if(self.home == nil){
self.home = NSHomeDirectory();
}

if(self.path == nil){
self.path = [self.home stringByAppendingPathComponent:self.executable];
}
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
selector: @selector(receiveWakeNote:)
name: NSWorkspaceDidWakeNotification object: NULL];
Expand Down
7 changes: 4 additions & 3 deletions WakeWatcher/main.m
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
//
// main.m
// WakeWatcher.m
// WakeWatcher
//
// Created by Eric Kobrin on 7/23/16.
// Updated by John Peterson on 5/1/20
// Released under CC0 1.0 (Public Domain)
// https://creativecommons.org/publicdomain/zero/1.0/
//



#import <Foundation/Foundation.h>
#import "WakeWatcher.h"

int main(int argc, const char * argv[]) {
// TODO: run under launchd
@autoreleasepool {
NSLog(@"Starting Wake Watcher!");
@try {
Expand Down
20 changes: 20 additions & 0 deletions com.corp.wakeWatcher.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.corp.wakeWatcher</string>
<key>StandardOutPath</key>
<string>/tmp/wakeWatcher.log</string>
<key>StandardErrorPath</key>
<string>/tmp/wakeWatcher.log</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/path/to/wakeWatcher</string>
</array>
</dict>
</plist>