this repo has no description
1
fork

Configure Feed

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

Unfinished work on fseventsd - will be finished after Linux 5.7 is released

+239
+1
CMakeLists.txt
··· 79 79 option(ENABLE_TESTS "Install in-prefix unit tests" OFF) 80 80 81 81 FindDsymutil() 82 + find_package(Setcap REQUIRED) 82 83 83 84 # Missing CMakeLists.txt must trigger an error 84 85 cmake_policy(SET CMP0014 NEW)
+6
src/frameworks/CoreServices/src/FSEvents/CMakeLists.txt
··· 13 13 Foundation 14 14 system 15 15 ) 16 + 17 + add_darling_executable(fseventsd fseventsd.m) 18 + target_link_libraries(fseventsd system Foundation CarbonCore) 19 + 20 + install(TARGETS fseventsd DESTINATION libexec/darling/usr/sbin) 21 + install(CODE "execute_process(COMMAND ${SETCAP_EXECUTABLE} \"cap_sys_admin+ep\" \"${CMAKE_INSTALL_PREFIX}/libexec/darling/usr/sbin/fseventsd\")")
+38
src/frameworks/CoreServices/src/FSEvents/fseventsd.h
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2020 Lubos Dolezel 5 + 6 + Darling is free software: you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation, either version 3 of the License, or 9 + (at your option) any later version. 10 + 11 + Darling is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #ifndef FSEVENTSD_H_ 21 + #define FSEVENTSD_H_ 22 + 23 + #define FSEVENTSD_SOCKET_PATH "/var/run/fseventsd.sock" 24 + 25 + typedef struct fseventsd_monitor { 26 + int id; 27 + char path[4096]; 28 + int flags; 29 + } fseventsd_monitor_t; 30 + 31 + typedef struct fseventsd_event { 32 + int id; 33 + char path[4096]; 34 + int flags; 35 + } fseventsd_event_t; 36 + 37 + #endif 38 +
+194
src/frameworks/CoreServices/src/FSEvents/fseventsd.m
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2020 Lubos Dolezel 5 + 6 + Darling is free software: you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation, either version 3 of the License, or 9 + (at your option) any later version. 10 + 11 + Darling is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <sys/socket.h> 21 + #include <sys/un.h> 22 + #include <stdio.h> 23 + #include <string.h> 24 + #include <stdlib.h> 25 + #include <ext/fanotify.h> 26 + #include <ext/file_handle.h> 27 + #include <linux/fanotify.h> 28 + #include <dispatch/dispatch.h> 29 + #include <CoreServices/FileManager.h> 30 + #import <Foundation/NSObjCRuntime.h> 31 + #import <Foundation/NSDictionary.h> 32 + #include "fseventsd.h" 33 + 34 + int g_listenSocket, g_fanotify; 35 + 36 + void setupListenSocket(void); 37 + void handleNewConnection(int fd); 38 + void setupFANotify(void); 39 + 40 + int main() 41 + { 42 + setupListenSocket(); 43 + setupFANotify(); 44 + 45 + dispatch_main(); 46 + return 0; 47 + } 48 + 49 + void setupListenSocket(void) 50 + { 51 + struct sockaddr_un sa; 52 + sa.sun_family = AF_UNIX; 53 + 54 + strcpy(sa.sun_path, FSEVENTSD_SOCKET_PATH); 55 + unlink(FSEVENTSD_SOCKET_PATH); 56 + 57 + g_listenSocket = socket(AF_UNIX, SOCK_SEQPACKET, 0); 58 + if (g_listenSocket == -1) 59 + { 60 + perror("bind"); 61 + exit(EXIT_FAILURE); 62 + } 63 + 64 + int rv = bind(g_listenSocket, (const struct sockaddr *) &sa, sizeof(sa)); 65 + if (rv == -1) 66 + { 67 + perror("bind"); 68 + exit(EXIT_FAILURE); 69 + } 70 + 71 + rv = listen(g_listenSocket, 5); 72 + if (rv == -1) 73 + { 74 + perror("listen"); 75 + exit(EXIT_FAILURE); 76 + } 77 + 78 + dispatch_source_t listenerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, g_listenSocket, 0, dispatch_get_main_queue()); 79 + dispatch_source_set_event_handler(listenerSource, ^{ 80 + struct sockaddr_un sa; 81 + sa.sun_family = AF_UNIX; 82 + 83 + socklen_t len = sizeof(sa); 84 + 85 + int rv = accept(g_listenSocket, (struct sockaddr*) &sa, &len); 86 + if (rv >= 0) 87 + handleNewConnection(rv); 88 + }); 89 + dispatch_resume(listenerSource); 90 + } 91 + 92 + void handleClientCommand(int fd, const fseventsd_monitor_t* cmd) 93 + { 94 + 95 + } 96 + 97 + void handleNewConnection(int fd) 98 + { 99 + dispatch_source_t socketSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatch_get_main_queue()); 100 + 101 + dispatch_source_set_event_handler(socketSource, ^{ 102 + fseventsd_monitor_t cmd; 103 + struct msghdr msg; 104 + struct iovec iov = { 105 + .iov_base = &cmd, 106 + .iov_len = sizeof(cmd) 107 + }; 108 + 109 + memset(&msg, 0, sizeof(msg)); 110 + msg.msg_iov = &iov; 111 + msg.msg_iovlen = 1; 112 + 113 + recvmsg(fd, &msg, 0); 114 + int rv = read(fd, &cmd, sizeof(cmd)); 115 + 116 + if (rv == sizeof(cmd)) 117 + handleClientCommand(fd, &cmd); 118 + }); 119 + 120 + dispatch_resume(socketSource); 121 + } 122 + 123 + void fileHandleToFSRef(const struct file_handle* fh, FSRef* ref) 124 + { 125 + static FSRef rootRef; 126 + static dispatch_once_t once; 127 + 128 + dispatch_once(&once, ^{ 129 + FSPathMakeRef((const UInt8*) "/", &rootRef, NULL); 130 + }); 131 + 132 + RefData* refData = (RefData*) ref; 133 + refData->mount_id = ((RefData*)&rootRef)->mount_id; 134 + 135 + memcpy(&refData->fh, fh, sizeof(FSRef) - sizeof(refData->mount_id)); 136 + } 137 + 138 + void setupFANotify(void) 139 + { 140 + // FAN_REPORT_FID = provide file handles 141 + // Linux file handle = FSRef in Darling 142 + g_fanotify = fanotify_init(FAN_REPORT_FID, 0); 143 + if (g_fanotify == -1) 144 + { 145 + perror("fanotify_init"); 146 + exit(EXIT_FAILURE); 147 + } 148 + 149 + int rv = fanotify_mark(g_fanotify, FAN_MARK_ADD | FAN_MARK_FILESYSTEM, 150 + FAN_CREATE | FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | FAN_MODIFY | FAN_ONDIR, AT_FDCWD, "/"); 151 + if (rv == -1) 152 + { 153 + perror("fanotify_mark"); 154 + exit(EXIT_FAILURE); 155 + } 156 + 157 + dispatch_source_t faSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, g_fanotify, 0, dispatch_get_main_queue()); 158 + 159 + dispatch_source_set_event_handler(faSource, ^{ 160 + char events_buf[4096]; 161 + int len = read(g_fanotify, events_buf, sizeof(events_buf)); 162 + printf("Read %d bytes of event data\n", len); 163 + 164 + for (struct fanotify_event_metadata* metadata = (struct fanotify_event_metadata *) events_buf; 165 + FAN_EVENT_OK(metadata, len); 166 + metadata = FAN_EVENT_NEXT(metadata, len)) 167 + { 168 + printf("Event mask: 0x%x\n", metadata->mask); 169 + struct fanotify_event_info_fid* fid = (struct fanotify_event_info_fid *) (metadata + 1); 170 + if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_FID) 171 + { 172 + struct file_handle* fh = (struct file_handle *) fid->handle; 173 + FSRef fsref; 174 + 175 + printf("fileHandleToFSRef: bytes: %d, type: %d\n", fh->handle_bytes, fh->handle_type); 176 + fileHandleToFSRef(fh, &fsref); 177 + 178 + char pathbuf[1024]; 179 + printf("FSRefMakePath\n"); 180 + if (FSRefMakePath(&fsref, (UInt8*)pathbuf, sizeof(pathbuf)) != 0) 181 + puts("FSRefMakePath failed"); 182 + else 183 + printf("Event on %s\n", pathbuf); 184 + } 185 + else 186 + { 187 + puts("Not a FID"); 188 + } 189 + printf("---\n"); 190 + } 191 + }); 192 + 193 + dispatch_resume(faSource); 194 + }