1/* 2 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// bundlerepository - directory search paths for bundles 27// 28#ifndef _H_BUNDLEREPOSITORY 29#define _H_BUNDLEREPOSITORY 30 31#include <security_utilities/cfutilities.h> 32#include <security_utilities/refcount.h> 33#include <CoreFoundation/CoreFoundation.h> 34#include <string> 35#include <vector> 36 37 38namespace Security { 39 40 41// 42// PathList abstracts a directory search path. 43// It's not really powerful enough to be useful on its own. 44// 45class PathList { 46public: 47 PathList(); 48 PathList(const string &subPath, const char *suffix = NULL, 49 const char *envar = NULL, bool forUser = true); 50 virtual ~PathList(); 51 52 void addDirectory(const string &dirPath); 53 54protected: 55 vector<string> mPaths; 56 string mSuffix; 57 IFDEBUG(string mDebugOverride); 58}; 59 60 61// 62// CodeRepository<Code> represents all code objects within the PathList search path, 63// represented forcibly as objects of type Code. 64// 65template <class Code> 66class CodeRepository : public vector<RefPointer<Code> >, public PathList { 67public: 68 CodeRepository() { } // empty - populate with paths 69 CodeRepository(const string &subPath, const char *suffix = NULL, 70 const char *envar = NULL, bool forUser = true) 71 : PathList(subPath, suffix, envar, forUser) { } 72 73 void update(); 74}; 75 76 77// 78// The generic implementation of update works with subclasses of GenericBundle, 79// represented through CFBundleRefs collected via CFBundle. 80// (Technically, this would work with anything that has a constructor from CFBundleRef.) 81// If we ever wanted a CodeRepository<ExecutableTool>, we'd specialize update() to deal with 82// ExecutableTool's slightly different constructor. 83// 84template <class Code> 85void CodeRepository<Code>::update() 86{ 87 vector<RefPointer<Code> > result; 88 for (vector<string>::const_iterator it = mPaths.begin(); it != mPaths.end(); it++) { 89 if (CFRef<CFArrayRef> bundles = CFBundleCreateBundlesFromDirectory(NULL, 90 CFTempURL(*it, true), mSuffix.empty() ? NULL : CFStringRef(CFTempString(mSuffix)))) { 91 CFIndex count = CFArrayGetCount(bundles); 92 secdebug("coderep", "%p directory %s has %ld entries", this, it->c_str(), count); 93 for (CFIndex n = 0; n < count; n++) 94 try { 95 result.push_back(new Code((CFBundleRef)CFArrayGetValueAtIndex(bundles, n))); 96 } catch (...) { 97 secdebug("coderep", "%p exception creating %s (skipped)", 98 this, cfString(CFBundleRef(CFArrayGetValueAtIndex(bundles, n))).c_str()); 99 } 100 } else 101 secdebug("coderep", "directory %s bundle read failed", it->c_str()); 102 } 103 secdebug("coderep", "%p total of %ld items in list", this, result.size()); 104 this->swap(result); 105} 106 107 108} // end namespace Security 109 110#endif //_H_BUNDLEREPOSITORY 111