#ifndef _H_OSXCODE
#define _H_OSXCODE
#include <security_utilities/codesigning.h>
#include <security_utilities/refcount.h>
#include <security_utilities/cfutilities.h>
#include <limits.h>
#include <string>
#include <vector>
#include <CoreFoundation/CFBundle.h>
namespace Security {
class OSXCode : public RefCount, public CodeSigning::Signable {
public:
virtual string encode() const = 0;
static OSXCode *decode(const char *extForm);
public:
static RefPointer<OSXCode> main();
static RefPointer<OSXCode> at(const char *path);
static RefPointer<OSXCode> at(const std::string &path)
{ return at(path.c_str()); }
template <class Code>
static RefPointer<Code> main() { return restrict<Code>(main()); }
template <class Code>
static RefPointer<Code> at(const char *path) { return restrict<Code>(at(path)); }
template <class Code>
static RefPointer<Code> at(const std::string &path) { return restrict<Code>(at(path)); }
template <class Sub>
static RefPointer<Sub> restrict(RefPointer<OSXCode> in)
{
if (Sub *sub = dynamic_cast<Sub *>(in.get()))
return sub;
else
UnixError::throwMe(ENOEXEC);
}
public:
virtual string canonicalPath() const = 0;
virtual string executablePath() const = 0;
protected:
OSXCode() { } static void scanFile(const char *pathname, CodeSigning::Signer::State &state); };
class ExecutableTool : public OSXCode {
public:
ExecutableTool(const char *path) : mPath(path) { }
string encode() const;
string path() const { return mPath; }
string canonicalPath() const;
string executablePath() const;
protected:
void scanContents(CodeSigning::Signer::State &state) const;
private:
string mPath; };
class GenericBundle : public OSXCode {
public:
GenericBundle(const char *path, const char *execPath = NULL); GenericBundle(CFBundleRef bundle, const char *root = NULL); ~GenericBundle();
string encode() const;
string canonicalPath() const;
string path() const { return mPath; }
string executablePath() const;
string identifier() const { return cfString(CFBundleGetIdentifier(cfBundle())); }
CFTypeRef infoPlistItem(const char *name) const;
string resourcePath() const { return cfString(CFBundleCopyResourcesDirectoryURL(cfBundle()), true); }
string resource(const char *name, const char *type, const char *subdir = NULL);
void resources(vector<string> &paths, const char *type, const char *subdir = NULL);
virtual void *lookupSymbol(const char *name);
protected:
void scanContents(CodeSigning::Signer::State &state) const;
CFBundleRef cfBundle() const;
protected:
string mPath; mutable string mExecutablePath; mutable CFBundleRef mBundle; };
class ApplicationBundle : public GenericBundle {
public:
ApplicationBundle(const char *pathname) : GenericBundle(pathname) { }
ApplicationBundle(CFBundleRef bundle) : GenericBundle(bundle) { }
};
class LoadableBundle : public GenericBundle {
public:
LoadableBundle(const char *pathname) : GenericBundle(pathname) { }
LoadableBundle(CFBundleRef bundle) : GenericBundle(bundle) { }
virtual bool isLoaded() const;
virtual void load();
virtual void unload();
};
}
#endif //_H_OSXCODE