#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
#include "SCPreferencesInternal.h"
#include <fcntl.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/errno.h>
#include <sys/param.h>
__private_extern__ CFDataRef
__SCPSignatureFromStatbuf(const struct stat *statBuf)
{
CFMutableDataRef signature;
SCPSignatureDataRef sig;
signature = CFDataCreateMutable(NULL, sizeof(SCPSignatureData));
CFDataSetLength(signature, sizeof(SCPSignatureData));
sig = (SCPSignatureDataRef)CFDataGetBytePtr(signature);
sig->st_dev = statBuf->st_dev;
sig->st_ino = statBuf->st_ino;
sig->st_mtimespec = statBuf->st_mtimespec;
sig->st_size = statBuf->st_size;
return signature;
}
__private_extern__ char *
__SCPreferencesPath(CFAllocatorRef allocator,
CFStringRef prefsID,
Boolean perUser,
CFStringRef user,
Boolean useNewPrefs)
{
CFStringRef path = NULL;
char *pathStr;
if (perUser) {
if (prefsID == NULL) {
return NULL;
} else if (CFStringHasPrefix(prefsID, CFSTR("/"))) {
path = CFStringCreateCopy(allocator, prefsID);
} else {
char login[MAXLOGNAME+1];
struct passwd *pwd;
bzero(&login, sizeof(login));
if (user == NULL) {
CFStringRef u;
u = SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL);
if (!u) {
return NULL;
}
(void)_SC_cfstring_to_cstring(u, login, sizeof(login), kCFStringEncodingASCII);
CFRelease(u);
} else {
(void)_SC_cfstring_to_cstring(user, login, sizeof(login), kCFStringEncodingASCII);
}
pwd = getpwnam(login);
if (pwd == NULL) {
return NULL;
}
path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%s/%@/%@"),
pwd->pw_dir,
PREFS_DEFAULT_USER_DIR,
prefsID);
}
} else {
if (prefsID == NULL) {
path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD,
useNewPrefs ? PREFS_DEFAULT_CONFIG : PREFS_DEFAULT_CONFIG_OLD);
} else if (CFStringHasPrefix(prefsID, CFSTR("/"))) {
path = CFStringCreateCopy(allocator, prefsID);
} else {
path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD,
prefsID);
if (useNewPrefs && CFStringHasSuffix(path, CFSTR(".xml"))) {
CFMutableStringRef newPath;
newPath = CFStringCreateMutableCopy(allocator, 0, path);
CFStringReplace(newPath,
CFRangeMake(CFStringGetLength(newPath)-4, 4),
CFSTR(".plist"));
CFRelease(path);
path = newPath;
}
}
}
pathStr = _SC_cfstring_to_cstring(path, NULL, 0, kCFStringEncodingASCII);
if (pathStr == NULL) {
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("could not convert path to C string"));
}
CFRelease(path);
return pathStr;
}
CFDataRef
SCPreferencesGetSignature(SCPreferencesRef session)
{
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesGetSignature:"));
sessionPrivate->accessed = TRUE;
return sessionPrivate->signature;
}
__private_extern__ CFStringRef
_SCPNotificationKey(CFAllocatorRef allocator,
CFStringRef prefsID,
Boolean perUser,
CFStringRef user,
int keyType)
{
CFStringRef key = NULL;
char *pathStr;
char *typeStr;
pathStr = __SCPreferencesPath(allocator, prefsID, perUser, user, TRUE);
if (pathStr == NULL) {
return NULL;
}
switch (keyType) {
case kSCPreferencesKeyLock :
typeStr = "lock";
break;
case kSCPreferencesKeyCommit :
typeStr = "commit";
break;
case kSCPreferencesKeyApply :
typeStr = "apply";
break;
default :
typeStr = "?";
}
key = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@%s:%s"),
kSCDynamicStoreDomainPrefs,
typeStr,
pathStr);
CFAllocatorDeallocate(NULL, pathStr);
return key;
}
CFStringRef
SCDynamicStoreKeyCreatePreferences(CFAllocatorRef allocator,
CFStringRef prefsID,
SCPreferencesKeyType keyType)
{
return _SCPNotificationKey(allocator, prefsID, FALSE, NULL, keyType);
}
CFStringRef
SCDynamicStoreKeyCreateUserPreferences(CFAllocatorRef allocator,
CFStringRef prefsID,
CFStringRef user,
SCPreferencesKeyType keyType)
{
return _SCPNotificationKey(allocator, prefsID, TRUE, user, keyType);
}