2 * Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 // diskrep - disk representations of code
29 #include <CoreFoundation/CFBundlePriv.h>
31 // specific disk representations created by the bestGuess() function
32 #include "filediskrep.h"
33 #include "bundlediskrep.h"
34 #include "cfmdiskrep.h"
35 #include "foreigndiskrep.h"
39 namespace CodeSigning
{
41 using namespace UnixPlusPlus
;
56 // Normal DiskReps are their own base.
58 DiskRep
*DiskRep::base()
65 // By default, DiskReps are read-only.
67 DiskRep::Writer
*DiskRep::writer()
69 MacOSError::throwMe(errSecCSBadObjectFormat
);
74 // Given a file system path, come up with the most likely correct
75 // disk representation for what's there.
76 // This is, strictly speaking, a heuristic that could be fooled - there's
77 // no fool-proof rule for figuring this out. But we'd expect this to work
78 // fine in ordinary use. If you happen to know what you're looking at
79 // (say, a bundle), then just create the suitable subclass of DiskRep directly.
80 // That's quite legal.
82 DiskRep
*DiskRep::bestGuess(const char *path
)
86 if (::stat(path
, &st
))
89 // if it's a directory, assume it's a bundle
90 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) // directory - assume bundle
91 return new BundleDiskRep(path
);
93 // see if it's the main executable of a recognized bundle
94 if (CFRef
<CFURLRef
> pathURL
= makeCFURL(path
))
95 if (CFRef
<CFBundleRef
> bundle
= _CFBundleCreateWithExecutableURLIfMightBeBundle(NULL
, pathURL
))
96 return new BundleDiskRep(bundle
);
98 // follow the file choosing rules
99 return bestFileGuess(path
);
100 } catch (const CommonError
&error
) {
101 switch (error
.unixError()) {
103 MacOSError::throwMe(errSecCSStaticCodeNotFound
);
111 DiskRep
*DiskRep::bestFileGuess(const char *path
)
113 AutoFileDesc
fd(path
, O_RDONLY
);
114 if (MachORep::candidiate(fd
))
115 return new MachORep(path
);
116 if (CFMDiskRep::candidiate(fd
))
117 return new CFMDiskRep(path
);
118 if (ForeignDiskRep::candidate(fd
))
119 return new ForeignDiskRep(path
);
121 return new FileDiskRep(path
);
126 // Default behaviors of DiskRep
128 string
DiskRep::resourcesRootPath()
130 return ""; // has no resources directory
133 CFDictionaryRef
DiskRep::defaultResourceRules()
138 void DiskRep::adjustResources(ResourceBuilder
&builder
)
143 const Requirements
*DiskRep::defaultRequirements(const Architecture
*)
148 Universal
*DiskRep::mainExecutableImage()
150 return NULL
; // no Mach-O executable
153 size_t DiskRep::pageSize()
155 return monolithicPageSize
; // unpaged (monolithic)
158 size_t DiskRep::signingBase()
160 return 0; // whole file (start at beginning)
163 CFArrayRef
DiskRep::modifiedFiles()
165 // by default, claim (just) the main executable modified
166 CFRef
<CFURLRef
> mainURL
= makeCFURL(mainExecutablePath());
167 return makeCFArray(1, mainURL
.get());
170 void DiskRep::flush()
179 DiskRep::Writer::Writer(uint32_t attrs
)
180 : mArch(CPU_TYPE_ANY
), mAttributes(attrs
)
184 DiskRep::Writer::~Writer()
187 uint32_t DiskRep::Writer::attributes() const
188 { return mAttributes
; }
190 void DiskRep::Writer::flush()
194 } // end namespace CodeSigning
195 } // end namespace Security