1/* 2 * Copyright (c) 2000-2006, 2009-2011, 2013 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 * June 1, 2001 Allan Nathanson <ajn@apple.com> 28 * - public API conversion 29 * 30 * March 24, 2000 Allan Nathanson <ajn@apple.com> 31 * - initial revision 32 */ 33 34#include <mach/mach.h> 35#include <mach/mach_error.h> 36 37#include <SystemConfiguration/SystemConfiguration.h> 38#include <SystemConfiguration/SCPrivate.h> 39#include "SCDynamicStoreInternal.h" 40#include "config.h" /* MiG generated file */ 41 42 43Boolean 44SCDynamicStoreSetMultiple(SCDynamicStoreRef store, 45 CFDictionaryRef keysToSet, 46 CFArrayRef keysToRemove, 47 CFArrayRef keysToNotify) 48{ 49 SCDynamicStorePrivateRef storePrivate; 50 kern_return_t status; 51 CFDataRef xmlSet = NULL; /* key/value pairs to set (XML serialized) */ 52 xmlData_t mySetRef = NULL; /* key/value pairs to set (serialized) */ 53 CFIndex mySetLen = 0; 54 CFDataRef xmlRemove = NULL; /* keys to remove (XML serialized) */ 55 xmlData_t myRemoveRef = NULL; /* keys to remove (serialized) */ 56 CFIndex myRemoveLen = 0; 57 CFDataRef xmlNotify = NULL; /* keys to notify (XML serialized) */ 58 xmlData_t myNotifyRef = NULL; /* keys to notify (serialized) */ 59 CFIndex myNotifyLen = 0; 60 int sc_status; 61 62 if (store == NULL) { 63 store = __SCDynamicStoreNullSession(); 64 if (store == NULL) { 65 /* sorry, you must provide a session */ 66 _SCErrorSet(kSCStatusNoStoreSession); 67 return FALSE; 68 } 69 } 70 71 storePrivate = (SCDynamicStorePrivateRef)store; 72 if (storePrivate->server == MACH_PORT_NULL) { 73 _SCErrorSet(kSCStatusNoStoreServer); 74 return FALSE; /* you must have an open session to play */ 75 } 76 77 /* serialize the key/value pairs to set*/ 78 if (keysToSet != NULL) { 79 CFDictionaryRef newInfo; 80 Boolean ok; 81 82 newInfo = _SCSerializeMultiple(keysToSet); 83 if (newInfo == NULL) { 84 _SCErrorSet(kSCStatusInvalidArgument); 85 return FALSE; 86 } 87 88 ok = _SCSerialize(newInfo, &xmlSet, (void **)&mySetRef, &mySetLen); 89 CFRelease(newInfo); 90 if (!ok) { 91 _SCErrorSet(kSCStatusInvalidArgument); 92 return FALSE; 93 } 94 } 95 96 /* serialize the keys to remove */ 97 if (keysToRemove != NULL) { 98 if (!_SCSerialize(keysToRemove, &xmlRemove, (void **)&myRemoveRef, &myRemoveLen)) { 99 if (xmlSet != NULL) CFRelease(xmlSet); 100 _SCErrorSet(kSCStatusInvalidArgument); 101 return FALSE; 102 } 103 } 104 105 /* serialize the keys to notify */ 106 if (keysToNotify != NULL) { 107 if (!_SCSerialize(keysToNotify, &xmlNotify, (void **)&myNotifyRef, &myNotifyLen)) { 108 if (xmlSet != NULL) CFRelease(xmlSet); 109 if (xmlRemove != NULL) CFRelease(xmlRemove); 110 _SCErrorSet(kSCStatusInvalidArgument); 111 return FALSE; 112 } 113 } 114 115 retry : 116 117 /* send the keys and patterns, fetch the associated result from the server */ 118 status = configset_m(storePrivate->server, 119 mySetRef, 120 (mach_msg_type_number_t)mySetLen, 121 myRemoveRef, 122 (mach_msg_type_number_t)myRemoveLen, 123 myNotifyRef, 124 (mach_msg_type_number_t)myNotifyLen, 125 (int *)&sc_status); 126 127 if (__SCDynamicStoreCheckRetryAndHandleError(store, 128 status, 129 &sc_status, 130 "SCDynamicStoreSetMultiple configset_m()")) { 131 goto retry; 132 } 133 134 /* clean up */ 135 if (xmlSet != NULL) CFRelease(xmlSet); 136 if (xmlRemove != NULL) CFRelease(xmlRemove); 137 if (xmlNotify != NULL) CFRelease(xmlNotify); 138 139 if (sc_status != kSCStatusOK) { 140 _SCErrorSet(sc_status); 141 return FALSE; 142 } 143 144 return TRUE; 145} 146 147Boolean 148SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value) 149{ 150 SCDynamicStorePrivateRef storePrivate; 151 kern_return_t status; 152 CFDataRef utfKey; /* serialized key */ 153 xmlData_t myKeyRef; 154 CFIndex myKeyLen; 155 CFDataRef xmlData; /* serialized data */ 156 xmlData_t myDataRef; 157 CFIndex myDataLen; 158 int sc_status; 159 int newInstance; 160 161 if (store == NULL) { 162 store = __SCDynamicStoreNullSession(); 163 if (store == NULL) { 164 /* sorry, you must provide a session */ 165 _SCErrorSet(kSCStatusNoStoreSession); 166 return FALSE; 167 } 168 } 169 170 storePrivate = (SCDynamicStorePrivateRef)store; 171 if (storePrivate->server == MACH_PORT_NULL) { 172 /* sorry, you must have an open session to play */ 173 _SCErrorSet(kSCStatusNoStoreServer); 174 return FALSE; 175 } 176 177 /* serialize the key */ 178 if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) { 179 _SCErrorSet(kSCStatusInvalidArgument); 180 return FALSE; 181 } 182 183 /* serialize the data */ 184 if (!_SCSerialize(value, &xmlData, (void **)&myDataRef, &myDataLen)) { 185 CFRelease(utfKey); 186 _SCErrorSet(kSCStatusInvalidArgument); 187 return FALSE; 188 } 189 190 retry : 191 192 /* send the key & data to the server, get new instance id */ 193 status = configset(storePrivate->server, 194 myKeyRef, 195 (mach_msg_type_number_t)myKeyLen, 196 myDataRef, 197 (mach_msg_type_number_t)myDataLen, 198 0, 199 &newInstance, 200 (int *)&sc_status); 201 202 if (__SCDynamicStoreCheckRetryAndHandleError(store, 203 status, 204 &sc_status, 205 "SCDynamicStoreSetValue configset()")) { 206 goto retry; 207 } 208 209 /* clean up */ 210 CFRelease(utfKey); 211 CFRelease(xmlData); 212 213 if (sc_status != kSCStatusOK) { 214 _SCErrorSet(sc_status); 215 return FALSE; 216 } 217 218 return TRUE; 219} 220