+
+static void
+clean_swap_directory(const char *path)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char buf[1024];
+
+ dir = opendir(path);
+ if (dir == NULL) {
+ fprintf(stderr,"dynamic_pager: cannot open swap directory %s\n", path);
+ exit(EXIT_FAILURE);
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_namlen>= 4 && strncmp(entry->d_name, "swap", 4) == 0) {
+ snprintf(buf, sizeof buf, "%s/%s", path, entry->d_name);
+ unlink(buf);
+ }
+ }
+
+ closedir(dir);
+}
+
+#define VM_PREFS_PLIST "/Library/Preferences/com.apple.virtualMemory.plist"
+#define VM_PREFS_ENCRYPT_SWAP_KEY "UseEncryptedSwap"
+
+static boolean_t
+should_encrypt_swap(void)
+{
+ CFPropertyListRef propertyList;
+ CFTypeID propertyListType;
+ CFStringRef errorString;
+ CFDataRef resourceData;
+ SInt32 errorCode;
+ CFURLRef fileURL;
+ CFTypeRef value;
+ boolean_t should_encrypt;
+ boolean_t explicit_value;
+ CFTypeRef snap;
+
+ explicit_value = false;
+
+ fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)VM_PREFS_PLIST, strlen(VM_PREFS_PLIST), false);
+ if (fileURL == NULL) {
+ /*fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), VM_PREFS_PLIST);*/
+ goto done;
+ }
+
+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) {
+ /*fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), VM_PREFS_PLIST, (int)errorCode);*/
+ CFRelease(fileURL);
+ goto done;
+ }
+
+ CFRelease(fileURL);
+ propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString);
+ if (propertyList == NULL) {
+ /*fprintf(stderr, "%s: cannot get XML propertyList %s\n", getprogname(), VM_PREFS_PLIST);*/
+ CFRelease(resourceData);
+ goto done;
+ }
+
+ propertyListType = CFGetTypeID(propertyList);
+
+ if (propertyListType == CFDictionaryGetTypeID()) {
+ value = (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef) propertyList, CFSTR(VM_PREFS_ENCRYPT_SWAP_KEY));
+ if (value == NULL) {
+ /* no value: use the default value */
+ } else if (CFGetTypeID(value) != CFBooleanGetTypeID()) {
+ fprintf(stderr, "%s: wrong type for key \"%s\"\n",
+ getprogname(), VM_PREFS_ENCRYPT_SWAP_KEY);
+ /* bogus value, assume it's "true" for safety's sake */
+ should_encrypt = true;
+ explicit_value = true;
+ } else {
+ should_encrypt = CFBooleanGetValue((CFBooleanRef)value);
+ explicit_value = true;
+ }
+ }
+ else {
+ /*fprintf(stderr, "%s: invalid propertyList type %d (not a dictionary)\n", getprogname(), propertyListType);*/
+ }
+ CFRelease(resourceData);
+ CFRelease(propertyList);
+
+done:
+ if (! explicit_value) {
+ /* by default, encrypt swap on laptops only */
+ mach_timespec_t w;
+ kern_return_t kr;
+
+ /* wait up to 60 seconds for IOKit to quiesce */
+ w.tv_sec = 60;
+ w.tv_nsec = 0;
+ kr = IOKitWaitQuiet(kIOMasterPortDefault, &w);
+ if (kr != kIOReturnSuccess) {
+ /*
+ * Can't tell if we're on a laptop,
+ * assume we do want encrypted swap.
+ */
+ should_encrypt = TRUE;
+ /*fprintf(stderr, "dynamic_pager: IOKitWaitQuiet ret 0x%x (%s)\n", kr, mach_error_string(kr));*/
+ } else {
+ /*
+ * Look for battery power source.
+ */
+ snap = IOPSCopyPowerSourcesInfo();
+ should_encrypt = (kCFBooleanTrue == IOPSPowerSourceSupported(snap, CFSTR(kIOPMBatteryPowerKey)));
+ CFRelease(snap);
+ /*fprintf(stderr, "dynamic_pager: battery power source: %d\n", should_encrypt);*/
+ }
+ }
+
+ return should_encrypt;
+}
+