]> git.saurik.com Git - cycript.git/commitdiff
Allow for connections from the client to the server.
authorJay Freeman (saurik) <saurik@saurik.com>
Tue, 10 Sep 2013 19:28:55 +0000 (12:28 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 10 Sep 2013 19:28:55 +0000 (12:28 -0700)
Console.cpp
Handler.mm

index 3dede2fb1702a7640f98b1e8b097f202a5f6dde2..fe03c314090cff31b649fdcd23511e377e5a6c45 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 
+#include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <netdb.h>
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -616,6 +618,9 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
     pid_t pid(_not(pid_t));
 #endif
 
+    const char *host(NULL);
+    const char *port(NULL);
+
     apr_getopt_t *state;
     _aprcall(apr_getopt_init(&state, pool, argc, argv));
 
@@ -628,6 +633,7 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
 #ifdef CY_ATTACH
             "p:"
 #endif
+            "r:"
             "s"
         , &opt, &arg));
 
@@ -641,6 +647,7 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
 #ifdef CY_ATTACH
                     " [-p <pid|name>]"
 #endif
+                    " [-r <host:port>]"
                     " [<script> [<arg>...]]\n"
                 );
                 return 1;
@@ -728,6 +735,27 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
             } break;
 #endif
 
+            case 'r': {
+                //size_t size(strlen(arg));
+
+                char *colon(strrchr(arg, ':'));
+                if (colon == NULL) {
+                    fprintf(stderr, "missing colon in hostspec\n");
+                    return 1;
+                }
+
+                /*char *end;
+                port = strtoul(colon + 1, &end, 10);
+                if (end != arg + size) {
+                    fprintf(stderr, "invalid port in hostspec\n");
+                    return 1;
+                }*/
+
+                host = arg;
+                *colon = '\0';
+                port = colon + 1;
+            } break;
+
             case 's':
                 strict_ = true;
             break;
@@ -800,6 +828,34 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
     client_ = -1;
 #endif
 
+    if (client_ == -1 && host != NULL && port != NULL) {
+        struct addrinfo hints;
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_UNSPEC;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = 0;
+        hints.ai_flags = 0;
+
+        struct addrinfo *infos;
+        _syscall(getaddrinfo(host, port, &hints, &infos));
+
+        _assert(infos != NULL); try {
+            for (struct addrinfo *info(infos); info != NULL; info = info->ai_next) {
+                int client(_syscall(socket(info->ai_family, info->ai_socktype, info->ai_protocol))); try {
+                    _syscall(connect(client, info->ai_addr, info->ai_addrlen));
+                    client_ = client;
+                    break;
+                } catch (...) {
+                    _syscall(close(client));
+                    throw;
+                }
+            }
+        } catch (...) {
+            freeaddrinfo(infos);
+            throw;
+        }
+    }
+
     if (script == NULL && tty)
         Console(options);
     else {
index d15eb6a9c3de25b5758f89b4cb12136c6d14b11b..e7b2c3bcf5e3e16dae386d992bafd80730a49b8b 100644 (file)
@@ -172,3 +172,55 @@ extern "C" void CYHandleServer(pid_t pid) {
         fprintf(stderr, "%s\n", error.PoolCString(pool));
     }
 }
+
+struct CYServer {
+    pthread_t thread_;
+    uint16_t port_;
+    int socket_;
+
+    CYServer(uint16_t port) :
+        port_(port),
+        socket_(-1)
+    {
+    }
+
+    ~CYServer() {
+        if (socket_ != -1)
+            _syscall(close(socket_));
+    }
+
+    void Listen() {
+        socket_ = _syscall(::socket(PF_INET, SOCK_STREAM, 0)); try {
+            sockaddr_in address;
+            address.sin_family = AF_INET;
+            address.sin_addr.s_addr = INADDR_ANY;
+            address.sin_port = htons(port_);
+            _syscall(::bind(socket_, reinterpret_cast<sockaddr *>(&address), sizeof(address)));
+
+            _syscall(::listen(socket_, -1));
+
+            for (;;) {
+                socklen_t length(sizeof(address));
+                int socket(_syscall(::accept(socket_, reinterpret_cast<sockaddr *>(&address), &length)));
+                CYHandleClient(socket);
+            }
+        } catch (const CYException &error) {
+            CYPool pool;
+            fprintf(stderr, "%s\n", error.PoolCString(pool));
+        }
+    }
+};
+
+static void *OnServer(void *data) {
+    CYServer *server(reinterpret_cast<CYServer *>(data));
+    server->Listen();
+    delete server;
+    return NULL;
+}
+
+extern "C" void CYListenServer(short port) {
+    CYInitializeDynamic();
+
+    CYServer *server(new CYServer(port));
+    _assert(pthread_create(&server->thread_, NULL, &OnServer, server) == 0);
+}