2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #import <Cocoa/Cocoa.h>
30 #import <CoreFoundation/CoreFoundation.h>
32 void displayErrorAndQuit(NSString *title, NSString *message)
35 NSRunCriticalAlertPanel(title, message, @"Quit", nil, nil);
39 void checkMacOSXVersion()
41 long versionNumber = 0;
42 OSErr error = Gestalt(gestaltSystemVersion, &versionNumber);
43 if (error != noErr || versionNumber < 0x1040)
44 displayErrorAndQuit(@"Mac OS X 10.4 is Required", @"Nightly builds of WebKit require Mac OS X 10.4 or newer.");
47 int getLastVersionShown()
49 [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:@"-1" forKey:@"StartPageShownInVersion"]];
50 return [[NSUserDefaults standardUserDefaults] integerForKey:@"StartPageShownInVersion"];
53 void saveLastVersionShown(int lastVersion)
55 [[NSUserDefaults standardUserDefaults] setInteger:lastVersion forKey:@"StartPageShownInVersion"];
56 [[NSUserDefaults standardUserDefaults] synchronize];
59 NSString *getPathForStartPage()
61 return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"start.html"];
64 int getShowStartPageVersion()
66 return getCurrentVersion() + 1;
69 int getCurrentVersion()
71 return [[[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleVersionKey] intValue];
74 BOOL startPageDisabled()
76 return [[NSUserDefaults standardUserDefaults] boolForKey:@"StartPageDisabled"];
79 void addStartPageToArgumentsIfNeeded(NSMutableArray *arguments)
81 if (startPageDisabled())
84 if (getLastVersionShown() < getShowStartPageVersion()) {
85 saveLastVersionShown(getCurrentVersion());
86 NSString *startPagePath = getPathForStartPage();
88 [arguments addObject:startPagePath];
92 static void myExecve(NSString *executable, NSArray *args, NSDictionary *environment)
94 char **argv = (char **)calloc(sizeof(char *), [args count] + 1);
95 char **env = (char **)calloc(sizeof(char *), [environment count] + 1);
97 NSEnumerator *e = [args objectEnumerator];
100 while (s = [e nextObject])
101 argv[i++] = (char *) [s UTF8String];
103 e = [environment keyEnumerator];
105 while (s = [e nextObject])
106 env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String];
108 execve([executable fileSystemRepresentation], argv, env);
111 NSBundle *locateSafariBundle()
113 NSArray *applicationDirectories = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSAllDomainsMask, YES);
114 NSEnumerator *e = [applicationDirectories objectEnumerator];
115 NSString *applicationDirectory;
116 while (applicationDirectory = [e nextObject]) {
117 NSString *possibleSafariPath = [applicationDirectory stringByAppendingPathComponent:@"Safari.app"];
118 NSBundle *possibleSafariBundle = [NSBundle bundleWithPath:possibleSafariPath];
119 if ([[possibleSafariBundle bundleIdentifier] isEqualToString:@"com.apple.Safari"])
120 return possibleSafariBundle;
123 CFURLRef safariURL = nil;
124 OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.Safari"), nil, nil, &safariURL);
126 displayErrorAndQuit(@"Unable to locate Safari", @"Nightly builds of WebKit require Safari to run. Please check that it is available and then try again.");
128 NSBundle *safariBundle = [NSBundle bundleWithPath:[(NSURL *)safariURL path]];
129 CFRelease(safariURL);
133 int main(int argc, char *argv[])
135 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
136 checkMacOSXVersion();
138 NSBundle *safariBundle = locateSafariBundle();
139 NSString *executablePath = [safariBundle executablePath];
140 NSString *frameworkPath = [[NSBundle mainBundle] resourcePath];
141 NSString *pathToEnablerLib = [[NSBundle mainBundle] pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"];
143 if ([frameworkPath rangeOfString:@":"].location != NSNotFound ||
144 [pathToEnablerLib rangeOfString:@":"].location != NSNotFound)
145 displayErrorAndQuit(@"Unable to launch Safari",
146 @"WebKit is located at a path containing an unsupported character. Please move WebKit to a different location and try again.");
148 NSMutableArray *arguments = [NSMutableArray arrayWithObjects:executablePath, @"-WebKitDeveloperExtras", @"YES", @"-WebKitScriptDebuggerEnabled", @"YES", nil];
149 NSMutableDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH", @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH",
150 pathToEnablerLib, @"DYLD_INSERT_LIBRARIES", [[NSBundle mainBundle] executablePath], @"WebKitAppPath", nil];
151 addStartPageToArgumentsIfNeeded(arguments);
154 [arguments addObject:[NSString stringWithUTF8String:*argv]];
156 myExecve(executablePath, arguments, environment);
158 char *error = strerror(errno);
159 NSString *errorMessage = [NSString stringWithFormat:@"Launching Safari at %@ failed with the error '%s' (%d)", [safariBundle bundlePath], error, errno];
160 displayErrorAndQuit(@"Unable to launch Safari", errorMessage);