From 416a5e3ddce7901b6bba29c731e1aa1292a3063f Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Fri, 15 Sep 2006 00:27:02 +0000 Subject: [PATCH] Add patcher/upgrader/installer thingy. --- stepmania/PBProject/Patcher/CopyFiles.h | 30 ++ stepmania/PBProject/Patcher/CopyFiles.m | 163 ++++++++ .../PBProject/Patcher/Identification.txt | 11 + stepmania/PBProject/Patcher/Info.plist | 28 ++ .../Patcher/Patcher.xcodeproj/project.pbxproj | 337 ++++++++++++++++ .../PBProject/Patcher/Patcher_Prefix.pch | 28 ++ stepmania/PBProject/Patcher/Upgrader.h | 56 +++ stepmania/PBProject/Patcher/Upgrader.m | 364 ++++++++++++++++++ .../Patcher/en.lproj/InfoPlist.strings | Bin 0 -> 198 bytes .../Patcher/en.lproj/Localizable.strings | Bin 0 -> 2862 bytes .../Patcher/en.lproj/MainMenu.nib/classes.nib | 23 ++ .../Patcher/en.lproj/MainMenu.nib/info.nib | 34 ++ .../en.lproj/MainMenu.nib/keyedobjects.nib | Bin 0 -> 11375 bytes stepmania/PBProject/Patcher/main.m | 29 ++ 14 files changed, 1103 insertions(+) create mode 100644 stepmania/PBProject/Patcher/CopyFiles.h create mode 100644 stepmania/PBProject/Patcher/CopyFiles.m create mode 100644 stepmania/PBProject/Patcher/Identification.txt create mode 100644 stepmania/PBProject/Patcher/Info.plist create mode 100644 stepmania/PBProject/Patcher/Patcher.xcodeproj/project.pbxproj create mode 100644 stepmania/PBProject/Patcher/Patcher_Prefix.pch create mode 100644 stepmania/PBProject/Patcher/Upgrader.h create mode 100644 stepmania/PBProject/Patcher/Upgrader.m create mode 100644 stepmania/PBProject/Patcher/en.lproj/InfoPlist.strings create mode 100644 stepmania/PBProject/Patcher/en.lproj/Localizable.strings create mode 100644 stepmania/PBProject/Patcher/en.lproj/MainMenu.nib/classes.nib create mode 100644 stepmania/PBProject/Patcher/en.lproj/MainMenu.nib/info.nib create mode 100644 stepmania/PBProject/Patcher/en.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 stepmania/PBProject/Patcher/main.m diff --git a/stepmania/PBProject/Patcher/CopyFiles.h b/stepmania/PBProject/Patcher/CopyFiles.h new file mode 100644 index 0000000000..79b11dd728 --- /dev/null +++ b/stepmania/PBProject/Patcher/CopyFiles.h @@ -0,0 +1,30 @@ +#import + +BOOL NeedsPrivs( NSString *path ); +NSString *CopyWithPrivs( NSString *src, NSString *dest ); +NSString *Copy( NSString *src, NSString *dest ); + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/PBProject/Patcher/CopyFiles.m b/stepmania/PBProject/Patcher/CopyFiles.m new file mode 100644 index 0000000000..356b36bd47 --- /dev/null +++ b/stepmania/PBProject/Patcher/CopyFiles.m @@ -0,0 +1,163 @@ +#import "CopyFiles.h" +#include +#include +#include +#include +#include +#include +#include + +static NSString *COPY_FAILED; +static NSString *EXECUTE_FAILED; +static NSString *AUTH_FAILED; + +static void LoadStrings() +{ + static bool bLoaded = false; + if( bLoaded ) + return; + COPY_FAILED = NSLocalizedString( @"Copy failed.", nil ); + EXECUTE_FAILED = NSLocalizedString( @"Execute failed.", nil ); + AUTH_FAILED = NSLocalizedString( @"Authentication failed. File not patched.", nil ); + bLoaded = true; +} + +static BOOL CheckDir( const char *path ) +{ + DIR *dir = opendir( path ); + int fd = dirfd( dir ); + struct dirent entry, *ep; + int err; + + fchdir( fd ); + for( err = readdir_r(dir, &entry, &ep); ep && !err; err = readdir_r(dir, &entry, &ep) ) + { + if( !strcmp(".", entry.d_name) || !strcmp("..", entry.d_name) ) + continue; + if( access(entry.d_name, W_OK|R_OK) ) + { + closedir( dir ); + return YES; + } + if( entry.d_type == DT_DIR ) + { + if( CheckDir(entry.d_name) ) + { + closedir( dir ); + return YES; + } + fchdir( fd ); + } + } + closedir( dir ); + return err; +} + +BOOL NeedsPrivs( NSString *path ) +{ + const char *p = [path UTF8String]; + struct stat sb; + + if( stat(p, &sb) ) + return YES; + if( access(p, W_OK|R_OK) ) // I don't care to parse stat output. + return YES; + if( (sb.st_mode & S_IFDIR) && CheckDir(p) ) + return YES; + + return NO; +} + +NSString *CopyWithPrivs( NSString *src, NSString *dest ) +{ + LoadStrings(); + OSStatus error; + static AuthorizationRef authRef; + static BOOL bCreated = false; + + if( !bCreated ) + { + AuthorizationFlags flags = kAuthorizationFlagDefaults; + AuthorizationItem item = { kAuthorizationRightExecute, 0, NULL, 0 }; + AuthorizationRights rights = { 1, &item }; + + error = AuthorizationCreate( NULL, kAuthorizationEmptyEnvironment, flags, &authRef ); + + if (error != errAuthorizationSuccess) + return @"Failed to create authorization."; + + + flags = kAuthorizationFlagDefaults | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize | + kAuthorizationFlagExtendRights; + + error = AuthorizationCopyRights( authRef, &rights, NULL, flags, NULL ); + + if (error != errAuthorizationSuccess) + return AUTH_FAILED; + bCreated = YES; + } + + + // Don't pass path as the first argument. AuthorizationExecuteWithPrivileges must do it. + char path[] = "/bin/cp"; + const char *argv[] = { "-Rf", [src UTF8String], [dest UTF8String], NULL }; + NSString *result = nil; + + error = AuthorizationExecuteWithPrivileges( authRef, path, kAuthorizationFlagDefaults, (char **)argv, NULL ); + + if (error == errAuthorizationSuccess) + { + int status = 0; + pid_t pid = wait( &status ); + + if( pid == -1 ) + result = [NSString stringWithUTF8String:strerror(errno)]; + else if( !WIFEXITED(status) || WEXITSTATUS(status) ) + result = COPY_FAILED; + } + else + { + result = EXECUTE_FAILED; + } + + + return result; +} + +NSString *Copy( NSString *src, NSString *dest ) +{ + LoadStrings(); + // Again, don't pass the path. + NSArray *argv = [NSArray arrayWithObjects:@"-Rf", src, dest, nil]; + NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/bin/cp" arguments:argv]; + + [task waitUntilExit]; + return [task terminationStatus] ? COPY_FAILED : nil; +} + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/PBProject/Patcher/Identification.txt b/stepmania/PBProject/Patcher/Identification.txt new file mode 100644 index 0000000000..6b0ede8d25 --- /dev/null +++ b/stepmania/PBProject/Patcher/Identification.txt @@ -0,0 +1,11 @@ +# The format of this file is: +# Application name +# Bundle ID +# version1 +# version2 +# ... +# The version key -ALL- or no version keys matches all versions. + +StepMania +com.StepMania +-ALL- diff --git a/stepmania/PBProject/Patcher/Info.plist b/stepmania/PBProject/Patcher/Info.plist new file mode 100644 index 0000000000..c80d835021 --- /dev/null +++ b/stepmania/PBProject/Patcher/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + smicon + CFBundleIdentifier + com.StepMania.Patcher + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ITGp + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/stepmania/PBProject/Patcher/Patcher.xcodeproj/project.pbxproj b/stepmania/PBProject/Patcher/Patcher.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..fe9714d1a1 --- /dev/null +++ b/stepmania/PBProject/Patcher/Patcher.xcodeproj/project.pbxproj @@ -0,0 +1,337 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + AA2BF5C30A4F6E1B00A21643 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AA2BF5C10A4F6E1B00A21643 /* Localizable.strings */; }; + AAD7D8740A36C53E0073BAC6 /* Identification.txt in Resources */ = {isa = PBXBuildFile; fileRef = AAD7D8730A36C53E0073BAC6 /* Identification.txt */; }; + AAD7D8BF0A36CC020073BAC6 /* smicon.icns in Resources */ = {isa = PBXBuildFile; fileRef = AAD7D8BE0A36CC020073BAC6 /* smicon.icns */; }; + AAF586BC0A27D9300046D33E /* CopyFiles.m in Sources */ = {isa = PBXBuildFile; fileRef = AAF586BB0A27D9300046D33E /* CopyFiles.m */; }; + AAF586BF0A27D9410046D33E /* Upgrader.m in Sources */ = {isa = PBXBuildFile; fileRef = AAF586BE0A27D9410046D33E /* Upgrader.m */; }; + AAF586CC0A27DA7F0046D33E /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = AAF586CA0A27DA7F0046D33E /* MainMenu.nib */; }; + AAF586CF0A27DA900046D33E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AAF586CD0A27DA900046D33E /* InfoPlist.strings */; }; + AAF587560A2826240046D33E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAF587550A2826240046D33E /* Security.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* Patcher_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Patcher_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* Patcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Patcher.app; sourceTree = BUILT_PRODUCTS_DIR; }; + AA2BF5C20A4F6E1B00A21643 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + AAD7D8730A36C53E0073BAC6 /* Identification.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Identification.txt; sourceTree = ""; }; + AAD7D8BE0A36CC020073BAC6 /* smicon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = smicon.icns; path = ../smicon.icns; sourceTree = SOURCE_ROOT; }; + AAF586BA0A27D9300046D33E /* CopyFiles.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; path = CopyFiles.h; sourceTree = ""; }; + AAF586BB0A27D9300046D33E /* CopyFiles.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CopyFiles.m; sourceTree = ""; }; + AAF586BD0A27D9410046D33E /* Upgrader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Upgrader.h; sourceTree = ""; }; + AAF586BE0A27D9410046D33E /* Upgrader.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Upgrader.m; sourceTree = ""; }; + AAF586CB0A27DA7F0046D33E /* en */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = en; path = en.lproj/MainMenu.nib; sourceTree = ""; }; + AAF586CE0A27DA900046D33E /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + AAF587550A2826240046D33E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + AAF587560A2826240046D33E /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + AAF586BD0A27D9410046D33E /* Upgrader.h */, + AAF586BE0A27D9410046D33E /* Upgrader.m */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* Patcher.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Patcher */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Patcher; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + AAF586BA0A27D9300046D33E /* CopyFiles.h */, + AAF586BB0A27D9300046D33E /* CopyFiles.m */, + 32CA4F630368D1EE00C91783 /* Patcher_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + AA2BF5C10A4F6E1B00A21643 /* Localizable.strings */, + AAD7D8BE0A36CC020073BAC6 /* smicon.icns */, + AAD7D8730A36C53E0073BAC6 /* Identification.txt */, + 8D1107310486CEB800E47090 /* Info.plist */, + AAF586CD0A27DA900046D33E /* InfoPlist.strings */, + AAF586CA0A27DA7F0046D33E /* MainMenu.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + AAF587550A2826240046D33E /* Security.framework */, + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* Patcher */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Patcher" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Patcher; + productInstallPath = "$(HOME)/Applications"; + productName = Patcher; + productReference = 8D1107320486CEB800E47090 /* Patcher.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Patcher" */; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* Patcher */; + projectDirPath = ""; + targets = ( + 8D1107260486CEB800E47090 /* Patcher */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AAF586CC0A27DA7F0046D33E /* MainMenu.nib in Resources */, + AAF586CF0A27DA900046D33E /* InfoPlist.strings in Resources */, + AAD7D8740A36C53E0073BAC6 /* Identification.txt in Resources */, + AAD7D8BF0A36CC020073BAC6 /* smicon.icns in Resources */, + AA2BF5C30A4F6E1B00A21643 /* Localizable.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072D0486CEB800E47090 /* main.m in Sources */, + AAF586BC0A27D9300046D33E /* CopyFiles.m in Sources */, + AAF586BF0A27D9410046D33E /* Upgrader.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + AA2BF5C10A4F6E1B00A21643 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + AA2BF5C20A4F6E1B00A21643 /* en */, + ); + name = Localizable.strings; + sourceTree = SOURCE_ROOT; + }; + AAF586CA0A27DA7F0046D33E /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + AAF586CB0A27DA7F0046D33E /* en */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; + AAF586CD0A27DA900046D33E /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + AAF586CE0A27DA900046D33E /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Patcher; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Patcher; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/.."; + GCC_VERSION = 3.3; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 3.3; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk; + ZERO_LINK = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/.."; + GCC_VERSION = 3.3; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 3.3; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Patcher" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Patcher" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/stepmania/PBProject/Patcher/Patcher_Prefix.pch b/stepmania/PBProject/Patcher/Patcher_Prefix.pch new file mode 100644 index 0000000000..59fd7194f0 --- /dev/null +++ b/stepmania/PBProject/Patcher/Patcher_Prefix.pch @@ -0,0 +1,28 @@ +#ifdef __OBJC__ + #import +#endif + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/PBProject/Patcher/Upgrader.h b/stepmania/PBProject/Patcher/Upgrader.h new file mode 100644 index 0000000000..785a531d16 --- /dev/null +++ b/stepmania/PBProject/Patcher/Upgrader.h @@ -0,0 +1,56 @@ +/* Upgrader */ + +#import + +@interface Upgrader : NSObject +{ + IBOutlet NSButton *m_Choose; + IBOutlet NSButton *m_Okay; + IBOutlet NSPanel *m_Panel; + IBOutlet NSProgressIndicator *m_ProgressBar; + IBOutlet NSProgressIndicator *m_Searching; + IBOutlet NSTextField *m_StatusText; + IBOutlet NSTextField *m_SelectionText; + IBOutlet NSTextField *m_PatchingText; + IBOutlet NSWindow *m_Window; + NSString *m_sAppID; + NSArray *m_vVersions; + NSString *m_sName; + NSString *m_sError; + NSString *m_sPath; +} +- (IBAction) chooseFile:(id)sender; +- (IBAction) upgrade:(id)sender; +- (void) findApp:(id)obj; +- (void) foundApp:(id)obj; +- (void) upgradeFile:(id)path; +- (void) sheetEnded:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +- (BOOL) panel:(id)sender isValidFilename:(NSString *)filename; +- (BOOL) panel:(id)sender shouldShowFilename:(NSString *)filename; +- (BOOL) checkPath:(NSString *)path; +@end + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/PBProject/Patcher/Upgrader.m b/stepmania/PBProject/Patcher/Upgrader.m new file mode 100644 index 0000000000..7d8fcecaec --- /dev/null +++ b/stepmania/PBProject/Patcher/Upgrader.m @@ -0,0 +1,364 @@ +#import "Upgrader.h" +#import "CopyFiles.h" +#include +#include +#include + +@implementation Upgrader + +// Generate English strings using: genstring -o en.lproj Upgrader.m + +static NSString *CHOOSE_FILE; +static NSString *PATCH_FILE; +static NSString *PATCH_COMPLETE; +static NSString *QUIT; +static NSString *ERROR; +static NSString *ERROR_MESSAGE; +static NSString *PATCH_FILES_MISSING; +static NSString *PATCHER_CORRUPTED; +static NSString *CORRUPT_TITLE; +static NSString *PATCHING; +static NSString *SEARCHING; +static NSString *SELECTION; +static NSString *WINDOW_TITLE; + +static NSOpenPanel *panel = nil; + +- (void)awakeFromNib +{ + NSString *path = [[NSBundle mainBundle] pathForResource:@"Identification" ofType:@"txt"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + NSString *stringData = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + + CHOOSE_FILE = NSLocalizedString( @"Choose file to patch.", nil ); + PATCH_FILE = NSLocalizedString( @"Patch file.", nil ); + PATCH_COMPLETE = NSLocalizedString( @"Patch complete.", nil ); + QUIT = NSLocalizedString( @"Quit", nil ); + ERROR = NSLocalizedString( @"Error", nil ); + ERROR_MESSAGE = NSLocalizedString( @"Patching failed:\n%@", nil ); + PATCH_FILES_MISSING = NSLocalizedString( @"Patch files missing.", nil ); + PATCHER_CORRUPTED = NSLocalizedString( @"This patcher has become corrupted.", nil ); + CORRUPT_TITLE = NSLocalizedString( @"Corrupt Patcher", nil ); + PATCHING = NSLocalizedString( @"Patching", nil ); + SEARCHING = NSLocalizedString( @"Searching for %@...", nil ); + SELECTION = NSLocalizedString( @"You have chosen to patch \"%@\" in the folder:\n%@", nil ); + WINDOW_TITLE = NSLocalizedString( @"StepMania Patcher", nil ); + + if( !data ) + { + NSRunCriticalAlertPanel( CORRUPT_TITLE, PATCHER_CORRUPTED, @"OK", nil, nil ); + [NSApp terminate:self]; + } + + m_sName = nil; + m_sAppID = nil; + m_vVersions = nil; + + NSArray *lines = [stringData componentsSeparatedByString:@"\n"]; + NSEnumerator *iter = [lines objectEnumerator]; + NSString *line; + NSMutableArray *versions = [NSMutableArray array]; + + while( (line = [iter nextObject]) ) + { + line = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if( [line length] == 0 || [line characterAtIndex:0] == '#' ) + continue; + if( m_sName == nil ) + { + m_sName = [line retain]; + } + else if( m_sAppID == nil ) + { + m_sAppID = [line retain]; + } + else if( [line isEqualToString:@"-ALL-"] ) + { + versions = nil; + break; + } + else + { + [versions addObject:line]; + } + } + + if( !m_sName || !m_sAppID ) + { + NSRunCriticalAlertPanel( CORRUPT_TITLE, PATCHER_CORRUPTED, @"OK", nil, nil ); + [NSApp terminate:self]; + } + + if( versions && [versions count] ) + m_vVersions = [versions retain]; + + // Set strings. + [m_StatusText setStringValue:[NSString stringWithFormat:SEARCHING, m_sName]]; + [m_SelectionText setStringValue:@""]; + [m_PatchingText setStringValue:PATCHING]; + + [m_Searching setUsesThreadedAnimation:YES]; + [m_ProgressBar setUsesThreadedAnimation:YES]; + [m_Window setTitle:WINDOW_TITLE]; + + [NSThread detachNewThreadSelector:@selector(findApp:) toTarget:self withObject:nil]; + [m_Choose setEnabled:YES]; +} + +- (void) dealloc +{ + [m_sName release]; + [m_sAppID release]; + [m_vVersions release]; + [super dealloc]; +} + +- (IBAction) chooseFile:(id)sender +{ + if( !panel ) + { + panel = [[NSOpenPanel openPanel] retain]; + [panel setCanChooseDirectories:YES]; + [panel setAllowsMultipleSelection:NO]; + [panel setDelegate:self]; + [panel setDirectory:@"/Applications"]; + } + + if( [panel runModal] == NSFileHandlingPanelOKButton ) + { + NSString *dir, *app; + + [m_StatusText setStringValue:PATCH_FILE]; + [m_Okay setEnabled:YES]; + [m_sPath release]; + m_sPath = [[panel filename] retain]; + dir = [m_sPath stringByDeletingLastPathComponent]; + app = [[m_sPath lastPathComponent] stringByDeletingPathExtension]; + [m_SelectionText setStringValue:[NSString stringWithFormat:SELECTION, app, dir]]; + [m_Okay setTitle:@"OK"]; + [m_Okay setAction:@selector(upgrade:)]; + [m_Okay setTarget:self]; + } +} + +- (IBAction) upgrade:(id)sender +{ + [NSApp beginSheet:m_Panel + modalForWindow:[sender window] + modalDelegate:self + didEndSelector:@selector(sheetEnded:returnCode:contextInfo:) + contextInfo:NULL]; + [NSThread detachNewThreadSelector:@selector(upgradeFile:) toTarget:self withObject:m_sPath]; +} + +- (void) findApp:(id)obj +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [m_Searching startAnimation:self]; + + // Find ITG + CFStringRef key = CFSTR( "ApplicationBundlePath" ); + CFPropertyListRef list = CFPreferencesCopyAppValue( key, (CFStringRef)m_sAppID ); + + NSString *sPath = nil; + + if( list && CFGetTypeID(list) != CFDictionaryGetTypeID() ) + { + CFRelease( list ); + list = NULL; + } + if( list ) + { + CFTypeRef value; + CFDictionaryRef dict = (CFDictionaryRef)list; + + if( m_vVersions ) + { + NSEnumerator *iter = [m_vVersions objectEnumerator]; + id version; + + while( (version = [iter nextObject]) ) + { + if( CFDictionaryGetValueIfPresent(dict, (CFStringRef)version, &value) && + CFGetTypeID(value) == CFStringGetTypeID() && + [self checkPath:(NSString *)value] ) + { + sPath = (NSString *)CFRetain( value ); + [sPath autorelease]; + } + } + } + else + { + NSDictionary *dict = (NSDictionary *)list; + NSEnumerator *iter = [dict objectEnumerator]; + id path; + + while( (path = [iter nextObject]) ) + { + if( ![path isKindOfClass:[NSString class]] || ![self checkPath:path] ) + continue; + sPath = [[path retain] autorelease]; + break; + } + } + CFRelease( list ); + } + if( !sPath ) + { + NSWorkspace *ws = [NSWorkspace sharedWorkspace]; + + [ws findApplications]; + sPath = [ws fullPathForApplication:m_sName]; + + if( ![self checkPath:sPath] ) + sPath = nil; + } + [self performSelectorOnMainThread:@selector(foundApp:) withObject:sPath waitUntilDone:YES]; + [m_Searching stopAnimation:self]; + [pool release]; +} + +- (void) foundApp:(id)obj +{ + NSString *path = (NSString *)obj; + + if( path ) // found + { + NSString *dir = [path stringByDeletingLastPathComponent]; + NSString *app = [[path lastPathComponent] stringByDeletingPathExtension]; + + [m_sPath release]; + m_sPath = [path retain]; + [m_Okay setEnabled:YES]; + [m_StatusText setStringValue:PATCH_FILE]; + [m_SelectionText setStringValue:[NSString stringWithFormat:SELECTION, app, dir]]; + } + else + { + m_sPath = @""; + [m_StatusText setStringValue:CHOOSE_FILE]; + } + [m_Choose setEnabled:YES]; + [m_Choose setNeedsDisplay:YES]; + [m_Okay setNeedsDisplay:YES]; + [m_StatusText setNeedsDisplay:YES]; + [m_SelectionText setNeedsDisplay:YES]; +} + +- (void) upgradeFile:(id)path +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSBundle *bundle = [NSBundle mainBundle]; + NSString *patch = [bundle pathForResource:@"Contents" ofType:@"" inDirectory:@"Patch"]; + NSArray *parentFiles = [bundle pathsForResourcesOfType:@"" inDirectory:@"Patch/ParentContents"]; + + if( patch && parentFiles) + { + [m_ProgressBar startAnimation:self]; + + if( NeedsPrivs(path) ) + m_sError = CopyWithPrivs( patch, path ); + else + m_sError = Copy( patch, path ); + + path = [path stringByDeletingLastPathComponent]; + NSEnumerator *enumerator = [parentFiles objectEnumerator]; + while( !m_sError && (patch = [enumerator nextObject]) ) + { + if( NeedsPrivs(path) ) + m_sError = CopyWithPrivs( patch, path ); + else + m_sError = Copy( patch, path ); + } + + [m_ProgressBar stopAnimation:self]; + } + else + { + m_sError = PATCH_FILES_MISSING; + } + [NSApp performSelectorOnMainThread:@selector(endSheet:) withObject:m_Panel waitUntilDone:YES]; + [pool release]; +} + +- (void) sheetEnded:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + [m_Panel orderOut:self]; + if( m_sError ) + { + NSRunCriticalAlertPanel( ERROR, ERROR_MESSAGE, @"OK", nil, nil, m_sError ); + return; + } + [m_StatusText setStringValue:PATCH_COMPLETE]; + [m_Okay setTitle:QUIT]; + [m_Okay setAction:@selector(terminate:)]; + [m_Okay setTarget:NSApp]; +} + +- (BOOL) panel:(id)sender isValidFilename:(NSString *)filename +{ + return [filename hasSuffix:@".app"] && [self checkPath:filename]; +} + +- (BOOL) panel:(id)sender shouldShowFilename:(NSString *)filename +{ + if( [filename hasSuffix:@".app"] ) + return [self checkPath:filename]; + + struct stat sb; + + if( stat([filename UTF8String], &sb) ) + return NO; + return (sb.st_mode & S_IFDIR) == S_IFDIR; +} + +- (BOOL) checkPath:(NSString *)path +{ + NSBundle *b = [NSBundle bundleWithPath:path]; + + if( !b ) + return NO; + if( ![[b objectForInfoDictionaryKey:@"CFBundleIdentifier"] isEqualToString:m_sAppID] ) + return NO; + if( m_vVersions == nil ) + return YES; + + NSString *bundleVersion = [b objectForInfoDictionaryKey:@"CFBundleVersion"]; + NSEnumerator *iter = [m_vVersions objectEnumerator]; + NSString *version; + + while( (version = [iter nextObject]) ) + if( [bundleVersion isEqualToString:version] ) + return YES; + return NO; +} + +@end + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/stepmania/PBProject/Patcher/en.lproj/InfoPlist.strings b/stepmania/PBProject/Patcher/en.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..4e6d64404c65b4d7da06b3655f614e3636171dc7 GIT binary patch literal 198 zcmW-bI|{;35JgYzDuQJY6$=}&vQZEVvw|2CBWe;7Kg1omN%im;nBTki%=`YB5EHSb zCL`s_nKwB{cTa0e=ccBzM%Kc-aVqS`G(q2ScY9IY2URR{VC+a(^WY}8V()t@H|3x! pXC@x{s$9f#dxx65X$8zPJj}V<-mAfS4Ab&(($xv-BZjKViVh=H4KV{Fg zSz)x;J&eYvjcW7H#=iV<&^{?jo(MN7*h>xQ3C;&6P`a8^oG+YMu3IzvzAsK&nE$_P zjN|Py(9c)CE#MdZ;q>I}%<;B9GYu-csafN{(R`9?q_WKFSSNM4^$cuU^CzvH?^ge* z9O3lrYvWA0V@ + + + + IBDocumentLocation + 39 98 356 240 0 0 1920 1178 + IBEditorPositions + + 29 + 207 529 151 44 0 0 1920 1178 + + IBFramework Version + 446.1 + IBOpenObjects + + 29 + 217 + + IBSystem Version + 8J135 + IBUserGuides + + 21 + + guideLocations + + Horizontal:180.000000 + + guidesLocked + + + + + diff --git a/stepmania/PBProject/Patcher/en.lproj/MainMenu.nib/keyedobjects.nib b/stepmania/PBProject/Patcher/en.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..e8c4bb6372d55a0d9e72cb3e14125f77ede3c520 GIT binary patch literal 11375 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 Ut58Jb@BQJAeNcVx{9iizzoiRD!2kdN literal 0 HcmV?d00001 diff --git a/stepmania/PBProject/Patcher/main.m b/stepmania/PBProject/Patcher/main.m new file mode 100644 index 0000000000..692105e5d2 --- /dev/null +++ b/stepmania/PBProject/Patcher/main.m @@ -0,0 +1,29 @@ +int main( int argc, const char *argv[] ) +{ + return NSApplicationMain( argc, argv ); +} + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */