coderepository.cpp [plain text]
#include <security_utilities/coderepository.h>
#include <security_utilities/debugging.h>
namespace Security {
PathList::PathList()
{
}
PathList::PathList(const string &subPath,
const char *suffix ,
const char *envar ,
bool forUser )
: mSuffix(suffix)
{
if (envar)
if (const char *envPath = getenv(envar)) {
#if !defined(NDEBUG)
if (envPath[0] == '!') {
mDebugOverride = envPath + 1;
secdebug("pathlist", "%p env(\"%s\") overrides to \"%s\"",
this, envar, mDebugOverride.c_str());
return;
}
#endif //NDEBUG
secdebug("pathlist", "%p configuring from env(\"%s\")", this, envar);
while (const char *p = strchr(envPath, ':')) {
addDirectory(string(envPath, p - envPath));
envPath = p + 1;
}
addDirectory(envPath);
return;
}
secdebug("pathlist", "%p configuring from default path set \"%s\"", this, subPath.c_str());
if (forUser)
secdebug("pathlist", "user search list not yet implemented");
addDirectory("/Library/" + subPath);
addDirectory("/System/Library/" + subPath);
}
PathList::~PathList()
{
}
void PathList::addDirectory(const string &dirPath)
{
mPaths.push_back(dirPath);
}
template <class Code>
void CodeRepository<Code>::update()
{
#if !defined(NDEBUG)
if (!mDebugOverride.empty()) {
erase(this->begin(), this->end());
try {
push_back(OSXCode::at<Code>(mDebugOverride));
secdebug("coderep", "%p debug override to (just) %s", this, mDebugOverride.c_str());
return;
} catch (...) {
secdebug("coderep", "%p debug override failed, proceeding normally", this);
}
}
#endif //NDEBUG
vector<RefPointer<Code> > result;
for (vector<string>::const_iterator it = mPaths.begin(); it != mPaths.end(); it++) {
if (CFRef<CFArrayRef> bundles = CFBundleCreateBundlesFromDirectory(NULL,
CFTempURL(*it, true), mSuffix.empty() ? NULL : CFStringRef(CFTempString(mSuffix)))) {
CFIndex count = CFArrayGetCount(bundles);
secdebug("coderep", "%p directory %s has %ld entries", this, it->c_str(), count);
for (CFIndex n = 0; n < count; n++)
try {
result.push_back(new Code((CFBundleRef)CFArrayGetValueAtIndex(bundles, n)));
} catch (...) {
secdebug("coderep", "%p exception creating %s (skipped)",
this, cfString(CFBundleRef(CFArrayGetValueAtIndex(bundles, n))).c_str());
}
} else
secdebug("coderep", "directory %s bundle read failed", it->c_str());
}
secdebug("coderep", "%p total of %ld items in list", this, result.size());
this->swap(result);
}
template void CodeRepository<GenericBundle>::update();
template void CodeRepository<ApplicationBundle>::update();
template void CodeRepository<LoadableBundle>::update();
}