From: Jay Freeman (saurik) Date: Sun, 23 Nov 2008 14:42:21 +0000 (+0000) Subject: Drastic performance improvements. X-Git-Tag: v0.9.3900~61 X-Git-Url: https://git.saurik.com/winterboard.git/commitdiff_plain/4df9352e59ac6350383c61d4928d84280830d5be Drastic performance improvements. --- diff --git a/Library.mm b/Library.mm index fc3674c..ee4221f 100644 --- a/Library.mm +++ b/Library.mm @@ -128,23 +128,28 @@ bool Engineer_ = false; - (void) wb$setOpaque:(BOOL)opaque; - (void) wb$setInDock:(BOOL)docked; - (void) wb$didMoveToSuperview; -+ (UIImage *) wb$imageNamed:(NSString *)name inBundle:(NSBundle *)bundle; -+ (UIImage *) wb$applicationImageNamed:(NSString *)name; - (NSDictionary *) wb$infoDictionary; - (UIImage *) wb$icon; - (void) wb$appendIconList:(SBIconList *)list; - (id) wb$initWithStatusBar:(id)bar mode:(int)mode; - (id) wb$initWithMode:(int)mode orientation:(int)orientation; -- (id) wb$imageAtPath:(NSString *)path; -- (id) wb$initWithContentsOfFile:(NSString *)file; -- (id) wb$initWithContentsOfFile:(NSString *)file cache:(BOOL)cache; - (void) wb$setStatusBarMode:(int)mode orientation:(int)orientation duration:(float)duration fenceID:(int)id animation:(int)animation; @end +static UIImage *(*_UIApplicationImageWithName)(NSString *name); +static UIImage *(*_UIImageAtPath)(NSString *name, NSBundle *path); +static CGImageRef (*_UIImageRefAtPath)(NSString *name, bool cache, UIImageOrientation *orientation); +static UIImage *(*_UIImageWithNameInDomain)(NSString *name, NSString *domain); +static NSBundle *(*_UIKitBundle)(); +static void (*_UISharedImageInitialize)(bool); +static int (*_UISharedImageNameGetIdentifier)(NSString *); +static UIImage *(*_UISharedImageWithIdentifier)(int); + static NSMutableDictionary *UIImages_; static NSMutableDictionary *PathImages_; static NSMutableDictionary *Cache_; static NSMutableDictionary *Strings_; +static NSMutableDictionary *Bundles_; static NSFileManager *Manager_; static NSDictionary *English_; @@ -165,6 +170,34 @@ static NSString *$getTheme$(NSArray *files, bool parent = false) { return nil; } +static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool ui) { + NSString *identifier = [bundle bundleIdentifier]; + NSMutableArray *names = [NSMutableArray arrayWithCapacity:8]; + + if (identifier != nil) + [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]]; + if (NSString *folder = [[bundle bundlePath] lastPathComponent]) + [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]]; + if (ui) + [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]]; + + #define remapResourceName(oldname, newname) \ + else if ([file isEqualToString:oldname]) \ + [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \ + + if (identifier == nil); + else if ([identifier isEqualToString:@"com.apple.calculator"]) + [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]]; + else if (![identifier isEqualToString:@"com.apple.springboard"]); + remapResourceName(@"FSO_BG.png", @"StatusBar") + remapResourceName(@"SBDockBG.png", @"Dock") + remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather") + + if (NSString *path = $getTheme$(names)) + return path; + return nil; +} + static NSString *$pathForIcon$(SBApplication *self) { NSString *identifier = [self bundleIdentifier]; NSString *path = [self path]; @@ -203,6 +236,60 @@ static NSString *$pathForIcon$(SBApplication *self) { return nil; } +@interface NSBundle (WinterBoard) ++ (NSBundle *) wb$bundleWithFile:(NSString *)path; +@end + +@implementation NSBundle (WinterBoard) + ++ (NSBundle *) wb$bundleWithFile:(NSString *)path { + path = [path stringByDeletingLastPathComponent]; + if (path == nil || [path length] == 0 || [path isEqualToString:@"/"]) + return nil; + + NSBundle *bundle([Bundles_ objectForKey:path]); + if (reinterpret_cast(bundle) == [NSNull null]) + return nil; + else if (bundle == nil) { + bundle = [NSBundle bundleWithPath:path]; + if (bundle == nil) + bundle = [NSBundle wb$bundleWithFile:path]; + if (Debug_) + NSLog(@"WB:Debug:PathBundle(%@, %@)", path, bundle); + [Bundles_ setObject:(bundle == nil ? [NSNull null] : reinterpret_cast(bundle)) forKey:path]; + } + + return bundle; +} + +@end + +@interface NSString (WinterBoard) +- (NSString *) wb$themedPath; +@end + +@implementation NSString (WinterBoard) + +- (NSString *) wb$themedPath { + if (Debug_) + NSLog(@"WB:Debug:Bypass(\"%@\")", self); + + if (NSBundle *bundle = [NSBundle wb$bundleWithFile:self]) { + NSString *file([self stringByResolvingSymlinksInPath]); + NSString *prefix([[bundle bundlePath] stringByResolvingSymlinksInPath]); + if ([file hasPrefix:prefix]) { + NSUInteger length([prefix length]); + if (length != [file length]) + if (NSString *path = $pathForFile$inBundle$([file substringFromIndex:(length + 1)], bundle, false)) + return path; + } + } + + return self; +} + +@end + static void SBIconModel$cacheImageForIcon$(SBIconModel *self, SEL sel, SBIcon *icon) { [self wb$cacheImageForIcon:icon]; NSString *key([icon displayIdentifier]); @@ -255,98 +342,52 @@ static NSString *SBApplication$pathForIcon(SBApplication *self, SEL return [self wb$pathForIcon]; } -static NSString *$pathForFile$inBundle$(NSString *file, NSBundle *bundle, bool ui) { - NSString *identifier = [bundle bundleIdentifier]; - NSMutableArray *names = [NSMutableArray arrayWithCapacity:8]; - - if (identifier != nil) - [names addObject:[NSString stringWithFormat:@"Bundles/%@/%@", identifier, file]]; - if (NSString *folder = [[bundle bundlePath] lastPathComponent]) - [names addObject:[NSString stringWithFormat:@"Folders/%@/%@", folder, file]]; - if (ui) - [names addObject:[NSString stringWithFormat:@"UIImages/%@", file]]; - - #define remapResourceName(oldname, newname) \ - else if ([file isEqualToString:oldname]) \ - [names addObject:[NSString stringWithFormat:@"%@.png", newname]]; \ - - if (identifier == nil); - else if ([identifier isEqualToString:@"com.apple.calculator"]) - [names addObject:[NSString stringWithFormat:@"Files/Applications/Calculator.app/%@", file]]; - else if (![identifier isEqualToString:@"com.apple.springboard"]); - remapResourceName(@"FSO_BG.png", @"StatusBar") - remapResourceName(@"SBDockBG.png", @"Dock") - remapResourceName(@"SBWeatherCelsius.png", @"Icons/Weather") - - if (NSString *path = $getTheme$(names)) - return path; - return nil; -} - static UIImage *CachedImageAtPath(NSString *path) { + path = [path stringByResolvingSymlinksInPath]; UIImage *image = [PathImages_ objectForKey:path]; if (image != nil) return reinterpret_cast(image) == [NSNull null] ? nil : image; - image = [[UIImage alloc] wb$initWithContentsOfFile:path cache:true]; + image = [[UIImage alloc] initWithContentsOfFile:path cache:true]; if (image != nil) image = [image autorelease]; [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:path]; return image; } -static UIImage *UIImage$imageNamed$inBundle$(Class self, SEL sel, NSString *name, NSBundle *bundle) { - NSString *key = [NSString stringWithFormat:@"B:%@/%@", [bundle bundleIdentifier], name]; - UIImage *image = [PathImages_ objectForKey:key]; - if (image != nil) - return reinterpret_cast(image) == [NSNull null] ? nil : image; +MSHook(CGImageRef, _UIImageRefAtPath, NSString *name, bool cache, UIImageOrientation *orientation) { if (Debug_) - NSLog(@"WB:Debug: [UIImage(%@) imageNamed:\"%@\"]", [bundle bundleIdentifier], name); - if (NSString *path = $pathForFile$inBundle$(name, bundle, false)) - image = CachedImageAtPath(path); - if (image == nil) - image = [self wb$imageNamed:name inBundle:bundle]; - [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; - return image; + NSLog(@"WB:Debug: _UIImageRefAtPath(\"%@\", %s)", name, cache ? "true" : "false"); + return __UIImageRefAtPath([name wb$themedPath], cache, orientation); } -static UIImage *UIImage$imageNamed$(Class self, SEL sel, NSString *name) { - return UIImage$imageNamed$inBundle$(self, sel, name, [NSBundle mainBundle]); -} +/*MSHook(UIImage *, _UIImageAtPath, NSString *name, NSBundle *bundle) { + if (bundle == nil) + return __UIImageAtPath(name, nil); + else { + NSString *key = [NSString stringWithFormat:@"B:%@/%@", [bundle bundleIdentifier], name]; + UIImage *image = [PathImages_ objectForKey:key]; + if (image != nil) + return reinterpret_cast(image) == [NSNull null] ? nil : image; + if (Debug_) + NSLog(@"WB:Debug: _UIImageAtPath(\"%@\", %@)", name, bundle); + if (NSString *path = $pathForFile$inBundle$(name, bundle, false)) + image = CachedImageAtPath(path); + if (image == nil) + image = __UIImageAtPath(name, bundle); + [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; + return image; + } +}*/ -static UIImage *UIImage$applicationImageNamed$(Class self, SEL sel, NSString *name) { +MSHook(UIImage *, _UIApplicationImageWithName, NSString *name) { NSBundle *bundle = [NSBundle mainBundle]; if (Debug_) - NSLog(@"WB:Debug: [UIImage(%@) applicationImageNamed:\"%@\"]", [bundle bundleIdentifier], name); + NSLog(@"WB:Debug: _UIApplicationImageWithName(\"%@\", %@)", name, bundle); if (NSString *path = $pathForFile$inBundle$(name, bundle, false)) return CachedImageAtPath(path); - return [self wb$applicationImageNamed:name]; -} - -@interface NSString (WinterBoard) -- (NSString *) wb$themedPath; -@end - -@implementation NSString (WinterBoard) - -- (NSString *) wb$themedPath { - if (Debug_) - NSLog(@"WB:Debug:Bypass(\"%@\")", self); - - if (NSBundle *bundle = [NSBundle mainBundle]) { - NSString *prefix([bundle bundlePath]); - if ([self hasPrefix:prefix]) { - NSUInteger length([prefix length]); - if (length != [self length]) - if (NSString *path = $pathForFile$inBundle$([self substringFromIndex:(length + 1)], bundle, false)) - return path; - } - } - - return self; + return __UIApplicationImageWithName(name); } -@end - #define WBDelegate(delegate) \ - (NSMethodSignature*) methodSignatureForSelector:(SEL)sel { \ if (Engineer_) \ @@ -494,18 +535,6 @@ static void $didMoveToSuperview(SBButtonBar *self, SEL sel) { [self wb$didMoveToSuperview]; } -static id UIImage$imageAtPath$(NSObject *self, SEL sel, NSString *path) { - return [self wb$imageAtPath:[path wb$themedPath]]; -} - -static id $initWithContentsOfFile$(NSObject *self, SEL sel, NSString *file) { - return [self wb$initWithContentsOfFile:[file wb$themedPath]]; -} - -static id UIImage$initWithContentsOfFile$cache$(UIImage *self, SEL sel, NSString *file, BOOL cache) { - return [self wb$initWithContentsOfFile:[file wb$themedPath] cache:cache]; -} - static UIImage *UIImage$defaultDesktopImage$(UIImage *self, SEL sel) { if (Debug_) NSLog(@"WB:Debug:DefaultDesktopImage"); @@ -559,7 +588,7 @@ static id SBContentLayer$initWithSize$(SBContentLayer *self, SEL se UIImage *image; if (path != nil) { - image = [[UIImage alloc] wb$initWithContentsOfFile:path]; + image = [[UIImage alloc] initWithContentsOfFile:path]; if (image != nil) image = [image autorelease]; } else image = nil; @@ -869,7 +898,7 @@ static void SBIconLabel$drawRect$(SBIconLabel *self, SEL sel, CGRec void mSMSMessageTranscriptController$loadView(mSMSMessageTranscriptController *self, SEL sel) { [self wb$loadView]; if (NSString *path = $getTheme$([NSArray arrayWithObjects:@"SMSBackground.png", @"SMSBackground.jpg", nil])) - if (UIImage *image = [[UIImage alloc] wb$initWithContentsOfFile:path]) { + if (UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]) { [image autorelease]; UIView *&_transcriptLayer(MSHookIvar(self, "_transcriptLayer")); UIView *parent([_transcriptLayer superview]); @@ -879,24 +908,10 @@ void mSMSMessageTranscriptController$loadView(mSMSMessageTranscriptController(image) == [NSNull null] ? nil : image; if (NSString *path = $pathForFile$inBundle$(name, _UIKitBundle(), true)) { - image = [[UIImage alloc] wb$initWithContentsOfFile:path]; + image = [[UIImage alloc] initWithContentsOfFile:path]; if (image != nil) [image autorelease]; } @@ -917,7 +932,7 @@ static UIImage *$_UIImageWithName(NSString *name) { } } -static UIImage *$_UIImageWithNameInDomain(NSString *name, NSString *domain) { +MSHook(UIImage *, _UIImageWithNameInDomain, NSString *name, NSString *domain) { NSString *key = [NSString stringWithFormat:@"D:%zu%@%@", [domain length], domain, name]; UIImage *image = [PathImages_ objectForKey:key]; if (image != nil) @@ -925,12 +940,12 @@ static UIImage *$_UIImageWithNameInDomain(NSString *name, NSString *domain) { if (Debug_) NSLog(@"WB:Debug: UIImageWithNameInDomain(\"%@\", \"%@\")", name, domain); if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Domains/%@/%@", domain, name]])) { - image = [[UIImage alloc] wb$initWithContentsOfFile:path]; + image = [[UIImage alloc] initWithContentsOfFile:path]; if (image != nil) [image autorelease]; } if (image == nil) - image = _UIImageWithNameInDomain(name, domain); + image = __UIImageWithNameInDomain(name, domain); [PathImages_ setObject:(image == nil ? [NSNull null] : reinterpret_cast(image)) forKey:key]; return image; } @@ -974,7 +989,7 @@ static void ChangeWallpaper( UIImage *image; if (WallpaperFile_ != nil) { - image = [[UIImage alloc] wb$initWithContentsOfFile:WallpaperFile_]; + image = [[UIImage alloc] initWithContentsOfFile:WallpaperFile_]; if (image != nil) image = [image autorelease]; } else image = nil; @@ -1004,29 +1019,33 @@ extern "C" void WBInitialize() { NSLog(@"WB:Notice: WinterBoard"); - struct nlist nl[8]; + struct nlist nl[9]; memset(nl, 0, sizeof(nl)); - nl[0].n_un.n_name = (char *) "__UIImageAtPath"; - nl[1].n_un.n_name = (char *) "__UIImageWithName"; - nl[2].n_un.n_name = (char *) "__UIImageWithNameInDomain"; - nl[3].n_un.n_name = (char *) "__UIKitBundle"; - nl[4].n_un.n_name = (char *) "__UISharedImageInitialize"; - nl[5].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier"; - nl[6].n_un.n_name = (char *) "__UISharedImageWithIdentifier"; + nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName"; + nl[1].n_un.n_name = (char *) "__UIImageAtPath"; + nl[2].n_un.n_name = (char *) "__UIImageRefAtPath"; + nl[3].n_un.n_name = (char *) "__UIImageWithNameInDomain"; + nl[4].n_un.n_name = (char *) "__UIKitBundle"; + nl[5].n_un.n_name = (char *) "__UISharedImageInitialize"; + nl[6].n_un.n_name = (char *) "__UISharedImageNameGetIdentifier"; + nl[7].n_un.n_name = (char *) "__UISharedImageWithIdentifier"; nlist(UIKit, nl); - _UIImageAtPath = (UIImage *(*)(NSString *, NSBundle *)) nl[0].n_value; - _UIImageWithName = (UIImage *(*)(NSString *)) nl[1].n_value; - _UIImageWithNameInDomain = (UIImage *(*)(NSString *, NSString *)) nl[2].n_value; - _UIKitBundle = (NSBundle *(*)()) nl[3].n_value; - _UISharedImageInitialize = (void (*)(bool)) nl[4].n_value; - _UISharedImageNameGetIdentifier = (int (*)(NSString *)) nl[5].n_value; - _UISharedImageWithIdentifier = (UIImage *(*)(int)) nl[6].n_value; + _UIApplicationImageWithName = (UIImage *(*)(NSString *)) nl[0].n_value; + _UIImageAtPath = (UIImage *(*)(NSString *, NSBundle *)) nl[1].n_value; + _UIImageRefAtPath = (CGImageRef (*)(NSString *, bool, UIImageOrientation *)) nl[2].n_value; + _UIImageWithNameInDomain = (UIImage *(*)(NSString *, NSString *)) nl[3].n_value; + _UIKitBundle = (NSBundle *(*)()) nl[4].n_value; + _UISharedImageInitialize = (void (*)(bool)) nl[5].n_value; + _UISharedImageNameGetIdentifier = (int (*)(NSString *)) nl[6].n_value; + _UISharedImageWithIdentifier = (UIImage *(*)(int)) nl[7].n_value; - MSHookFunction(_UIImageWithName, &$_UIImageWithName, &_UIImageWithName); - MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &_UIImageWithNameInDomain); + MSHookFunction(_UIApplicationImageWithName, &$_UIApplicationImageWithName, &__UIApplicationImageWithName); + MSHookFunction(_UIImageRefAtPath, &$_UIImageRefAtPath, &__UIImageRefAtPath); + MSHookFunction(_UIImageWithName, &$_UIImageWithName, &__UIImageWithName); + MSHookFunction(_UIImageWithNameInDomain, &$_UIImageWithNameInDomain, &__UIImageWithNameInDomain); if (dlopen(AudioToolbox, RTLD_LAZY | RTLD_NOLOAD) != NULL) { struct nlist nl[2]; @@ -1037,11 +1056,7 @@ extern "C" void WBInitialize() { MSHookFunction(_Z24GetFileNameForThisActionmPcRb, &$_Z24GetFileNameForThisActionmPcRb, &_Z24GetFileNameForThisActionmPcRb); } - WBRename(false, "UIImage", @selector(applicationImageNamed:), (IMP) &UIImage$applicationImageNamed$); WBRename(false, "UIImage", @selector(defaultDesktopImage), (IMP) &UIImage$defaultDesktopImage$); - WBRename(false, "UIImage", @selector(imageAtPath:), (IMP) &UIImage$imageAtPath$); - WBRename(false, "UIImage", @selector(imageNamed:), (IMP) &UIImage$imageNamed$); - WBRename(false, "UIImage", @selector(imageNamed:inBundle:), (IMP) &UIImage$imageNamed$inBundle$); //WBRename("UINavigationBar", @selector(initWithCoder:", (IMP) &UINavigationBar$initWithCoder$); //WBRename("UINavigationBarBackground", @selector(initWithFrame:withBarStyle:withTintColor:", (IMP) &UINavigationBarBackground$initWithFrame$withBarStyle$withTintColor$); @@ -1049,8 +1064,6 @@ extern "C" void WBInitialize() { WBRename(true, "NSBundle", @selector(localizedStringForKey:value:table:), (IMP) &NSBundle$localizedStringForKey$value$table$); WBRename(true, "NSBundle", @selector(pathForResource:ofType:), (IMP) &NSBundle$pathForResource$ofType$); - WBRename(true, "UIImage", @selector(initWithContentsOfFile:), (IMP) &$initWithContentsOfFile$); - WBRename(true, "UIImage", @selector(initWithContentsOfFile:cache:), (IMP) &UIImage$initWithContentsOfFile$cache$); WBRename(true, "UINavigationBar", @selector(setBarStyle:), (IMP) &UINavigationBar$setBarStyle$); WBRename(true, "UIToolbar", @selector(setBarStyle:), (IMP) &UIToolbar$setBarStyle$); @@ -1060,6 +1073,7 @@ extern "C" void WBInitialize() { UIImages_ = [[NSMutableDictionary alloc] initWithCapacity:16]; PathImages_ = [[NSMutableDictionary alloc] initWithCapacity:16]; Strings_ = [[NSMutableDictionary alloc] initWithCapacity:0]; + Bundles_ = [[NSMutableDictionary alloc] initWithCapacity:2]; themes_ = [[NSMutableArray alloc] initWithCapacity:8]; diff --git a/control b/control index 2be35c7..c26c005 100644 --- a/control +++ b/control @@ -3,7 +3,7 @@ Priority: optional Section: System Maintainer: Jay Freeman (saurik) Architecture: iphoneos-arm -Version: 0.9.2600-1 +Version: 0.9.2636-1 Description: more powerful, open-source SummerBoard Name: WinterBoard Depends: mobilesubstrate (>= 0.9.2587-1) diff --git a/makefile b/makefile index efffd9a..ed1c9b9 100644 --- a/makefile +++ b/makefile @@ -10,13 +10,13 @@ clean: rm -f WinterBoard WinterBoard.dylib UIImages WinterBoard.dylib: Library.mm makefile ../mobilesubstrate/substrate.h - $(target)g++ -dynamiclib -g0 -O2 -Wall -o $@ $(filter %.mm,$^) -framework CoreFoundation -framework Foundation -lobjc -init _WBInitialize -I/apl/inc/iPhoneOS-2.0 -framework CoreGraphics -I../mobilesubstrate -L../mobilesubstrate -lsubstrate -framework UIKit + $(target)g++ -dynamiclib -g0 -O2 -Wall -o $@ $(filter %.mm,$^) -framework CoreFoundation -framework Foundation -lobjc -init _WBInitialize -I/apl/inc/iPhoneOS-2.0 -framework CoreGraphics -I../mobilesubstrate -L../mobilesubstrate -lsubstrate -framework UIKit -multiply_defined suppress UIImages: UIImages.mm makefile - $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -I/apl/inc/iPhoneOS-2.0 + $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -I/apl/inc/iPhoneOS-2.0 -multiply_defined suppress WinterBoard: Application.mm makefile - $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -framework CoreGraphics -I/apl/sdk + $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -framework CoreGraphics -I/apl/sdk -multiply_defined suppress package: rm -rf winterboard diff --git a/preinst b/preinst index b55968e..8018e12 100755 --- a/preinst +++ b/preinst @@ -36,7 +36,6 @@ EOF chmod --reference=/etc/notify.conf /etc/notify.conf_ && chown --reference=/etc/notify.conf /etc/notify.conf_ && mv -f /etc/notify.conf{_,} || rm -f /etc/notify.conf_ - killall -1 notifyd fi exit 0 diff --git a/prerm b/prerm index f01b2ed..61375f6 100755 --- a/prerm +++ b/prerm @@ -12,7 +12,6 @@ if [[ $1 == remove ]]; then chmod --reference=/etc/notify.conf /etc/notify.conf_ && chown --reference=/etc/notify.conf /etc/notify.conf_ && mv -f /etc/notify.conf{_,} || rm -f /etc/notify.conf_ - killall -1 notifyd fi exit 0