summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt14
-rw-r--r--hscript/CMakeLists.txt8
-rw-r--r--image/backends/CMakeLists.txt4
-rw-r--r--image/backends/tar.cc67
4 files changed, 84 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 76b191c..a12e125 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,10 @@ else()
-Werror)
endif()
+if(POLICY CMP0100)
+ cmake_policy(SET CMP0100 NEW)
+endif()
+
option(BUILD_TOOLS "Enable building of tools (Validator, Simulator, etc)" ON)
option(BUILD_UI "Enable user interface" ON)
@@ -85,6 +89,16 @@ ELSE(INSTALL)
ENDIF(INSTALL)
+if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ SET(FS_LIBRARY stdc++fs)
+ add_definitions(-DFS_IS_STDCXX)
+ELSE()
+ find_package(Boost REQUIRED COMPONENTS filesystem)
+ SET(FS_LIBRARY ${Boost_FILESYSTEM_LIBRARY})
+ add_definitions(-DFS_IS_BOOST)
+ENDIF()
+
+
add_subdirectory(hscript)
add_subdirectory(owner)
IF(BUILD_TOOLS)
diff --git a/hscript/CMakeLists.txt b/hscript/CMakeLists.txt
index 1f8c358..ff35372 100644
--- a/hscript/CMakeLists.txt
+++ b/hscript/CMakeLists.txt
@@ -23,13 +23,7 @@ target_compile_features(hscript PUBLIC cxx_unicode_literals)
if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set_property(TARGET hscript PROPERTY CXX_STANDARD 17)
- SET(FS_LIBRARY stdc++fs)
- add_definitions(-DFS_IS_STDCXX)
-ELSE()
- find_package(Boost REQUIRED COMPONENTS filesystem)
- SET(FS_LIBRARY ${Boost_FILESYSTEM_LIBRARY})
- add_definitions(-DFS_IS_BOOST)
-ENDIF()
+endif()
target_link_libraries(hscript ${BLKID_LIBRARIES} ${FS_LIBRARY} ${LIBUDEV_LIBRARIES} ${PARTED_LIBRARIES})
diff --git a/image/backends/CMakeLists.txt b/image/backends/CMakeLists.txt
index 726d4eb..2c79c8e 100644
--- a/image/backends/CMakeLists.txt
+++ b/image/backends/CMakeLists.txt
@@ -14,3 +14,7 @@ endif()
add_library(hi-backends ${BACKEND_SRCS})
target_link_libraries(hi-backends ${BACKEND_LIBS})
install(TARGETS hi-backends DESTINATION lib)
+
+if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ set_property(TARGET hi-backends PROPERTY CXX_STANDARD 17)
+endif()
diff --git a/image/backends/tar.cc b/image/backends/tar.cc
index d4ed584..7ca9f75 100644
--- a/image/backends/tar.cc
+++ b/image/backends/tar.cc
@@ -11,7 +11,15 @@
*/
#include <archive.h>
+#include <archive_entry.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
#include "basic.hh"
+#include "util/filesystem.hh"
#include "util/output.hh"
namespace Horizon {
@@ -54,7 +62,7 @@ public:
break;
}
- res = archive_write_open_filename(a, this->out_path.c_str()) < ARCHIVE_OK;
+ res = archive_write_open_filename(a, this->out_path.c_str());
if(res < ARCHIVE_OK) {
if(res < ARCHIVE_WARN) {
output_error("tar backend", archive_error_string(a));
@@ -68,7 +76,62 @@ public:
}
int create() override {
- return 0;
+ struct archive_entry *entry = archive_entry_new();
+ error_code ec;
+ int fd, r, code = 0;
+ struct stat s;
+ void *buff;
+
+ for(const auto& dent : fs::recursive_directory_iterator(this->ir_dir,
+ ec)) {
+ fs::path relpath = dent.path().lexically_relative(this->ir_dir);
+#define OUTPUT_FAILURE(x) \
+ output_error("tar backend", "failed to " x " '" + std::string(dent.path()) + "'",\
+ strerror(errno));
+ r = lstat(dent.path().c_str(), &s);
+ if(r == -1) {
+ OUTPUT_FAILURE("stat")
+ code = -1;
+ goto ret;
+ }
+ archive_entry_copy_stat(entry, &s);
+ if(dent.is_symlink()) {
+ archive_entry_set_filetype(entry, AE_IFLNK);
+ fs::path resolved = fs::read_symlink(dent.path(), ec);
+ const fs::path::value_type *c_rpath = resolved.c_str();
+ archive_entry_set_symlink(entry, c_rpath);
+ }
+ archive_entry_set_pathname(entry, relpath.c_str());
+ if(archive_write_header(this->a, entry) != ARCHIVE_OK) {
+ output_error("tar backend", archive_error_string(a));
+ code = -1;
+ goto ret;
+ }
+ if(dent.is_regular_file() && dent.file_size() > 0) {
+ fd = open(dent.path().c_str(), O_RDONLY);
+ if(fd == -1) {
+ OUTPUT_FAILURE("open")
+ code = -1;
+ goto ret;
+ }
+ buff = mmap(NULL, dent.file_size(), PROT_READ, MAP_SHARED,
+ fd, 0);
+ if(buff == MAP_FAILED) {
+ OUTPUT_FAILURE("map")
+ close(fd);
+ code = -1;
+ goto ret;
+ }
+ archive_write_data(this->a, buff, dent.file_size());
+ close(fd);
+ }
+ archive_write_finish_entry(this->a);
+ archive_entry_clear(entry);
+ }
+
+ret:
+ archive_entry_free(entry);
+ return code;
}
int finalise() override {