Reviewed by Darin, landed by Maciej.
[WebKit-https.git] / WebKitTools / WebKitLauncher / main.m
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Mark Rowe.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #import <Cocoa/Cocoa.h>
31 #import <CoreFoundation/CoreFoundation.h>
32
33 void displayErrorAndQuit(NSString *title, NSString *message)
34 {
35     NSApplicationLoad();
36     NSRunCriticalAlertPanel(title, message, @"Quit", nil, nil);
37     exit(0);
38 }
39
40 void checkMacOSXVersion()
41 {
42     long versionNumber = 0;
43     OSErr error = Gestalt(gestaltSystemVersion, &versionNumber);
44     if (error != noErr || versionNumber < 0x1040)
45         displayErrorAndQuit(@"Mac OS X 10.4 is Required", @"Nightly builds of WebKit require Mac OS X 10.4 or newer.");
46 }
47
48 int getLastVersionShown()
49 {
50     [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:@"-1" forKey:@"StartPageShownInVersion"]];
51     return [[NSUserDefaults standardUserDefaults] integerForKey:@"StartPageShownInVersion"];
52 }
53
54 void saveLastVersionShown(int lastVersion)
55 {
56     [[NSUserDefaults standardUserDefaults] setInteger:lastVersion forKey:@"StartPageShownInVersion"];
57     [[NSUserDefaults standardUserDefaults] synchronize];
58 }
59
60 NSString *getPathForStartPage()
61 {
62     return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"start.html"];
63 }
64
65 int getShowStartPageVersion()
66 {
67     return getCurrentVersion() + 1;
68 }
69
70 int getCurrentVersion()
71 {
72     return [[[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleVersionKey] intValue];
73 }
74
75 BOOL startPageDisabled()
76 {
77     return [[NSUserDefaults standardUserDefaults] boolForKey:@"StartPageDisabled"];
78 }
79
80 void addStartPageToArgumentsIfNeeded(NSMutableArray *arguments)
81 {
82     if (startPageDisabled())
83         return;
84
85     if (getLastVersionShown() < getShowStartPageVersion()) {
86         saveLastVersionShown(getCurrentVersion());
87         NSString *startPagePath = getPathForStartPage();
88         if (startPagePath)
89             [arguments addObject:startPagePath];
90     }
91 }
92
93 static void myExecve(NSString *executable, NSArray *args, NSDictionary *environment)
94 {
95     char **argv = (char **)calloc(sizeof(char *), [args count] + 1);
96     char **env = (char **)calloc(sizeof(char *), [environment count] + 1);
97     
98     NSEnumerator *e = [args objectEnumerator];
99     NSString *s;
100     int i = 0;
101     while (s = [e nextObject])
102         argv[i++] = (char *) [s UTF8String];
103     
104     e = [environment keyEnumerator];
105     i = 0;
106     while (s = [e nextObject])
107         env[i++] = (char *) [[NSString stringWithFormat:@"%@=%@", s, [environment objectForKey:s]] UTF8String];
108    
109     execve([executable fileSystemRepresentation], argv, env);
110 }
111
112 int main(int argc, char *argv[])
113 {
114     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
115     checkMacOSXVersion();
116
117     CFURLRef safariURL = nil;
118     OSStatus err = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.Safari"), nil, nil, &safariURL);
119     if (err != noErr)
120         displayErrorAndQuit(@"Unable to locate Safari", @"Nightly builds of WebKit require Safari to run.  Please check that it is available and then try again.");
121
122     NSString *frameworkPath = [[NSBundle mainBundle] resourcePath];
123     NSString *executablePath = [[NSBundle bundleWithPath:[(NSURL *)safariURL path]] executablePath];
124     NSString *pathToEnablerLib = [[NSBundle mainBundle] pathForResource:@"WebKitNightlyEnabler" ofType:@"dylib"];
125     
126     NSMutableArray *arguments = [NSMutableArray arrayWithObjects:executablePath, @"-WebKitDeveloperExtras", @"YES", nil];
127     addStartPageToArgumentsIfNeeded(arguments);
128
129     while (*++argv)
130         [arguments addObject:[NSString stringWithUTF8String:*argv]];
131
132     myExecve(executablePath,
133              arguments,
134              [NSDictionary dictionaryWithObjectsAndKeys:frameworkPath, @"DYLD_FRAMEWORK_PATH", 
135              @"YES", @"WEBKIT_UNSET_DYLD_FRAMEWORK_PATH", 
136              pathToEnablerLib, @"DYLD_INSERT_LIBRARIES", 
137              [[NSBundle mainBundle] executablePath], @"CFProcessPath",
138               nil]);
139
140      char *error = strerror(errno);
141      NSString *errorMessage = [NSString stringWithFormat:@"Launching Safari at %@ failed with the error '%s' (%d)", [(NSURL *)safariURL  path], error, errno];
142      displayErrorAndQuit(@"Unable to launch Safari", errorMessage);
143
144     [pool release];
145     return 0;
146 }
147 \ No newline at end of file