]>
Commit | Line | Data |
---|---|---|
5958d7c0 A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | ||
23 | #include "configd.h" | |
24 | #include "session.h" | |
25 | ||
26 | SCDStatus | |
27 | _SCDTouch(SCDSessionRef session, CFStringRef key) | |
28 | { | |
29 | SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session; | |
30 | SCDStatus scd_status; | |
31 | boolean_t wasLocked; | |
32 | SCDHandleRef handle; | |
33 | CFPropertyListRef value; | |
34 | ||
35 | SCDLog(LOG_DEBUG, CFSTR("_SCDTouch:")); | |
36 | SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key); | |
37 | ||
38 | if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) { | |
39 | return SCD_NOSESSION; /* you can't do anything with a closed session */ | |
40 | } | |
41 | ||
42 | /* | |
43 | * 1. Determine if the cache lock is currently held by this session | |
44 | * and acquire the lock if necessary. | |
45 | */ | |
46 | wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked); | |
47 | if (!wasLocked) { | |
48 | scd_status = _SCDLock(session); | |
49 | if (scd_status != SCD_OK) { | |
50 | SCDLog(LOG_DEBUG, CFSTR(" _SCDLock(): %s"), SCDError(scd_status)); | |
51 | return scd_status; | |
52 | } | |
53 | } | |
54 | ||
55 | /* | |
56 | * 2. Grab the current (or establish a new) cache entry for this key. | |
57 | */ | |
58 | scd_status = _SCDGet(session, key, &handle); | |
59 | switch (scd_status) { | |
60 | case SCD_NOKEY : | |
61 | /* cache entry does not exist, create */ | |
62 | handle = SCDHandleInit(); | |
63 | value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); | |
64 | SCDLog(LOG_DEBUG, CFSTR(" new time stamp = %@"), value); | |
65 | SCDHandleSetData(handle, value); | |
66 | CFRelease(value); | |
67 | break; | |
68 | ||
69 | case SCD_OK : | |
70 | /* cache entry exists, update */ | |
71 | value = SCDHandleGetData(handle); | |
72 | if (CFGetTypeID(value) == CFDateGetTypeID()) { | |
73 | /* if value is a CFDate */ | |
74 | value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent()); | |
75 | SCDLog(LOG_DEBUG, CFSTR(" new time stamp = %@"), value); | |
76 | SCDHandleSetData(handle, value); | |
77 | CFRelease(value); | |
78 | } /* else, we'll just save the data (again) to bump the instance */ | |
79 | break; | |
80 | ||
81 | default : | |
82 | SCDLog(LOG_DEBUG, CFSTR(" _SCDGet(): %s"), SCDError(scd_status)); | |
83 | goto done; | |
84 | } | |
85 | ||
86 | scd_status = _SCDSet(session, key, handle); | |
87 | SCDHandleRelease(handle); | |
88 | ||
89 | done : | |
90 | ||
91 | /* | |
92 | * 8. Release the lock if we acquired it as part of this request. | |
93 | */ | |
94 | if (!wasLocked) | |
95 | _SCDUnlock(session); | |
96 | ||
97 | return SCD_OK; | |
98 | } | |
99 | ||
100 | ||
101 | kern_return_t | |
102 | _configtouch(mach_port_t server, | |
103 | xmlData_t keyRef, /* raw XML bytes */ | |
104 | mach_msg_type_number_t keyLen, | |
105 | int *scd_status | |
106 | ) | |
107 | { | |
108 | kern_return_t status; | |
109 | serverSessionRef mySession = getSession(server); | |
110 | CFDataRef xmlKey; /* key (XML serialized) */ | |
111 | CFStringRef key; /* key (un-serialized) */ | |
112 | CFStringRef xmlError; | |
113 | ||
114 | SCDLog(LOG_DEBUG, CFSTR("Touch key in configuration database.")); | |
115 | SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server); | |
116 | ||
117 | /* un-serialize the key */ | |
118 | xmlKey = CFDataCreate(NULL, keyRef, keyLen); | |
119 | status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen); | |
120 | if (status != KERN_SUCCESS) { | |
121 | SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status)); | |
122 | /* non-fatal???, proceed */ | |
123 | } | |
124 | key = CFPropertyListCreateFromXMLData(NULL, | |
125 | xmlKey, | |
126 | kCFPropertyListImmutable, | |
127 | &xmlError); | |
128 | CFRelease(xmlKey); | |
129 | if (xmlError) { | |
130 | SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError); | |
131 | *scd_status = SCD_FAILED; | |
132 | return KERN_SUCCESS; | |
133 | } | |
134 | ||
135 | *scd_status = _SCDTouch(mySession->session, key); | |
136 | CFRelease(key); | |
137 | ||
138 | return KERN_SUCCESS; | |
139 | } |