]> git.saurik.com Git - cycript.git/blob - Connector.cpp
Not quite the original, but pretty damn near close.
[cycript.git] / Connector.cpp
1 #include <substrate.h>
2
3 #include "cycript.hpp"
4 #include "Pooling.hpp"
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <sys/un.h>
10
11 #include <apr-1/apr_thread_proc.h>
12
13 #include <fcntl.h>
14 #include <unistd.h>
15
16 #import <CoreFoundation/CFLogUtilities.h>
17
18 struct CYServer :
19 CYData
20 {
21 int socket_;
22 };
23
24 apr_status_t CYPoolDLClose_(void *data) {
25 void *handle(reinterpret_cast<void *>(data));
26 dlclose(handle);
27 return APR_SUCCESS;
28 }
29
30 static void * APR_THREAD_FUNC Cyrver(apr_thread_t *thread, void *data) {
31 CYServer *server(reinterpret_cast<CYServer *>(data));
32
33 for (;;) {
34 int socket(_syscall(accept(server->socket_, NULL, NULL)));
35
36 if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_LOCAL)) {
37 apr_pool_t *pool;
38 _aprcall(apr_pool_create(&pool, NULL));
39
40 apr_pool_cleanup_register(pool, handle, &CYPoolDLClose_, &apr_pool_cleanup_null);
41
42 if (void (*CYHandleClient_)(apr_pool_t *, int) = reinterpret_cast<void (*)(apr_pool_t *, int)>(dlsym(handle, "CYHandleClient")))
43 (*CYHandleClient_)(pool, socket);
44 else
45 apr_pool_destroy(pool);
46 } else
47 CFLog(kCFLogLevelError, CFSTR("CY:Error: cannot load: %s"), dlerror());
48 }
49
50 delete server;
51 return NULL;
52 }
53
54 static void Unlink() {
55 pid_t pid(getpid());
56 char path[104];
57 sprintf(path, "/tmp/.s.cy.%u", pid);
58 unlink(path);
59 }
60
61 MSInitialize {
62 _aprcall(apr_initialize());
63
64 CYServer *server(new CYServer());
65 server->socket_ = _syscall(socket(PF_UNIX, SOCK_STREAM, 0));
66
67 struct sockaddr_un address;
68 memset(&address, 0, sizeof(address));
69 address.sun_family = AF_UNIX;
70
71 pid_t pid(getpid());
72 sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
73
74 try {
75 _syscall(bind(server->socket_, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
76 atexit(&Unlink);
77 _syscall(listen(server->socket_, 0));
78
79 apr_threadattr_t *attr;
80 _aprcall(apr_threadattr_create(&attr, server->pool_));
81
82 apr_thread_t *thread;
83 _aprcall(apr_thread_create(&thread, attr, &Cyrver, server, server->pool_));
84 } catch (...) {
85 CFLog(kCFLogLevelError, CFSTR("CY:Error: cannot bind unix domain socket"));
86 }
87 }