1/* 2 * Copyright (c) 2000-2004, 2006, 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 * 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 35#include "configd.h" 36#include "session.h" 37#include "pattern.h" 38 39 40static int 41removeKey(CFMutableArrayRef keys, CFStringRef key) 42{ 43 CFIndex i; 44 CFIndex n; 45 46 if (keys == NULL) { 47 /* sorry, empty notifier list */ 48 return kSCStatusNoKey; 49 } 50 51 n = CFArrayGetCount(keys); 52 i = CFArrayGetFirstIndexOfValue(keys, CFRangeMake(0, n), key); 53 if (i == kCFNotFound) { 54 /* sorry, key does not exist in notifier list */ 55 return kSCStatusNoKey; 56 } 57 58 /* remove key from this sessions notifier list */ 59 CFArrayRemoveValueAtIndex(keys, i); 60 return kSCStatusOK; 61} 62 63 64__private_extern__ 65int 66__SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, Boolean internal) 67{ 68 int sc_status = kSCStatusOK; 69 CFNumberRef sessionNum; 70 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; 71 72 if (_configd_trace) { 73 SCTrace(TRUE, _configd_trace, 74 CFSTR("%s : %5d : %s : %@\n"), 75 internal ? "*watch-" : "watch- ", 76 storePrivate->server, 77 isRegex ? "pattern" : "key", 78 key); 79 } 80 81 /* 82 * remove key from this sessions notifier list after checking that 83 * it was previously defined. 84 */ 85 if (isRegex) { 86 sc_status = removeKey(storePrivate->patterns, key); 87 if (sc_status != kSCStatusOK) { 88 goto done; 89 } 90 91 /* remove this session as a pattern watcher */ 92 sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server); 93 patternRemoveSession(key, sessionNum); 94 CFRelease(sessionNum); 95 } else { 96 sc_status = removeKey(storePrivate->keys, key); 97 if (sc_status != kSCStatusOK) { 98 goto done; 99 } 100 101 /* 102 * We are watching a specific key. As such, update the 103 * store to remove our interest in any changes. 104 */ 105 sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server); 106 _removeWatcher(sessionNum, key); 107 CFRelease(sessionNum); 108 } 109 110 done : 111 112 return sc_status; 113} 114 115 116__private_extern__ 117kern_return_t 118_notifyremove(mach_port_t server, 119 xmlData_t keyRef, /* raw XML bytes */ 120 mach_msg_type_number_t keyLen, 121 int isRegex, 122 int *sc_status 123) 124{ 125 CFStringRef key = NULL; /* key (un-serialized) */ 126 serverSessionRef mySession; 127 128 /* un-serialize the key */ 129 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) { 130 *sc_status = kSCStatusFailed; 131 goto done; 132 } 133 134 if (!isA_CFString(key)) { 135 *sc_status = kSCStatusInvalidArgument; 136 goto done; 137 } 138 139 mySession = getSession(server); 140 if (mySession == NULL) { 141 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */ 142 goto done; 143 } 144 145 *sc_status = __SCDynamicStoreRemoveWatchedKey(mySession->store, 146 key, 147 isRegex != 0, 148 FALSE); 149 150 done : 151 152 if (key) CFRelease(key); 153 return KERN_SUCCESS; 154} 155 156