mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 09:29:52 +03:00
Merge PR #1293: hamcorebuilder: Use libhamcore to build archive
This commit is contained in:
commit
d5fa90cc71
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -7,3 +7,6 @@
|
|||||||
[submodule "3rdparty/BLAKE2"]
|
[submodule "3rdparty/BLAKE2"]
|
||||||
path = 3rdparty/BLAKE2
|
path = 3rdparty/BLAKE2
|
||||||
url = https://github.com/BLAKE2/BLAKE2.git
|
url = https://github.com/BLAKE2/BLAKE2.git
|
||||||
|
[submodule "src/libhamcore"]
|
||||||
|
path = src/libhamcore
|
||||||
|
url = https://github.com/SoftEtherVPN/libhamcore.git
|
||||||
|
@ -25,7 +25,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check that submodules are present only if source was downloaded with git
|
# Check that submodules are present only if source was downloaded with git
|
||||||
if(EXISTS "${TOP_DIRECTORY}/.git" AND NOT EXISTS "${TOP_DIRECTORY}/src/Mayaqua/3rdparty/cpu_features/CMakeLists.txt")
|
if(EXISTS "${TOP_DIRECTORY}/.git" AND NOT EXISTS "${TOP_DIRECTORY}/src/libhamcore/CMakeLists.txt")
|
||||||
message (FATAL_ERROR "Submodules are not initialized. Run\n\tgit submodule update --init --recursive")
|
message (FATAL_ERROR "Submodules are not initialized. Run\n\tgit submodule update --init --recursive")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -123,9 +123,6 @@ add_subdirectory(Cedar)
|
|||||||
# Mayaqua kernel
|
# Mayaqua kernel
|
||||||
add_subdirectory(Mayaqua)
|
add_subdirectory(Mayaqua)
|
||||||
|
|
||||||
# hamcorebuilder utility
|
|
||||||
add_subdirectory(hamcorebuilder)
|
|
||||||
|
|
||||||
# vpnserver
|
# vpnserver
|
||||||
add_subdirectory(vpnserver)
|
add_subdirectory(vpnserver)
|
||||||
|
|
||||||
@ -141,6 +138,12 @@ add_subdirectory(vpncmd)
|
|||||||
# vpntest
|
# vpntest
|
||||||
add_subdirectory(vpntest)
|
add_subdirectory(vpntest)
|
||||||
|
|
||||||
|
# libhamcore
|
||||||
|
add_subdirectory(libhamcore)
|
||||||
|
|
||||||
|
# hamcorebuilder utility
|
||||||
|
add_subdirectory(hamcorebuilder)
|
||||||
|
|
||||||
# hamcore.se2 archive file
|
# hamcore.se2 archive file
|
||||||
add_custom_target(hamcore-archive-build
|
add_custom_target(hamcore-archive-build
|
||||||
ALL
|
ALL
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
include(TestBigEndian)
|
|
||||||
|
|
||||||
add_executable(hamcorebuilder
|
add_executable(hamcorebuilder
|
||||||
main.c
|
main.c
|
||||||
FileSystem.c
|
FileSystem.c
|
||||||
@ -10,12 +8,6 @@ if(WIN32)
|
|||||||
target_compile_definitions(hamcorebuilder PRIVATE "OS_WINDOWS")
|
target_compile_definitions(hamcorebuilder PRIVATE "OS_WINDOWS")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
test_big_endian(BIG_ENDIAN)
|
|
||||||
if(BIG_ENDIAN)
|
|
||||||
target_compile_definitions(hamcorebuilder PRIVATE "BYTE_ORDER_BIG_ENDIAN")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(hamcorebuilder PRIVATE "${TOP_DIRECTORY}/3rdparty/tinydir")
|
target_include_directories(hamcorebuilder PRIVATE "${TOP_DIRECTORY}/3rdparty/tinydir")
|
||||||
|
|
||||||
find_package(ZLIB REQUIRED)
|
target_link_libraries(hamcorebuilder PRIVATE libhamcore)
|
||||||
target_link_libraries(hamcorebuilder PRIVATE ZLIB::ZLIB)
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
ENTRIES *EnumEntries(const char *path)
|
ENTRIES *EnumEntries(const char *path)
|
||||||
{
|
{
|
||||||
@ -121,83 +119,6 @@ void FreeEntries(ENTRIES *entries)
|
|||||||
free(entries);
|
free(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *FileOpen(const char *path, const bool write)
|
|
||||||
{
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fopen(path, write ? "wb" : "rb");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileClose(FILE *file)
|
|
||||||
{
|
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fclose(file) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileRead(FILE *file, void *dst, const size_t size)
|
|
||||||
{
|
|
||||||
if (!file || !dst || size == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fread(dst, 1, size, file) == size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileWrite(FILE *file, const void *src, const size_t size)
|
|
||||||
{
|
|
||||||
if (!file || !src || size == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fwrite(src, 1, size, file) == size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileSize(const char *path)
|
|
||||||
{
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (stat(path, &st) == -1)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return st.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *PathRelativeToBase(char *full, const char *base)
|
|
||||||
{
|
|
||||||
if (!full || !base)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strstr(full, base) != &full[0])
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
full += strlen(base);
|
|
||||||
if (full[0] == '/')
|
|
||||||
{
|
|
||||||
++full;
|
|
||||||
}
|
|
||||||
|
|
||||||
return full;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef OS_WINDOWS
|
#ifndef OS_WINDOWS
|
||||||
bool IsWindowsExtension(const char *extension)
|
bool IsWindowsExtension(const char *extension)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#define FILESYSTEM_H
|
#define FILESYSTEM_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <tinydir.h>
|
#include <tinydir.h>
|
||||||
|
|
||||||
@ -24,14 +23,6 @@ ENTRIES *EnumEntries(const char *path);
|
|||||||
ENTRIES *EnumEntriesRecursively(const char *path, const bool files_only);
|
ENTRIES *EnumEntriesRecursively(const char *path, const bool files_only);
|
||||||
void FreeEntries(ENTRIES *entries);
|
void FreeEntries(ENTRIES *entries);
|
||||||
|
|
||||||
FILE *FileOpen(const char *path, const bool write);
|
|
||||||
bool FileClose(FILE *file);
|
|
||||||
bool FileRead(FILE *file, void *dst, const size_t size);
|
|
||||||
bool FileWrite(FILE *file, const void *src, const size_t size);
|
|
||||||
size_t FileSize(const char *path);
|
|
||||||
|
|
||||||
char *PathRelativeToBase(char *full, const char *base);
|
|
||||||
|
|
||||||
#ifndef OS_WINDOWS
|
#ifndef OS_WINDOWS
|
||||||
bool IsWindowsExtension(const char *extension);
|
bool IsWindowsExtension(const char *extension);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,237 +1,6 @@
|
|||||||
#include "GlobalConst.h"
|
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "Hamcore.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#ifdef BYTE_ORDER_BIG_ENDIAN
|
|
||||||
# define BigEndian32
|
|
||||||
#else
|
|
||||||
# define BigEndian32 Swap32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct CompressedFile
|
|
||||||
{
|
|
||||||
char *Path;
|
|
||||||
uint8_t *Data;
|
|
||||||
size_t Size;
|
|
||||||
size_t OriginalSize;
|
|
||||||
size_t Offset;
|
|
||||||
} CompressedFile;
|
|
||||||
|
|
||||||
size_t CompressionBufferSize(const size_t original_size)
|
|
||||||
{
|
|
||||||
return original_size * 2 + 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Swap32(const uint32_t value)
|
|
||||||
{
|
|
||||||
uint32_t swapped;
|
|
||||||
((uint8_t *)&swapped)[0] = ((uint8_t *)&value)[3];
|
|
||||||
((uint8_t *)&swapped)[1] = ((uint8_t *)&value)[2];
|
|
||||||
((uint8_t *)&swapped)[2] = ((uint8_t *)&value)[1];
|
|
||||||
((uint8_t *)&swapped)[3] = ((uint8_t *)&value)[0];
|
|
||||||
return swapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteAndSeek(uint8_t **dst, const void *src, const size_t size)
|
|
||||||
{
|
|
||||||
if (!dst || !*dst)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(*dst, src, size);
|
|
||||||
*dst += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildHamcore(const char *dst, const char *src)
|
|
||||||
{
|
|
||||||
ENTRIES *entries = EnumEntriesRecursively(src, true);
|
|
||||||
if (!entries)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *buffer = NULL;
|
|
||||||
size_t buffer_size = 0;
|
|
||||||
const size_t num = entries->Num;
|
|
||||||
CompressedFile *files = calloc(num, sizeof(CompressedFile));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num; ++i)
|
|
||||||
{
|
|
||||||
CompressedFile *file = &files[i];
|
|
||||||
char *path = entries->List[i].Path;
|
|
||||||
|
|
||||||
file->OriginalSize = FileSize(path);
|
|
||||||
if (file->OriginalSize == 0)
|
|
||||||
{
|
|
||||||
printf("Skipping \"%s\" because empty...\n", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *handle = FileOpen(path, false);
|
|
||||||
if (!handle)
|
|
||||||
{
|
|
||||||
printf("Failed to open \"%s\", skipping...\n", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *content = malloc(file->OriginalSize);
|
|
||||||
int ret = FileRead(handle, content, file->OriginalSize);
|
|
||||||
FileClose(handle);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
printf("FileRead() failed for \"%s\", skipping...\n", path);
|
|
||||||
free(content);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t wanted_size = CompressionBufferSize(file->OriginalSize);
|
|
||||||
if (buffer_size < wanted_size)
|
|
||||||
{
|
|
||||||
const size_t prev_size = buffer_size;
|
|
||||||
buffer_size = wanted_size;
|
|
||||||
buffer = realloc(buffer, buffer_size);
|
|
||||||
memset(buffer + prev_size, 0, buffer_size - prev_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
file->Size = buffer_size;
|
|
||||||
ret = compress(buffer, (uLongf *)&file->Size, content, (uLong)file->OriginalSize);
|
|
||||||
free(content);
|
|
||||||
|
|
||||||
if (ret != Z_OK)
|
|
||||||
{
|
|
||||||
printf("Failed to compress \"%s\" with error %d, skipping...\n", path, ret);
|
|
||||||
file->Size = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relative_path = PathRelativeToBase(path, src);
|
|
||||||
if (!relative_path)
|
|
||||||
{
|
|
||||||
printf("Failed to get relative path for \"%s\", skipping...\n", path);
|
|
||||||
file->Size = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t path_size = strlen(relative_path) + 1;
|
|
||||||
file->Path = malloc(path_size);
|
|
||||||
memcpy(file->Path, relative_path, path_size);
|
|
||||||
|
|
||||||
file->Data = malloc(file->Size);
|
|
||||||
memcpy(file->Data, buffer, file->Size);
|
|
||||||
|
|
||||||
printf("\"%s\": %zu bytes -> %zu bytes\n", file->Path, file->OriginalSize, file->Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeEntries(entries);
|
|
||||||
|
|
||||||
size_t offset = HAMCORE_HEADER_SIZE;
|
|
||||||
// Number of files
|
|
||||||
offset += sizeof(uint32_t);
|
|
||||||
// File table
|
|
||||||
for (size_t i = 0; i < num; ++i)
|
|
||||||
{
|
|
||||||
CompressedFile *file = &files[i];
|
|
||||||
if (file->Size == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path (length + string)
|
|
||||||
offset += sizeof(uint32_t) + strlen(file->Path);
|
|
||||||
// Original size
|
|
||||||
offset += sizeof(uint32_t);
|
|
||||||
// Size
|
|
||||||
offset += sizeof(uint32_t);
|
|
||||||
// Offset
|
|
||||||
offset += sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num; ++i)
|
|
||||||
{
|
|
||||||
CompressedFile *file = &files[i];
|
|
||||||
if (file->Size == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->Offset = offset;
|
|
||||||
printf("Offset for \"%s\": %zu\n", file->Path, file->Offset);
|
|
||||||
offset += file->Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer_size < offset)
|
|
||||||
{
|
|
||||||
buffer_size = offset;
|
|
||||||
buffer = realloc(buffer, buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *ptr = buffer;
|
|
||||||
WriteAndSeek(&ptr, HAMCORE_HEADER_DATA, HAMCORE_HEADER_SIZE);
|
|
||||||
uint32_t tmp = BigEndian32((uint32_t)num);
|
|
||||||
WriteAndSeek(&ptr, &tmp, sizeof(tmp));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num; ++i)
|
|
||||||
{
|
|
||||||
CompressedFile *file = &files[i];
|
|
||||||
if (file->Size == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t path_length = strlen(file->Path);
|
|
||||||
tmp = BigEndian32((uint32_t)path_length + 1);
|
|
||||||
WriteAndSeek(&ptr, &tmp, sizeof(tmp));
|
|
||||||
WriteAndSeek(&ptr, file->Path, path_length);
|
|
||||||
free(file->Path);
|
|
||||||
|
|
||||||
tmp = BigEndian32((uint32_t)file->OriginalSize);
|
|
||||||
WriteAndSeek(&ptr, &tmp, sizeof(tmp));
|
|
||||||
|
|
||||||
tmp = BigEndian32((uint32_t)file->Size);
|
|
||||||
WriteAndSeek(&ptr, &tmp, sizeof(tmp));
|
|
||||||
|
|
||||||
tmp = BigEndian32((uint32_t)file->Offset);
|
|
||||||
WriteAndSeek(&ptr, &tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num; ++i)
|
|
||||||
{
|
|
||||||
CompressedFile *file = &files[i];
|
|
||||||
WriteAndSeek(&ptr, file->Data, file->Size);
|
|
||||||
free(file->Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(files);
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
FILE *handle = FileOpen(dst, true);
|
|
||||||
if (!handle)
|
|
||||||
{
|
|
||||||
printf("FileOpen() failed!\n");
|
|
||||||
goto FINAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\nWriting to \"%s\"...\n", dst);
|
|
||||||
|
|
||||||
if (!FileWrite(handle, buffer, buffer_size))
|
|
||||||
{
|
|
||||||
printf("FileWrite() failed!\n");
|
|
||||||
goto FINAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = true;
|
|
||||||
FINAL:
|
|
||||||
FileClose(handle);
|
|
||||||
free(buffer);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(const int argc, const char *argv[])
|
int main(const int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
@ -249,11 +18,39 @@ int main(const int argc, const char *argv[])
|
|||||||
printf("Destination: \"%s\"\n", dst);
|
printf("Destination: \"%s\"\n", dst);
|
||||||
printf("Source: \"%s\"\n\n", src);
|
printf("Source: \"%s\"\n\n", src);
|
||||||
|
|
||||||
if (!BuildHamcore(dst, src))
|
ENTRIES *entries = EnumEntriesRecursively(src, true);
|
||||||
|
if (!entries)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nDone!\n");
|
const size_t num = entries->Num;
|
||||||
|
char **paths = malloc(sizeof(char *) * num);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num; ++i)
|
||||||
|
{
|
||||||
|
const ENTRY *entry = &entries->List[i];
|
||||||
|
const size_t path_len = strlen(entry->Path);
|
||||||
|
paths[i] = malloc(path_len + 1);
|
||||||
|
memcpy(paths[i], entry->Path, path_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeEntries(entries);
|
||||||
|
|
||||||
|
const bool ok = HamcoreBuild(dst, src, (const char **)paths, num);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num; ++i)
|
||||||
|
{
|
||||||
|
free(paths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(paths);
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Done!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
1
src/libhamcore
Submodule
1
src/libhamcore
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit b7f5d8d735b280fc77673c4a29f0436a92ca6660
|
Loading…
Reference in New Issue
Block a user