- SCDLog(LOG_DEBUG, CFSTR(" _addWatcher: %@, %@"), sessionNum, watchedKey);
-
- return;
-}
-
-
-/*
- * _addRegexWatcherByKey()
- *
- * This is a CFDictionaryApplierFunction which will iterate over each key
- * defined in the "cacheData" dictionary. The arguments are the dictionary
- * key, it's associated cache dictionary, and a context structure which
- * includes the following:
- *
- * 1. the session which has just added a regex notification request
- * 2. the compiled regular expression associated with the above key.
- *
- * If a (real) dictionary key is found which matches the provided regular
- * expression then we mark that key as being watched by the session.
- */
-void
-_addRegexWatcherByKey(const void *key, void *val, void *context)
-{
- CFStringRef cacheStr = key;
- CFDictionaryRef info = val;
- mach_port_t sessionID = ((addContextRef)context)->session->server;
- regex_t *preg = ((addContextRef)context)->preg;
- int cacheKeyLen;
- char *cacheKey;
- CFNumberRef sessionNum;
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
-
- if (CFDictionaryContainsKey(info, kSCDData) == FALSE) {
- /* if no data (yet) */
- return;
- }
-
- /* convert cache key to C string */
- cacheKeyLen = CFStringGetLength(cacheStr) + 1;
- cacheKey = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
- if (!CFStringGetCString(cacheStr, cacheKey, cacheKeyLen, kCFStringEncodingMacRoman)) {
- SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert cache key to C string"));
- CFAllocatorDeallocate(NULL, cacheKey);
- return;
- }
-
- /* compare cache key to new notification keys regular expression pattern */
- reError = regexec(preg, cacheKey, 0, NULL, 0);
- switch (reError) {
- case 0 :
- /* we've got a match */
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionID);
- _addWatcher(sessionNum, cacheStr);
- CFRelease(sessionNum);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
- CFAllocatorDeallocate(NULL, cacheKey);
-}
-
-
-/*
- * _addRegexWatchersBySession()
- *
- * This is a CFDictionaryApplierFunction which will iterate over each session
- * defined in the "sessionData" dictionary. The arguments are the session
- * key, it's associated session dictionary, , and the cache key being added.
- *
- * If an active session includes any regular expression keys which match the
- * key being added to the "cacheData" dictionary then we mark this key as being
- * watched by the session.
- */
-void
-_addRegexWatchersBySession(const void *key, void *val, void *context)
-{
- CFStringRef sessionKey = key;
- CFDictionaryRef info = val;
- CFStringRef addedKey = context;
- CFIndex newKeyLen;
- char *newKeyStr;
- CFArrayRef rKeys;
- CFArrayRef rData;
- CFIndex i;
-
- if (info == NULL) {
- /* if no dictionary for this session */
- return;
- }
-
- rKeys = CFDictionaryGetValue(info, kSCDRegexKeys);
- if (rKeys == NULL) {
- /* if no regex keys for this session */
- return;
- }
- rData = CFDictionaryGetValue(info, kSCDRegexData);
-
- /* convert new key to C string */
- newKeyLen = CFStringGetLength(addedKey) + 1;
- newKeyStr = CFAllocatorAllocate(NULL, newKeyLen, 0);
- if (!CFStringGetCString(addedKey, newKeyStr, newKeyLen, kCFStringEncodingMacRoman)) {
- SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert new key to C string"));
- CFAllocatorDeallocate(NULL, newKeyStr);
- return;
- }
-
- /* iterate over the regex keys looking for an pattern which matches the new key */
- for (i=0; i<CFArrayGetCount(rKeys); i++) {
- CFDataRef regexData = CFArrayGetValueAtIndex(rData, i);
- regex_t *preg = (regex_t *)CFDataGetBytePtr(regexData);
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
- SInt32 sessionInt;
- CFNumberRef sessionNum;
-
- /* check if this key matches the regular expression */
- reError = regexec(preg, newKeyStr, 0, NULL, 0);
- switch (reError) {
- case 0 :
- /* we've got a match, add a reference */
- sessionInt = CFStringGetIntValue(sessionKey);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionInt);
- _addWatcher(sessionNum, addedKey);
- CFRelease(sessionNum);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
-
- }
- CFAllocatorDeallocate(NULL, newKeyStr);