|  | @@ -8,7 +8,6 @@ | 
														
													
														
															
																|  |  | #include <sys/param.h> // for MAXPATHLEN |  |  | #include <sys/param.h> // for MAXPATHLEN | 
														
													
														
															
																|  |  | #include <fcntl.h> |  |  | #include <fcntl.h> | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | #include <curl/curl.h> |  |  |  | 
														
													
														
															
																|  |  | #include <zip.h> |  |  | #include <zip.h> | 
														
													
														
															
																|  |  | #include <jansson.h> |  |  | #include <jansson.h> | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -23,17 +22,18 @@ | 
														
													
														
															
																|  |  | #include <dirent.h> |  |  | #include <dirent.h> | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | #include "plugin.hpp" |  |  | #include "plugin.hpp" | 
														
													
														
															
																|  |  |  |  |  | #include "util/request.hpp" | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | namespace rack { |  |  | namespace rack { | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | std::list<Plugin*> gPlugins; |  |  | std::list<Plugin*> gPlugins; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static const std::string apiUrl = "http://localhost:8081"; |  |  |  | 
														
													
														
															
																|  |  | static std::string token; |  |  | static std::string token; | 
														
													
														
															
																|  |  | static bool isDownloading = false; |  |  | static bool isDownloading = false; | 
														
													
														
															
																|  |  | static float downloadProgress = 0.0; |  |  | static float downloadProgress = 0.0; | 
														
													
														
															
																|  |  | static std::string downloadName; |  |  | static std::string downloadName; | 
														
													
														
															
																|  |  |  |  |  | static std::string loginStatus; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | Plugin::~Plugin() { |  |  | Plugin::~Plugin() { | 
														
													
												
													
														
															
																|  | @@ -92,7 +92,7 @@ static int loadPlugin(std::string slug) { | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginInit() { |  |  | void pluginInit() { | 
														
													
														
															
																|  |  | curl_global_init(CURL_GLOBAL_NOTHING); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | requestInit(); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | // Load core |  |  | // Load core | 
														
													
														
															
																|  |  | // This function is defined in core.cpp |  |  | // This function is defined in core.cpp | 
														
													
												
													
														
															
																|  | @@ -118,49 +118,13 @@ void pluginDestroy() { | 
														
													
														
															
																|  |  | delete plugin; |  |  | delete plugin; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | gPlugins.clear(); |  |  | gPlugins.clear(); | 
														
													
														
															
																|  |  | curl_global_cleanup(); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | requestDestroy(); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | //////////////////// |  |  | //////////////////// | 
														
													
														
															
																|  |  | // CURL and libzip helpers |  |  | // CURL and libzip helpers | 
														
													
														
															
																|  |  | //////////////////// |  |  | //////////////////// | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static size_t write_file_callback(void *data, size_t size, size_t nmemb, void *p) { |  |  |  | 
														
													
														
															
																|  |  | int fd = *((int*)p); |  |  |  | 
														
													
														
															
																|  |  | ssize_t len = write(fd, data, size*nmemb); |  |  |  | 
														
													
														
															
																|  |  | return len; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { |  |  |  | 
														
													
														
															
																|  |  | if (dltotal == 0.0) |  |  |  | 
														
													
														
															
																|  |  | return 0; |  |  |  | 
														
													
														
															
																|  |  | float progress = dlnow / dltotal; |  |  |  | 
														
													
														
															
																|  |  | downloadProgress = progress; |  |  |  | 
														
													
														
															
																|  |  | return 0; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | static CURLcode download_file(int fd, const char *url) { |  |  |  | 
														
													
														
															
																|  |  | CURL *curl = curl_easy_init(); |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_URL, url); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_callback); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fd); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL); |  |  |  | 
														
													
														
															
																|  |  | CURLcode res = curl_easy_perform(curl); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_cleanup(curl); |  |  |  | 
														
													
														
															
																|  |  | return res; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | static size_t write_string_callback(void *data, size_t size, size_t nmemb, void *p) { |  |  |  | 
														
													
														
															
																|  |  | std::string &text = *((std::string*)p); |  |  |  | 
														
													
														
															
																|  |  | char *dataStr = (char*) data; |  |  |  | 
														
													
														
															
																|  |  | size_t len = size * nmemb; |  |  |  | 
														
													
														
															
																|  |  | text.append(dataStr, len); |  |  |  | 
														
													
														
															
																|  |  | return len; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static void extract_zip(const char *dir, int zipfd) { |  |  | static void extract_zip(const char *dir, int zipfd) { | 
														
													
														
															
																|  |  | int err = 0; |  |  | int err = 0; | 
														
													
												
													
														
															
																|  | @@ -210,50 +174,32 @@ cleanup: | 
														
													
														
															
																|  |  | // plugin manager |  |  | // plugin manager | 
														
													
														
															
																|  |  | //////////////////// |  |  | //////////////////// | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginOpenBrowser(std::string url) { |  |  |  | 
														
													
														
															
																|  |  | // shell injection is possible, so make sure the URL is trusted |  |  |  | 
														
													
														
															
																|  |  | #if ARCH_LIN |  |  |  | 
														
													
														
															
																|  |  | std::string command = "xdg-open " + url; |  |  |  | 
														
													
														
															
																|  |  | system(command.c_str()); |  |  |  | 
														
													
														
															
																|  |  | #endif |  |  |  | 
														
													
														
															
																|  |  | #if ARCH_MAC |  |  |  | 
														
													
														
															
																|  |  | std::string command = "open " + url; |  |  |  | 
														
													
														
															
																|  |  | system(command.c_str()); |  |  |  | 
														
													
														
															
																|  |  | #endif |  |  |  | 
														
													
														
															
																|  |  | #if ARCH_WIN |  |  |  | 
														
													
														
															
																|  |  | ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL); |  |  |  | 
														
													
														
															
																|  |  | #endif |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static std::string apiHost = "http://api.vcvrack.com"; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginLogIn(std::string email, std::string password) { |  |  | void pluginLogIn(std::string email, std::string password) { | 
														
													
														
															
																|  |  | CURL *curl = curl_easy_init(); |  |  |  | 
														
													
														
															
																|  |  | assert(curl); |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | std::string postFields = "email=" + email + "&password=" + password; |  |  |  | 
														
													
														
															
																|  |  | std::string url = apiUrl + "/token"; |  |  |  | 
														
													
														
															
																|  |  | std::string resText; |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_string_callback); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str()); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postFields.size()); |  |  |  | 
														
													
														
															
																|  |  | CURLcode res = curl_easy_perform(curl); |  |  |  | 
														
													
														
															
																|  |  | curl_easy_cleanup(curl); |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | if (res == CURLE_OK) { |  |  |  | 
														
													
														
															
																|  |  | // Parse JSON response |  |  |  | 
														
													
														
															
																|  |  | json_error_t error; |  |  |  | 
														
													
														
															
																|  |  | json_t *rootJ = json_loads(resText.c_str(), 0, &error); |  |  |  | 
														
													
														
															
																|  |  | if (rootJ) { |  |  |  | 
														
													
														
															
																|  |  | json_t *tokenJ = json_object_get(rootJ, "token"); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | json_t *reqJ = json_object(); | 
														
													
														
															
																|  |  |  |  |  | json_object_set(reqJ, "email", json_string(email.c_str())); | 
														
													
														
															
																|  |  |  |  |  | json_object_set(reqJ, "password", json_string(password.c_str())); | 
														
													
														
															
																|  |  |  |  |  | json_t *resJ = requestJson(POST_METHOD, apiHost + "/token", reqJ); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (resJ) { | 
														
													
														
															
																|  |  |  |  |  | // TODO parse response | 
														
													
														
															
																|  |  |  |  |  | json_t *errorJ = json_object_get(resJ, "error"); | 
														
													
														
															
																|  |  |  |  |  | if (errorJ) { | 
														
													
														
															
																|  |  |  |  |  | const char *errorStr = json_string_value(errorJ); | 
														
													
														
															
																|  |  |  |  |  | loginStatus = errorStr; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | else { | 
														
													
														
															
																|  |  |  |  |  | json_t *tokenJ = json_object_get(resJ, "token"); | 
														
													
														
															
																|  |  | if (tokenJ) { |  |  | if (tokenJ) { | 
														
													
														
															
																|  |  | // Set the token, which logs the user in |  |  |  | 
														
													
														
															
																|  |  | token = json_string_value(tokenJ); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | const char *tokenStr = json_string_value(tokenJ); | 
														
													
														
															
																|  |  |  |  |  | token = tokenStr; | 
														
													
														
															
																|  |  |  |  |  | loginStatus = ""; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | json_decref(rootJ); |  |  |  | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  | json_decref(resJ); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  | json_decref(reqJ); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginLogOut() { |  |  | void pluginLogOut() { | 
														
													
												
													
														
															
																|  | @@ -261,6 +207,9 @@ void pluginLogOut() { | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static void pluginRefreshPlugin(json_t *pluginJ) { |  |  | static void pluginRefreshPlugin(json_t *pluginJ) { | 
														
													
														
															
																|  |  |  |  |  | // TODO | 
														
													
														
															
																|  |  |  |  |  | // Refactor | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | json_t *slugJ = json_object_get(pluginJ, "slug"); |  |  | json_t *slugJ = json_object_get(pluginJ, "slug"); | 
														
													
														
															
																|  |  | if (!slugJ) return; |  |  | if (!slugJ) return; | 
														
													
														
															
																|  |  | std::string slug = json_string_value(slugJ); |  |  | std::string slug = json_string_value(slugJ); | 
														
													
												
													
														
															
																|  | @@ -290,7 +239,7 @@ static void pluginRefreshPlugin(json_t *pluginJ) { | 
														
													
														
															
																|  |  | snprintf(path, sizeof(path), "%s/%s.zip", dir, slug.c_str()); |  |  | snprintf(path, sizeof(path), "%s/%s.zip", dir, slug.c_str()); | 
														
													
														
															
																|  |  | int zip = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); |  |  | int zip = open(path, O_RDWR | O_TRUNC | O_CREAT, 0644); | 
														
													
														
															
																|  |  | // Download zip |  |  | // Download zip | 
														
													
														
															
																|  |  | download_file(zip, url.c_str()); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | // download_file(zip, url.c_str()); | 
														
													
														
															
																|  |  | // Unzip file |  |  | // Unzip file | 
														
													
														
															
																|  |  | lseek(zip, 0, SEEK_SET); |  |  | lseek(zip, 0, SEEK_SET); | 
														
													
														
															
																|  |  | extract_zip(dir, zip); |  |  | extract_zip(dir, zip); | 
														
													
												
													
														
															
																|  | @@ -302,9 +251,13 @@ static void pluginRefreshPlugin(json_t *pluginJ) { | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginRefresh() { |  |  | void pluginRefresh() { | 
														
													
														
															
																|  |  |  |  |  | // TODO | 
														
													
														
															
																|  |  |  |  |  | // Refactor with requestJson() | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | if (token.empty()) |  |  | if (token.empty()) | 
														
													
														
															
																|  |  | return; |  |  | return; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* | 
														
													
														
															
																|  |  | isDownloading = true; |  |  | isDownloading = true; | 
														
													
														
															
																|  |  | downloadProgress = 0.0; |  |  | downloadProgress = 0.0; | 
														
													
														
															
																|  |  | downloadName = ""; |  |  | downloadName = ""; | 
														
													
												
													
														
															
																|  | @@ -341,6 +294,7 @@ void pluginRefresh() { | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | isDownloading = false; |  |  | isDownloading = false; | 
														
													
														
															
																|  |  |  |  |  | */ | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void pluginCancelDownload() { |  |  | void pluginCancelDownload() { | 
														
													
												
													
														
															
																|  | @@ -363,5 +317,9 @@ std::string pluginGetDownloadName() { | 
														
													
														
															
																|  |  | return downloadName; |  |  | return downloadName; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | std::string pluginGetLoginStatus() { | 
														
													
														
															
																|  |  |  |  |  | return loginStatus; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | } // namespace rack |  |  | } // namespace rack |