1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/* 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Redistribution and use in source and binary forms, with or without 5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * modification, are permitted provided that the following conditions 6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * are met: 7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 1. Redistributions of source code must retain the above copyright 9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * notice, this list of conditions and the following disclaimer. 10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 2. Redistributions in binary form must reproduce the above copyright 11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * notice, this list of conditions and the following disclaimer in the 12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * documentation and/or other materials provided with the distribution. 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * its contributors may be used to endorse or promote products derived 15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * from this software without specific prior written permission. 16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */ 28563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <Cocoa/Cocoa.h> 30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <CoreFoundation/CoreFoundation.h> 31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// We need to weak-import posix_spawn and friends as they're not available on Tiger. 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// The BSD-level system headers do not have availability macros, so we redeclare the 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// functions ourselves with the "weak" attribute. 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define WEAK_IMPORT __attribute__((weak)) 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define POSIX_SPAWN_SETEXEC 0x0040 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef void *posix_spawnattr_t; 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef void *posix_spawn_file_actions_t; 410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint posix_spawnattr_init(posix_spawnattr_t *) WEAK_IMPORT; 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint posix_spawn(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) WEAK_IMPORT; 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) WEAK_IMPORT; 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint posix_spawnattr_setflags(posix_spawnattr_t *, short) WEAK_IMPORT; 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void displayErrorAndQuit(NSString *title, NSString *message) 48563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 49563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSApplicationLoad(); 50563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSRunCriticalAlertPanel(title, message, @"Quit", nil, nil); 51563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark exit(0); 52563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 53563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int getLastVersionShown() 55563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 56563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:@"-1" forKey:@"StartPageShownInVersion"]]; 57563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return [[NSUserDefaults standardUserDefaults] integerForKey:@"StartPageShownInVersion"]; 58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void saveLastVersionShown(int lastVersion) 61563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 62563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[NSUserDefaults standardUserDefaults] setInteger:lastVersion forKey:@"StartPageShownInVersion"]; 63563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[NSUserDefaults standardUserDefaults] synchronize]; 64563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 65563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic NSString *getPathForStartPage() 67563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 68563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"start.html"]; 69563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 70563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int getCurrentVersion() 72563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return [[[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleVersionKey] intValue]; 74563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int getShowStartPageVersion() 77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return getCurrentVersion() + 1; 79563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic BOOL startPageDisabled() 82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return [[NSUserDefaults standardUserDefaults] boolForKey:@"StartPageDisabled"]; 84563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void addStartPageToArgumentsIfNeeded(NSMutableArray *arguments) 87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (startPageDisabled()) 89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return; 90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (getLastVersionShown() < getShowStartPageVersion()) { 92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark saveLastVersionShown(getCurrentVersion()); 93563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *startPagePath = getPathForStartPage(); 94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (startPagePath) 95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [arguments addObject:startPagePath]; 96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic cpu_type_t preferredArchitecture() 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if defined(__ppc__) 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return CPU_TYPE_POWERPC; 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#elif defined(__LP64__) 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return CPU_TYPE_X86_64; 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return CPU_TYPE_X86; 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void myExecve(NSString *executable, NSArray *args, NSDictionary *environment) 111563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 112563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark char **argv = (char **)calloc(sizeof(char *), [args count] + 1); 113563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark char **env = (char **)calloc(sizeof(char *), [environment count] + 1); 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEnumerator *e = [args objectEnumerator]; 116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *s; 117563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark int i = 0; 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while ((s = [e nextObject])) 119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark argv[i++] = (char *) [s UTF8String]; 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 121563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark e = [environment keyEnumerator]; 122563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark i = 0; 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while ((s = [e nextObject])) 124563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String]; 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (posix_spawnattr_init && posix_spawn && posix_spawnattr_setbinpref_np && posix_spawnattr_setflags) { 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch posix_spawnattr_t attr; 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch posix_spawnattr_init(&attr); 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch cpu_type_t architecturePreference[] = { preferredArchitecture(), CPU_TYPE_X86 }; 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch posix_spawnattr_setbinpref_np(&attr, 2, architecturePreference, 0); 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch short flags = POSIX_SPAWN_SETEXEC; 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch posix_spawnattr_setflags(&attr, flags); 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch posix_spawn(NULL, [executable fileSystemRepresentation], NULL, &attr, argv, env); 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else 1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch execve([executable fileSystemRepresentation], argv, env); 136563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 137563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic NSBundle *locateSafariBundle() 139563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 140563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSArray *applicationDirectories = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, YES); 141563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEnumerator *e = [applicationDirectories objectEnumerator]; 142563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *applicationDirectory; 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while ((applicationDirectory = [e nextObject])) { 144563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *possibleSafariPath = [applicationDirectory stringByAppendingPathComponent:@"Safari.app"]; 145563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSBundle *possibleSafariBundle = [NSBundle bundleWithPath:possibleSafariPath]; 146563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([[possibleSafariBundle bundleIdentifier] isEqualToString:@"com.apple.Safari"]) 147563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return possibleSafariBundle; 148563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark CFURLRef safariURL = nil; 151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.Safari"), nil, nil, &safariURL); 152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (err != noErr) 153563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark displayErrorAndQuit(@"Unable to locate Safari", @"Nightly builds of WebKit require Safari to run. Please check that it is available and then try again."); 154563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 155563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSBundle *safariBundle = [NSBundle bundleWithPath:[(NSURL *)safariURL path]]; 156563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark CFRelease(safariURL); 157563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return safariBundle; 158563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 159563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic NSString *currentMacOSXVersion() 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SInt32 version; 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (Gestalt(gestaltSystemVersion, &version) != noErr) 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"10.4"; 1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return [NSString stringWithFormat:@"%x.%x", (version & 0xFF00) >> 8, (version & 0x00F0) >> 4]; 1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 169d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic NSString *fallbackMacOSXVersion(NSString *systemVersion) 170d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 171d0825bca7fe65beaee391d30da42e937db621564Steve Block NSDictionary *fallbackVersionMap = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"FallbackSystemVersions"]; 172d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!fallbackVersionMap) 173d0825bca7fe65beaee391d30da42e937db621564Steve Block return nil; 174d0825bca7fe65beaee391d30da42e937db621564Steve Block NSString *fallbackSystemVersion = [fallbackVersionMap objectForKey:systemVersion]; 175d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!fallbackSystemVersion || ![fallbackSystemVersion isKindOfClass:[NSString class]]) 176d0825bca7fe65beaee391d30da42e937db621564Steve Block return nil; 177d0825bca7fe65beaee391d30da42e937db621564Steve Block return fallbackSystemVersion; 178d0825bca7fe65beaee391d30da42e937db621564Steve Block} 179d0825bca7fe65beaee391d30da42e937db621564Steve Block 1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic BOOL checkFrameworkPath(NSString *frameworkPath) 1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch BOOL isDirectory = NO; 1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return [[NSFileManager defaultManager] fileExistsAtPath:frameworkPath isDirectory:&isDirectory] && isDirectory; 1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic BOOL checkSafariVersion(NSBundle *safariBundle) 1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *safariBundleVersion = [[safariBundle infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey]; 1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *majorComponent = [[safariBundleVersion componentsSeparatedByString:@"."] objectAtIndex:0]; 1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *majorVersion = [majorComponent substringFromIndex:[majorComponent length] - 3]; 1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return [majorVersion intValue] >= 530; 1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 194563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkint main(int argc, char *argv[]) 195563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 196563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *systemVersion = currentMacOSXVersion(); 1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *frameworkPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:systemVersion]; 200563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 201d0825bca7fe65beaee391d30da42e937db621564Steve Block BOOL frameworkPathIsUsable = checkFrameworkPath(frameworkPath); 2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 203d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!frameworkPathIsUsable) { 204d0825bca7fe65beaee391d30da42e937db621564Steve Block NSString *fallbackSystemVersion = fallbackMacOSXVersion(systemVersion); 205d0825bca7fe65beaee391d30da42e937db621564Steve Block if (fallbackSystemVersion) { 206d0825bca7fe65beaee391d30da42e937db621564Steve Block frameworkPath = [[[NSBundle mainBundle] privateFrameworksPath] stringByAppendingPathComponent:fallbackSystemVersion]; 207d0825bca7fe65beaee391d30da42e937db621564Steve Block frameworkPathIsUsable = checkFrameworkPath(frameworkPath); 208d0825bca7fe65beaee391d30da42e937db621564Steve Block } 209d0825bca7fe65beaee391d30da42e937db621564Steve Block } 210d0825bca7fe65beaee391d30da42e937db621564Steve Block 211d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!frameworkPathIsUsable) 2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch displayErrorAndQuit([NSString stringWithFormat:@"Mac OS X %@ is not supported", systemVersion], 2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [NSString stringWithFormat:@"Nightly builds of WebKit are not supported on Mac OS X %@ at this time.", systemVersion]); 2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 215d0825bca7fe65beaee391d30da42e937db621564Steve Block NSString *pathToEnablerLib = [[NSBundle mainBundle] pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"]; 216d0825bca7fe65beaee391d30da42e937db621564Steve Block 217d0825bca7fe65beaee391d30da42e937db621564Steve Block NSBundle *safariBundle = locateSafariBundle(); 218d0825bca7fe65beaee391d30da42e937db621564Steve Block NSString *executablePath = [safariBundle executablePath]; 219d0825bca7fe65beaee391d30da42e937db621564Steve Block 2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!checkSafariVersion(safariBundle)) { 2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *safariVersion = [[safariBundle localizedInfoDictionary] objectForKey:@"CFBundleShortVersionString"]; 2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch displayErrorAndQuit([NSString stringWithFormat:@"Safari %@ is not supported", safariVersion], 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [NSString stringWithFormat:@"Nightly builds of WebKit are not supported with Safari %@ at this time. Please update to a newer version of Safari.", safariVersion]); 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 225563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 226563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([frameworkPath rangeOfString:@":"].location != NSNotFound || 227563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [pathToEnablerLib rangeOfString:@":"].location != NSNotFound) 228563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark displayErrorAndQuit(@"Unable to launch Safari", 229563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"WebKit is located at a path containing an unsupported character. Please move WebKit to a different location and try again."); 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSMutableArray *arguments = [NSMutableArray arrayWithObject:executablePath]; 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSMutableDictionary *environment = [[[NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH", @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH", 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch pathToEnablerLib, @"DYLD_INSERT_LIBRARIES", [[NSBundle mainBundle] executablePath], @"WebKitAppPath", nil] mutableCopy] autorelease]; 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [environment addEntriesFromDictionary:[[NSProcessInfo processInfo] environment]]; 235563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark addStartPageToArgumentsIfNeeded(arguments); 236563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 237563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark while (*++argv) 238563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [arguments addObject:[NSString stringWithUTF8String:*argv]]; 239563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 240563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark myExecve(executablePath, arguments, environment); 241563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 242563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark char *error = strerror(errno); 243563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *errorMessage = [NSString stringWithFormat:@"Launching Safari at %@ failed with the error '%s' (%d)", [safariBundle bundlePath], error, errno]; 244563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark displayErrorAndQuit(@"Unable to launch Safari", errorMessage); 245563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 246563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [pool release]; 247563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return 0; 248563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 249