Make the __FILE__ and __LINE__ part of the log message.
[apple-ir-control.git] / apple-ir-control.cc
index c92eb8054dc4100245afb9e05417507dad7b54e9..5a56489d56eace4d323873284ba145cd141d0523 100644 (file)
@@ -1,3 +1,12 @@
+//
+// apple-ir-control
+// Copyright (c) 2016, Robert Sesek <https://www.bluestatic.org>
+//
+// This program is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or any later version.
+//
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <IOKit/hid/IOHIDLib.h>
 #include <IOKit/IOKitLib.h>
@@ -8,17 +17,20 @@ const CFStringRef kPrefDomain = CFSTR("com.apple.driver.AppleIRController");
 const CFStringRef kPrefEnabled = CFSTR("DeviceEnabled");
 
 #if NDEBUG
-bool VERBOSE = false;
+const bool VERBOSE = false;
 #else
-bool VERBOSE = true;
+const bool VERBOSE = true;
 #endif
 
+#define LOCATION_LINE(x) #x
+#define LOCATION(line) __FILE__ ":" LOCATION_LINE(line)
+
 #define LOG(msg, ...) do { \
     if (VERBOSE) { \
-      printf(msg "   [%s:%d]\n", ##__VA_ARGS__, __FILE__, __LINE__); \
+      printf("[" LOCATION(__LINE__) "] " msg "\n", ##__VA_ARGS__); \
     } \
   } while(0)
-#define ERROR(msg, ...) fprintf(stderr, msg "   [%s:%d]\n", ##__VA_ARGS__, __FILE__, __LINE__)
+#define ERROR(msg, ...) fprintf(stderr, "[" LOCATION(__LINE__) "] " msg "\n", ##__VA_ARGS__)
 
 class ScopedIOHIDManager {
  public:
@@ -67,6 +79,7 @@ bool IsIRAvailable() {
     ERROR("Failed to IOHIDManagerCopyDevices");
     return false;
   }
+
   std::vector<void*> devices_array(CFSetGetCount(devices.get()), nullptr);
   CFSetGetValues(devices.get(), const_cast<const void**>(devices_array.data()));
   for (const auto& device : devices_array) {
@@ -94,39 +107,31 @@ const char* GetBooleanDescription(CFTypeRef boolean) {
 
 bool SynchronizePrefs() {
   bool rv = CFPreferencesSynchronize(kPrefDomain, kCFPreferencesAnyUser,
-          kCFPreferencesCurrentHost);
+      kCFPreferencesCurrentHost);
   if (!rv) {
     ERROR("Failed to CFPreferencesSynchronize");
   }
   return rv;
 }
 
-CFTypeRef GetUserPropertyValue() {
-  return CFPreferencesCopyValue(kPrefEnabled, kPrefDomain,
-      kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
-}
-
-io_iterator_t CreateIOServiceIterator() {
+bool CreateIOServiceIterator(io_iterator_t* iterator) {
   CFMutableDictionaryRef matching_dict = IOServiceMatching("AppleIRController");
-  io_iterator_t iterator;
   kern_return_t kr = IOServiceGetMatchingServices(
-      kIOMasterPortDefault, matching_dict, &iterator);
+      kIOMasterPortDefault, matching_dict, iterator);
   if (kr != KERN_SUCCESS) {
     ERROR("Failed to IOServiceGetMatchingServices: 0x%x", kr);
-    return 0;
+    return false;
   }
-  return iterator;
+  return true;;
 }
 
 int HandleRead() {
-  if (!SynchronizePrefs())
-    return EXIT_FAILURE;
-
-  CFTypeRef user_prop = GetUserPropertyValue();
+  CFTypeRef user_prop = CFPreferencesCopyValue(kPrefEnabled, kPrefDomain,
+      kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
   printf("Userspace property value: %s\n", GetBooleanDescription(user_prop));
 
-  io_iterator_t iterator = CreateIOServiceIterator();
-  if (!iterator)
+  io_iterator_t iterator;
+  if (!CreateIOServiceIterator(&iterator))
     return EXIT_FAILURE;
 
   io_object_t service;
@@ -147,20 +152,10 @@ int HandleRead() {
         IORegistryEntryCreateCFProperty(service, kPrefEnabled, nullptr, 0));
     printf("Kernel property value %s: %s\n",
         name, GetBooleanDescription(device_enabled.get()));
-
-#if 0
-    ScopedCFTypeRef<CFMutableDictionaryRef> props;
-    kr = IORegistryEntryCreateCFProperties(service, props.pointer_to(), nullptr, 0);
-    if (kr != KERN_SUCCESS) {
-      ERROR("Failed to IORegistryEntryCreateCFProperties(%s) = 0x%x", name, kr);
-      continue;
-    }
-    CFShow(props.get());
-#endif
   }
 
   if (!did_find) {
-    ERROR("Failed to match AppleIRController");
+    ERROR("Failed to match any AppleIRController");
     return EXIT_FAILURE;
   }
 
@@ -168,6 +163,11 @@ int HandleRead() {
 }
 
 int HandleWrite(bool enable) {
+  if (geteuid() != 0) {
+    ERROR("This operation must be performed as root");
+    return EXIT_FAILURE;
+  }
+
   const CFBooleanRef enabled_value = enable ? kCFBooleanTrue : kCFBooleanFalse;
 
   CFPreferencesSetValue(kPrefEnabled, enabled_value, kPrefDomain,
@@ -175,7 +175,10 @@ int HandleWrite(bool enable) {
   if (!SynchronizePrefs())
     return EXIT_FAILURE;
 
-  io_iterator_t iterator = CreateIOServiceIterator();
+  io_iterator_t iterator;
+  if (!CreateIOServiceIterator(&iterator))
+    return EXIT_FAILURE;
+
   io_object_t service;
   while ((service = IOIteratorNext(iterator))) {
     io_name_t name;