X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/a54c832626117d45aaf828a9ea9b327fa5feb359..2c4a8bb6222b88ff96fbf25372179646ce15f706:/Console.cpp diff --git a/Console.cpp b/Console.cpp index 1f725ae..2f24e58 100644 --- a/Console.cpp +++ b/Console.cpp @@ -249,11 +249,23 @@ void Setup(CYOutput &out, CYDriver &driver, CYOptions &options, bool lower) { driver.Replace(options); } -static CYUTF8String Run(CYPool &pool, int client, CYUTF8String code) { - const char *json; - uint32_t size; +class CYRemote { + public: + virtual CYUTF8String Run(CYPool &pool, CYUTF8String code) = 0; + + inline CYUTF8String Run(CYPool &pool, const std::string &code) { + return Run(pool, CYUTF8String(code.c_str(), code.size())); + } +}; + +class CYLocalRemote : + public CYRemote +{ + public: + virtual CYUTF8String Run(CYPool &pool, CYUTF8String code) { + const char *json; + uint32_t size; - if (client == -1) { mode_ = Running; #ifdef CY_EXECUTE json = CYExecute(CYGetJSContext(), pool, code); @@ -265,31 +277,95 @@ static CYUTF8String Run(CYPool &pool, int client, CYUTF8String code) { size = 0; else size = strlen(json); - } else { + + return CYUTF8String(json, size); + } +}; + +class CYSocketRemote : + public CYRemote +{ + private: + int socket_; + + public: + CYSocketRemote(const char *host, const char *port) { + 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) { + socket_ = _syscall(socket(info->ai_family, info->ai_socktype, info->ai_protocol)); try { + _syscall(connect(socket_, info->ai_addr, info->ai_addrlen)); + break; + } catch (...) { + _syscall(close(socket_)); + throw; + } + } + } catch (...) { + freeaddrinfo(infos); + throw; + } + } + + virtual CYUTF8String Run(CYPool &pool, CYUTF8String code) { + const char *json; + uint32_t size; + mode_ = Sending; size = code.size; - _assert(CYSendAll(client, &size, sizeof(size))); - _assert(CYSendAll(client, code.data, code.size)); + _assert(CYSendAll(socket_, &size, sizeof(size))); + _assert(CYSendAll(socket_, code.data, code.size)); mode_ = Waiting; - _assert(CYRecvAll(client, &size, sizeof(size))); + _assert(CYRecvAll(socket_, &size, sizeof(size))); if (size == _not(uint32_t)) { size = 0; json = NULL; } else { char *temp(new(pool) char[size + 1]); - _assert(CYRecvAll(client, temp, size)); + _assert(CYRecvAll(socket_, temp, size)); temp[size] = '\0'; json = temp; } mode_ = Working; + + return CYUTF8String(json, size); } +}; - return CYUTF8String(json, size); -} +void InjectLibrary(pid_t, std::ostream &stream, int, const char *const []); -static CYUTF8String Run(CYPool &pool, int client, const std::string &code) { - return Run(pool, client, CYUTF8String(code.c_str(), code.size())); -} +class CYInjectRemote : + public CYRemote +{ + private: + int pid_; + + public: + CYInjectRemote(int pid) : + pid_(pid) + { + // XXX: wait + } + + virtual CYUTF8String Run(CYPool &pool, CYUTF8String code) { + std::ostringstream stream; + const char *args[2] = {"-e", code.data}; + InjectLibrary(pid_, stream, 2, args); + std::string json(stream.str()); + if (!json.empty() && json[json.size() - 1] == '\n') + json.resize(json.size() - 1); + return CYUTF8String(strdup(json.c_str()), json.size()); + } +}; static std::ostream *out_; @@ -315,7 +391,7 @@ static void Output(CYUTF8String json, std::ostream *out, bool reparse = false) { const char *data(json.data); size_t size(json.size); - if (data == NULL || out == NULL) + if (size == 0 || out == NULL) return; CYLexerHighlight(data, size, *out); @@ -326,10 +402,10 @@ int (*append_history$)(int, const char *); static std::string command_; -static int client_; +static CYRemote *remote_; static CYUTF8String Run(CYPool &pool, const std::string &code) { - return Run(pool, client_, code); + return remote_->Run(pool, code); } static char **Complete(const char *word, int start, int end) { @@ -610,7 +686,7 @@ static void CYConsolePrepTerm(int meta) { static void CYOutputRun(const std::string &code, bool reparse = false) { CYPool pool; - Output(Run(pool, client_, code), &std::cout, reparse); + Output(Run(pool, code), &std::cout, reparse); } static void Console(CYOptions &options) { @@ -780,8 +856,6 @@ static void Console(CYOptions &options) { } } -void InjectLibrary(pid_t, int, const char *const []); - static uint64_t CYGetTime() { #ifdef __APPLE__ return mach_absolute_time(); @@ -800,9 +874,7 @@ int Main(int argc, char * const argv[], char const * const envp[]) { append_history$ = (int (*)(int, const char *)) (dlsym(RTLD_DEFAULT, "append_history")); -#ifdef CY_ATTACH pid_t pid(_not(pid_t)); -#endif const char *host(NULL); const char *port(NULL); @@ -816,18 +888,14 @@ int Main(int argc, char * const argv[], char const * const envp[]) { "c" "g:" "n:" -#ifdef CY_ATTACH "p:" -#endif "r:" "s" , (const struct option[]) { {NULL, no_argument, NULL, 'c'}, {NULL, required_argument, NULL, 'g'}, {NULL, required_argument, NULL, 'n'}, -#ifdef CY_ATTACH {NULL, required_argument, NULL, 'p'}, -#endif {NULL, required_argument, NULL, 'r'}, {NULL, no_argument, NULL, 's'}, {0, 0, 0, 0}}, NULL)); @@ -840,9 +908,7 @@ int Main(int argc, char * const argv[], char const * const envp[]) { case '?': fprintf(stderr, "usage: cycript [-c]" -#ifdef CY_ATTACH " [-p ]" -#endif " [-r ]" " [