]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/dy_framework.c
9366fe4f0d24b5ca5f51c1ed2fec6031cdb9e8c3
[apple/configd.git] / SystemConfiguration.fproj / dy_framework.c
1 /*
2 * Copyright (c) 2002-2008, 2010-2012 Apple 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 * Modification History
26 *
27 * October 31, 2000 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/stat.h>
35 #include <dlfcn.h>
36
37 #include "dy_framework.h"
38
39
40
41 #pragma mark -
42 #pragma mark IOKit.framework APIs
43
44 static void *
45 __loadIOKit(void) {
46 static void *image = NULL;
47 if (NULL == image) {
48 const char *framework = "/System/Library/Frameworks/IOKit.framework/IOKit";
49 struct stat statbuf;
50 const char *suffix = getenv("DYLD_IMAGE_SUFFIX");
51 char path[MAXPATHLEN];
52
53 strlcpy(path, framework, sizeof(path));
54 if (suffix) strlcat(path, suffix, sizeof(path));
55 if (0 <= stat(path, &statbuf)) {
56 image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
57 } else {
58 image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
59 }
60 }
61 return (void *)image;
62 }
63
64
65 __private_extern__ CFMutableDictionaryRef
66 _IOBSDNameMatching(mach_port_t masterPort, uint32_t options, const char *bsdName)
67 {
68 #undef IOBSDNameMatching
69 static typeof (IOBSDNameMatching) *dyfunc = NULL;
70 if (!dyfunc) {
71 void *image = __loadIOKit();
72 if (image) dyfunc = dlsym(image, "IOBSDNameMatching");
73 }
74 return dyfunc ? dyfunc(masterPort, options, bsdName) : NULL;
75 }
76
77
78 __private_extern__ io_object_t
79 _IOIteratorNext(io_iterator_t iterator)
80 {
81 #undef IOIteratorNext
82 static typeof (IOIteratorNext) *dyfunc = NULL;
83 if (!dyfunc) {
84 void *image = __loadIOKit();
85 if (image) dyfunc = dlsym(image, "IOIteratorNext");
86 }
87 return dyfunc ? dyfunc(iterator) : 0;
88 }
89
90
91 __private_extern__ kern_return_t
92 _IOMasterPort(mach_port_t bootstrapPort, mach_port_t *masterPort)
93 {
94 #undef IOMasterPort
95 static typeof (IOMasterPort) *dyfunc = NULL;
96 if (!dyfunc) {
97 void *image = __loadIOKit();
98 if (image) dyfunc = dlsym(image, "IOMasterPort");
99 }
100 return dyfunc ? dyfunc(bootstrapPort, masterPort) : KERN_FAILURE;
101 }
102
103
104 __private_extern__ boolean_t
105 _IOObjectConformsTo(io_object_t object, const io_name_t className)
106 {
107 #undef IOObjectConformsTo
108 static typeof (IOObjectConformsTo) *dyfunc = NULL;
109 if (!dyfunc) {
110 void *image = __loadIOKit();
111 if (image) dyfunc = dlsym(image, "IOObjectConformsTo");
112 }
113 return dyfunc ? dyfunc(object, className) : FALSE;
114 }
115
116
117 __private_extern__ boolean_t
118 _IOObjectGetClass(io_object_t object, io_name_t className)
119 {
120 #undef IOObjectGetClass
121 static typeof (IOObjectGetClass) *dyfunc = NULL;
122 if (!dyfunc) {
123 void *image = __loadIOKit();
124 if (image) dyfunc = dlsym(image, "IOObjectGetClass");
125 }
126 return dyfunc ? dyfunc(object, className) : FALSE;
127 }
128
129
130 __private_extern__ kern_return_t
131 _IOObjectRelease(io_object_t object)
132 {
133 #undef IOObjectRelease
134 static typeof (IOObjectRelease) *dyfunc = NULL;
135 if (!dyfunc) {
136 void *image = __loadIOKit();
137 if (image) dyfunc = dlsym(image, "IOObjectRelease");
138 }
139 return dyfunc ? dyfunc(object) : KERN_FAILURE;
140 }
141
142
143 __private_extern__ CFTypeRef
144 _IORegistryEntryCreateCFProperty(io_registry_entry_t entry, CFStringRef key, CFAllocatorRef allocator, IOOptionBits options)
145 {
146 #undef IORegistryEntryCreateCFProperty
147 static typeof (IORegistryEntryCreateCFProperty) *dyfunc = NULL;
148 if (!dyfunc) {
149 void *image = __loadIOKit();
150 if (image) dyfunc = dlsym(image, "IORegistryEntryCreateCFProperty");
151 }
152 return dyfunc ? dyfunc(entry, key, allocator, options) : NULL;
153 }
154
155
156 __private_extern__ kern_return_t
157 _IORegistryEntryCreateCFProperties(io_registry_entry_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, IOOptionBits options)
158 {
159 #undef IORegistryEntryCreateCFProperties
160 static typeof (IORegistryEntryCreateCFProperties) *dyfunc = NULL;
161 if (!dyfunc) {
162 void *image = __loadIOKit();
163 if (image) dyfunc = dlsym(image, "IORegistryEntryCreateCFProperties");
164 }
165 return dyfunc ? dyfunc(entry, properties, allocator, options) : KERN_FAILURE;
166 }
167
168
169 __private_extern__ kern_return_t
170 _IORegistryEntryCreateIterator(mach_port_t masterPort, const io_name_t plane, IOOptionBits options, io_iterator_t *iterator)
171 {
172 #undef IORegistryEntryCreateIterator
173 static typeof (IORegistryEntryCreateIterator) *dyfunc = NULL;
174 if (!dyfunc) {
175 void *image = __loadIOKit();
176 if (image) dyfunc = dlsym(image, "IORegistryEntryCreateIterator");
177 }
178 return dyfunc ? dyfunc(masterPort, plane, options, iterator) : KERN_FAILURE;
179 }
180
181
182 __private_extern__ kern_return_t
183 _IORegistryEntryGetLocationInPlane(io_registry_entry_t entry, const io_name_t plane, io_name_t location)
184 {
185 #undef IORegistryEntryGetLocationInPlane
186 static typeof (IORegistryEntryGetLocationInPlane) *dyfunc = NULL;
187 if (!dyfunc) {
188 void *image = __loadIOKit();
189 if (image) dyfunc = dlsym(image, "IORegistryEntryGetLocationInPlane");
190 }
191 return dyfunc ? dyfunc(entry, plane, location) : KERN_FAILURE;
192 }
193
194
195 __private_extern__ kern_return_t
196 _IORegistryEntryGetName(io_registry_entry_t entry, io_name_t name)
197 {
198 #undef IORegistryEntryGetName
199 static typeof (IORegistryEntryGetName) *dyfunc = NULL;
200 if (!dyfunc) {
201 void *image = __loadIOKit();
202 if (image) dyfunc = dlsym(image, "IORegistryEntryGetName");
203 }
204 return dyfunc ? dyfunc(entry, name) : KERN_FAILURE;
205 }
206
207
208 __private_extern__ kern_return_t
209 _IORegistryEntryGetNameInPlane(io_registry_entry_t entry, const io_name_t plane, io_name_t name)
210 {
211 #undef IORegistryEntryGetNameInPlane
212 static typeof (IORegistryEntryGetNameInPlane) *dyfunc = NULL;
213 if (!dyfunc) {
214 void *image = __loadIOKit();
215 if (image) dyfunc = dlsym(image, "IORegistryEntryGetNameInPlane");
216 }
217 return dyfunc ? dyfunc(entry, plane, name) : KERN_FAILURE;
218 }
219
220
221 __private_extern__ kern_return_t
222 _IORegistryEntryGetParentEntry(io_registry_entry_t entry, const io_name_t plane, io_registry_entry_t *parent)
223 {
224 #undef IORegistryEntryGetParentEntry
225 static typeof (IORegistryEntryGetParentEntry) *dyfunc = NULL;
226 if (!dyfunc) {
227 void *image = __loadIOKit();
228 if (image) dyfunc = dlsym(image, "IORegistryEntryGetParentEntry");
229 }
230 return dyfunc ? dyfunc(entry, plane, parent) : KERN_FAILURE;
231 }
232
233
234 __private_extern__ kern_return_t
235 _IORegistryEntryGetPath(io_registry_entry_t entry, const io_name_t plane, io_string_t path)
236 {
237 #undef IORegistryEntryGetPath
238 static typeof (IORegistryEntryGetPath) *dyfunc = NULL;
239 if (!dyfunc) {
240 void *image = __loadIOKit();
241 if (image) dyfunc = dlsym(image, "IORegistryEntryGetPath");
242 }
243 return dyfunc ? dyfunc(entry, plane, path) : KERN_FAILURE;
244 }
245
246
247 __private_extern__ kern_return_t
248 _IORegistryEntryGetRegistryEntryID(io_registry_entry_t entry, uint64_t *entryID)
249 {
250 #undef IORegistryEntryGetRegistryEntryID
251 static typeof (IORegistryEntryGetRegistryEntryID) *dyfunc = NULL;
252 if (!dyfunc) {
253 void *image = __loadIOKit();
254 if (image) dyfunc = dlsym(image, "IORegistryEntryGetRegistryEntryID");
255 }
256 return dyfunc ? dyfunc(entry, entryID) : KERN_FAILURE;
257 }
258
259
260 __private_extern__ CFTypeRef
261 _IORegistryEntrySearchCFProperty(io_registry_entry_t entry, const io_name_t plane, CFStringRef key, CFAllocatorRef allocator, IOOptionBits options)
262 {
263 #undef IORegistryEntrySearchCFProperty
264 static typeof (IORegistryEntrySearchCFProperty) *dyfunc = NULL;
265 if (!dyfunc) {
266 void *image = __loadIOKit();
267 if (image) dyfunc = dlsym(image, "IORegistryEntrySearchCFProperty");
268 }
269 return dyfunc ? dyfunc(entry, plane, key, allocator, options) : NULL;
270 }
271
272
273 __private_extern__ kern_return_t
274 _IOServiceGetMatchingServices(mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t *existing)
275 {
276 #undef IOServiceGetMatchingServices
277 static typeof (IOServiceGetMatchingServices) *dyfunc = NULL;
278 if (!dyfunc) {
279 void *image = __loadIOKit();
280 if (image) dyfunc = dlsym(image, "IOServiceGetMatchingServices");
281 }
282 return dyfunc ? dyfunc(masterPort, matching, existing) : KERN_FAILURE;
283 }
284
285
286 __private_extern__ CFMutableDictionaryRef
287 _IOServiceMatching(const char *name)
288 {
289 #undef IOServiceMatching
290 static typeof (IOServiceMatching) *dyfunc = NULL;
291 if (!dyfunc) {
292 void *image = __loadIOKit();
293 if (image) dyfunc = dlsym(image, "IOServiceMatching");
294 }
295 return dyfunc ? dyfunc(name) : NULL;
296 }
297
298 #pragma mark -
299 #pragma mark Security.framework APIs
300
301 static void *
302 __loadSecurity(void) {
303 static void *image = NULL;
304 if (NULL == image) {
305 const char *framework = "/System/Library/Frameworks/Security.framework/Security";
306 struct stat statbuf;
307 const char *suffix = getenv("DYLD_IMAGE_SUFFIX");
308 char path[MAXPATHLEN];
309
310 strlcpy(path, framework, sizeof(path));
311 if (suffix) strlcat(path, suffix, sizeof(path));
312 if (0 <= stat(path, &statbuf)) {
313 image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
314 } else {
315 image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
316 }
317 }
318 return (void *)image;
319 }
320
321 #define SECURITY_FRAMEWORK_EXTERN(t, s) \
322 __private_extern__ t \
323 _ ## s() \
324 { \
325 static t *dysym = NULL; \
326 if (!dysym) { \
327 void *image = __loadSecurity(); \
328 if (image) dysym = dlsym(image, #s ); \
329 } \
330 return (dysym != NULL) ? *dysym : NULL; \
331 }
332
333 #if !TARGET_OS_IPHONE
334 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecAttrService)
335 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecClass)
336 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecClassGenericPassword)
337 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchLimit)
338 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchLimitAll)
339 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecMatchSearchList)
340 SECURITY_FRAMEWORK_EXTERN(CFTypeRef, kSecReturnRef)
341
342 __private_extern__ OSStatus
343 _AuthorizationMakeExternalForm(AuthorizationRef authorization, AuthorizationExternalForm *extForm)
344 {
345 #undef AuthorizationMakeExternalForm
346 static typeof (AuthorizationMakeExternalForm) *dyfunc = NULL;
347 if (!dyfunc) {
348 void *image = __loadSecurity();
349 if (image) dyfunc = dlsym(image, "AuthorizationMakeExternalForm");
350 }
351 return dyfunc ? dyfunc(authorization, extForm) : -1;
352 }
353
354 __private_extern__ OSStatus
355 _SecAccessCreate(CFStringRef descriptor, CFArrayRef trustedlist, SecAccessRef *accessRef)
356 {
357 #undef SecAccessCreate
358 static typeof (SecAccessCreate) *dyfunc = NULL;
359 if (!dyfunc) {
360 void *image = __loadSecurity();
361 if (image) dyfunc = dlsym(image, "SecAccessCreate");
362 }
363 return dyfunc ? dyfunc(descriptor, trustedlist, accessRef) : -1;
364 }
365
366 #if (__MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
367 __private_extern__ OSStatus
368 _SecAccessCreateFromOwnerAndACL(const CSSM_ACL_OWNER_PROTOTYPE *owner, uint32 aclCount, const CSSM_ACL_ENTRY_INFO *acls, SecAccessRef *accessRef)
369 {
370 #undef SecAccessCreateFromOwnerAndACL
371 static typeof (SecAccessCreateFromOwnerAndACL) *dyfunc = NULL;
372 if (!dyfunc) {
373 void *image = __loadSecurity();
374 if (image) dyfunc = dlsym(image, "SecAccessCreateFromOwnerAndACL");
375 }
376 return dyfunc ? dyfunc(owner, aclCount, acls, accessRef) : -1;
377 }
378 #else // (__MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
379 __private_extern__ SecAccessRef
380 _SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAccessOwnerType ownerType, CFArrayRef acls, CFErrorRef *error)
381 {
382 #undef SecAccessCreateWithOwnerAndACL
383 static typeof (SecAccessCreateWithOwnerAndACL) *dyfunc = NULL;
384 if (!dyfunc) {
385 void *image = __loadSecurity();
386 if (image) dyfunc = dlsym(image, "SecAccessCreateWithOwnerAndACL");
387 }
388 return dyfunc ? dyfunc(userId, groupId, ownerType, acls, error) : NULL;
389 }
390 #endif // (__MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
391
392 __private_extern__ OSStatus
393 _SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)
394 {
395 #undef SecItemCopyMatching
396 static typeof (SecItemCopyMatching) *dyfunc = NULL;
397 if (!dyfunc) {
398 void *image = __loadSecurity();
399 if (image) dyfunc = dlsym(image, "SecItemCopyMatching");
400 }
401 return dyfunc ? dyfunc(query, result) : -1;
402 }
403
404 __private_extern__ OSStatus
405 _SecKeychainCopyDomainDefault(SecPreferencesDomain domain, SecKeychainRef *keychain)
406 {
407 #undef SecKeychainCopyDomainDefault
408 static typeof (SecKeychainCopyDomainDefault) *dyfunc = NULL;
409 if (!dyfunc) {
410 void *image = __loadSecurity();
411 if (image) dyfunc = dlsym(image, "SecKeychainCopyDomainDefault");
412 }
413 return dyfunc ? dyfunc(domain, keychain) : -1;
414 }
415
416 __private_extern__ OSStatus
417 _SecKeychainGetPreferenceDomain(SecPreferencesDomain *domain)
418 {
419 #undef SecKeychainGetPreferenceDomain
420 static typeof (SecKeychainGetPreferenceDomain) *dyfunc = NULL;
421 if (!dyfunc) {
422 void *image = __loadSecurity();
423 if (image) dyfunc = dlsym(image, "SecKeychainGetPreferenceDomain");
424 }
425 return dyfunc ? dyfunc(domain) : -1;
426 }
427
428 __private_extern__ OSStatus
429 _SecKeychainOpen(const char *pathName, SecKeychainRef *keychain)
430 {
431 #undef SecKeychainOpen
432 static typeof (SecKeychainOpen) *dyfunc = NULL;
433 if (!dyfunc) {
434 void *image = __loadSecurity();
435 if (image) dyfunc = dlsym(image, "SecKeychainOpen");
436 }
437 return dyfunc ? dyfunc(pathName, keychain) : -1;
438 }
439
440 __private_extern__ OSStatus
441 _SecKeychainSetDomainDefault(SecPreferencesDomain domain, SecKeychainRef keychain)
442 {
443 #undef SecKeychainSetDomainDefault
444 static typeof (SecKeychainSetDomainDefault) *dyfunc = NULL;
445 if (!dyfunc) {
446 void *image = __loadSecurity();
447 if (image) dyfunc = dlsym(image, "SecKeychainSetDomainDefault");
448 }
449 return dyfunc ? dyfunc(domain, keychain) : -1;
450 }
451
452 __private_extern__ OSStatus
453 _SecKeychainSetPreferenceDomain(SecPreferencesDomain domain)
454 {
455 #undef SecKeychainSetPreferenceDomain
456 static typeof (SecKeychainSetPreferenceDomain) *dyfunc = NULL;
457 if (!dyfunc) {
458 void *image = __loadSecurity();
459 if (image) dyfunc = dlsym(image, "SecKeychainSetPreferenceDomain");
460 }
461 return dyfunc ? dyfunc(domain) : -1;
462 }
463
464 __private_extern__ OSStatus
465 _SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
466 {
467 #undef SecKeychainItemCopyContent
468 static typeof (SecKeychainItemCopyContent) *dyfunc = NULL;
469 if (!dyfunc) {
470 void *image = __loadSecurity();
471 if (image) dyfunc = dlsym(image, "SecKeychainItemCopyContent");
472 }
473 return dyfunc ? dyfunc(itemRef, itemClass, attrList, length, outData) : -1;
474 }
475
476 __private_extern__ OSStatus
477 _SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void *data, SecKeychainRef keychainRef, SecAccessRef initialAccess, SecKeychainItemRef *itemRef)
478 {
479 #undef SecKeychainItemCreateFromContent
480 static typeof (SecKeychainItemCreateFromContent) *dyfunc = NULL;
481 if (!dyfunc) {
482 void *image = __loadSecurity();
483 if (image) dyfunc = dlsym(image, "SecKeychainItemCreateFromContent");
484 }
485 return dyfunc ? dyfunc(itemClass, attrList, length, data, keychainRef, initialAccess, itemRef) : -1;
486 }
487
488 __private_extern__ OSStatus
489 _SecKeychainItemDelete(SecKeychainItemRef itemRef)
490 {
491 #undef SecKeychainItemDelete
492 static typeof (SecKeychainItemDelete) *dyfunc = NULL;
493 if (!dyfunc) {
494 void *image = __loadSecurity();
495 if (image) dyfunc = dlsym(image, "SecKeychainItemDelete");
496 }
497 return dyfunc ? dyfunc(itemRef) : -1;
498 }
499
500 __private_extern__ OSStatus
501 _SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data)
502 {
503 #undef SecKeychainItemFreeContent
504 static typeof (SecKeychainItemFreeContent) *dyfunc = NULL;
505 if (!dyfunc) {
506 void *image = __loadSecurity();
507 if (image) dyfunc = dlsym(image, "SecKeychainItemFreeContent");
508 }
509 return dyfunc ? dyfunc(attrList, data) : -1;
510 }
511
512 __private_extern__ OSStatus
513 _SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data)
514 {
515 #undef SecKeychainItemModifyContent
516 static typeof (SecKeychainItemModifyContent) *dyfunc = NULL;
517 if (!dyfunc) {
518 void *image = __loadSecurity();
519 if (image) dyfunc = dlsym(image, "SecKeychainItemModifyContent");
520 }
521 return dyfunc ? dyfunc(itemRef, attrList, length, data) : -1;
522 }
523
524
525 __private_extern__ OSStatus
526 _SecTrustedApplicationCreateFromPath(const char *path, SecTrustedApplicationRef *app)
527 {
528 #undef SecTrustedApplicationCreateFromPath
529 static typeof (SecTrustedApplicationCreateFromPath) *dyfunc = NULL;
530 if (!dyfunc) {
531 void *image = __loadSecurity();
532 if (image) dyfunc = dlsym(image, "SecTrustedApplicationCreateFromPath");
533 }
534 return dyfunc ? dyfunc(path, app) : -1;
535 }
536
537 #else // TARGET_OS_IPHONE
538
539 SECURITY_FRAMEWORK_EXTERN(CFStringRef, kSecPropertyKeyValue)
540 SECURITY_FRAMEWORK_EXTERN(CFStringRef, kSecPropertyKeyLabel)
541
542 __private_extern__ CFArrayRef
543 _SecCertificateCopyProperties(SecCertificateRef certRef)
544 {
545 #undef SecCertificateCopyProperties
546 static typeof (SecCertificateCopyProperties) *dyfunc = NULL;
547 if (!dyfunc) {
548 void *image = __loadSecurity();
549 if (image) dyfunc = dlsym(image, "SecCertificateCopyProperties");
550 }
551 return dyfunc ? dyfunc(certRef) : NULL;
552 }
553
554 #endif // TARGET_OS_IPHONE
555
556 __private_extern__ SecCertificateRef
557 _SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data)
558 {
559 #undef SecCertificateCreateWithData
560 static typeof (SecCertificateCreateWithData) *dyfunc = NULL;
561 if (!dyfunc) {
562 void *image = __loadSecurity();
563 if (image) dyfunc = dlsym(image, "SecCertificateCreateWithData");
564 }
565 return dyfunc ? dyfunc(allocator, data) : NULL;
566 }
567