this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Steps towards open command

- Basic open executable that invokes LaunchServices on it's parameter
- LaunchServices sees that it's a file URL and ends in .app so
it gets the main executable in it's Info.plist

Current state: prints out the path to the main executable.

Next step: get that to launch (can't just be a fork,
owned by launchd on macOS??)

+172 -11
+2 -2
src/frameworks/CoreServices/LaunchServices.cpp
··· 226 226 return noErr; // dummy operation 227 227 } 228 228 229 - OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL) 229 + /*OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL) 230 230 { 231 231 // TODO: use 'xdg-mime query' and 'xdg-mime default' to determine the app? 232 232 ··· 236 236 launchApp(g_scXdgOpenPath,args); 237 237 outLaunchedURL = nullptr; 238 238 return unimpErr; 239 - } 239 + }*/ 240 240 241 241 OSStatus LSOpenFSRef(const FSRef *inRef, FSRef *outLaunchedRef) 242 242 {
+13
src/frameworks/CoreServices/include/LaunchServices/LaunchServices.h
··· 26 26 #define kLSNotifyApplicationDeath 1 27 27 #define kLSUnknownErr -1 28 28 29 + #define kLSApplicationNotFoundErr -10814; 30 + 29 31 #define kLSDefaultSessionID 1 30 32 31 33 enum ··· 64 66 OSStatus LSInit(LSInitializeFlags flags); 65 67 OSStatus LSTerm(void); 66 68 69 + typedef struct LSLaunchURLSpec 70 + { 71 + CFURLRef appURL; 72 + CFArrayRef itemURLs; 73 + const AEDesc *passThruParams; 74 + LSLaunchFlags launchFlags; 75 + void *asyncRefCon; 76 + } LSLaunchURLSpec; 77 + 78 + 67 79 OSStatus LSOpenApplication(const LSApplicationParameters *appParams, ProcessSerialNumber *outPSN); 68 80 OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL); 81 + OSStatus LSOpenFromURLSpec(const LSLaunchURLSpec *inLaunchSpec, CFURLRef *outLaunchedURL); 69 82 OSStatus LSOpenFSRef(const FSRef *inRef, FSRef *outLaunchedRef); 70 83 71 84 OSStatus LSGetExtensionInfo(UniCharCount inNameLen, const UniChar* inNameBuffer, UniCharCount *outExtStartIndex);
+113
src/frameworks/CoreServices/src/LaunchServices/LaunchServices.c
··· 21 21 #include <stdio.h> 22 22 #include <stdlib.h> 23 23 24 + static CFStringRef get_main_executable(CFURLRef appURL); 25 + 24 26 OSStatus LSRegisterURL(CFURLRef inURL, Boolean inUpdate) 25 27 { 26 28 printf("STUB: LSRegisterURL\n"); 27 29 return 0; 28 30 } 31 + 32 + OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL) 33 + { 34 + OSStatus ret; 35 + LSLaunchURLSpec spec; 36 + spec.itemURLs = CFArrayCreate(kCFAllocatorDefault, (const void**)&inURL, 1, NULL); 37 + ret = LSOpenFromURLSpec(&spec, outLaunchedURL); 38 + CFRelease(spec.itemURLs); 39 + return ret; 40 + } 41 + 42 + OSStatus LSOpenFromURLSpec(const LSLaunchURLSpec *inLaunchSpec, CFURLRef *outLaunchedURL) 43 + { 44 + CFStringRef scheme, extension, executable; 45 + CFIndex count, i; 46 + CFURLRef url, url_plus_exec, pre; 47 + CFRange range; 48 + OSStatus ret = 0; 49 + 50 + /* Inspect scheme of URL */ 51 + count = CFArrayGetCount(inLaunchSpec->itemURLs); 52 + for (i = 0; i < count; i++) 53 + { 54 + url = CFArrayGetValueAtIndex(inLaunchSpec->itemURLs, i); 55 + scheme = CFURLCopyScheme(url); 56 + range = CFRangeMake(0, CFStringGetLength(scheme)); 57 + 58 + if (CFStringCompareWithOptions(scheme, CFSTR("file"), range, kCFCompareCaseInsensitive) == kCFCompareEqualTo) 59 + { 60 + /* First check if it's a "mac thing", if not forward to xdg-open */ 61 + 62 + /* Check for .app suffix */ 63 + extension = CFURLCopyPathExtension(url); 64 + range = CFRangeMake(0, CFStringGetLength(extension)); 65 + if (CFStringCompareWithOptions(extension, CFSTR("app"), range, kCFCompareCaseInsensitive) == kCFCompareEqualTo) 66 + { 67 + /* Read info.plist, find path to main executable */ 68 + if ((executable = get_main_executable(url)) == NULL) 69 + { 70 + ret = 1; 71 + } 72 + else 73 + { 74 + url_plus_exec = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, url, CFSTR("Contents"), TRUE); 75 + pre = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, url_plus_exec, CFSTR("MacOS"), TRUE); 76 + CFRelease(url_plus_exec); 77 + url_plus_exec = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, pre, executable, FALSE); 78 + CFRelease(pre); 79 + 80 + /* Launch the executable */ 81 + executable = CFURLGetString(url_plus_exec); 82 + CFShow(executable); 83 + 84 + CFRelease(url_plus_exec); 85 + CFRelease(executable); 86 + } 87 + } 88 + else 89 + { 90 + printf("TODO: forward to xdg-open\n"); 91 + ret = 1; 92 + } 93 + 94 + CFRelease(extension); 95 + } 96 + else 97 + { 98 + printf("We can't handle this scheme yet\n"); 99 + CFShow(scheme); 100 + ret = kLSApplicationNotFoundErr; 101 + } 102 + CFRelease(scheme); 103 + } 104 + return ret; 105 + } 106 + 107 + static CFStringRef get_main_executable(CFURLRef appURL) 108 + { 109 + CFURLRef pre = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, appURL, CFSTR("Contents"), TRUE); 110 + CFURLRef info_plist_url = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, pre, CFSTR("Info.plist"), FALSE); 111 + CFReadStreamRef rs = CFReadStreamCreateWithFile(kCFAllocatorDefault, info_plist_url); 112 + CFDictionaryRef info_plist; 113 + CFStringRef ret = NULL; 114 + 115 + CFRelease(pre); 116 + 117 + if (!CFReadStreamOpen(rs)) 118 + { 119 + printf("Failed to read Info.plist\n"); 120 + goto err_pre_info; 121 + } 122 + 123 + info_plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, rs, 0, 0, NULL, NULL); 124 + 125 + if (CFGetTypeID(info_plist) != CFDictionaryGetTypeID()) 126 + { 127 + printf("Root object of Info.plist not CFDictionaryRef!\n"); 128 + goto err; 129 + } 130 + 131 + ret = CFDictionaryGetValue(info_plist, CFSTR("CFBundleExecutable")); 132 + if (ret != NULL) 133 + ret = CFStringCreateCopy(kCFAllocatorDefault, ret); 134 + 135 + err: 136 + CFRelease(info_plist); 137 + err_pre_info: 138 + CFRelease(rs); 139 + CFRelease(info_plist_url); 140 + return ret; 141 + }
+8 -2
src/tools/CMakeLists.txt
··· 1 1 project(tools) 2 2 3 + add_compile_options( 4 + -Werror 5 + -Wall 6 + ) 7 + 3 8 add_darling_executable(sw_vers sw_vers.c) 4 9 add_darling_executable(sudo sudo.c) 5 10 add_darling_executable(codesign codesign.c) 6 - #add_darling_executable(open open.c) 11 + add_darling_executable(open open.c) 7 12 add_darling_executable(dsmemberutil dsmemberutil.c) 8 13 add_darling_executable(softwareupdate softwareupdate.c) 9 14 10 - install(TARGETS sw_vers sudo codesign dsmemberutil DESTINATION libexec/darling/usr/bin) 15 + install(TARGETS sw_vers sudo codesign dsmemberutil open DESTINATION libexec/darling/usr/bin) 11 16 install(TARGETS softwareupdate DESTINATION libexec/darling/usr/sbin) 12 17 13 18 target_link_libraries(sw_vers CoreFoundation) 19 + target_link_libraries(open CoreFoundation ApplicationServices)
+36 -7
src/tools/open.c
··· 18 18 */ 19 19 20 20 #include <stdio.h> 21 + #include <string.h> 22 + #include <sys/types.h> 23 + #include <sys/stat.h> 24 + #include <unistd.h> 25 + #include <stdlib.h> 26 + 21 27 #include <CoreFoundation/CoreFoundation.h> 22 28 #include <ApplicationServices/ApplicationServices.h> 23 29 24 - void usage(void); 30 + static void usage(void); 25 31 32 + /* TODO: Options */ 26 33 int main(int argc, char *argv[]) 27 34 { 28 - if (argc < 0) 35 + CFStringRef url_or_path; 36 + CFURLRef url; 37 + struct stat path_stat; 38 + if (argc != 2) 29 39 { 30 40 usage(); 31 - return 1; 41 + return EXIT_FAILURE; 42 + } 43 + url_or_path = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8); 44 + /* TODO: What is the URL is not a file URL? (http:, ftp:, etc) */ 45 + /* url = CFURLCreateWithString(kCFAllocatorDefault, url_or_path, NULL); */ 46 + url = NULL; 47 + 48 + if (url == NULL) 49 + { 50 + if (lstat(argv[1], &path_stat)) 51 + { 52 + perror(argv[1]); 53 + return EXIT_FAILURE; 54 + } 55 + url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, url_or_path, kCFURLPOSIXPathStyle, path_stat.st_mode & S_IFDIR); 56 + if (url == NULL) 57 + { 58 + printf("Failed to create file url: %s\n", argv[1]); 59 + return EXIT_FAILURE; 60 + } 32 61 } 33 - CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingMacRoman); 34 - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, str, kCFURLPOSIXPathStyle, FALSE); 35 62 63 + LSOpenCFURLRef(url, NULL); 36 64 65 + CFRelease(url); 37 66 38 - return 0; 67 + return EXIT_SUCCESS; 39 68 } 40 69 41 - void usage(void) 70 + static void usage(void) 42 71 { 43 72 printf("Usage: open [filenames]\n" 44 73 "Help: Use open to open files, folders, and URLs from the command line.\n");