1/* 2 * Copyright (c) 2006-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <CoreFoundation/CoreFoundation.h> 25#include <CoreFoundation/CFXPCBridge.h> 26#include <DiskArbitration/DiskArbitration.h> 27 28#include "NetworkAuthenticationHelper.h" 29 30#include <sys/types.h> 31#include <stdio.h> 32#include <stdlib.h> 33#include <asl.h> 34 35#include <xpc/xpc.h> 36 37static char * 38cf2cstring(CFStringRef inString) 39{ 40 char *string = NULL; 41 CFIndex length; 42 43 string = (char *) CFStringGetCStringPtr(inString, kCFStringEncodingUTF8); 44 if (string) 45 return strdup(string); 46 47 length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(inString), 48 kCFStringEncodingUTF8) + 1; 49 string = malloc (length); 50 if (string == NULL) 51 return NULL; 52 if (!CFStringGetCString(inString, string, length, kCFStringEncodingUTF8)) { 53 free (string); 54 return NULL; 55 } 56 return string; 57} 58 59static void 60callback(xpc_object_t disk) 61{ 62 CFDictionaryRef dict = NULL; 63 CFStringRef path, ident; 64 char *str, *str2; 65 CFURLRef url; 66 size_t len; 67 68 asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "DiskUnmountWatcher: %s", __func__); 69 70 xpc_object_t desc = xpc_dictionary_get_value(disk, "Description"); 71 if (desc == NULL) 72 goto out; 73 74 dict = _CFXPCCreateCFObjectFromXPCObject(desc); 75 if (dict == NULL) 76 goto out; 77 78 url = (CFURLRef)CFDictionaryGetValue(dict, kDADiskDescriptionVolumePathKey); 79 if (url == NULL) 80 goto out; 81 82 path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); 83 if (path == NULL) 84 goto out; 85 86 str = cf2cstring(path); 87 CFRelease(path); 88 if (str == NULL) 89 goto out; 90 91 /* remove trailing / */ 92 len = strlen(str); 93 if (len > 0 && str[len - 1] == '/') 94 len--; 95 96 asprintf(&str2, "fs:%.*s", (int)len, str); 97 free(str); 98 99 ident = CFStringCreateWithCString(NULL, str2, kCFStringEncodingUTF8); 100 asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "DiskUnmountWatcher: %s find and release %s", __func__, str2); 101 free(str2); 102 if (ident) { 103 NAHFindByLabelAndRelease(ident); 104 CFRelease(ident); 105 } 106out: 107 if (dict) 108 CFRelease(dict); 109} 110 111int 112main(int argc, char **argv) 113{ 114 asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "DiskUnmountWatcher: %s", __func__); 115 116 xpc_set_event_stream_handler("com.apple.diskarbitration", dispatch_get_main_queue(), 117 ^(xpc_object_t disk) { 118 callback(disk); 119 }); 120 121 asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "DiskUnmountWatcher: %s", __func__); 122 123 dispatch_main(); 124 125 return 0; 126} 127 128