adium/adium

1.5.10.3b1
adium-1.5.10.3
2017-03-23, Evan D. Schoenberg, M.D.
6d760b7b1d69
1.5.10.3b1
//
// SystemVersionCheck.m
// SystemVersionCheck
//
// Created by Chris Campbell on 12/03/2005.
// Copyright Big Nerd Ranch 2005. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <stdlib.h>
#include <unistd.h>
static void GetVersionComponentsFromString(int *majorPtr, int *minorPtr, int *bugfixPtr, NSString *versionString)
{
int major = 0;
int minor = 0;
int bugfix = 0;
NSArray *array = [versionString componentsSeparatedByString:@"."];
if ([array count] > 0) {
major = [[array objectAtIndex:0] intValue];
if ([array count] > 1) {
minor = [[array objectAtIndex:1] intValue];
if ([array count] > 2) {
bugfix = [[array objectAtIndex:2] intValue];
}
}
}
if (majorPtr != NULL) {
*majorPtr = major;
}
if (minorPtr != NULL) {
*minorPtr = minor;
}
if (bugfixPtr != NULL) {
*bugfixPtr = bugfix;
}
}
static BOOL CheckSystemVersion(NSString **requiredVersionPtr, BOOL *sameMajorMinorPtr)
{
// Determine the required version
NSString *requiredVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"LSEnvironment"] objectForKey:@"MinimumSystemVersion"];
if ([requiredVersion length] == 0) {
requiredVersion = @"10.3.9";
}
if (requiredVersionPtr != NULL) {
*requiredVersionPtr = requiredVersion;
}
int requiredMajor, requiredMinor, requiredBugfix;
GetVersionComponentsFromString(&requiredMajor, &requiredMinor, &requiredBugfix, requiredVersion);
// Determine the system version
NSString *systemVersion = [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
if ([systemVersion length] == 0) {
// Can't parse the system version
if (sameMajorMinorPtr != NULL) {
*sameMajorMinorPtr = NO;
return NO;
}
}
int systemMajor, systemMinor, systemBugfix;
GetVersionComponentsFromString(&systemMajor, &systemMinor, &systemBugfix, systemVersion);
if (sameMajorMinorPtr != NULL) {
*sameMajorMinorPtr = (systemMajor == requiredMajor && systemMinor == requiredMinor);
}
if (systemMajor < requiredMajor) {
return NO;
} else if (systemMajor > requiredMajor) {
return YES;
}
// systemMajor == requiredMajor...
if (systemMinor < requiredMinor) {
return NO;
} else if (systemMinor > requiredMinor) {
return YES;
}
// systemMinor == requiredMinor...
if (systemBugfix < requiredBugfix) {
return NO;
}
// syhsemBugfix >= requiredBugfix...
return YES;
}
static NSString *LocalizedInfoStringForKey(NSString *key)
{
// First, look for an InfoPlist.strings entry
NSBundle *bundle = [NSBundle mainBundle];
NSString *value = [bundle localizedStringForKey:key value:nil table:@"InfoPlist"];
if (key != value) {
return value;
}
// Otherwise, look in the Info.plist file
return [[bundle infoDictionary] objectForKey:key];
}
static NSString *LocalizedApplicationName()
{
NSString *value = LocalizedInfoStringForKey(@"CFBundleDisplayName");
if (!value) {
value = LocalizedInfoStringForKey(@"CFBundleName");
}
return value;
}
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Grab the executable name from the Info.plist.
// If there isn't one, error out and exit
NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
if (!executableName) {
fprintf(stderr, "ERROR: %s must be run from inside a .app wrapper\n", argv[0]);
return EXIT_FAILURE;
}
NSString *requiredVersion;
BOOL sameMajorMinor;
BOOL canLaunch = CheckSystemVersion(&requiredVersion, &sameMajorMinor);
if (!canLaunch) {
NSString *applicationName = LocalizedApplicationName();
// Use the name of the application as the alert window's title
NSString *windowTitle = applicationName;
if ([windowTitle length] == 0) {
windowTitle = @"";
}
if ([applicationName length] == 0) {
applicationName = @"This application";
}
NSString *title = [NSString stringWithFormat:@"%@ requires Mac OS X %@ or later", applicationName, requiredVersion];
NSString *messageFormat;
NSString *defaultButton;
NSString *alternateButton;
if (sameMajorMinor) {
messageFormat = @"Please use Software Update to upgrade to Mac OS X %@ or later.\n";
defaultButton = @"Open Software Update";
alternateButton = @"Quit";
} else {
messageFormat = @"Please install Mac OS X %@ or later.\n";
defaultButton = @"Quit";
alternateButton = nil;
}
// Load NSApplication and all the GUI stuff
[NSApplication sharedApplication];
NSPanel *alertPanel = NSGetAlertPanel(title, messageFormat, defaultButton, alternateButton, nil, requiredVersion);
[alertPanel setTitle:windowTitle];
int choice = [NSApp runModalForWindow:alertPanel];
NSReleaseAlertPanel(alertPanel);
alertPanel = nil;
if (sameMajorMinor && choice == NSAlertDefaultReturn) {
// Open Software Update
[[NSWorkspace sharedWorkspace] openFile:@"/System/Library/CoreServices/Software Update.app"];
}
return EXIT_SUCCESS;
}
// Get the path of the real executable
NSString *path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:[NSString stringWithFormat:@"%@.real", executableName]];
if (!path) {
return EXIT_FAILURE;
}
// Construct a new argv array for the exec'ed process
NSMutableData *argvData = [[NSMutableData alloc] initWithBytes:argv length:(argc * sizeof(*argv))];
// Change the first argument to the path of the new executable
((const char **)[argvData mutableBytes])[0] = [path UTF8String];
// Append a NULL char* to the end of the array
char *nullPtr = NULL;
[argvData appendBytes:&nullPtr length:sizeof(nullPtr)];
[pool release];
pool = [[NSAutoreleasePool alloc] init];
execv(((const char **)[argvData bytes])[0], (char * const *)[argvData bytes]);
// This should never be reached
[argvData release];
argvData = nil;
[pool release];
pool = nil;
return EXIT_FAILURE;
}