1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 01:19:52 +03:00

hamcorebuilder: Use libhamcore to build archive

https://github.com/SoftEtherVPN/libhamcore
This commit is contained in:
Davide Beatrici 2021-03-10 02:13:00 +01:00
parent de03b3ec59
commit 68574e9af9
8 changed files with 44 additions and 336 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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)
{ {

View File

@ -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

View File

@ -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

@ -0,0 +1 @@
Subproject commit b7f5d8d735b280fc77673c4a29f0436a92ca6660