diff options
-rwxr-xr-x | build.sh | 4 | ||||
m--------- | lib/lua | 0 | ||||
m--------- | lib/openssl | 0 | ||||
-rw-r--r-- | lpm.c | 96 | ||||
-rw-r--r-- | lpm.lua | 45 |
5 files changed, 120 insertions, 25 deletions
@@ -26,7 +26,7 @@ if [[ "$@" != *"-lgit2"* ]]; then LDFLAGS="-Llib/libgit2/build -l:libgit2.a $LDFLAGS" && CFLAGS="$CFLAGS -Ilib/prefix/include" && LDFLAGS="$LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64" fi if [[ "$@" != *"-lcurl"* ]]; then - [ ! -e "lib/curl/build" ] && cd lib/curl && mkdir build && cd build && cmake .. $CURL_CONFIGURE -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DENABLE_UNICODE=OFF -DBUILD_CURL_EXE=OFF -DCURL_USE_LIBSSH2=OFF -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../ + [ ! -e "lib/curl/build" ] && cd lib/curl && mkdir build && cd build && cmake .. $CURL_CONFIGURE -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DUSE_LIBIDN2=OFF -DENABLE_UNICODE=OFF -DBUILD_CURL_EXE=OFF -DCURL_USE_LIBSSH2=OFF -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../ LDFLAGS="-Llib/curl/build -l:libcurl.a $LDFLAGS" && CFLAGS="$CFLAGS -Ilib/prefix/include -DCURL_STATICLIB" && LDFLAGS="$LDFLAGS -Llib/prefix/lib" fi [[ "$@" != *"-llua"* ]] && CFLAGS="$CFLAGS -Ilib/lua -DMAKE_LIB=1" && SRCS="$SRCS lib/lua/onelua.c" @@ -34,7 +34,7 @@ fi # Build the pre-packaged lua file into the executbale. xxd -i lpm.lua > lpm.lua.c -[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread -l:libidn2.a -l:libunistring.a" +[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread" [[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && LDFLAGS="$LDFLAGS -lws2_32 -lz -lwinhttp -lole32 -lcrypt32 -lrpcrt4" [[ "$@" != *" -g "* || "$@" != *" -O"* ]] && CFLAGS="$CFLAGS -O3" && LDFLAGS="$LDFLAGS -s" diff --git a/lib/lua b/lib/lua -Subproject 997f11f54322883c3181225f29d101a597f3173 +Subproject 71bc69c2afaf49ab5f54f3443af9ae70dd1fed0 diff --git a/lib/openssl b/lib/openssl -Subproject fd24de9f93049b05a54c48da5316f4288248923 +Subproject 45e7ef5fe34b3f519f1454c47dc08aa4563e424 @@ -24,14 +24,35 @@ static char hexDigits[] = "0123456789abcdef"; static int lpm_hash(lua_State* L) { size_t len; const char* data = luaL_checklstring(L, 1, &len); + const char* type = luaL_checkstring(L, 2); unsigned char buffer[SHA256_DIGEST_LENGTH]; + SHA256_CTX c + SHA256_Init(&c); + if (strcmp(type, "file") == 0) { + FILE* file = fopen(data, "rb"); + if (!file) { + SHA256_Final(buffer, &c) + return luaL_error(L, "can't open %s", data); + } + while (true) { + unsigned char chunk[4096]; + size_t bytes = fread(chunk, 1, sizeof(chunk), file); + SHA256_Update(&c, chunk, bytes); + if (bytes < 4096) + break; + } + fclose(file); + } else { + SHA256_Update(&c, data, len); + } + SHA256_Final(buffer, &c) char hexBuffer[SHA256_DIGEST_LENGTH * 2]; SHA256(data, len, buffer); - for (size_t i = 0; i < len; ++i) { + for (size_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) { hexBuffer[i*2+0] = hexDigits[buffer[i] >> 4]; hexBuffer[i*2+1] = hexDigits[buffer[i] & 0xF]; } - lua_pushlstring(L, buffer, SHA256_DIGEST_LENGTH * 2); + lua_pushlstring(L, hexBuffer, SHA256_DIGEST_LENGTH * 2); return 1; } @@ -363,17 +384,20 @@ static int lpm_fetch(lua_State* L) { } +static CURL *curl; static int lpm_set_certs(lua_State* L) { const char* type = luaL_checkstring(L, 1); const char* path = luaL_checkstring(L, 2); - if (strcmp(type, "dir") == 0) + if (strcmp(type, "dir") == 0) { git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, path); - else + curl_easy_setopt(curl, CURLOPT_CAINFO, path); + } else { git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, path, NULL); + curl_easy_setopt(curl, CURLOPT_CAPATH, path); + } return 0; } -static CURL *curl; static int lpm_status(lua_State* L) { const char* path = luaL_checkstring(L, 1); git_repository* repository; @@ -398,17 +422,33 @@ static size_t lpm_curl_write_callback(char *ptr, size_t size, size_t nmemb, void static int lpm_get(lua_State* L) { const char* url = luaL_checkstring(L, 1); - curl_easy_reset(curl); + const char* path = luaL_optstring(L, 2, NULL); + // curl_easy_reset(curl); curl_easy_setopt(curl, CURLOPT_URL, url); - CURLcode res = curl_easy_perform(curl); - if (res != CURLE_OK) - return luaL_error(L, "curl error: %d", res); - luaL_Buffer B; - luaL_buffinit(L, &B); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lpm_curl_write_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &B); - luaL_pushresult(&B); - lua_newtable(L); + if (path) { + FILE* file = fopen(path, "wb"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) { + fclose(file); + return luaL_error(L, "curl error: %d", res); + } + fclose(file); + lua_pushnil(L); + lua_newtable(L); + return 2; + } else { + luaL_Buffer B; + luaL_buffinit(L, &B); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lpm_curl_write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &B); + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) + return luaL_error(L, "curl error: %d", res); + luaL_pushresult(&B); + lua_newtable(L); + } return 2; } @@ -432,6 +472,26 @@ static const luaL_Reg system_lib[] = { #define LPM_VERSION "unknown" #endif + +#ifndef LITE_ARCH_TUPLE + #if __x86_64__ || _WIN64 || __MINGW64__ + #define ARCH_PROCESSOR "x86_64" + #else + #define ARCH_PROCESSOR "x86" + #endif + #if _WIN32 + #define ARCH_PLATFORM "windows" + #elif __linux__ + #define ARCH_PLATFORM "linux" + #elif __APPLE__ + #define ARCH_PLATFORM "darwin" + #else + #error "Please define -DLITE_ARCH_TUPLE." + #endif + #define LITE_ARCH_TUPLE ARCH_PROCESSOR "-" ARCH_PLATFORM +#endif + + extern const char lpm_lua[]; extern unsigned int lpm_lua_len; int main(int argc, char* argv[]) { @@ -459,8 +519,10 @@ int main(int argc, char* argv[]) { #endif lua_setglobal(L, "PATHSEP"); lua_setglobal(L, "PLATFORM"); - // if (luaL_loadbuffer(L, lpm_lua, lpm_lua_len, "lpm.lua")) { - if (luaL_loadfile(L, "lpm.lua")) { + lua_pushliteral(L, LITE_ARCH_TUPLE); + lua_setglobal(L, "ARCH"); + if (luaL_loadbuffer(L, lpm_lua, lpm_lua_len, "lpm.lua")) { + //if (luaL_loadfile(L, "lpm.lua")) { fprintf(stderr, "internal error when starting the application: %s\n", lua_tostring(L, -1)); return -1; } @@ -485,6 +485,8 @@ function Plugin.new(repository, metadata) if stat and (not metadata.lite_version or metadata.lite_version == LITE_VERSION) and (not metadata.mod_version or tonumber(metadata.mod_version) == tonumber(MOD_VERSION)) then self.status = "installed" self.type = stat.type == "dir" and "complex" or "singleton" + else + self.type = self.files or self.remote and "complex" or "singleton" end return self end @@ -561,13 +563,37 @@ function Plugin:install(installing) end end if self.status == "upgradable" then - log_action("Upgrading plugin located at " .. self.local_path .. " to " .. self.install_path) + log_action("Upgrading " .. self.type .. "plugin located at " .. self.local_path .. " to " .. self.install_path) common.rmrf(self.install_path) - common.copy(self.local_path, self.install_path) else - log_action("Installing plugin located at " .. self.local_path .. " to " .. self.install_path) + log_action("Installing " .. self.type .. " plugin located at " .. self.local_path .. " to " .. self.install_path) + end + + if self.url then + log_action("Downloading file " .. self.url .. "...") + local path = self.install_path .. (self.type == 'singleton' and (PATHSEP .. "init.lua") or "") + system.get(file.url, path) + log_action("Downloaded file " .. self.url .. " to " .. path) + if system.hash(path, "file") ~= file.checksum then error("checksum doesn't match") end + elseif self.remote then + log_action("Cloning repository " .. self.remote .. " into " .. self.install_path) + common.mkdirp(self.install_path) + local _, _, url, branch = self.remote:find("^(.*):(.*)$") + system.init(self.install_path, url) + system.reset(self.install_path, branch) + else common.copy(self.local_path, self.install_path) end + for i,file in ipairs(self.files) do + if not file.arch or file.arch == ARCH then + if not file.checksum then error("requires a checksum") end + local path = self.install_path .. PATHSEP .. (file.path or common.basename(file.url)) + log_action("Downloading file " .. file.url .. "...") + system.get(file.url, path) + log_action("Downloaded file " .. file.url .. " to " .. path) + if system.hash(path, "file") ~= file.checksum then error("checksum doesn't match") end + end + end end @@ -651,9 +677,14 @@ function Repository:generate_manifest() for line in io.lines(path .. PATHSEP .. "README.md") do local _, _, name, path, description = line:find("^%s*%|%s*%[`([%w_]+)%??.-`%]%((.-)%).-%|%s*(.-)%s*%|%s*$") if name then - plugin_map[name] = { name = name, description = description } + plugin_map[name] = { name = name, description = description, files = {} } if path:find("^http") then - plugin_map[name].remote = path + if path:find("%.lua") then + plugin_map[name].url = path + plugin_map[name].checksum = system.hash(system.get(path)) + else + plugin_map[name].remote = path + end else plugin_map[name].path = path:gsub("%?.*$", "") end @@ -662,7 +693,7 @@ function Repository:generate_manifest() end for i, file in ipairs(system.ls(path .. plugin_dir)) do if file:find("%.lua$") then - local plugin = { description = nil, name = common.basename(file):gsub("%.lua$", ""), dependencies = {}, mod_version = 3, version = "1.0", tags = {}, path = plugin_dir .. file } + local plugin = { description = nil, files = {}, name = common.basename(file):gsub("%.lua$", ""), dependencies = {}, mod_version = 3, version = "1.0", tags = {}, path = plugin_dir .. file } for line in io.lines(path .. plugin_dir .. file) do local _, _, mod_version = line:find("%-%-.*mod%-version:%s*(%w+)") if mod_version then plugin.mod_version = mod_version end @@ -1037,6 +1068,7 @@ Flags have the following effects: ) return 0 end + VERBOSE = ARGS["verbose"] or false JSON = ARGS["json"] or os.getenv("LPM_JSON") QUIET = ARGS["quiet"] or os.getenv("LPM_QUIET") @@ -1051,6 +1083,7 @@ Flags have the following effects: if not system.stat(USERDIR) then error("can't find user directory " .. USERDIR) end CACHEDIR = ARGS["cachedir"] or os.getenv("LPM_CACHE") or USERDIR .. PATHSEP .. "lpm" + if ARGS[2] == "purge" then return lpm_purge() end if ARGS["ssl_certs"] then local stat = system.stat(ARGS["ssl_certs"]) if not stat then error("can't find " .. ARGS["ssl_certs"]) end |