// CVLoaderService.mm: CocoaVanilla loader utilities // // Copyright (c) 2004-2006 The OpenVanilla Project (http://openvanilla.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. Neither the name of OpenVanilla nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // #define OV_DEBUG #include "CVLoaderUtility.h" #include #include #include #include // #define CVLOADER_USE_ATOMIC_LOCK OVLoadedLibrary *CVLoadLibraryFromBundle(NSString *p); OVLoadedLibrary *CVLoadLibraryFromDylib(NSString *p); // we still need the full pathname of the loaded library because we need // to extract the loaded path (and then append /Contents for .bundle!) // that is required for the loaded modules in the initialization process; // we also need to supply a dictionary to prevent module-id conflicts NSString *CVGetRealLoadedPath(NSString *libname); NSArray *CVMilkModulesFromLibrary(NSString *libname, OVLoadedLibrary *lib, NSMutableDictionary *namedict, NSMutableArray *history); NSArray* CVLoadEverything(NSArray *paths, OVService *srv, NSArray *libexcludelist, NSArray *modexcludelist, NSMutableDictionary *history, NSString *atomic) { const char *func="CVLoadEveryThing"; // (add statically linked modules) NSMutableArray *libList=[[NSMutableArray new] autorelease]; NSMutableArray *modList=[[NSMutableArray new] autorelease]; NSMutableDictionary *dict=[[NSMutableDictionary new] autorelease]; NSMutableDictionary *histdict=[[NSMutableDictionary new] autorelease]; NSEnumerator *enm=[paths objectEnumerator]; NSString *i; while (i=[enm nextObject]) { [libList addObjectsFromArray:CVEnumeratePath(i, @".bundle")]; [libList addObjectsFromArray:CVEnumeratePath(i, @".app")]; [libList addObjectsFromArray:CVEnumeratePath(i, @".dylib")]; } // add module-exclusion list into the named dict if (modexcludelist) { int c=[modexcludelist count]; for (int i=0; iinitialize(srv, [rlp UTF8String])) { murmur("%s: library initialization failed (%s), module milking ignored", func, [i UTF8String]); continue; } NSMutableArray *ha=[[NSMutableArray new] autorelease]; [modList addObjectsFromArray: CVMilkModulesFromLibrary(i, l, dict, ha)]; [histdict setValue:ha forKey:i]; CVAtomicInitEnd(atomic); } if (history) [history addEntriesFromDictionary:histdict]; return modList; } void CVAtomicInitStart(NSString *f, NSString *libname) { if (!f) return; // NSError *err; // NSLog(@"writing atomicinit file %@ for lib %@", f, libname); // this won't work in OS X 10.3 // [libname writeToFile:f atomically:NO encoding:NSUTF8StringEncoding error:&err]; #ifdef CVLOADER_USE_ATOMIC_LOCK [libname writeToFile:f atomically:NO]; #endif } void CVAtomicInitEnd(NSString *f) { if (!f) return; #ifdef CVLOADER_USE_ATOMIC_LOCK if (CVIfPathExists(f)) { // NSLog(@"unlinking existing atomicinit file: %@", f); unlink([f UTF8String]); } #endif } BOOL CVStringIsInArray(NSString *s, NSArray *a) { if (!a) return NO; int c=[a count]; for (int i=0; igetModule(idx); idx++) { // murmur("%s: loading module idx %d (module id=%s) from library %s", func, idx, m->identifier(), [shortName UTF8String]); NSString *i=[NSString stringWithUTF8String:m->identifier()]; if ([namedict objectForKey: i]) { murmur("%s: module '%s' already exists or in exclude-list!", func, m->identifier()); } else { [namedict setObject: @"1" forKey: i]; [a addObject: [[[CVModuleWrapper alloc] initWithModule:m loadedPath:realPath fromLibrary:libname] autorelease]]; if (history) [history addObject:i]; } } return a; } BOOL CVIfPathExists(NSString *p) { struct stat st; if (stat([[p stringByStandardizingPath] UTF8String], &st)) return NO; return YES; }