2626#define kStrMoveApplicationQuestionInfoWillRequirePasswd _I10NS (@" Note that this will require an administrator password." )
2727#define kStrMoveApplicationQuestionInfoInDownloadsFolder _I10NS (@" This will keep your Downloads folder uncluttered." )
2828
29- // Needs to be defined for compiling under 10.4 SDK
30- #ifndef NSAppKitVersionNumber10_4
31- #define NSAppKitVersionNumber10_4 824
32- #endif
3329// Needs to be defined for compiling under 10.5 SDK
3430#ifndef NSAppKitVersionNumber10_5
3531 #define NSAppKitVersionNumber10_5 949
4844static NSString *PreferredInstallLocation (BOOL *isUserDirectory);
4945static BOOL IsInApplicationsFolder (NSString *path);
5046static BOOL IsInDownloadsFolder (NSString *path);
47+ static BOOL IsApplicationAtPathRunning (NSString *path);
5148static NSString *ContainingDiskImageDevice (void );
5249static BOOL Trash (NSString *path);
5350static BOOL DeleteOrTrash (NSString *path);
@@ -113,17 +110,13 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
113110 NSButton *cancelButton = [alert addButtonWithTitle: kStrMoveApplicationButtonDoNotMove ];
114111 [cancelButton setKeyEquivalent: @" \e " ];
115112
116- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
117- if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
118- // Setup suppression button
119- [alert setShowsSuppressionButton: YES ];
113+ // Setup suppression button
114+ [alert setShowsSuppressionButton: YES ];
120115
121- if (PFUseSmallAlertSuppressCheckbox) {
122- [[[alert suppressionButton ] cell ] setControlSize: NSSmallControlSize ];
123- [[[alert suppressionButton ] cell ] setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize ]]];
124- }
116+ if (PFUseSmallAlertSuppressCheckbox) {
117+ [[[alert suppressionButton ] cell ] setControlSize: NSSmallControlSize ];
118+ [[[alert suppressionButton ] cell ] setFont: [NSFont systemFontOfSize: [NSFont smallSystemFontSize ]]];
125119 }
126- #endif
127120 }
128121
129122 // Activate app -- work-around for focus issues related to "scary file from internet" OS dialog.
@@ -153,30 +146,7 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
153146 // If a copy already exists in the Applications folder, put it in the Trash
154147 if ([fm fileExistsAtPath: destinationPath]) {
155148 // But first, make sure that it's not running
156- BOOL destinationIsRunning = NO ;
157-
158- // Use the new API on 10.6 or higher to determine if the app is already running
159- if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_5 ) {
160- for (NSRunningApplication *runningApplication in [[NSWorkspace sharedWorkspace ] runningApplications ]) {
161- NSString *executablePath = [[runningApplication executableURL ] path ];
162- if ([executablePath hasPrefix: destinationPath]) {
163- destinationIsRunning = YES ;
164- break ;
165- }
166- }
167- }
168- // Use the shell to determine if the app is already running on systems 10.5 or lower
169- else {
170- NSString *script = [NSString stringWithFormat: @" /bin/ps ax -o comm | /usr/bin/grep %@ / | /usr/bin/grep -v grep >/dev/null" , ShellQuotedString (destinationPath)];
171- NSTask *task = [NSTask launchedTaskWithLaunchPath: @" /bin/sh" arguments: [NSArray arrayWithObjects: @" -c" , script, nil ]];
172- [task waitUntilExit ];
173-
174- // If the task terminated with status 0, it means that the final grep produced 1 or more lines of output.
175- // Which means that the app is already running
176- destinationIsRunning = ([task terminationStatus ] == 0 );
177- }
178-
179- if (destinationIsRunning) {
149+ if (IsApplicationAtPathRunning (destinationPath)) {
180150 // Give the running app focus and terminate myself
181151 NSLog (@" INFO -- Switching to an already running version" );
182152 [[NSTask launchedTaskWithLaunchPath: @" /usr/bin/open" arguments: [NSArray arrayWithObject: destinationPath]] waitUntilExit ];
@@ -214,19 +184,9 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
214184
215185 exit (0 );
216186 }
217- else {
218- if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
219- // Save the alert suppress preference if checked
220- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
221- if ([[alert suppressionButton ] state ] == NSOnState ) {
222- [[NSUserDefaults standardUserDefaults ] setBool: YES forKey: AlertSuppressKey];
223- }
224- #endif
225- }
226- else {
227- // Always suppress after the first decline on 10.4 since there is no suppression checkbox
228- [[NSUserDefaults standardUserDefaults ] setBool: YES forKey: AlertSuppressKey];
229- }
187+ // Save the alert suppress preference if checked
188+ else if ([[alert suppressionButton ] state ] == NSOnState ) {
189+ [[NSUserDefaults standardUserDefaults ] setBool: YES forKey: AlertSuppressKey];
230190 }
231191
232192 return ;
@@ -277,11 +237,9 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
277237
278238static BOOL IsInApplicationsFolder (NSString *path) {
279239 // Check all the normal Application directories
280- NSEnumerator *e = [NSSearchPathForDirectoriesInDomains (NSApplicationDirectory, NSAllDomainsMask, YES ) objectEnumerator ];
281- NSString *appDirPath = nil ;
282-
283- while ((appDirPath = [e nextObject ])) {
284- if ([path hasPrefix: appDirPath]) return YES ;
240+ NSArray *applicationDirs = NSSearchPathForDirectoriesInDomains (NSApplicationDirectory, NSAllDomainsMask, YES );
241+ for (NSString *appDir in applicationDirs) {
242+ if ([path hasPrefix: appDir]) return YES ;
285243 }
286244
287245 // Also, handle the case that the user has some other Application directory (perhaps on a separate data partition).
@@ -293,21 +251,35 @@ static BOOL IsInApplicationsFolder(NSString *path) {
293251}
294252
295253static BOOL IsInDownloadsFolder (NSString *path) {
296- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
297- // 10.5 or higher has NSDownloadsDirectory
298- if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
299- NSEnumerator *e = [NSSearchPathForDirectoriesInDomains (NSDownloadsDirectory, NSAllDomainsMask, YES ) objectEnumerator ];
300- NSString *downloadsDirPath = nil ;
301-
302- while ((downloadsDirPath = [e nextObject ])) {
303- if ([path hasPrefix: downloadsDirPath]) return YES ;
304- }
254+ NSArray *downloadDirs = NSSearchPathForDirectoriesInDomains (NSDownloadsDirectory, NSAllDomainsMask, YES );
255+ for (NSString *downloadsDirPath in downloadDirs) {
256+ if ([path hasPrefix: downloadsDirPath]) return YES ;
257+ }
258+
259+ return NO ;
260+ }
305261
262+ static BOOL IsApplicationAtPathRunning (NSString *path) {
263+ #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
264+ // Use the new API on 10.6 or higher to determine if the app is already running
265+ if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_5 ) {
266+ for (NSRunningApplication *runningApplication in [[NSWorkspace sharedWorkspace ] runningApplications ]) {
267+ NSString *executablePath = [[runningApplication executableURL ] path ];
268+ if ([executablePath hasPrefix: path]) {
269+ return YES ;
270+ }
271+ }
306272 return NO ;
307273 }
308274#endif
309- // 10.4
310- return [[[path stringByDeletingLastPathComponent ] lastPathComponent ] isEqualToString: @" Downloads" ];
275+ // Use the shell to determine if the app is already running on systems 10.5 or lower
276+ NSString *script = [NSString stringWithFormat: @" /bin/ps ax -o comm | /usr/bin/grep %@ / | /usr/bin/grep -v grep >/dev/null" , ShellQuotedString (path)];
277+ NSTask *task = [NSTask launchedTaskWithLaunchPath: @" /bin/sh" arguments: [NSArray arrayWithObjects: @" -c" , script, nil ]];
278+ [task waitUntilExit ];
279+
280+ // If the task terminated with status 0, it means that the final grep produced 1 or more lines of output.
281+ // Which means that the app is already running
282+ return [task terminationStatus ] == 0 ;
311283}
312284
313285static NSString *ContainingDiskImageDevice (void ) {
@@ -328,13 +300,16 @@ static BOOL IsInDownloadsFolder(NSString *path) {
328300
329301 NSData *data = [[[hdiutil standardOutput ] fileHandleForReading ] readDataToEndOfFile ];
330302 id info;
331-
303+ # if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
332304 if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_5 ) {
333305 info = [NSPropertyListSerialization propertyListWithData: data options: NSPropertyListImmutable format: NULL error: NULL ];
334306 }
335307 else {
308+ #endif
336309 info = [NSPropertyListSerialization propertyListFromData: data mutabilityOption: NSPropertyListImmutable format: NULL errorDescription: NULL ];
310+ #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
337311 }
312+ #endif
338313
339314 if (![info isKindOfClass: [NSDictionary class ]])
340315 return nil ;
@@ -465,28 +440,15 @@ static OSStatus (*security_AuthorizationExecuteWithPrivileges)(AuthorizationRef
465440
466441static BOOL CopyBundle (NSString *srcPath, NSString *dstPath) {
467442 NSFileManager *fm = [NSFileManager defaultManager ];
443+ NSError *error = nil ;
468444
469- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
470- // 10.5 or higher
471- if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
472- NSError *error = nil ;
473- if ([fm copyItemAtPath: srcPath toPath: dstPath error: &error]) {
474- return YES ;
475- }
476- else {
477- NSLog (@" ERROR -- Could not copy '%@ ' to '%@ ' (%@ )" , srcPath, dstPath, error);
478- }
479- }
480- #endif
481- #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
482- if ([fm copyPath: srcPath toPath: dstPath handler: nil ]) {
445+ if ([fm copyItemAtPath: srcPath toPath: dstPath error: &error]) {
483446 return YES ;
484447 }
485448 else {
486- NSLog (@" ERROR -- Could not copy '%@ ' to '%@ '" , srcPath, dstPath);
449+ NSLog (@" ERROR -- Could not copy '%@ ' to '%@ ' (%@ )" , srcPath, dstPath, error);
450+ return NO ;
487451 }
488- #endif
489- return NO ;
490452}
491453
492454static NSString *ShellQuotedString (NSString *string) {
@@ -506,15 +468,13 @@ static void Relaunch(NSString *destinationPath) {
506468 // OS X >=10.5:
507469 // Before we launch the new app, clear xattr:com.apple.quarantine to avoid
508470 // duplicate "scary file from the internet" dialog.
509- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
510471 if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_5 ) {
511472 // Add the -r flag on 10.6
512473 preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d -r com.apple.quarantine %@ " , quotedDestinationPath];
513474 }
514- else if ( floor ( NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
475+ else {
515476 preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d com.apple.quarantine %@ " , quotedDestinationPath];
516477 }
517- #endif
518478
519479 NSString *script = [NSString stringWithFormat: @" (while /bin/kill -0 %d >&/dev/null; do /bin/sleep 0.1; done; %@ ; /usr/bin/open %@ ) &" , pid, preOpenCmd, quotedDestinationPath];
520480
0 commit comments