#include "macros.hpp"
#include "common.hpp"
#include "smb_server_prefs.h"
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/time.h>
bool is_server_system(void)
{
struct stat sbuf;
if (stat("/System/Library/CoreServices/ServerVersion.plist", &sbuf) == 0) {
return true;
}
return false;
}
CFStringRef cfstring_wrap(const char * str)
{
CFStringRef ret = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, str,
kCFStringEncodingUTF8,
kCFAllocatorNull);
if (ret == NULL) {
throw std::runtime_error("CFString wrapping failed");
}
return ret;
}
std::string cfstring_convert(CFStringRef cfstr)
{
const char * ptr;
CFIndex bufsz;
char * buf;
if ((ptr = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8))) {
return std::string(ptr);
}
if (CFStringGetLength(cfstr) == 0) {
return std::string();
}
bufsz = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
kCFStringEncodingUTF8);
if ((buf = new char[bufsz + 1]) == NULL) {
throw std::runtime_error("out of memory");
}
if (!CFStringGetCString(cfstr, buf, bufsz, kCFStringEncodingUTF8)) {
free(buf);
throw std::runtime_error("CFString conversion failed");
}
std::string result = std::string(buf);
free(buf);
return result;
}
std::string cftype_string(CFTypeID obj_type)
{
CFStringRef str = CFCopyTypeIDDescription(obj_type);
if (str == NULL) {
return std::string("<invalid_type>");
}
std::string ret(cfstring_convert(str));
safe_release(str);
return ret;
}
SyncMutex::SyncMutex()
{
this->m_fd = ::open(kSMBPreferencesSyncTool, O_RDONLY | O_EXLOCK);
if (this->m_fd == -1) {
throw std::runtime_error("unable to acquire preferences mutex");
}
}
SyncMutex::~SyncMutex()
{
::close(this->m_fd);
}
unsigned long long time_now_usec(void)
{
struct timeval tv;
unsigned long long now;
if (::gettimeofday(&tv, NULL) == -1) {
throw std::runtime_error("gettimeofday failed");
}
now = SEC_TO_USEC(tv.tv_sec) + tv.tv_usec;
return now;
}
#define SERVICE_CHANGED "com.apple.ServiceConfigurationChangedNotification"
void post_service_notification(const char * service_name,
const char * service_state)
{
CFNotificationCenterRef notify;
notify = CFNotificationCenterGetDistributedCenter();
if (notify == NULL) {
return;
}
VERBOSE("posting %s with %s=>%s\n",
SERVICE_CHANGED, service_name, service_state);
cf_typeref<CFMutableDictionaryRef>
info(CFDictionaryCreateMutable(kCFAllocatorDefault,
0 ,
&kCFTypeDictionaryKeyCallBacks ,
&kCFTypeDictionaryValueCallBacks ));
if (info == (CFMutableDictionaryRef)NULL) {
return;
}
try {
cf_typeref<CFStringRef> name(cfstring_wrap(service_name));
cf_typeref<CFStringRef> state(cfstring_wrap(service_state));
CFDictionaryAddValue(info, CFSTR("ServiceName"), name);
CFDictionaryAddValue(info, CFSTR("State"), state);
CFNotificationCenterPostNotificationWithOptions(notify,
CFSTR(SERVICE_CHANGED),
NULL , info,
kCFNotificationPostToAllSessions);
} catch (...) {
return;
}
}