aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules6
-rw-r--r--README.md4
-rwxr-xr-xbuild.sh7
m---------lib/libtar0
m---------lib/microtar0
-rw-r--r--src/lpm.c99
6 files changed, 67 insertions, 49 deletions
diff --git a/.gitmodules b/.gitmodules
index ef53f82..5f540c7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -8,9 +8,9 @@
[submodule "lib/zlib"]
path = lib/zlib
url = https://github.com/madler/zlib.git
-[submodule "lib/libtar"]
- path = lib/libtar
- url = https://github.com/tklauser/libtar.git
[submodule "lib/libzip"]
path = lib/libzip
url = https://github.com/nih-at/libzip.git
+[submodule "lib/microtar"]
+ path = lib/microtar
+ url = https://github.com/rxi/microtar.git
diff --git a/README.md b/README.md
index bfbb626..1c099de 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ build `lpm`:
* `libgit2` (accessing git repositories directly)
* `libz` (supporting library for everything)
* `libzip` (for unpacking .zip files)
-* `libtar` (for unpacking .tar.gz files)
+* `libmicrotar` (for unpacking .tar.gz files)
## Use in CI
@@ -86,7 +86,7 @@ lpm --help
### Linux to Windows
```
-CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar WINDRES=x86_64-w64-mingw32-windres CMAKE_DEFAULT_FLAGS="-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_INCLUDE_PATH=/usr/share/mingw-w64/include" GIT2_CONFIGURE="-DDLLTOOL=x86_64-w64-mingw32-dlltool" ./build.sh -DLPM_VERSION='"'$VERSION-x86_64-windows-`git rev-parse --short HEAD`'"'
+CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar WINDRES=x86_64-w64-mingw32-windres CMAKE_DEFAULT_FLAGS="-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_INCLUDE_PATH=/usr/share/mingw-w64/include" TAR_CONFIGURE="--host=x86_64-w64-mingw32" GIT2_CONFIGURE="-DDLLTOOL=x86_64-w64-mingw32-dlltool" ./build.sh -DLPM_VERSION='"'$VERSION-x86_64-windows-`git rev-parse --short HEAD`'"'
```
diff --git a/build.sh b/build.sh
index bde63a2..31b5dce 100755
--- a/build.sh
+++ b/build.sh
@@ -16,7 +16,7 @@ CMAKE_DEFAULT_FLAGS=" $CMAKE_DEFAULT_FLAGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_PR
mkdir -p lib/prefix/include lib/prefix/lib
if [[ "$@" != *"-lz"* ]]; then
[ ! -e "lib/zlib" ] && echo "Make sure you've cloned submodules. (git submodule update --init --depth=1)" && exit -1
- [[ ! -e "lib/zlib/build" && $OSTYPE != 'msys'* ]] && cd lib/zlib && mkdir build && cd build && ../configure --prefix=`pwd`/../../prefix && $MAKE -j $JOBS && $MAKE install && cd ../../../
+ [[ ! -e "lib/zlib/build" && $OSTYPE != 'msys'* ]] && cd lib/zlib && mkdir build && cd build && ../configure --static --prefix=`pwd`/../../prefix && $MAKE -j $JOBS && $MAKE install && cd ../../../
[[ ! -e "lib/zlib/build" && $OSTYPE == 'msys'* ]] && cd lib/zlib && mkdir build && $MAKE -f ../win32/Makefile.gcc -j $JOBS && cp *.a ../prefix/lib && cp *.h ../prefix/include && cd ../../
LDFLAGS="$LDFLAGS -l:libz.a"
fi
@@ -32,10 +32,7 @@ if [[ "$@" != *"-lzip"* ]]; then
[ ! -e "lib/libzip/build" ] && cd lib/libzip && mkdir build && cd build && cmake .. -G "Unix Makefiles" $CMAKE_DEFAULT_FLAGS -DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOC=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_BZIP2=OFF -DENABLE_LZMA=OFF -DENABLE_ZSTD=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../
LDFLAGS="$LDFLAGS -l:libzip.a"
fi
-if [[ "$@" != *"-ltar"* ]]; then
- [ ! -e "lib/libtar/build" ] && cd lib/libtar && mkdir build && autoreconf --force --install && cd build && ../configure --prefix=`pwd`/../../prefix && $MAKE -j $JOBS && $MAKE install && cd ../../../
- LDFLAGS="$LDFLAGS -l:libtar.a"
-fi
+[[ "$@" != *"-lmicrotar"* ]] && CFLAGS="$CFLAGS -Ilib/microtar/src" && SRCS="$SRCS lib/microtar/src/microtar.c"
[[ "$@" != *"-llua"* ]] && CFLAGS="$CFLAGS -Ilib/lua -DMAKE_LIB=1" && SRCS="$SRCS lib/lua/onelua.c"
# Build the pre-packaged lua file into the executbale.
diff --git a/lib/libtar b/lib/libtar
deleted file mode 160000
-Subproject 6379b5d2ae777dad576aeae7056674067005782
diff --git a/lib/microtar b/lib/microtar
new file mode 160000
+Subproject 27076e1b9290e9c7842bb7890a54fcf172406c8
diff --git a/src/lpm.c b/src/lpm.c
index b17e2ae..5c0f232 100644
--- a/src/lpm.c
+++ b/src/lpm.c
@@ -35,7 +35,7 @@
#include <mbedtls/net.h>
#include <zlib.h>
-#include <libtar.h>
+#include <microtar.h>
#include <zip.h>
static char hex_digits[] = "0123456789abcdef";
@@ -438,27 +438,21 @@ static int lpm_certs(lua_State* L) {
}
-// We can have one because we're single-threaded, and extracting is an atomic operation.
-static gzFile gzf;
-static int gzopen_frontend(char *pathname, int oflags, int mode) {
- int fd = open(pathname, oflags, mode);
- if (fd == -1)
- return -1;
- if (!(gzf = gzdopen(fd, "rb"))) {
- errno = ENOMEM;
- gzf = NULL;
- return -1;
- }
- return fd;
+static int mkdirp(char* path, int len) {
+ for (int i = 0; i < len; ++i) {
+ if (path[i] == '/') {
+ path[i] = 0;
+ if (mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) && errno != EEXIST)
+ return -1;
+ path[i] = '/';
+ }
+ }
+ return 0;
}
-static int gzread_frontend(int fd, void* buf, size_t len) { return gzread(gzf, buf, len); }
-static int gzwrite_frontend(int fd, void* buf, size_t len) { return gzwrite(gzf, buf, len); }
-static int gzclose_frontend(int fd) { gzclose(gzf); }
-tartype_t gztype = {
- (openfunc_t) gzopen_frontend, (closefunc_t) gzclose_frontend,
- (readfunc_t) gzread_frontend, (writefunc_t) gzwrite_frontend
-};
+static int gzip_read(mtar_t* tar, void* data, unsigned int size) { return gzread(tar->stream, data, size) >= 0 ? MTAR_ESUCCESS : -1; }
+static int gzip_seek(mtar_t* tar, unsigned int pos) { return gzseek(tar->stream, pos, SEEK_SET) >= 0 ? MTAR_ESUCCESS : -1; }
+static int gzip_close(mtar_t* tar) { return gzclose(tar->stream) == Z_OK ? MTAR_ESUCCESS : -1; }
static int lpm_extract(lua_State* L) {
const char* src = luaL_checkstring(L, 1);
@@ -485,16 +479,10 @@ static int lpm_extract(lua_State* L) {
}
char target[MAX_PATH];
int target_length = snprintf(target, sizeof(target), "%s/%s", dst, zip_name);
- for (int i = 0; i < target_length; ++i) {
- if (target[i] == '/') {
- target[i] = 0;
- if (mkdir(target, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) && errno != EEXIST) {
- zip_fclose(zip_file);
- zip_close(archive);
- return luaL_error(L, "can't extract zip archive file %s, can't create directory %s: %s", src, target, strerror(errno));
- }
- target[i] = '/';
- }
+ if (!mkdirp(target, target_length)) {
+ zip_fclose(zip_file);
+ zip_close(archive);
+ return luaL_error(L, "can't extract zip archive file %s, can't create directory %s: %s", src, target, strerror(errno));
}
if (target[target_length-1] != '/') {
FILE* file = fopen(target, "wb");
@@ -521,15 +509,48 @@ static int lpm_extract(lua_State* L) {
}
zip_close(archive);
} else if (strstr(src, ".tar")) {
- TAR* archive;
- if (tar_open(&archive, src, strstr(src, ".gz") ? &gztype : NULL, O_RDONLY, 0, TAR_GNU))
- return luaL_error(L, "can't open tar archive %s: %s", src, strerror(errno));
- if (tar_extract_all(archive, (char*)dst)) {
- tar_close(archive);
- return luaL_error(L, "can't extract tar archive %s to %s: %s", src, dst, strerror(errno));
- }
- if (tar_close(archive))
- return luaL_error(L, "can't close tar archive %s: %s", src, strerror(errno));
+ mtar_t tar = {0};
+ int err;
+ if (strstr(src, ".gz")) {
+ tar.stream = gzopen(src, "rb");
+ if (!tar.stream)
+ return luaL_error(L, "can't open tar.gz archive %s: %s", src, strerror(errno));
+ tar.read = gzip_read;
+ tar.seek = gzip_seek;
+ tar.close = gzip_close;
+ } else if ((err = mtar_open(&tar, src, "r")))
+ return luaL_error(L, "can't open tar archive %s: %s", src, mtar_strerror(err));
+ mtar_header_t h;
+ while ((mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD ) {
+ if (h.type == MTAR_TREG) {
+ char target[MAX_PATH];
+ int target_length = snprintf(target, sizeof(target), "%s/%s", dst, h.name);
+ if (mkdirp(target, target_length)) {
+ mtar_close(&tar);
+ return luaL_error(L, "can't extract tar archive file %s, can't create directory %s: %s", src, target, strerror(errno));
+ }
+ char buffer[8192];
+ FILE* file = fopen(target, "wb");
+ if (!file) {
+ mtar_close(&tar);
+ return luaL_error(L, "can't extract tar archive file %s, can't create file %s: %s", src, target, strerror(errno));
+ }
+ int remaining = h.size;
+ while (remaining > 0) {
+ int read_size = remaining < sizeof(buffer) ? remaining : sizeof(buffer);
+ if (mtar_read_data(&tar, buffer, read_size) != MTAR_ESUCCESS) {
+ fclose(file);
+ mtar_close(&tar);
+ return luaL_error(L, "can't write file %s: %s", target, strerror(errno));
+ }
+ fwrite(buffer, sizeof(char), read_size, file);
+ remaining -= read_size;
+ }
+ fclose(file);
+ }
+ mtar_next(&tar);
+ }
+ mtar_close(&tar);
} else
return luaL_error(L, "unrecognized archive format %s", src);
return 0;