From 265e2d3130b174ef0de9aeaed7fe5ee71e9ddaca Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:16:18 +0100 Subject: [PATCH 01/23] minor fixes --- compile_flags.txt | 1 - include/globals.h | 2 +- include/libspm.h | 103 +++----- makefile | 13 +- src/clean.c | 2 +- src/create.c | 105 --------- src/download.c | 28 --- src/environment.c | 90 ------- src/globals.c | 4 +- src/install.c | 538 +++++++++++++----------------------------- src/list.c | 81 ------- src/load.c | 148 ------------ src/locations.c | 26 -- src/make.c | 25 +- src/pkg.c | 92 ++++---- src/quit.c | 23 -- src/remove.c | 50 ---- src/{get.c => repo.c} | 28 +-- src/uninstall.c | 38 --- src/update.c | 112 +-------- src/util.c | 294 +++++++++++++++++++++++ src/version.c | 7 - test/package.c | 6 +- test/spm.c | 3 + test/test.c | 3 + 25 files changed, 566 insertions(+), 1256 deletions(-) delete mode 100644 compile_flags.txt delete mode 100644 src/create.c delete mode 100644 src/download.c delete mode 100644 src/environment.c delete mode 100644 src/load.c delete mode 100755 src/locations.c delete mode 100644 src/quit.c delete mode 100644 src/remove.c rename src/{get.c => repo.c} (89%) create mode 100644 src/util.c delete mode 100644 src/version.c diff --git a/compile_flags.txt b/compile_flags.txt deleted file mode 100644 index 43fa758..0000000 --- a/compile_flags.txt +++ /dev/null @@ -1 +0,0 @@ --I./include diff --git a/include/globals.h b/include/globals.h index f6c2d73..d815e7d 100755 --- a/include/globals.h +++ b/include/globals.h @@ -1,6 +1,6 @@ #include "stdbool.h" -#define QUEUE_MAX 64 +#define QUEUE_MAX 256 #define MAX_PATH 2048 /* diff --git a/include/libspm.h b/include/libspm.h index 4ce64de..7465635 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -33,6 +33,7 @@ struct package char* sha256; char* url; char* environment; + char* repo; char** files; int filesCount; @@ -58,26 +59,42 @@ struct package }; -//test +// List of installed packages int list_installed(); + +// num. of installed packages int count_installed(); + +// Serach for a package by term char** search(char *term, int *num_results); + +// Check what packages need updating int update(); + +// Upgrade all packages that need updating int upgrade(); + +// Create links for the package void create_links(char build_loc[4096], char dest_loc[4096]); + +// Get all repositories currently present int get_repos(char** list); + +// Get all files from a location, ignoring root in the result char** get_all_files(const char* root, const char *path, int *num_files); -int download(char* url, FILE* fp); -int parse_env(char** in); -int add_repo(char* name, char* url); -void clean_install(); -//end test +// Download a file from url into fp with curl +// note: it does not open nor close the FILE +int download(char* url, FILE* fp); -// package info +// Pare the string in for environment variables, the original in will be freed and replaced +int parse_env(char** in); +// Clone a git repository +int add_repo(char* name, char* url); -// shared function to be called by external programs +// Cleanup unneded files after a package is installed +void clean_install(); // This prints the version , its bad // TODO: Rework this @@ -109,21 +126,7 @@ float version(); - 0: Package installed successfully. - -1: Installation failed. */ -int install_package_source(const char* spm_path,int as_dep); -int f_install_package_source(const char* spm_path, int as_dep, char* repo); - -// Function to install a package from a binary archive -/* -Accepts: -- const char* archivePath: Path to the binary archive. -- int as_dep: Flag indicating if the package is a dependency. - -Returns: -- int: An integer indicating the result of the installation. - - 0: Package installed successfully. - - -1: Installation failed. -*/ -int install_package_binary(const char* archivePath, int as_dep, const char* repo); +int install_package_source(struct package* pkg); // Function to uninstall packages /* @@ -160,30 +163,6 @@ int uninstall(char* name); */ int check(const char* name); -// Function to create a binary package from source with input and output formats -/* -Accepts: -- const char* src_path: The path to the source package. -- const char* bin_path: The path where the binary package will be created. -- const char* in_format: The input format (optional). -- const char* out_format: The output format. - -Returns: -- int: An integer indicating the result of the binary package creation. -*/ -int f_create_binary_from_source(const char* src_path,const char* bin_path,const char* in_format,const char* out_format); - -// Function to create a binary package from source -/* -Accepts: -- const char* spm_path: The path to the source package. -- const char* bin_path: The path where the binary package will be created. - -Returns: -- int: An integer indicating the result of the binary package creation. -*/ -int create_binary_from_source(const char* spm_path,const char* bin_path); - // Function to retrieve a package from a data repository /* Accepts: @@ -211,12 +190,13 @@ This function iterates through the given file locations and moves the binaries t Returns: None */ void move_binaries(char** locations,long loc_size); + // build a package from source int make (char* package_dir,struct package* pkg); + // execute post install scripts int exec_special(const char* cmd,const char* package_dir); - // update the system int update(); @@ -231,6 +211,7 @@ int update(); - mkdir(make_dir, 0755): Creating the make directory with the specified permissions. */ int clean(); + // Function to synchronize the local repository with a remote repository int repo_sync(); @@ -298,7 +279,7 @@ This function creates a package file at the specified path using the provided fo - 0: Package created successfully. - -1: File is not a valid package file or the format plugin isn't loaded. */ -int create_pkg(const char* path,struct package* pkg,const char* format); +int create_pkg(struct package* pkg,const char* format); // Load a format plugin, execute a specific function, and close the plugin /* @@ -320,19 +301,6 @@ This function loads a format plugin, executes a specified function within the pl */ int runFormatLib (const char* format,const char* fn,const char* pkg_path,struct package* pkg); -// Function to get the package name from a binary archive path -/* -Accepts: -- const char* bin_path: Path to the binary package archive. -- char* name: A character array to store the package name. - -Returns: -- int: An integer indicating the result of name extraction. - - 0: Name extracted successfully. - - -1: Extraction failed. -*/ -int get_bin_name(const char* bin_path,char* name); - // Function to check if a package is already installed /* Accepts: @@ -382,17 +350,6 @@ char* load_from_repo(const char* in, const char* repo, const char* file_path); */ int loadFile(const char* path, const char* file_path); -// Function to retrieve file locations within a directory -/* -Accepts: -- char*** locations: Pointer to an array of strings to store file locations. -- const char* loc_dir: Path to the directory to search for files. - -Returns: -- long: The number of file locations retrieved. -*/ -long get_locations(char*** locations, const char* loc_dir); - diff --git a/makefile b/makefile index 9a2f40a..51b6fa5 100755 --- a/makefile +++ b/makefile @@ -34,7 +34,7 @@ DBGFLAGS = -g -fsanitize=address # set local lib to lib/*/*.a LOCAL_LIBS = $(wildcard lib/*/*.a) -LIBS = ${LOCAL_LIBS} -lgit2 -lcurl -lm -lcrypto +LIBS = ${LOCAL_LIBS} -lgit2 -lcurl -lsqlite3 -lm -lcrypto # change these to proper directories where each file should be SRCDIR = src @@ -72,16 +72,17 @@ $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c test: - $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) - $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/package.c ${DEVDIR}/test.c $(LIBS) -o bin/package-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) +# $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) +# $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/package.c ${DEVDIR}/test.c $(LIBS) -o bin/package-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) @echo "Test binary created" check-all: - bin/spm-test all - @if [ $$? -gt 0 ]; then echo "Error Tests Failed"; else echo "All good"; fi + echo "..." +# bin/spm-test all +# @if [ $$? -gt 0 ]; then echo "Error Tests Failed"; else echo "All good"; fi check: test check-all - @echo "All Tests Passed" + @echo "ERROR: no tests ran" # This will conflict with other artifacts so you should run make clean before `make debug` and after you're done diff --git a/src/clean.c b/src/clean.c index a2edb39..ff650ab 100755 --- a/src/clean.c +++ b/src/clean.c @@ -38,7 +38,7 @@ void clean_install() char* full_cleanup_path = calloc(strlen(build_dir) + strlen(cleanup_loc[i]) + 2, 1); snprintf(full_cleanup_path, strlen(build_dir) + strlen(cleanup_loc[i]) + 1, "%s%s", build_dir, cleanup_loc[i]); - if(strstr(full_cleanup_path, "/.") != NULL) + if(strstr(full_cleanup_path, "/..") != NULL) { dbg(1, "path %s is sus", full_cleanup_path); } diff --git a/src/create.c b/src/create.c deleted file mode 100644 index 40d1c83..0000000 --- a/src/create.c +++ /dev/null @@ -1,105 +0,0 @@ -#include // Standard I/O library for file operations -#include // Standard library for general functions -#include // Standard library for string manipulation - -#include "libspm.h" // Custom library for package management -#include "cutils.h" // Custom utility library - -// Function prototype for creating an archive from a directory -int create_archive(const char* DIR, const char* out_path); - -// Function to create a binary package from source -/* -Accepts: -- const char* spm_path: The path to the source package. -- const char* bin_path: The path where the binary package will be created. - -Returns: -- int: An integer indicating the result of the binary package creation. -*/ -int create_binary_from_source(const char* spm_path, const char* bin_path) { - return f_create_binary_from_source(spm_path, bin_path, NULL, getenv("SOVIET_DEFAULT_FORMAT")); -} - -// Function to create a binary package from source with input and output formats -/* -Accepts: -- const char* src_path: The path to the source package. -- const char* bin_path: The path where the binary package will be created. -- const char* in_format: The input format (optional). -- const char* out_format: The output format. - -Returns: -- int: An integer indicating the result of the binary package creation. -*/ -int f_create_binary_from_source(const char* src_path, const char* bin_path, const char* in_format, const char* out_format) -{ - struct package pkg; - - // Open the package source - open_pkg(src_path, &pkg, NULL); - - PACKAGE_QUEUE[QUEUE_COUNT] = pkg.name; // Add the package name to the PKG_QUEUE ARRAY - QUEUE_COUNT++; - dbg(1, "Added %s at QUEUE[%d] ", pkg.name, QUEUE_COUNT); - - /* - Here we have some problems: - The legacy package directory was in MAKE_DIR/$NAME-$VERSION - Should we keep it or not? - I choose, for compatibility reasons, to keep it. - If someone wants to change this, you can vote here: - - keep it: 1 - - change it: 0 - */ - const char* MAKE_DIR = getenv("SOVIET_MAKE_DIR"); - const char* BUILD_DIR = getenv("SOVIET_BUILD_DIR"); - - char legacy_dir[MAX_PATH]; - sprintf(legacy_dir, "%s/%s-%s", MAKE_DIR, pkg.name, pkg.version); - dbg(1, "legacy dir: %s", legacy_dir); - - // Make the package - if (make(legacy_dir, &pkg) != 0) { - msg(FATAL, "Make failed"); - } - dbg(1, "Make done - %s", pkg.name); - - // Get package locations - dbg(1, "Getting locations - %s", pkg.name); - pkg.locationsCount = get_locations(&pkg.locations, BUILD_DIR); - - char file_path[MAX_PATH]; - sprintf(file_path, "%s/%s.%s", BUILD_DIR, pkg.name, getenv("SOVIET_DEFAULT_FORMAT")); - - // Create a package file - create_pkg(file_path, &pkg, NULL); - - // Compress binaries to a package archive - dbg(1, "Compressing binaries - %s", pkg.name); - create_archive(BUILD_DIR, bin_path); - - // Clean working directories - clean(); - - return 0; -} - -// Function to create an archive from a directory -/* -Accepts: -- const char* DIR: The directory to be archived. -- const char* out_path: The path where the archive file will be created. - -Returns: -- int: An integer indicating the result of the archive creation. -*/ -int create_archive(const char* DIR, const char* out_path) -{ - char* archive_cmd = calloc(256, sizeof(char)); - sprintf(archive_cmd, "( cd %s && tar -czf %s . )", DIR, out_path); - dbg(1, "archive_cmd: %s", archive_cmd); - int EXIT = system(archive_cmd); - free(archive_cmd); - return EXIT; -} diff --git a/src/download.c b/src/download.c deleted file mode 100644 index abe3e26..0000000 --- a/src/download.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "math.h" -#include -#include -#include - -#include - -// Include necessary headers - -// class stuff -#include "libspm.h" -#include "cutils.h" - -int download(char* url, FILE* fp) { - CURL *curl = curl_easy_init(); - if(curl) { - CURLcode res; - (void) res; - curl_easy_setopt(curl, CURLOPT_USERAGENT, "CCCP/1.0 (https://www.sovietlinux.org/)"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - } - return 0; -} diff --git a/src/environment.c b/src/environment.c deleted file mode 100644 index 104c8d7..0000000 --- a/src/environment.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "stdio.h" -#include -#include - -#include "libspm.h" -#include "globals.h" -#include "cutils.h" - -#include - -// This will parse a string for environment variables -// It makes an assumption that a variable is: $A-Z_0-9 - -int parse_env(char** in) -{ - dbg(2, "Parsing string %s for env variables", *in); - char* env = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_"; - char* start = strchr(*in, '$'); - char* end = NULL; - int i, start_i; - - if (start == NULL) - { - return 0; - } - - dbg(2, "Start: %s", start); - - start_i = strlen(*in) - strlen(start); - - dbg(2, "Start i: %d, from '%d' and '%d'", start_i, strlen(*in), strlen(start)); - - for (i = 1; i < strlen(start); i++) - { - end = strchr(env, start[i]); - - if (end == NULL) - { - if(i == 0) - { - return 0; - } - - if(start[i] != '\0') - { - end = &start[i]; - } - - break; - } - - if(i + 1 == strlen(start)) - { - end = " "; - } - } - - char* var = strdup(*in + start_i + 1); - char* dup_in = calloc(start_i + 1, 1); - if(start_i != 0) - { - snprintf(dup_in, start_i + 1, "%s", *in); - } - var[--i] = '\0'; - - dbg(2, "Var: %s", var); - dbg(2, "In: %s", *in); - - char* full_var = getenv(var); - - if(full_var == NULL) - { - return 0; - } - - dbg(2, "Full var: %s", full_var); - - char* full_in = calloc(strlen(*in) + strlen(full_var) + strlen(end) + 1, 1); - - sprintf(full_in, "%s%s%s", dup_in, full_var, end); - - free(*in); - free(dup_in); - free(var); - *in = full_in; - - dbg(2, "Result: %s", *in); - - return parse_env(in); -} \ No newline at end of file diff --git a/src/globals.c b/src/globals.c index 3ad4af1..a637da5 100644 --- a/src/globals.c +++ b/src/globals.c @@ -5,7 +5,7 @@ #include "globals.h" // Define a constant for the maximum queue size -#define QUEUE_MAX 64 +#define QUEUE_MAX 256 // Declare global variables @@ -29,4 +29,4 @@ char* USER_CHOISE[2]; // Array for package queue and its count char* PACKAGE_QUEUE[QUEUE_MAX]; -int QUEUE_COUNT; +int QUEUE_COUNT = 0; diff --git a/src/install.c b/src/install.c index 9cf90d5..8cb9e91 100755 --- a/src/install.c +++ b/src/install.c @@ -13,265 +13,171 @@ // include header for wait() #include -// Function to install a package from source (archive) -/* -Accepts: -- const char* spm_path: Path to the package archive. -- int as_dep: Flag indicating if the package is a dependency. - -Returns: -- int: An integer indicating the result of the installation. - - 0: Package installed successfully. - - -1: Installation failed. -*/ -int install_package_source(const char* spm_path, int as_dep) { - return f_install_package_source(spm_path, as_dep, NULL); -} - // Function to install a package from source with a specific format /* Accepts: - const char* spm_path: Path to the package archive. -- int as_dep: Flag indicating if the package is a dependency. -- const char* format: Specific package format (optional). Returns: - int: An integer indicating the result of the installation. - 0: Package installed successfully. - -1: Installation failed. */ -int f_install_package_source(const char* spm_path, int as_dep, char* repo) { - // Check if spm_path is NULL - - if (spm_path == NULL) { - msg(ERROR, "spm_path is NULL"); - return -1; - } - +int install_package_source(struct package* pkg) +{ // Get required directory paths - char* make_dir = getenv("SOVIET_MAKE_DIR"); - char* build_dir = getenv("SOVIET_BUILD_DIR"); - - if (make_dir == NULL || build_dir == NULL) { - msg(ERROR, "SOVIET_MAKE_DIR or SOVIET_BUILD_DIR is not set"); - return -1; - } - - // Initialize the package structure - struct package pkg = {0}; - - char* format = "ecmp"; - - // Attempt to open the package archive - if (open_pkg(spm_path, &pkg, format) != 0) { - msg(ERROR, "Failed to open package"); - return -1; - } - - msg(INFO, "Installing %s", pkg.name); - - // Add the package name to the queue - PACKAGE_QUEUE[QUEUE_COUNT] = pkg.name; - QUEUE_COUNT++; - dbg(1, "Added %s to the queue", pkg.name); - - // Set the package info section as environment vadiables for make script - setenv("NAME", pkg.name, 1); - setenv("VERSION", pkg.version, 1); - - if (pkg.url != NULL) - { - parse_env(&(pkg.url)); - dbg(1, "URL: %s", pkg.url); - setenv("URL", pkg.url, 1); - } - - if (pkg.type != NULL) { - setenv("TYPE", pkg.type, 1); - } + char* make_dir = getenv("SOVIET_MAKE_DIR"); + char* build_dir = getenv("SOVIET_BUILD_DIR"); + char* format = getenv("SOVIET_DEFAULT_FORMAT"); + // Temporary for compatibility + setenv("BUILD_ROOT", build_dir, 1); - if (pkg.license != NULL) - { - setenv("LICENSE", pkg.license, 1); - } - - if (pkg.sha256 != NULL) - { - setenv("SHA256", pkg.sha256, 1); + if (make_dir == NULL || build_dir == NULL) + { + msg(ERROR, "SOVIET_MAKE_DIR or SOVIET_BUILD_DIR is not set"); + return -1; + } } - // Set environment variables for building - setenv("BUILD_ROOT", build_dir, 1); + msg(INFO, "Installing %s", pkg->name); - /* Warning: there is something sussy going on beyond this point */ - - // Get global environment variables - if (pkg.environment != NULL) - { - dbg(1, "Getting environment variables..."); - char* env_path = calloc(MAX_PATH, 1); - sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg.environment); - - readConfig(env_path, 1); - } - - // Set global environment variables - if (pkg.exports != NULL && pkg.exportsCount > 0 && strlen(pkg.exports[0]) > 0) + // Set the package info section as environment vadiables for make script { - dbg(1, "Setting environment variables..."); - char* env_path = calloc(MAX_PATH, 1); - sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg.name); - - FILE *env_file; - env_file = fopen(env_path, "w"); + setenv("NAME", pkg->name, 1); + setenv("VERSION", pkg->version, 1); + + if (pkg->url != NULL) + { + parse_env(&(pkg->url)); + dbg(1, "URL: %s", pkg->url); + setenv("URL", pkg->url, 1); + } - for (int i = 0; i < pkg.exportsCount; i++) + if (pkg->type != NULL) { - fprintf(env_file, "%s\n", pkg.exports[i]); - char* line = strdup(pkg.exports[i]); - parse_env(&line); - - if(((line[0] != '#') && ((line[0] != '/') && (line[1] != '/'))) && (strstr(line, "=") != 0)) - { - char* key = strtok(line, "="); - char* value = strchr(line, '\0') + 1; - - if (key == NULL || value == NULL) - { - msg(ERROR, "Invalid config file"); - } - - dbg(2, "Key: %s Value: %s", key, value); + setenv("TYPE", pkg->type, 1); + } - // Set environment variables based on the key-value pairs in the config file - setenv(key, value, 1); - } - free(line); + if (pkg->license != NULL) + { + setenv("LICENSE", pkg->license, 1); } - fclose(env_file); + if (pkg->sha256 != NULL) + { + setenv("SHA256", pkg->sha256, 1); + } } - // Check if a package is a collection - if(strcmp(pkg.type, "con") != 0) + if(strcmp(pkg->type, "con") != 0) { // Legacy directory path for compatibility char legacy_dir[MAX_PATH]; - sprintf(legacy_dir, "%s/%s-%s", getenv("SOVIET_MAKE_DIR"), pkg.name, pkg.version); - // ... - chmod(getenv("SOVIET_MAKE_DIR"), 0777); - chmod(getenv("SOVIET_BUILD_DIR"), 0777); - - pid_t p = fork(); - int status = 0; - if ( p == 0) + // Build the package { + sprintf(legacy_dir, "%s/%s-%s", getenv("SOVIET_MAKE_DIR"), pkg->name, pkg->version); + + // ... + chmod(getenv("SOVIET_MAKE_DIR"), 0777); + chmod(getenv("SOVIET_BUILD_DIR"), 0777); - if (getuid() == 0) + pid_t p = fork(); + int status = 0; + if ( p == 0) { - /* process is running as root, drop privileges */ - if (setgid(65534) != 0) + if (getuid() == 0) { - msg(ERROR, "setgid: Unable to drop group privileges"); + /* process is running as root, drop privileges */ + if (setgid(65534) != 0) + { + msg(ERROR, "setgid: Unable to drop group privileges"); + } + if (setuid(65534) != 0) + { + msg(ERROR, "setuid: Unable to drop user privileges"); + } } - if (setuid(65534) != 0) - { - msg(ERROR, "setuid: Unable to drop user privileges"); + // Build the package + dbg(1, "Making %s", pkg->name); + if (make(legacy_dir, &pkg) != 0) { + msg(ERROR, "Failed to make %s", pkg->name); + exit(1); } + exit(0); + } + while(wait(&status) > 0); + + if(WEXITSTATUS(status) != 0) + { + msg(FATAL, "make exited with error code %d", pkg->name, WEXITSTATUS(status)); } - // Build the package - dbg(1, "Making %s", pkg.name); - if (make(legacy_dir, &pkg) != 0) { - msg(ERROR, "Failed to make %s", pkg.name); - exit(1); - } - exit(0); - } - while(wait(&status) > 0); - if(WEXITSTATUS(status) != 0) - { - msg(FATAL, "make exited with error code %d", pkg.name, status); + dbg(1, "Making %s done", pkg->name); } - dbg(1, "Making %s done", pkg.name); - // Run 'install' command - if (pkg.info.install == NULL && strlen(pkg.info.install) == 0) { - msg(FATAL, "No install command!"); - } + { + if (pkg->info.install == NULL && strlen(pkg->info.install) == 0) { + msg(FATAL, "No install command!"); + } - char install_cmd[64 + strlen(legacy_dir) + strlen(pkg.info.install)]; - sprintf(install_cmd, "( cd %s && %s )", legacy_dir, pkg.info.install); + char install_cmd[64 + strlen(legacy_dir) + strlen(pkg->info.install)]; + sprintf(install_cmd, "( cd %s && %s )", legacy_dir, pkg->info.install); - dbg(2, "Executing install command: %s", install_cmd); - if (system(install_cmd) != 0) { - msg(FATAL, "Failed to install %s", pkg.name); - return -2; + dbg(2, "Executing install command: %s", install_cmd); + if (system(install_cmd) != 0) { + msg(FATAL, "Failed to install %s", pkg->name); + return -2; + } + clean_install(); + dbg(1, "Install command executed!"); } - clean_install(); - dbg(1, "Install command executed!"); - // Get package locations - dbg(1, "Getting locations for %s", pkg.name); - pkg.locationsCount = get_locations(&pkg.locations, getenv("SOVIET_BUILD_DIR")); - - if (pkg.locationsCount <= 0) { - msg(ERROR, "Failed to get locations for %s", pkg.name); - return -1; - } + { + dbg(1, "Getting locations for %s", pkg->name); + pkg->locations = get_all_files(getenv("SOVIET_BUILD_DIR") + 1, getenv("SOVIET_BUILD_DIR"), &(pkg->locationsCount)); + + if (pkg->locationsCount <= 0) { + msg(ERROR, "Failed to get locations for %s", pkg->name); + return -1; + } - dbg(1, "Got %d locations for %s", pkg.locationsCount, pkg.name); + dbg(1, "Got %d locations for %s", pkg->locationsCount, pkg->name); - // Check if the package is already installed - if (is_installed(pkg.name)) { - msg(WARNING, "Package %s is already installed, reinstalling", pkg.name); - uninstall(pkg.name); - } else { - dbg(3, "Package %s is not installed", pkg.name); - } + // Check if the package is already installed + if (is_installed(pkg->name)) { + msg(WARNING, "Package %s is already installed, reinstalling", pkg->name); + uninstall(pkg->name); + } else { + dbg(3, "Package %s is not installed", pkg->name); + } - // Move binaries to their destination - dbg(1, "Moving binaries for %s", pkg.name); - move_binaries(pkg.locations, pkg.locationsCount); + // Move binaries to their destination + dbg(1, "Moving binaries for %s", pkg->name); + move_binaries(pkg->locations, pkg->locationsCount); + } } // Execute post-install scripts - if (pkg.info.special != NULL && strlen(pkg.info.special) > 0) { - msg(WARNING, "Special: %s", pkg.info.special); - dbg(1, "Executing post install script for %s", pkg.name); - exec_special(pkg.info.special, getenv("SOVIET_BUILD_DIR")); - } - - // Format the path using sprintf - char file_path[MAX_PATH]; - - if(!repo) { - repo = "local"; - } - - dbg(1, "spm dir is %s", getenv("SOVIET_SPM_DIR")); - dbg(1, "repo is %s", repo); - dbg(1, "name is %s", pkg.name); - dbg(1, "description is %s", pkg.info.description); - - - char repo_path[MAX_PATH]; - sprintf(repo_path, "%s/%s", getenv("SOVIET_SPM_DIR"), repo); - - if(isdir(repo_path) != 0) - { - pmkdir(repo_path); + if (pkg->info.special != NULL && strlen(pkg->info.special) > 0) + { + msg(WARNING, "Special: %s", pkg->info.special); + dbg(1, "Executing post install script for %s", pkg->name); + if (system(pkg->info.special) != 0) + { + msg(FATAL, "Failed to run post-install script for %s", pkg->name); + return -2; + } + } } - sprintf(file_path, "%s/%s/%s.%s", getenv("SOVIET_SPM_DIR"), repo, pkg.name, getenv("SOVIET_DEFAULT_FORMAT")); - create_pkg(file_path, &pkg, NULL); - dbg(1, "Package %s installed", pkg.name); + create_pkg(&pkg, NULL); + dbg(1, "Package %s installed", pkg->name); // Clean up clean(); @@ -280,103 +186,57 @@ int f_install_package_source(const char* spm_path, int as_dep, char* repo) { QUEUE_COUNT--; PACKAGE_QUEUE[QUEUE_COUNT] = NULL; - // Free allocated memory - free_pkg(&pkg); return 0; } -// Utilities declaration for binary install -// Untar a binary package to another directory -/* -Accepts: -- const char* bin_path: Path to the binary package archive. -- const char* dest_dir: Destination directory for untarring. - -Returns: -- int: An integer indicating the result of the untarring. - - 0: Untarring completed successfully. - - Non-zero: An error occurred during untarring. -*/ -__attribute__((unused)) int uncompress_binary(const char* bin_path, const char* dest_dir); - -// Function to install a package from a binary archive -/* -Accepts: -- const char* archivePath: Path to the binary archive. -- int as_dep: Flag indicating if the package is a dependency. - -Returns: -- int: An integer indicating the result of the installation. - - 0: Package installed successfully. - - -1: Installation failed. -*/ -int install_package_binary(const char* archivePath, int as_dep, const char* repo) { - - struct package pkg; - - // Get required environment variables - char* default_format = getenv("SOVIET_DEFAULT_FORMAT"); - char* build_dir = getenv("SOVIET_BUILD_DIR"); - char* spm_dir = getenv("SOVIET_SPM_DIR"); - - if (default_format == NULL || build_dir == NULL || spm_dir == NULL) { - msg(ERROR, "Environment variables not set"); - return -1; - } - - // Initialize package name - pkg.name = calloc(sizeof(archivePath), sizeof(char)); - - // Get the package name from the binary archive - if (get_bin_name(archivePath, pkg.name) != 0) { - msg(ERROR, "Could not get name from archive path"); - return -1; - } - - // Uncompress binary and check the output - if (uncompress_binary(archivePath, build_dir) != 0) - return -1; +/* Warning: there is something sussy going on beyond this point */ +int configure_package(struct package* pkg) +{ + // Get global environment variables + if (pkg->environment != NULL) + { + dbg(1, "Getting environment variables..."); + char* env_path = calloc(MAX_PATH, 1); + sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->environment); - // Format the path using sprintf - char spm_path[MAX_PATH]; - sprintf(spm_path, "%s/%s.%s", build_dir, pkg.name, default_format); - if (access(spm_path, F_OK) != 0) { - msg(ERROR, "%s not found", spm_path); - return -1; + readConfig(env_path, 1); } - // Open the package - open_pkg(spm_path, &pkg, NULL); - - // Add the package name to the queue - PACKAGE_QUEUE[QUEUE_COUNT] = pkg.name; - QUEUE_COUNT++; - dbg(1, "Added %s to QUEUE[%d]", pkg.name, QUEUE_COUNT - 1); - - // Move binaries to their destination - dbg(1, "Moving binaries for %s", pkg.name); - move_binaries(pkg.locations, pkg.locationsCount); - - // Execute post-install scripts - exec_special(pkg.info.special, build_dir); + // Set global environment variables + if (pkg->exports != NULL && pkg->exportsCount > 0 && strlen(pkg->exports[0]) > 0) + { + dbg(1, "Setting environment variables..."); + char* env_path = calloc(MAX_PATH, 1); + sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->name); - // Format the path using sprintf - char file_path[MAX_PATH]; - sprintf(file_path, "%s/%s/%s.%s", getenv("SOVIET_SPM_DIR"), repo, pkg.name, getenv("SOVIET_DEFAULT_FORMAT")); - create_pkg(file_path, &pkg, NULL); + FILE *env_file; + env_file = fopen(env_path, "w"); - dbg(1, "Package %s installed", pkg.name); + for (int i = 0; i < pkg->exportsCount; i++) + { + fprintf(env_file, "%s\n", pkg->exports[i]); + char* line = strdup(pkg->exports[i]); + parse_env(&line); - free_pkg(&pkg); + if(((line[0] != '#') && ((line[0] != '/') && (line[1] != '/'))) && (strstr(line, "=") != 0)) + { + char* key = strtok(line, "="); + char* value = strchr(line, '\0') + 1; - // Clean up - clean(); + if (key == NULL || value == NULL) + { + msg(ERROR, "Invalid config file"); + } - // Remove the package from the queue - QUEUE_COUNT--; - PACKAGE_QUEUE[QUEUE_COUNT] = NULL; + dbg(2, "Key: %s Value: %s", key, value); - return 0; + // Set environment variables based on the key-value pairs in the config file + setenv(key, value, 1); + } + free(line); + } + fclose(env_file); + } } // Function to check if a package is already installed @@ -389,7 +249,8 @@ int install_package_binary(const char* archivePath, int as_dep, const char* repo - true: Package is installed. - false: Package is not installed. */ -bool is_installed(const char* name) { +bool is_installed(const char* name) +{ char path[1024]; char** FORMATS; int FORMAT_COUNT = splita(strdup(getenv("SOVIET_FORMATS")),' ',&FORMATS); @@ -415,90 +276,15 @@ bool is_installed(const char* name) { return false; } -// Function to get the package name from a binary archive path -/* -Accepts: -- const char* bin_path: Path to the binary package archive. -- char* name: A character array to store the package name. - -Returns: -- int: An integer indicating the result of name extraction. - - 0: Name extracted successfully. - - -1: Extraction failed. -*/ -int get_bin_name(const char* bin_path, char* name) { - const char* file_name = strrchr(bin_path, '/'); - if (file_name == NULL) - file_name = bin_path; - else - file_name++; - for (int i = 0; i < (int)strlen(file_name); i++) { - if (file_name[i] == '.') { - sprintf(name, "%.*s", i, file_name); - return 0; - } - } - return -1; -} - -// Function to free memory allocated for a package structure -/* -Accepts: -- struct package* pkg: Pointer to a package structure. - -Returns: -- int: An integer indicating the result of memory deallocation. - - 0: Memory freed successfully. -*/ -int free_pkg(struct package* pkg) { - if (pkg->name != NULL) free(pkg->name); - if (pkg->version != NULL) free(pkg->version); - if (pkg->license != NULL) free(pkg->license); - if (pkg->type != NULL) free(pkg->type); - if (pkg->url != NULL) free(pkg->url); - - if (pkg->info.make != NULL) free(pkg->info.make); - if (pkg->info.special != NULL) free(pkg->info.special); - if (pkg->info.download != NULL) free(pkg->info.download); - if (pkg->info.install != NULL) free(pkg->info.install); - if (pkg->info.prepare != NULL) free(pkg->info.prepare); - if (pkg->info.test != NULL) free(pkg->info.test); - - if (pkg->locations) { - if (*pkg->locations) free(*pkg->locations); - free(pkg->locations); - } - if (pkg->dependencies) { - if (*pkg->dependencies) free(*pkg->dependencies); - free(pkg->dependencies); - } - if (pkg->optional) { - if (*pkg->optional) free(*pkg->optional); - free(pkg->optional); - } - if (pkg->files) { - if (*pkg->files) free(*pkg->files); - free(pkg->files); +int add_to_queue(const char* name) +{ + // Add the package name to the queue + PACKAGE_QUEUE[QUEUE_COUNT] = name; + QUEUE_COUNT++; + if (QUEUE_COUNT > QUEUE_MAX) + { + msg(FATAL, "Package tree too large"); } - return 0; -} - -// Function to untar a binary package to a destination directory -/* -Accepts: -- const char* bin_path: Path to the binary package archive. -- const char* dest_dir: Destination directory for untarring. - -Returns: -- int: An integer indicating the result of untarring. - - 0: Untarring completed successfully. - - Non-zero: An error occurred during untarring. -*/ -int uncompress_binary(const char* bin_path, const char* dest_dir) { - // Format the untar command using sprintf - char untar_cmd[strlen(bin_path) + strlen(dest_dir) + 64]; - sprintf(untar_cmd, "tar -xvf %s -C %s", bin_path, dest_dir); - // Execute the untar command - return system(untar_cmd); -} + dbg(1, "Added %s to the queue", name); +} \ No newline at end of file diff --git a/src/list.c b/src/list.c index 00df5b6..0ec889f 100644 --- a/src/list.c +++ b/src/list.c @@ -10,87 +10,6 @@ #include "libspm.h" #include "cutils.h" -#define MAX_PATH_LENGTH 1024 -#define OPEN_ERROR -1 -#define READ_ERROR -2 - -// Function to recursively retrieve all files in a directory and its subdirectories -char **get_all_files(const char* root, const char *path, int *num_files) { - DIR *dir; - struct dirent *entry; - struct stat stat_buf; - char* origin = strdup(path); - // Open the directory - dir = opendir(path); - if (dir == NULL) { - // Print an error message if directory couldn't be opened - fprintf(stderr, "Error opening directory %s: %s\n", path, strerror(errno)); - free(origin); - return NULL; - } - - // Initialize variables - char **files_array = NULL; - int file_count = 0; - - // Loop through directory entries - while ((entry = readdir(dir)) != NULL) { - // Skip '.' and '..' entries - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - // Construct full path of the current entry - char full_path[MAX_PATH_LENGTH]; - snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name); - - // Get information about the current entry - if (stat(full_path, &stat_buf) == 0) { - // If it's a directory, recursively call get_all_files - if (S_ISDIR(stat_buf.st_mode)) { - struct stat dir_stat_buf; - if (lstat(full_path, &dir_stat_buf) == 0) { - // Check if a directory is a symlink (this can probably be optimized out) - if (!S_ISLNK(dir_stat_buf.st_mode)) { - // If it isn't - treat it as a directory - int sub_files_count; - char **sub_files = get_all_files(root, full_path, &sub_files_count); - if (sub_files != NULL) { - // Resize files_array and copy contents of sub_files into it - files_array = realloc(files_array, (file_count + sub_files_count) * sizeof(char *)); - for (int i = 0; i < sub_files_count; i++) { - files_array[file_count++] = sub_files[i]; - } - free(sub_files); - } - } - else { - // If it is - treat it as a file - files_array = realloc(files_array, (file_count + 1) * sizeof(char *)); - files_array[file_count] = strdup(full_path + strlen(root) + 1); - file_count++; - } - } - } else if (S_ISREG(stat_buf.st_mode)) { - // If it's a regular file, add it to files_array - files_array = realloc(files_array, (file_count + 1) * sizeof(char *)); - files_array[file_count] = strdup(full_path + strlen(root) + 1); - file_count++; - } - } - } - // Close the directory - closedir(dir); - - // Update num_files if it's not NULL - if (num_files != NULL) - *num_files = file_count; - - // Return the array of file paths - free(origin); - - return files_array; -} - // Function to count the number of installed packages int count_installed() { const char *path = getenv("SOVIET_SPM_DIR"); diff --git a/src/load.c b/src/load.c deleted file mode 100644 index b0fe0c4..0000000 --- a/src/load.c +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include - -#include - -// Include necessary headers - -// class stuff -#include "libspm.h" -#include "cutils.h" - -// Additional custom header includes - -// Function to get a file from a local repository -/* -Accepts: -- const char* file_path: The local file path to save the downloaded resource. - -Returns: -- int: An integer indicating the result of the download operation. - - 0: get success. - - 1: get failure. -*/ -char* load_from_repo(const char* in, const char* in_repo, const char* file_path) -{ - // Try to find package in repos - dbg(3, "loading %s from %s", in, in_repo); - - char* path = calloc(MAX_PATH, 1); - sprintf(path, "%s/%s", getenv("SOVIET_REPOS_DIR"), in_repo); - - int count; - char **found = get_all_files(path, path, &count); - char* pkg = calloc(MAX_PATH + strlen(getenv("SOVIET_DEFAULT_FORMAT")) + 1, sizeof(char)); - if(!strstr(in, ".ecmp")) - { - sprintf(pkg, "%s.%s", in, getenv("SOVIET_DEFAULT_FORMAT")); - } - else - { - pkg = strdup(in); - } - - if (found != NULL) - { - // Print each file path - for (int i = 0; i < count; i++) - { - - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - dbg(3, "checking %s", found[i]); - char* temp = strdup(found[i]); - char* temp_path = strdup(found[i]); - - char* tok = strtok(temp, "/"); - char* repo = strdup(tok); - char* package = NULL; - while(tok != NULL ) - { - tok = strtok(NULL, "/"); - if(tok != NULL) - { - if(strstr(tok, ".ecmp")) - { - package = strdup(tok); - } - } - } - if(package == NULL) - { - dbg(3, "%s not .ecmp package, moving on", found[i]); - // Move the file to the end - char* tar = found[i]; - for (int k = i; k < count - 1; k++) - { - found[k] = found[k + 1]; - } - found[count - 1] = tar; - count--; - i--; - } - else - { - dbg(3, "Comparing %s and %s", package, pkg); - - if (strcmp(package, pkg) == 0) - { - // Compare the filename - dbg(3, "Loading package %s from %s", temp_path, in_repo); - - // Create the full PATH by combining the repository URL and the provided path - char* path = calloc(strlen(repo) + strlen(getenv("SOVIET_REPOS_DIR")) + MAX_PATH, sizeof(char)); - sprintf(path, "%s/%s/%s", getenv("SOVIET_REPOS_DIR"), in_repo, temp_path); - dbg(3, "Loading package from path: %s", path); - // Log a message about the download process - - // Attempt to load the file - if (loadFile(path, file_path) == 0) - { - // Clean up and return success - free(path); - free(found); - return repo; - } - // Clean up URL memory - free(path); - free(found); - } - - // Free each file path string - free(package); - free(repo); - free(temp); - } - } - } - return NULL; -} - -// Function to load a file from a given repo and save it to a specified path -/* -Accepts: -- const char* path: The path of the file to download. -- const char* file_path: The local file path to save the downloaded file. - -Returns: -- int: An integer indicating the result of the download operation. - - 0: Download success. - - -1: Download failure. -*/ -int loadFile(const char* path, const char* file_path) -{ - char cmd[PATH_MAX*2 + 64]; - sprintf(cmd, "cp %s %s", path, file_path); - - // Check if the download was successful - // lmao - if (system(cmd) == -1) - { - return -1; - } - // Return success - - return 0; -} diff --git a/src/locations.c b/src/locations.c deleted file mode 100755 index 4e5bcd4..0000000 --- a/src/locations.c +++ /dev/null @@ -1,26 +0,0 @@ -#include - -// Include necessary headers -#include "globals.h" -#include "libspm.h" -#include "cutils.h" - -// Function to retrieve file locations within a directory -/* -Accepts: -- char*** locations: Pointer to an array of strings to store file locations. -- const char* loc_dir: Path to the directory to search for files. - -Returns: -- long: The number of file locations retrieved. -*/ -long get_locations(char*** locations, const char* loc_dir) { - - int num_files; - *locations = get_all_files(loc_dir+1, loc_dir, &num_files); - // Log the count of retrieved locations for debugging - dbg(2, "Got %d locations", num_files); - - // Return the count of file locations - return num_files; -} diff --git a/src/make.c b/src/make.c index 13fb3d5..bb82240 100755 --- a/src/make.c +++ b/src/make.c @@ -24,8 +24,6 @@ - -3: No install command found. */ int make(char* package_dir, struct package* pkg) { - char* build_dir = getenv("SOVIET_BUILD_DIR"); - (void)build_dir; char* make_dir = getenv("SOVIET_MAKE_DIR"); char* cmd_params; @@ -200,25 +198,4 @@ int make(char* package_dir, struct package* pkg) { } return 0; -} - -// Function to execute a special command for post-installation -/* -Accepts: -- const char* cmd: The special command to execute. -- const char* package_dir: Path to the package directory. - -Returns: -- int: An integer indicating the result of the special command execution. - - 0: Special command executed successfully. - - 1: An error occurred during special command execution. -*/ -int exec_special(const char* cmd, const char* package_dir) { - dbg(2, "Executing special command: %s", cmd); - - if (system(cmd) != 0) { - return 1; - } - dbg(1, "Special command executed!"); - return 0; -} +} \ No newline at end of file diff --git a/src/pkg.c b/src/pkg.c index 137359c..de4c10f 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -3,6 +3,7 @@ #include "string.h" #include #include +#include #include "cutils.h" #include "libspm.h" @@ -23,7 +24,8 @@ This function opens a package from the specified path, reads the package file's - 1: File does not exist or is not a valid package file. - 1: File is not a valid package file or the format plugin isn't loaded. */ -int open_pkg(const char* path, struct package* pkg, const char* format) { +int open_pkg(const char* path, struct package* pkg, const char* format) +{ dbg(2, "Setting everything to NULL"); // Set all variables to NULL memset(pkg, 0, sizeof(struct package)); @@ -81,7 +83,19 @@ This function creates a package file at the specified path using the provided fo - 0: Package created successfully. - -1: File is not a valid package file or the format plugin isn't loaded. */ -int create_pkg(const char* path, struct package* pkg, const char* format) { +int create_pkg(struct package* pkg, const char* format) +{ + char repo_path[MAX_PATH]; + sprintf(repo_path, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->repo); + + if(isdir(repo_path) != 0) + { + pmkdir(repo_path); + } + + char path[MAX_PATH]; + sprintf(path, "%s/%s/%s.%s", getenv("SOVIET_SPM_DIR"), pkg->repo, pkg->name, getenv("SOVIET_DEFAULT_FORMAT")); + msg(INFO, "Creating package %s", path); char** FORMATS; @@ -100,10 +114,9 @@ int create_pkg(const char* path, struct package* pkg, const char* format) { { if (strcmp(format,FORMATS[i]) == 0) { - dbg(2,"Opening package with %s format",FORMATS[i]); - runFormatLib(FORMATS[i],"create",path,pkg); + dbg(2, "Opening package with %s format", FORMATS[i]); + runFormatLib(FORMATS[i], "create", path, pkg); //free(*FORMATS); - //free(FORMATS); return 0; } } @@ -114,50 +127,47 @@ int create_pkg(const char* path, struct package* pkg, const char* format) { return -1; } -// Load a format plugin, execute a specific function, and close the plugin +// Function to free memory allocated for a package structure /* Accepts: -- const char* format: The format of the package. -- const char* fn: The name of the function to execute in the format plugin. -- const char* pkg_path: The path to the package file. -- struct package* pkg: A pointer to the package structure. - -Description: -This function loads a format plugin, executes a specified function within the plugin, and then closes the plugin. +- struct package* pkg: Pointer to a package structure. Returns: -- int: An integer indicating the result of running the format plugin. - - 0: Format plugin executed successfully. - - 1: Format plugin file does not exist. - - 1: Error loading or executing the format plugin. - - -1: Format plugin function returned an error. +- int: An integer indicating the result of memory deallocation. + - 0: Memory freed successfully. */ -int runFormatLib(const char* format, const char* fn, const char* pkg_path, struct package* pkg) { - char lib_path[MAX_PATH]; - sprintf(lib_path, "%s/%s.so", getenv("SOVIET_PLUGIN_DIR"), format); - dbg(2, "Loading %s", lib_path); - - if (access(lib_path, F_OK) != 0) { - msg(ERROR, "File %s does not exist", lib_path); - return 1; +int free_pkg(struct package* pkg) +{ + if (pkg->name != NULL) free(pkg->name); + if (pkg->version != NULL) free(pkg->version); + if (pkg->license != NULL) free(pkg->license); + if (pkg->type != NULL) free(pkg->type); + if (pkg->url != NULL) free(pkg->url); + + if (pkg->info.make != NULL) free(pkg->info.make); + if (pkg->info.special != NULL) free(pkg->info.special); + if (pkg->info.download != NULL) free(pkg->info.download); + if (pkg->info.install != NULL) free(pkg->info.install); + if (pkg->info.prepare != NULL) free(pkg->info.prepare); + if (pkg->info.test != NULL) free(pkg->info.test); + + if (pkg->locations) { + if (*pkg->locations) free(*pkg->locations); + free(pkg->locations); } - - // Load a function from the shared library - void* handle = dlopen(lib_path, RTLD_LAZY); - if (!handle) { - fprintf(stderr, "%s\n", dlerror()); - return 1; + if (pkg->dependencies) { + if (*pkg->dependencies) free(*pkg->dependencies); + free(pkg->dependencies); } - int (*func)(const char*, struct package*) = dlsym(handle, fn); - char* error = dlerror(); - if (error != NULL) { - fprintf(stderr, "%s\n", error); - return 1; + if (pkg->optional) { + if (*pkg->optional) free(*pkg->optional); + free(pkg->optional); } - if (func(pkg_path, pkg) != 0) { - return -1; + if (pkg->files) { + if (*pkg->files) free(*pkg->files); + free(pkg->files); } - - dlclose(handle); return 0; } + +int create_package_db(){} \ No newline at end of file diff --git a/src/quit.c b/src/quit.c deleted file mode 100644 index 51331d5..0000000 --- a/src/quit.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -#include "cutils.h" - -// Quit the program with the given status code and display an error message if status is not 0 -/* -Accepts: -- int status: The exit status code. - -Description: -This function exits the program with the specified status code. If the status code is not 0 (indicating an error), it also displays an error message. - -Returns: -- void: This function does not return a value. -*/ -void quit(int status) { - if (status != 0) { - msg(ERROR, "Exiting with status %d", status); - exit(status); - } -} diff --git a/src/remove.c b/src/remove.c deleted file mode 100644 index f62e03a..0000000 --- a/src/remove.c +++ /dev/null @@ -1,50 +0,0 @@ -#define _XOPEN_SOURCE 500 -#include -#include -#include - -#include "libspm.h" - -// Callback function used by nftw to unlink files and directories -/* -Accepts: -- const char *fpath: The path of the file or directory being processed. -- const struct stat *sb: A pointer to a structure containing information about the file. -- int typeflag: A flag indicating the type of the file (file, directory, etc.). -- struct FTW *ftwbuf: A pointer to a structure containing state information for the traversal. - -Returns: -- int: An integer indicating the result of the operation. - - 0: The operation was successful. - - Non-zero: An error occurred during the operation. - -Description: -This function is used as a callback by the nftw function to unlink (remove) files and directories. It attempts to remove the file or directory specified by 'fpath' and returns 0 if the removal is successful. If an error occurs during the removal, it returns a non-zero value and prints an error message indicating the file or directory that caused the error. -*/ -int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -{ - int rv = remove(fpath); - - if (rv) - perror(fpath); - - return rv; -} - -// Recursively remove a directory and its contents -/* -Accepts: -- char *path: The path of the directory to be removed. - -Returns: -- int: An integer indicating the result of the operation. - - 0: The directory and its contents were successfully removed. - - Non-zero: An error occurred during the removal. - -Description: -This function recursively removes a directory and its contents. It utilizes the nftw function to traverse the directory and its subdirectories, invoking the 'unlink_cb' callback function to unlink and remove files and directories. It returns 0 if the removal is successful and a non-zero value if an error occurs during the operation. -*/ -int rmrf(char *path) -{ - return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); -} diff --git a/src/get.c b/src/repo.c similarity index 89% rename from src/get.c rename to src/repo.c index bf8ebe6..2845eec 100755 --- a/src/get.c +++ b/src/repo.c @@ -1,7 +1,7 @@ -#include #include #include #include +#include #include #include #include @@ -11,27 +11,7 @@ #include "globals.h" #include "cutils.h" -// Function to retrieve a package from a data repository -/* -Accepts: -- struct package* i_pkg: A pointer to a package structure with package details. -- const char* out_path: The local path to save the downloaded package. - -Returns: -- char*: A pointer to the package format or NULL if there's an error. -*/ -char* get(struct package* i_pkg, const char* repo, const char* out_path) -{ - // Check if the package name is specified - if (i_pkg->name == NULL) - { - msg(ERROR, "Package name not specified!"); - return NULL; - } - - return load_from_repo(i_pkg->name, repo, out_path); -} - +// Get currently present repos int get_repos(char** list) { dbg(3, "checking for repos"); @@ -83,7 +63,8 @@ int get_repos(char** list) } // Function to synchronize the local repository with a remote repository -int repo_sync() { +int repo_sync() +{ char* repo_dir = getenv("SOVIET_REPOS_DIR"); char* repo_url = getenv("SOVIET_DEFAULT_REPO_URL"); char* submodule_name = getenv("SOVIET_DEFAULT_REPO"); @@ -143,6 +124,7 @@ int repo_sync() { return 0; } +// Add a new repository from a git repo int add_repo(char* name, char* url) { const char* repo_dir = getenv("SOVIET_REPOS_DIR"); diff --git a/src/uninstall.c b/src/uninstall.c index a2b7dff..95e4bae 100755 --- a/src/uninstall.c +++ b/src/uninstall.c @@ -9,9 +9,6 @@ #include "libspm.h" #include "cutils.h" -// remove a file or link or directory -int rmany(char* path); - // Function to uninstall packages /* Accepts: @@ -79,38 +76,3 @@ int uninstall(char* name) } -int rmany(char* path) { - // check if its a symlink - struct stat s; - - if (lstat(path, &s) == 0) { - if (S_ISLNK(s.st_mode)) { - // remove the symlink - if (unlink(path) == 0) { - return 0; - } else { - return -1; - } - } - // check if its a directory - if (S_ISDIR(s.st_mode)) { - // remove the directory - if (rmdir(path) == 0) { - return 0; - } else { - msg(ERROR, "Error removing directory %s (Probably not empty)", path); - return -1; - } - } - // check if its a file - if (S_ISREG(s.st_mode)) { - // remove the file - if (remove(path) == 0) { - return 0; - } else { - return -1; - } - } - } - return -1; -} \ No newline at end of file diff --git a/src/update.c b/src/update.c index 1b7ea24..711acc2 100644 --- a/src/update.c +++ b/src/update.c @@ -124,114 +124,4 @@ int update() } return 0; -} - -int upgrade() -{ - msg(INFO, "upgrading"); - int new_version_installed = 0; - - const char *path = getenv("SOVIET_SPM_DIR"); - const char *repo_path = getenv("SOVIET_REPOS_DIR"); - int num_files; - char **files_array = get_all_files(path, path, &num_files); - - if (files_array != NULL) - { - // Print each file path - for (int i = 0; i < num_files; i++) - { - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* local_repo = strtok(files_array[i], "/"); - char* local_package_name = strchr(files_array[i], '\0') + 1; - - // Allocate the packages to be compared - struct package* local = calloc(1, sizeof(struct package)); - struct package* remote = calloc(1, sizeof(struct package)); - - char* local_path = calloc(MAX_PATH, sizeof(char)); - char* remote_path = calloc(MAX_PATH, sizeof(char)); - - sprintf(local_path, "%s/%s/%s", path, local_repo, local_package_name); - - int num_searched_files; - char **searched_files_array = get_all_files(repo_path, repo_path, &num_searched_files); - - if (searched_files_array != NULL) - { - // Print each file path - for (int j = 0; j < num_searched_files; j++) - { - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* remote_repo = strtok(searched_files_array[j], "/"); - char* remote_package = strchr(searched_files_array[j], '\0') + 1; - char* remote_package_name = calloc(strlen(remote_package) + 2, sizeof(char)); - strcpy(remote_package_name, remote_package); - - while(strtok(remote_package_name, "/")) - { - char* tmp = remote_package_name; - remote_package_name = strchr(remote_package_name, '\0') + 1; - if(strcmp(remote_package_name, "") == 0) - { - remote_package_name = tmp; - break; - } - } - - //printf("%s, %s \n", remote_package_name, local_package_name); - - if (strcmp(remote_repo, local_repo) == 0) - { - if (strcmp(remote_package_name, local_package_name) == 0) - { - // Compare the filename - sprintf(remote_path, "%s/%s/%s", repo_path, remote_repo, remote_package); - - open_pkg(local_path, local, "ecmp"); - open_pkg(remote_path, remote, "ecmp"); - - // Compare the versions - if(strcmp(local->version, remote->version) != 0) - { - msg(INFO, "package %s is at version %s, available version is %s", local->name, local->version, remote->version); - msg(INFO, "upgrading %s from %s to %s", local->name, local->version, remote->version); - uninstall(local->name); - - f_install_package_source(remote_path, 0, local_repo); - new_version_installed = 1; - } - - free(local); - free(remote); - } - } - // Free each file path string - free(searched_files_array[j]); - } - // Free each file path string - free(files_array[i]); - } - // Free the array of file paths - free(searched_files_array); - } - // Free the array of file paths - free(files_array); - } - else - { - // If no files found, print a message - printf("No files found.\n"); - } - - if(new_version_installed == 0) - { - msg(WARNING, "all packages are up to date"); - } - - return 0; -} +} \ No newline at end of file diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..a681ba7 --- /dev/null +++ b/src/util.c @@ -0,0 +1,294 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "math.h" +#include "libspm.h" +#include "cutils.h" +#include "globals.h" + +// Callback function used by nftw to unlink files and directories +int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) +{ + int rv = remove(fpath); + + if (rv) + perror(fpath); + + return rv; +} + +// Recursively remove a directory and its contents +int rmrf(char *path) +{ + return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); +} + +// remove a file or link or directory +int rmany(char* path) +{ + // check if its a symlink + struct stat s; + + if (lstat(path, &s) == 0) { + if (S_ISLNK(s.st_mode)) { + // remove the symlink + if (unlink(path) == 0) { + return 0; + } else { + return -1; + } + } + // check if its a directory + if (S_ISDIR(s.st_mode)) { + // remove the directory + if (rmdir(path) == 0) { + return 0; + } else { + msg(ERROR, "Error removing directory %s (Probably not empty)", path); + return -1; + } + } + // check if its a file + if (S_ISREG(s.st_mode)) { + // remove the file + if (remove(path) == 0) { + return 0; + } else { + return -1; + } + } + } + return -1; +} + +// Quit the program with the given status code and display an error message if status is not 0 +void quit(int status) +{ + if (status != 0) { + msg(ERROR, "Exiting with status %d", status); + exit(status); + } +} + +// Function to recursively retrieve all files in a directory and its subdirectories +char **get_all_files(const char* root, const char *path, int *num_files) +{ + DIR *dir; + struct dirent *entry; + struct stat stat_buf; + char* origin = strdup(path); + // Open the directory + dir = opendir(path); + if (dir == NULL) { + // Print an error message if directory couldn't be opened + fprintf(stderr, "Error opening directory %s: %s\n", path, strerror(errno)); + free(origin); + return NULL; + } + + // Initialize variables + char **files_array = NULL; + int file_count = 0; + + // Loop through directory entries + while ((entry = readdir(dir)) != NULL) { + // Skip '.' and '..' entries + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + + // Construct full path of the current entry + char full_path[MAX_PATH]; + snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name); + + // Get information about the current entry + if (stat(full_path, &stat_buf) == 0) { + // If it's a directory, recursively call get_all_files + if (S_ISDIR(stat_buf.st_mode)) { + struct stat dir_stat_buf; + if (lstat(full_path, &dir_stat_buf) == 0) { + // Check if a directory is a symlink (this can probably be optimized out) + if (!S_ISLNK(dir_stat_buf.st_mode)) { + // If it isn't - treat it as a directory + int sub_files_count; + char **sub_files = get_all_files(root, full_path, &sub_files_count); + if (sub_files != NULL) { + // Resize files_array and copy contents of sub_files into it + files_array = realloc(files_array, (file_count + sub_files_count) * sizeof(char *)); + for (int i = 0; i < sub_files_count; i++) { + files_array[file_count++] = sub_files[i]; + } + free(sub_files); + } + } + else { + // If it is - treat it as a file + files_array = realloc(files_array, (file_count + 1) * sizeof(char *)); + files_array[file_count] = strdup(full_path + strlen(root) + 1); + file_count++; + } + } + } else if (S_ISREG(stat_buf.st_mode)) { + // If it's a regular file, add it to files_array + files_array = realloc(files_array, (file_count + 1) * sizeof(char *)); + files_array[file_count] = strdup(full_path + strlen(root) + 1); + file_count++; + } + } + } + // Close the directory + closedir(dir); + + // Update num_files if it's not NULL + if (num_files != NULL) + *num_files = file_count; + + // Return the array of file paths + free(origin); + + return files_array; +} + +// Load a format plugin, execute a specific function, and close the plugin +int runFormatLib(const char* format, const char* fn, const char* pkg_path, struct package* pkg) +{ + char lib_path[MAX_PATH]; + sprintf(lib_path, "%s/%s.so", getenv("SOVIET_PLUGIN_DIR"), format); + dbg(2, "Loading %s", lib_path); + + if (access(lib_path, F_OK) != 0) { + msg(ERROR, "File %s does not exist", lib_path); + return 1; + } + + // Load a function from the shared library + void* handle = dlopen(lib_path, RTLD_LAZY); + if (!handle) { + fprintf(stderr, "%s\n", dlerror()); + return 1; + } + int (*func)(const char*, struct package*) = dlsym(handle, fn); + char* error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + return 1; + } + if (func(pkg_path, pkg) != 0) { + return -1; + } + + dlclose(handle); + return 0; +} + +// A function to retrieve the version number of the libspm library. +float version() +{ + return LIBSPM_VERSION; +} + +// This will parse a string for environment variables +// It makes an assumption that a variable is: $A-Z_0-9 +int parse_env(char** in) +{ + dbg(2, "Parsing string %s for env variables", *in); + char* env = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_"; + char* start = strchr(*in, '$'); + char* end = NULL; + int i, start_i; + + if (start == NULL) + { + return 0; + } + + dbg(2, "Start: %s", start); + + start_i = strlen(*in) - strlen(start); + + dbg(2, "Start i: %d, from '%d' and '%d'", start_i, strlen(*in), strlen(start)); + + for (i = 1; i < strlen(start); i++) + { + end = strchr(env, start[i]); + + if (end == NULL) + { + if(i == 0) + { + return 0; + } + + if(start[i] != '\0') + { + end = &start[i]; + } + + break; + } + + if(i + 1 == strlen(start)) + { + end = " "; + } + } + + char* var = strdup(*in + start_i + 1); + char* dup_in = calloc(start_i + 1, 1); + if(start_i != 0) + { + snprintf(dup_in, start_i + 1, "%s", *in); + } + var[--i] = '\0'; + + dbg(2, "Var: %s", var); + dbg(2, "In: %s", *in); + + char* full_var = getenv(var); + + if(full_var == NULL) + { + return 0; + } + + dbg(2, "Full var: %s", full_var); + + char* full_in = calloc(strlen(*in) + strlen(full_var) + strlen(end) + 1, 1); + + sprintf(full_in, "%s%s%s", dup_in, full_var, end); + + free(*in); + free(dup_in); + free(var); + *in = full_in; + + dbg(2, "Result: %s", *in); + + return parse_env(in); +} + +// Download a file from url into FILE +int download(char* url, FILE* fp) { + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + (void) res; + curl_easy_setopt(curl, CURLOPT_USERAGENT, "CCCP/1.0 (https://www.sovietlinux.org/)(rip i guess)"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } + return 0; +} \ No newline at end of file diff --git a/src/version.c b/src/version.c deleted file mode 100644 index 9cded6f..0000000 --- a/src/version.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "libspm.h" - -// A function to retrieve the version number of the libspm library. -float version() -{ - return LIBSPM_VERSION; -} diff --git a/test/package.c b/test/package.c index 10198f3..696902c 100644 --- a/test/package.c +++ b/test/package.c @@ -1,3 +1,5 @@ +// Tests disabled for now +#if 0 // this file will be used by the our to check a package's validity. // it replaces in this usage the test.c file, now only used for libspm testing. @@ -33,4 +35,6 @@ int main(int argc, char const *argv[]) msg(INFO,"Package installed successfully"); return 0; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/test/spm.c b/test/spm.c index 359e087..f0e0906 100644 --- a/test/spm.c +++ b/test/spm.c @@ -1,3 +1,5 @@ +// Tests disabled for now +#if 0 #include "test.h" #include @@ -89,3 +91,4 @@ int main(int argc, char const *argv[]) msg(INFO,"Done testing LibSPM."); return 0; } +#endif \ No newline at end of file diff --git a/test/test.c b/test/test.c index 36d129f..c34cf16 100644 --- a/test/test.c +++ b/test/test.c @@ -1,3 +1,5 @@ +// Tests disabled for now +#if 0 #include "test.h" #include "../include/libspm.h" @@ -328,3 +330,4 @@ char* assemble(char** list,int count) { strcat(string,list[i]); return string; } +#endif \ No newline at end of file From a1acf9765f865c5d14bfe12d97d2d44a17823f92 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Sun, 22 Dec 2024 00:19:01 +0100 Subject: [PATCH 02/23] minor fixes --- include/libspm.h | 207 +++-------------------------------------------- src/clean.c | 19 +---- src/config.c | 9 ++- src/pkg.c | 166 ++++++++++++++++++++++++++++--------- src/util.c | 4 +- 5 files changed, 145 insertions(+), 260 deletions(-) diff --git a/include/libspm.h b/include/libspm.h index 7465635..dc34e2c 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -3,15 +3,11 @@ #include "cutils.h" #include "globals.h" - - #define LIBSPM_VERSION 1.000 #define SOURCE "src" #define BINARY "bin" - - struct cmd { // Commands @@ -23,6 +19,7 @@ struct cmd char* download; char* description; }; + struct package { // Basic infos @@ -59,6 +56,13 @@ struct package }; +struct packages +{ + int count; + int size; + struct package* buffer; +}; + // List of installed packages int list_installed(); @@ -100,95 +104,19 @@ void clean_install(); // TODO: Rework this float version(); -//# Package manipulation - -// Function to install a package from source with a specific format -/* -Accepts: -- const char* spm_path: Path to the package archive. -- int as_dep: Flag indicating if the package is a dependency. -- const char* format: Specific package format (optional). - -Returns: -- int: An integer indicating the result of the installation. - - 0: Package installed successfully. - - -1: Installation failed. -*/ // Function to install a package from source with a specific format -/* -Accepts: -- const char* spm_path: Path to the package archive. -- int as_dep: Flag indicating if the package is a dependency. -- const char* format: Specific package format (optional). - -Returns: -- int: An integer indicating the result of the installation. - - 0: Package installed successfully. - - -1: Installation failed. -*/ int install_package_source(struct package* pkg); // Function to uninstall packages -/* -Accepts: -- char* name: The name of the package to uninstall. - -Returns: -- int: An integer indicating the result of the uninstallation. - - 0: The package was successfully uninstalled. - - -1: An error occurred during the uninstallation. - -Description: -This function is used to uninstall packages. It relies on location data, which contains all the files that were installed by the program. This data is stored in a JSON array inside the package's SPM file in DATA_DIR. The function cycles through all the files in the JSON array and removes them from the system. It also removes the package's entry from the installed packages database. - -Note: -- The variable `DEFAULT_FORMAT` is not defined; you may need to replace it with the correct environment variable or value. For example, you can use `getenv("SOVIET_DEFAULT_FORMAT")` or replace it with a string representing the default format. -- The `INSTALLED_DB` variable is assumed to be defined elsewhere in your code. - -Please avoid making changes to this code unless there's a critical bug or an important missing feature. -*/ int uninstall(char* name); // Function to check if a package is installed and untouched -/* -Accepts: -- const char* name: The name of the package to be checked. - -Returns: -- int: An integer indicating the result of the check. - - 0: Good, package is installed and fine. - - 1: Package is not installed (Package data file is absent). - - 2: Package is corrupted (package data file is here but with no location info). - - 3: Package is corrupted (Some locations aren't here). -*/ int check(const char* name); // Function to retrieve a package from a data repository -/* -Accepts: -- struct package* i_pkg: A pointer to a package structure with package details. -- const char* out_path: The local path to save the downloaded package. - -Returns: -- char*: A pointer to the package format or NULL if there's an error. -*/ char* get(struct package *i_pkg, const char* repo, const char* out_path); // Function to move binaries to the correct locations -/* -Accepts: -- char** locations: An array of file locations. -- long loc_size: The number of locations in the array. - -Description: -This function iterates through the given file locations and moves the binaries to their correct destinations. - -Notes: -- It checks if the destination location is empty and moves files from the build directory to the destination. -- If the destination location is not empty, it provides a warning and optionally renames the file in the build directory. - -Returns: None -*/ void move_binaries(char** locations,long loc_size); // build a package from source @@ -201,15 +129,6 @@ int exec_special(const char* cmd,const char* package_dir); int update(); // Function to clean working directories -/* -Returns: -- int: An integer indicating the result of the cleaning operation. - - The return value is the sum of the following operations: - - rmrf(build_dir): Removing the build directory and its contents. - - rmrf(make_dir): Removing the make directory and its contents. - - mkdir(build_dir, 0755): Creating the build directory with the specified permissions. - - mkdir(make_dir, 0755): Creating the make directory with the specified permissions. -*/ int clean(); // Function to synchronize the local repository with a remote repository @@ -219,137 +138,29 @@ int repo_sync(); void init(); // Quit the program with the given status code and display an error message if status is not 0 -/* -Accepts: -- int status: The exit status code. - -Description: -This function exits the program with the specified status code. If the status code is not 0 (indicating an error), it also displays an error message. - -Returns: -- void: This function does not return a value. -*/ void quit(int status); +// Read the soviet config int readConfig(const char* configFilePath, int overwrite); // Function to check the existence of package locations -/* -Accepts: -- char** locations: An array of strings representing package locations. -- int locationsCount: The number of locations in the array. - -Returns: -- int: An integer indicating the result of the check. - - 0: All locations exist, so the package is installed and fine. - - 3: Some locations do not exist, indicating package corruption (some locations are missing). -*/ int check_locations(char** locations,int locationsCount); // Open a package from the given path and populate the package structure -/* -Accepts: -- const char* path: The path to the package file. -- struct package* pkg: A pointer to the package structure to populate. -- const char* format: The format of the package (optional). - -Description: -This function opens a package from the specified path, reads the package file's format, and populates the provided package structure with its contents. - -Returns: -- int: An integer indicating the result of opening the package. - - 0: Package opened successfully. - - 1: File does not exist or is not a valid package file. - - 1: File is not a valid package file or the format plugin isn't loaded. -*/ int open_pkg(const char* path, struct package* pkg,const char* format); // Create a package at the given path using the specified format and package structure -/* -Accepts: -- const char* path: The path to the package file to be created. -- struct package* pkg: A pointer to the package structure containing package data. -- const char* format: The format of the package (optional). - -Description: -This function creates a package file at the specified path using the provided format and package data from the package structure. - -Returns: -- int: An integer indicating the result of creating the package. - - 0: Package created successfully. - - -1: File is not a valid package file or the format plugin isn't loaded. -*/ int create_pkg(struct package* pkg,const char* format); // Load a format plugin, execute a specific function, and close the plugin -/* -Accepts: -- const char* format: The format of the package. -- const char* fn: The name of the function to execute in the format plugin. -- const char* pkg_path: The path to the package file. -- struct package* pkg: A pointer to the package structure. - -Description: -This function loads a format plugin, executes a specified function within the plugin, and then closes the plugin. - -Returns: -- int: An integer indicating the result of running the format plugin. - - 0: Format plugin executed successfully. - - 1: Format plugin file does not exist. - - 1: Error loading or executing the format plugin. - - -1: Format plugin function returned an error. -*/ int runFormatLib (const char* format,const char* fn,const char* pkg_path,struct package* pkg); // Function to check if a package is already installed -/* -Accepts: -- const char* name: Name of the package to check. - -Returns: -- bool: A boolean value indicating whether the package is installed. - - true: Package is installed. - - false: Package is not installed. -*/ bool is_installed(const char* name); // Function to free memory allocated for a package structure -/* -Accepts: -- struct package* pkg: Pointer to a package structure. - -Returns: -- int: An integer indicating the result of memory deallocation. - - 0: Memory freed successfully. -*/ int free_pkg(struct package* pkg); -// Function to download a file from a given URL and save it to a specified path -/* -Accepts: -- const char* url: The URL of the file to download. -- const char* file_path: The local file path to save the downloaded file. - -Returns: -- int: An integer indicating the result of the download operation. - - 0: Download success. - - -1: Download failure. -*/ -char* load_from_repo(const char* in, const char* repo, const char* file_path); - -// Function to download a repository from a given URL -/* -Accepts: -- const char* url_path: The path to the resource on the repository. -- const char* file_path: The local file path to save the downloaded resource. - -Returns: -- int: An integer indicating the result of the download operation. - - 0: Download success. - - 1: Download failure. -*/ -int loadFile(const char* path, const char* file_path); - diff --git a/src/clean.c b/src/clean.c index ff650ab..45970f3 100755 --- a/src/clean.c +++ b/src/clean.c @@ -46,24 +46,7 @@ void clean_install() { dbg(1, "deleting %s", full_cleanup_path); - if (lstat(full_cleanup_path, &st) != 0) - { - dbg(2, "Error getting file info"); - } - else - { - if (S_ISDIR(st.st_mode)) - { - dbg(2, "%s is a dir", full_cleanup_path); - rmrf(full_cleanup_path); - } - - if (S_ISREG(st.st_mode)) - { - dbg(2, "%s is a file", full_cleanup_path); - remove(full_cleanup_path); - } - } + rmany(full_cleanup_path); } } } \ No newline at end of file diff --git a/src/config.c b/src/config.c index 813ac8b..affa177 100755 --- a/src/config.c +++ b/src/config.c @@ -8,8 +8,6 @@ #include -#define DEFAULT_CONFIG_FILE "/etc/cccp.conf" // Default config file path - // A hashmap to store config values with default values typedef struct { const char* key; @@ -18,10 +16,11 @@ typedef struct { ConfigEntry configEntries[] = { { "SOVIET_ROOT", "/" }, + { "SOVIET_USER_ROOT", "~/.local/" }, { "SOVIET_DEFAULT_FORMAT", "ecmp" }, { "SOVIET_MAIN_DIR", "/var/cccp" }, { "SOVIET_WORK_DIR", "/var/cccp/work" }, - { "SOVIET_CONFIG_FILE", DEFAULT_CONFIG_FILE }, + { "SOVIET_CONFIG_FILE", "/etc/cccp.conf" }, { "SOVIET_REPOS_DIR", "/var/cccp/sources" }, { "SOVIET_SPM_DIR", "/var/cccp/spm" }, { "SOVIET_LOG_DIR", "/var/cccp/log" }, @@ -35,6 +34,8 @@ ConfigEntry configEntries[] = { { "SOVIET_SOURCE_DIR", "/usr/src/cccp" }, { "SOVIET_ENV_DIR", "/etc/cccp" }, { "SOVIET_CLEANUP", "/usr/share/info/dir:/usr/share/doc/" }, + { "SOVIET_ALL_DB", "/var/cccp/all.db" }, + { "SOVIET_INSTALLED_DB", "/var/cccp/installed.db" }, // Add more key-value pairs with default values as needed }; @@ -44,7 +45,7 @@ const size_t numConfigEntries = sizeof(configEntries) / sizeof(configEntries[0]) int readConfig(const char* configFilePath, int overwrite) { if (configFilePath == NULL) { - configFilePath = DEFAULT_CONFIG_FILE; // Use the default config file path + msg(FATAL, "Tried to use non-existing config"); } dbg(2, "config: %s", configFilePath); diff --git a/src/pkg.c b/src/pkg.c index de4c10f..42764de 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -8,22 +8,51 @@ #include "cutils.h" #include "libspm.h" +// Allocate an array of packages +struct packages create_pkgs(int reserve) +{ + packages pkgs; + pkgs.size = 1 + reserve; + pkgs.count = 0; + pkgs.buffer = (struct package*)calloc(1 + reserve, sizeof(struct package)); + return pkgs; +} + +// Merge 2 package arrays +void merge_pkgs(struct packages* destination, struct packages* source) +{ + for(int i = 0; i < source->count; i++) + { + pkg = pop_pkg(source); + push_pkg(destination, pkg); + free_pkg(pkg); + } +} + +// Push a package into the array +void push_pkg(struct packages* pkgs, struct package* pkg) +{ + if (pkgs->count == pkgs->size) + { + pkgs->buffer = realloc(pkgs->buffer, sizeof(struct package)*(pkgs->count + pkgs->size)); + pkgs->size = pkgs->count + pkgs->size; + } + memcpy(pkgs->buffer[pkgs->count], pkg, sizeof(struct package)); + pkgs->count++; +} + +// Pop the last added package from the array +struct package* pop_pkg(struct packages* pkgs) +{ + pkgs->count--; + struct package* pkg = calloc(1, sizeof(struct package)); + memcpy(pkg, pkgs->buffer[pkgs->count], sizeof(struct package)); + free_pkg(&(pkgs->buffer[pkgs->count])); + return pkg; +} + + // Open a package from the given path and populate the package structure -/* -Accepts: -- const char* path: The path to the package file. -- struct package* pkg: A pointer to the package structure to populate. -- const char* format: The format of the package (optional). - -Description: -This function opens a package from the specified path, reads the package file's format, and populates the provided package structure with its contents. - -Returns: -- int: An integer indicating the result of opening the package. - - 0: Package opened successfully. - - 1: File does not exist or is not a valid package file. - - 1: File is not a valid package file or the format plugin isn't loaded. -*/ int open_pkg(const char* path, struct package* pkg, const char* format) { dbg(2, "Setting everything to NULL"); @@ -69,20 +98,6 @@ int open_pkg(const char* path, struct package* pkg, const char* format) } // Create a package at the given path using the specified format and package structure -/* -Accepts: -- const char* path: The path to the package file to be created. -- struct package* pkg: A pointer to the package structure containing package data. -- const char* format: The format of the package (optional). - -Description: -This function creates a package file at the specified path using the provided format and package data from the package structure. - -Returns: -- int: An integer indicating the result of creating the package. - - 0: Package created successfully. - - -1: File is not a valid package file or the format plugin isn't loaded. -*/ int create_pkg(struct package* pkg, const char* format) { char repo_path[MAX_PATH]; @@ -128,14 +143,6 @@ int create_pkg(struct package* pkg, const char* format) } // Function to free memory allocated for a package structure -/* -Accepts: -- struct package* pkg: Pointer to a package structure. - -Returns: -- int: An integer indicating the result of memory deallocation. - - 0: Memory freed successfully. -*/ int free_pkg(struct package* pkg) { if (pkg->name != NULL) free(pkg->name); @@ -170,4 +177,87 @@ int free_pkg(struct package* pkg) return 0; } -int create_package_db(){} \ No newline at end of file +// Create the database that stores all packages in a directory +int create_pkg_db(char* db_path, struct packages* pkgs) +{ + remove(db_path); + sqlite3* db; + sqlite3_stmt* pkg_table; + int result = sqlite3_open(db_path, &db); + if(result) + { + msg(FATAL, "SQL error when creating SOVIET_DB"); + } + + result = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Packages (Name TEXT, Path TEXT)", NULL, NULL, NULL); + if (result != SQLITE_OK) + { + msg(FATAL, "SQL error when creating pkg_table"); + } + + char* ins = "INSERT INTO Packages VALUES (?,?)"; + + sqlite3_close(&db); +} + +// Get all packages from a directory +struct packages get_pkgs(char* path) +{ + int num_files; + char **files_array = get_all_files(path, path, &num_files); + if (files_array != NULL) + { + packages pkgs = create_pkgs(num_files); + // Print each file path + for (int j = 0; j < num_files; j++) + { + char* path = strdup(files_array[j]); + char* name = strdup(files_array[j]); + + while(strtok(package_name, "/")) + { + char* tmp = name; + name = strchr(package_name, '\0') + 1; + if(*name == '\0') + { + name = tmp; + break; + } + } + + dbg(1, "path is %s, name is %s", path, name); + + // Free each file path string + free(files_array[i]); + free(path); + } + // Free the array of file paths + free(files_array); + } + else + { + msg(ERROR, "Repository %s empty", REPOS[i]); + } +} + +// Get all packages from a directory +struct packages get_pkgs_from_repos() +{ + char** REPOS = calloc(512,sizeof(char*)); + int num_repos = get_repos(REPOS) + if(num_repos < 2) + { + msg(FATAL, "No local repositories"); + } + + struct packages pkgs = create_pkgs(0); + for(int i = 1; i < num_repos; i++) + { + char* path = calloc(MAX_PATH, 1); + sprintf(path, "%s/%s", getenv("SOVIET_REPOS_DIR"), REPOS[i]); + struct packages result = get_pkgs(path); + merge_pkgs(&pkgs, &result); + } + + return pkgs; +} diff --git a/src/util.c b/src/util.c index a681ba7..9454eda 100644 --- a/src/util.c +++ b/src/util.c @@ -51,10 +51,10 @@ int rmany(char* path) // check if its a directory if (S_ISDIR(s.st_mode)) { // remove the directory - if (rmdir(path) == 0) { + if (rmrf(path) == 0) { return 0; } else { - msg(ERROR, "Error removing directory %s (Probably not empty)", path); + msg(ERROR, "Error removing directory %s", path); return -1; } } From 4d64c3576119f2bdd51b865af2c73edbffe2358b Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Sun, 22 Dec 2024 00:48:44 +0100 Subject: [PATCH 03/23] added test prototypes --- include/globals.h | 2 - makefile | 10 +- src/globals.c | 3 - src/{list.c => list(TBD).c} | 0 test/spm.c | 75 ++------ test/test.c | 340 +++++------------------------------- test/test.h | 21 ++- 7 files changed, 75 insertions(+), 376 deletions(-) rename src/{list.c => list(TBD).c} (100%) diff --git a/include/globals.h b/include/globals.h index d815e7d..11b3101 100755 --- a/include/globals.h +++ b/include/globals.h @@ -15,8 +15,6 @@ extern bool TESTING; extern bool OVERWRITE; // enable verbose mode extern bool QUIET; -// Flag for skipping checksum validation -extern bool INSECURE; // Flag indicating that a user passed either Y or N to be used as default extern bool OVERWRITE_CHOISE; // Choise for passing N or Y to a prompt by default diff --git a/makefile b/makefile index 51b6fa5..442825f 100755 --- a/makefile +++ b/makefile @@ -72,17 +72,17 @@ $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c test: -# $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) -# $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/package.c ${DEVDIR}/test.c $(LIBS) -o bin/package-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) + $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) + $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/package.c ${DEVDIR}/test.c $(LIBS) -o bin/package-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) @echo "Test binary created" check-all: echo "..." -# bin/spm-test all -# @if [ $$? -gt 0 ]; then echo "Error Tests Failed"; else echo "All good"; fi + bin/spm-test + @if [ $$? -gt 0 ]; then echo "Error Tests Failed"; else echo "All good"; fi check: test check-all - @echo "ERROR: no tests ran" + @echo "All tests passed" # This will conflict with other artifacts so you should run make clean before `make debug` and after you're done diff --git a/src/globals.c b/src/globals.c index a637da5..1050bff 100644 --- a/src/globals.c +++ b/src/globals.c @@ -18,9 +18,6 @@ bool OVERWRITE = false; // Flag for quiet mode (no verbose output) bool QUIET = true; -// Flag for skipping checksum validation -bool INSECURE = false; - // Flag indicating that a user passed either Y or N to be used as default bool OVERWRITE_CHOISE = false; diff --git a/src/list.c b/src/list(TBD).c similarity index 100% rename from src/list.c rename to src/list(TBD).c diff --git a/test/spm.c b/test/spm.c index f0e0906..6022b04 100644 --- a/test/spm.c +++ b/test/spm.c @@ -1,18 +1,13 @@ // Tests disabled for now -#if 0 +#if 1 #include "test.h" #include char WORKING_DIR[2048]; -int main(int argc, char const *argv[]) +int main() { msg(INFO,"Started LibSPM test suite..."); - if (argc < 2) - { - printf("No arguments provided\n"); - return 1; - } /* START LIBSPM CONFIG */ setenv("SOVIET_DEBUG","3",1); @@ -20,9 +15,6 @@ int main(int argc, char const *argv[]) QUIET = false; OVERWRITE = true; DEBUG_UNIT = NULL; - // we want to chnage that later - // TODO: Add hash to test package - INSECURE = true; /* END LIBSPM CONFIG */ char cwd[2048]; @@ -32,63 +24,32 @@ int main(int argc, char const *argv[]) char TEST_SPM_PATH[2048]; sprintf(TEST_SPM_PATH,"%s/vim.ecmp",WORKING_DIR); - - - if (argc < 2 || strcmp(argv[1], "help") == 0) { - printf("Usage: %s [ecmp|all|make|install|uninstall|move|help|split|config|get]\n", argv[0]); - return 0; - } - // Check for root privileges for all other commands if (geteuid() != 0) { printf("You must have root privileges to run this command.\n"); return 1; } - if (strcmp(argv[1], "all") == 0) { - test_move(); - test_get(); - test_split(); - test_config(); - - test_ecmp(TEST_SPM_PATH); - test_make(TEST_SPM_PATH); - test_pm(TEST_SPM_PATH); - - int leaks = check_leaks(); - if (leaks > 0) { - msg(ERROR, "Leaks: %d",leaks); - } - - } else if (strcmp(argv[1], "ecmp") == 0) { - test_ecmp(TEST_SPM_PATH); - } else if (strcmp(argv[1], "make") == 0) { - test_make(TEST_SPM_PATH); - printf("Leaks: %d\n", check_leaks()); - } else if (strcmp(argv[1],"install") == 0 || - strcmp(argv[1],"pm") == 0) { - test_pm(TEST_SPM_PATH); - printf("Leaks: %d\n", check_leaks()); - return 0; - } else if (strcmp(argv[1], "move") == 0) { - test_move(); - } else if (strcmp(argv[1], "split") == 0) { - test_split(); - } else if (strcmp(argv[1], "config") == 0) { - test_config(); - } else if (strcmp(argv[1], "get") == 0) { - test_get(); - } else { - printf("Invalid argument\n"); - return 1; - } + test_check(); + test_clean(); + test_config(); + test_globals(); + test_init(); + test_install(); + test_make(); + test_move(); + test_pkg(); + test_repo(); + test_uninstall(); + test_update(); + test_util(); int leaks = check_leaks(); - if (leaks > 0) { + if (leaks > 0) + { msg(WARNING,"Leaks: %d",leaks); } msg(INFO,"Done testing LibSPM."); return 0; -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/test/test.c b/test/test.c index c34cf16..cb835ef 100644 --- a/test/test.c +++ b/test/test.c @@ -1,333 +1,73 @@ // Tests disabled for now -#if 0 +#if 1 #include "test.h" #include "../include/libspm.h" -char* assemble(char** list,int count); - -extern int open_ecmp(char* path,struct package* pkg); -extern int create_ecmp(char* path,struct package* pkg); - - -void test_pm(char* spm_path) { - - msg(INFO,"Testing 'install_package_source()' and 'uninstall()'.."); - - // install tests - char temp_dir_template[] = "/tmp/test_dir_XXXXXX"; - char* test_dir = mkdtemp(temp_dir_template); - setenv("SOVIET_ROOT",test_dir,1); - char test_spm_dir[2048]; - sprintf(test_spm_dir,"%s/spm/",test_dir); - setenv("SOVIET_SPM_DIR",test_spm_dir,1); - - init() ; - - assert(install_package_source(spm_path,0) == 0); - assert(uninstall("vim") == 0); - - unsetenv("SOVIET_ROOT"); - unsetenv("SOVIET_ROOT"); - +void test_check(char* spm_path) +{ return; } - - - -void test_move() { - - msg(INFO,"Testing 'move_binaries()'.."); - - char temp_dir_template[] = "/tmp/test_dir_XXXXXX"; - char* test_dir = mkdtemp(temp_dir_template); - char build_dir[2048]; - sprintf(build_dir,"%s/build",test_dir); - - #define l_d_count 5 - #define l_f_count 12 - #define l_l_count 3 - char* l_dirs[l_d_count] = {"b","b/d","s","s/j","s/j/k"}; - char* l_files[l_f_count] = {"w","b/d/e","a","d","b/y","b/c","b/f","s/j/k/z","s/j/k/x","s/j/k/c","s/j/k/v","s/j/k/b"}; - char* l_links[l_l_count][2] = {{"b/d/e","b/e"},{"s/j/k/z","s/z"},{"s/j/k/x","s/x"}}; - - setenv("SOVIET_ROOT",test_dir,1); - setenv("SOVIET_BUILD_DIR",build_dir,1); - init(); - - dbg(2,"creating test dirs"); - //make all dirs - for (int i = 0; i < l_d_count; i++) - { - dbg(3,"Creating %s\n",l_dirs[i]); - char* dir = malloc(256); - sprintf(dir,"%s/%s",build_dir,l_dirs[i]); - mkdir(dir,0777); - free(dir); - } - dbg(2,"creating test files"); - // make all files - for (int i = 0; i < l_f_count; i++) - { - dbg(3,"Creating %s\n",l_files[i]); - char* path = malloc(256); - sprintf(path,"%s/%s",build_dir,l_files[i]); - FILE* f = fopen(path,"w"); - fclose(f); - free(path); - } - dbg(2,"Creating test links\n"); - // make all links - for (int i = 0; i < l_l_count; i++) - { - dbg(3,"Creating %s -> %s\n",l_links[i][1],l_links[i][0]); - char* old_path = malloc(256); - sprintf(old_path,"%s/%s",build_dir,l_links[i][0]); - char* link_path = malloc(256); - sprintf(link_path,"%s/%s",build_dir,l_links[i][1]); - symlink(old_path,link_path); - free(old_path); - free(link_path); - } - - // get all the files with get_locatins - char** end_locations; - int end_count = get_locations(&end_locations,build_dir); - - assert(end_count == l_f_count + l_l_count); - - move_binaries(end_locations,end_count); - // Check if the move was successful - int EXIT = 0; - for (int i = 0; i < l_f_count; i++) - { - char* old_path = malloc(256); - sprintf(old_path,"%s/%s",build_dir,l_files[i]); - char* new_path = malloc(256); - sprintf(new_path,"%s/%s",test_dir,l_files[i]); - - assert(access(old_path, F_OK) == -1 && access(new_path, F_OK) == 0); - - free(old_path); - free(new_path); - } - // check if the links were moved - for (int i = 0; i < l_l_count; i++) - { - char* old_path = malloc(256); - sprintf(old_path,"%s/%s",build_dir,l_links[i][0]); - char* new_path = malloc(256); - sprintf(new_path,"%s/%s",test_dir,l_links[i][1]); - - // check using stat - struct stat st; - assert(stat(new_path,&st) == 0 && stat(old_path,&st) != 0); - - free(old_path); - free(new_path); - } - - - free(*end_locations); - free(end_locations); - - unsetenv("SOVIET_ROOT_DIR"); - unsetenv("SOVIET_BUILD_DIR"); - +void test_clean() +{ + return } -void test_make(char* spm_path) { - - // Set environment variables for building - setenv("BUILD_ROOT", getenv("SOVIET_BUILD_DIR"), 1); - - msg(INFO,"Testing 'make()'.."); - - init(); - struct package p = {0}; - - assert(open_pkg(spm_path, &p,NULL) == 0); - - setenv("NAME", p.name, 1); - setenv("VERSION", p.version, 1); - if (p.url != NULL) { - parse_env(&(p.url)); - dbg(1, "URL: %s", p.url); - setenv("URL", p.url, 1); - } - - char* legacy_dir = calloc(2048,1); - sprintf(legacy_dir,"%s/%s-%s",getenv("SOVIET_MAKE_DIR"),p.name,p.version); - - dbg(1,"Legacy dir: %s",legacy_dir); - - assert(make(legacy_dir,&p) == 0); - - // Run 'install' command - if (p.info.install == NULL && strlen(p.info.install) == 0) { - msg(FATAL, "No install command!"); - } - - char install_cmd[64 + strlen(legacy_dir) + strlen(p.info.install)]; - sprintf(install_cmd, "( cd %s && %s )", legacy_dir, p.info.install); - - dbg(2, "Executing install command: %s", install_cmd); - if (system(install_cmd) != 0) { - msg(FATAL, "Failed to install %s", p.name); - return -2; - } - dbg(1, "Install command executed!"); - - dbg(1,"Getting locations for %s",p.name); - p.locationsCount = get_locations(&p.locations,getenv("SOVIET_BUILD_DIR")); - assert(p.locationsCount > 0); - - free_pkg(&p); - - dbg(1,"Got %d locations for %s",p.locationsCount,p.name); - +void test_config() +{ return; } -void test_split() { - - msg(INFO,"Testing 'split()'.."); - - chdir(WORKING_DIR); - system("python3 gen_split.py split.txt 512"); - - char* split_str; - rdfile("split.txt",&split_str); - - char **split_list = NULL; - int count = splita(strdup(split_str),',',&split_list); - - char* str_split = assemble(split_list,count); - free(*split_list); - free(split_list); - - dbg(2, "str_split: %s", str_split); - dbg(2, "split_str: %s", split_str); - - assert(strcmp(str_split,split_str) == 0); - - free(split_str); - free(str_split); - +void test_globals() +{ return; } -void test_config() { - - msg(INFO,"Testing 'readConfig()'.."); - - assert(readConfig(getenv("SOVIET_CONFIG_FILE"), 0) == 0); +void test_init() +{ return; } - -void test_get() { - - msg(INFO,"Testing 'get()'.."); - - char db_path[2048]; - sprintf(db_path,"%s/get_test.db",WORKING_DIR); - - setenv("ALL_DB_PATH",db_path,1); - repo_sync(); - - struct package base_pkg = {0}; - char base_path[2048]; - sprintf(base_path,"%s/test.base.ecmp",WORKING_DIR); - assert(open_ecmp(base_path,&base_pkg) == 0); - - - struct package t_pkg; - t_pkg.name = "test"; - - dbg(2,"Repo: %s",getenv("SOVIET_DEFAULT_REPO")); - - char out_test[2048+16 ] = {0}; - sprintf(out_test,"%s/test.ecmp",WORKING_DIR); - dbg(3,"Copying to %s",out_test); - remove(out_test); - char* fmt = get(&t_pkg,getenv("SOVIET_DEFAULT_REPO"),out_test); - - assert(open_ecmp(out_test,&t_pkg) == 0); - - // print fmt and all package info - dbg(1,"fmt: %s",fmt); - dbg(1,"name: %s",t_pkg.name); - dbg(1,"version: %s",t_pkg.version); - dbg(1,"url: %s",t_pkg.url); - - assert(strcmp(base_pkg.name,t_pkg.name) == 0); - assert(strcmp(base_pkg.version,t_pkg.version) == 0); - assert(strcmp(base_pkg.url,t_pkg.url) == 0); - // add other cmp later - - free_pkg(&base_pkg); - free_pkg(&t_pkg); - +void test_install() +{ return; - } -void test_ecmp(char* spm_path) { - - msg(INFO,"Testing 'open_ecmp()' and 'create_ecmp()'.."); - - setenv("FORMATS","ecmp",1); - - struct package old_pkg = {0}; - - assert(open_ecmp(spm_path,&old_pkg) == 0); - - // print the pkg - dbg(2,"old_pkg: %s => %s %s\n",old_pkg.name,old_pkg.version,old_pkg.type); - - msg(INFO,"Creating ecmp package file"); - - - char mod_path[2048]; - sprintf(mod_path,"%s.mod",spm_path); - - assert(create_ecmp(mod_path, &old_pkg) == 0); - - // now reopen package and compare - struct package new_pkg = {0}; +void test_make() +{ + return; +} - assert(open_ecmp(mod_path,&new_pkg) == 0); +void test_move() +{ + return +} - // print the pkg - dbg(2,"new_pkg: %s => %s %s\n",new_pkg.name,new_pkg.version,new_pkg.type); +void test_pkg() +{ + return - // compare packages - assert(strcmp(new_pkg.name,old_pkg.name) == 0); - assert(strcmp(new_pkg.version,old_pkg.version) == 0); - assert(strcmp(new_pkg.type,old_pkg.type) == 0); +} - // free packages - free_pkg(&old_pkg); - free_pkg(&new_pkg); +void test_repo() +{ + return; +} - remove(mod_path); +void test_uninstall() +{ + return; +} +void test_update() +{ return; } -char* assemble(char** list,int count) { - dbg(3,"Assembling %d strings",count); - char* string = calloc(2048*count,sizeof(char)); - int i; - for (i = 0; i < count-1; i++) - { - strcat(string,list[i]); - strcat(string,","); - - } - strcat(string,list[i]); - return string; +void test_util() +{ + return; } + #endif \ No newline at end of file diff --git a/test/test.h b/test/test.h index 208b4fb..a1db99b 100644 --- a/test/test.h +++ b/test/test.h @@ -7,18 +7,21 @@ #include "../include/globals.h" #include "../include/cutils.h" - #define STATIC - -void test_move(); -void test_get(); -void test_split(); +void test_check(); +void test_clean(); void test_config(); - -void test_ecmp(char* spm_path); -void test_make(char* spm_path); -void test_pm(char* spm_path); +void test_globals(); +void test_init(); +void test_install(); +void test_make(); +void test_move(); +void test_pkg(); +void test_repo(); +void test_uninstall(); +void test_update(); +void test_util(); extern char WORKING_DIR[2048]; From 55313fb9662b92a97f8ccf3742af0e1e6c089454 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Sun, 22 Dec 2024 14:20:57 +0100 Subject: [PATCH 04/23] minor fixes --- include/libspm.h | 76 ++++++++++++----------- makefile | 12 ++-- src/clean.c | 2 +- src/install.c | 9 ++- src/{list(TBD).c => list_TBD.c} | 0 src/make.c | 19 ++---- src/pkg.c | 105 +++++++++++++------------------- src/util.c | 6 ++ 8 files changed, 104 insertions(+), 125 deletions(-) rename src/{list(TBD).c => list_TBD.c} (100%) diff --git a/include/libspm.h b/include/libspm.h index dc34e2c..da4edf0 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -30,7 +30,11 @@ struct package char* sha256; char* url; char* environment; - char* repo; + + // Internal + char* path; + char* format; + // char** files; int filesCount; @@ -84,26 +88,12 @@ void create_links(char build_loc[4096], char dest_loc[4096]); // Get all repositories currently present int get_repos(char** list); -// Get all files from a location, ignoring root in the result -char** get_all_files(const char* root, const char *path, int *num_files); - -// Download a file from url into fp with curl -// note: it does not open nor close the FILE -int download(char* url, FILE* fp); - -// Pare the string in for environment variables, the original in will be freed and replaced -int parse_env(char** in); - // Clone a git repository int add_repo(char* name, char* url); // Cleanup unneded files after a package is installed void clean_install(); -// This prints the version , its bad -// TODO: Rework this -float version(); - // Function to install a package from source with a specific format int install_package_source(struct package* pkg); @@ -137,33 +127,51 @@ int repo_sync(); // init the system void init(); -// Quit the program with the given status code and display an error message if status is not 0 -void quit(int status); - // Read the soviet config int readConfig(const char* configFilePath, int overwrite); // Function to check the existence of package locations int check_locations(char** locations,int locationsCount); -// Open a package from the given path and populate the package structure -int open_pkg(const char* path, struct package* pkg,const char* format); - -// Create a package at the given path using the specified format and package structure -int create_pkg(struct package* pkg,const char* format); - -// Load a format plugin, execute a specific function, and close the plugin -int runFormatLib (const char* format,const char* fn,const char* pkg_path,struct package* pkg); - // Function to check if a package is already installed bool is_installed(const char* name); +/*pkg.c*/ +// Allocate an array of packages +struct packages create_pkgs(int reserve); +// Merge 2 package arrays +void merge_pkgs(struct packages* destination, struct packages* source); +// Push a package into the array +void push_pkg(struct packages* pkgs, struct package* pkg); +// Pop the last added package from the array +struct package* pop_pkg(struct packages* pkgs); +// Open a package from the given path and populate the package structure +int open_pkg(const char* path, struct package* pkg, const char* format); +// Create a package at the given path using the specified format and package structure +int create_pkg(struct package* pkg); // Function to free memory allocated for a package structure int free_pkg(struct package* pkg); - - - - - - - +// Create the database that stores all packages in a directory +int create_pkg_db(char* db_path, struct packages* pkgs); +// Get all packages from a directory +struct packages get_pkgs(char* path); + +/*util.c*/ +// Recursively remove a directory and its contents +int rmrf(char *path); +// remove a file or link or directory +int rmany(char* path); +// Quit the program with the given status code and display an error message if status is not 0 +void quit(int status); +// Function to recursively retrieve all files in a directory and its subdirectories +char **get_all_files(const char* root, const char *path, int *num_files); +// Load a format plugin, execute a specific function, and close the plugin +int runFormatLib(const char* format, const char* fn, const char* pkg_path, struct package* pkg); +// A function to retrieve the version number of the libspm library. +float version(); +// This will parse a string for environment variables +// It makes an assumption that a variable is: $A-Z_0-9 +int parse_env(char** in); +// Download a file from url into FILE +int download(char* url, FILE* fp); +int cp(char* from, char* to); \ No newline at end of file diff --git a/makefile b/makefile index 442825f..9155b7a 100755 --- a/makefile +++ b/makefile @@ -34,7 +34,7 @@ DBGFLAGS = -g -fsanitize=address # set local lib to lib/*/*.a LOCAL_LIBS = $(wildcard lib/*/*.a) -LIBS = ${LOCAL_LIBS} -lgit2 -lcurl -lsqlite3 -lm -lcrypto +LIBS = ${LOCAL_LIBS} -lgit2 -lsqlite3 -lcurl -lm -lcrypto # change these to proper directories where each file should be SRCDIR = src @@ -77,12 +77,11 @@ test: @echo "Test binary created" check-all: - echo "..." - bin/spm-test + bin/spm-test all @if [ $$? -gt 0 ]; then echo "Error Tests Failed"; else echo "All good"; fi check: test check-all - @echo "All tests passed" + @echo "All Tests Passed" # This will conflict with other artifacts so you should run make clean before `make debug` and after you're done @@ -117,7 +116,4 @@ install: $(BINDIR)/$(LIBOUT) @if [ ! -d $(DESTDIR)/usr/include/spm ]; then mkdir -p $(DESTDIR)/usr/include/spm; fi for i in include/*; do install -vDm 755 $$i $(DESTDIR)/usr/include/spm/; done install -vDm 755 $(BINDIR)/$(LIBOUT) $(DESTDIR)/usr/lib/$(LIBOUT) - install $(BINDIR)/plugins/ecmp.so -vDm 755 $(DESTDIR)/var/cccp/plugins/ecmp.so - - - + install $(BINDIR)/plugins/ecmp.so -vDm 755 $(DESTDIR)/var/cccp/plugins/ecmp.so \ No newline at end of file diff --git a/src/clean.c b/src/clean.c index 45970f3..c05604d 100755 --- a/src/clean.c +++ b/src/clean.c @@ -1,4 +1,5 @@ #include "cutils.h" // Custom utility library +#include "libspm.h" #include // Standard library for general functions #include // Standard library for file status information @@ -34,7 +35,6 @@ void clean_install() for(int i = 0; i < count; i++) { - struct stat st; char* full_cleanup_path = calloc(strlen(build_dir) + strlen(cleanup_loc[i]) + 2, 1); snprintf(full_cleanup_path, strlen(build_dir) + strlen(cleanup_loc[i]) + 1, "%s%s", build_dir, cleanup_loc[i]); diff --git a/src/install.c b/src/install.c index 8cb9e91..964b9e5 100755 --- a/src/install.c +++ b/src/install.c @@ -29,7 +29,6 @@ int install_package_source(struct package* pkg) { char* make_dir = getenv("SOVIET_MAKE_DIR"); char* build_dir = getenv("SOVIET_BUILD_DIR"); - char* format = getenv("SOVIET_DEFAULT_FORMAT"); // Temporary for compatibility setenv("BUILD_ROOT", build_dir, 1); @@ -102,7 +101,7 @@ int install_package_source(struct package* pkg) } // Build the package dbg(1, "Making %s", pkg->name); - if (make(legacy_dir, &pkg) != 0) { + if (make(legacy_dir, pkg) != 0) { msg(ERROR, "Failed to make %s", pkg->name); exit(1); } @@ -176,7 +175,7 @@ int install_package_source(struct package* pkg) } } - create_pkg(&pkg, NULL); + create_pkg(pkg); dbg(1, "Package %s installed", pkg->name); // Clean up @@ -190,7 +189,7 @@ int install_package_source(struct package* pkg) } /* Warning: there is something sussy going on beyond this point */ -int configure_package(struct package* pkg) +void configure_package(struct package* pkg) { // Get global environment variables if (pkg->environment != NULL) @@ -276,7 +275,7 @@ bool is_installed(const char* name) return false; } -int add_to_queue(const char* name) +void add_to_queue(char* name) { // Add the package name to the queue PACKAGE_QUEUE[QUEUE_COUNT] = name; diff --git a/src/list(TBD).c b/src/list_TBD.c similarity index 100% rename from src/list(TBD).c rename to src/list_TBD.c diff --git a/src/make.c b/src/make.c index bb82240..24c062e 100755 --- a/src/make.c +++ b/src/make.c @@ -44,8 +44,8 @@ int make(char* package_dir, struct package* pkg) { { int download_attempts = 3; (void)download_attempts; - int download_success = 0; - (void)download_success; + int download_success = 0; + (void)download_success; struct stat st_source = {0}; struct stat st_source_loc = {0}; @@ -81,13 +81,6 @@ int make(char* package_dir, struct package* pkg) { download(file_url, fp); fclose(fp); - // Check if the checksum shall be bypassed - - if (INSECURE) { - msg(WARNING, "The Checksum is being skipped"); - goto skip_checksum; - } - // Check the hash, abort if mismatch unsigned char hash[SHA256_DIGEST_LENGTH]; char* hash_str = calloc(SHA256_DIGEST_LENGTH, 8); @@ -108,7 +101,7 @@ int make(char* package_dir, struct package* pkg) { SHA256((unsigned char*) buffer, size, hash); - /* This caused and warning and functionally does nothing. Here hash is an array of unsigned char, but arrays in C are not pointers that can be NULL. This should probably be done with fread or fopen instead. Commenting out for now to silence the warning*/ + /* This caused and warning and functionally does nothing. Here hash is an array of unsigned char, but arrays in C are not pointers that can be NULL. This should probably be done with fread or fopen instead. Commenting out for now to silence the warning*/ /*if (hash == NULL) { msg(FATAL, "Could not verify the file's hash"); return -1; @@ -128,15 +121,13 @@ int make(char* package_dir, struct package* pkg) { free(hash_str); free(buffer); - skip_checksum: - dbg(1, "Download finished"); - loadFile(location, source_file_location); + cp(location, source_file_location); } else { dbg(1, "Loading form %s", source_location); - loadFile(source_file_location, location); + cp(source_file_location, location); } free(files); diff --git a/src/pkg.c b/src/pkg.c index 42764de..6173284 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -11,7 +11,7 @@ // Allocate an array of packages struct packages create_pkgs(int reserve) { - packages pkgs; + struct packages pkgs; pkgs.size = 1 + reserve; pkgs.count = 0; pkgs.buffer = (struct package*)calloc(1 + reserve, sizeof(struct package)); @@ -23,7 +23,7 @@ void merge_pkgs(struct packages* destination, struct packages* source) { for(int i = 0; i < source->count; i++) { - pkg = pop_pkg(source); + struct package* pkg = pop_pkg(source); push_pkg(destination, pkg); free_pkg(pkg); } @@ -37,7 +37,7 @@ void push_pkg(struct packages* pkgs, struct package* pkg) pkgs->buffer = realloc(pkgs->buffer, sizeof(struct package)*(pkgs->count + pkgs->size)); pkgs->size = pkgs->count + pkgs->size; } - memcpy(pkgs->buffer[pkgs->count], pkg, sizeof(struct package)); + memcpy(&(pkgs->buffer[pkgs->count]), pkg, sizeof(struct package)); pkgs->count++; } @@ -46,12 +46,11 @@ struct package* pop_pkg(struct packages* pkgs) { pkgs->count--; struct package* pkg = calloc(1, sizeof(struct package)); - memcpy(pkg, pkgs->buffer[pkgs->count], sizeof(struct package)); + memcpy(pkg, &(pkgs->buffer[pkgs->count]), sizeof(struct package)); free_pkg(&(pkgs->buffer[pkgs->count])); return pkg; } - // Open a package from the given path and populate the package structure int open_pkg(const char* path, struct package* pkg, const char* format) { @@ -98,46 +97,37 @@ int open_pkg(const char* path, struct package* pkg, const char* format) } // Create a package at the given path using the specified format and package structure -int create_pkg(struct package* pkg, const char* format) +int create_pkg(struct package* pkg) { - char repo_path[MAX_PATH]; - sprintf(repo_path, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->repo); + char path[MAX_PATH]; + sprintf(path, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->path); - if(isdir(repo_path) != 0) + if(isdir(path) != 0) { - pmkdir(repo_path); + pmkdir(path); + rmany(path); } - - char path[MAX_PATH]; - sprintf(path, "%s/%s/%s.%s", getenv("SOVIET_SPM_DIR"), pkg->repo, pkg->name, getenv("SOVIET_DEFAULT_FORMAT")); msg(INFO, "Creating package %s", path); char** FORMATS; int FORMAT_COUNT = splita(strdup(getenv("SOVIET_FORMATS")),' ',&FORMATS); - - // get file extension - if (format == NULL) - { - format = strrchr( path, '.' ) + 1; - } - /* This illustrates strrchr */ - if (format != NULL) + + if (pkg->format != NULL) { // this is experimental for (int i = 0; i < FORMAT_COUNT; i++) { - if (strcmp(format,FORMATS[i]) == 0) + if (strcmp(pkg->format, FORMATS[i]) == 0) { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "create", path, pkg); - //free(*FORMATS); + free(FORMATS[i]); return 0; } } } - msg(ERROR,"File %s is not a valid package file, or the format plugin isn't loaded",path); - //free(*FORMATS); + msg(ERROR,"File %s is not a valid package file, or the format plugin isn't loaded", path); free(FORMATS); return -1; } @@ -150,6 +140,7 @@ int free_pkg(struct package* pkg) if (pkg->license != NULL) free(pkg->license); if (pkg->type != NULL) free(pkg->type); if (pkg->url != NULL) free(pkg->url); + if (pkg->path != NULL) free(pkg->path); if (pkg->info.make != NULL) free(pkg->info.make); if (pkg->info.special != NULL) free(pkg->info.special); @@ -207,57 +198,45 @@ struct packages get_pkgs(char* path) char **files_array = get_all_files(path, path, &num_files); if (files_array != NULL) { - packages pkgs = create_pkgs(num_files); + struct packages pkgs = create_pkgs(num_files); // Print each file path for (int j = 0; j < num_files; j++) { - char* path = strdup(files_array[j]); - char* name = strdup(files_array[j]); - - while(strtok(package_name, "/")) + if(strstr(files_array[j], ".ecmp") != NULL) { - char* tmp = name; - name = strchr(package_name, '\0') + 1; - if(*name == '\0') + char* path = strdup(files_array[j]); + char* name = strdup(files_array[j]); + + while(strtok(name, "/")) { - name = tmp; - break; + char* tmp = name; + name = strchr(name, '\0') + 1; + if(*name == '\0') + { + name = tmp; + break; + } } - } - dbg(1, "path is %s, name is %s", path, name); + dbg(1, "path is %s, name is %s", path, name); + + + struct package pkg = {0}; + pkg.name = strdup(name); + pkg.path = strdup(path); - // Free each file path string - free(files_array[i]); - free(path); + push_pkg(&pkgs, &pkg); + + // Free each file path string + free(path); + } + free(files_array[j]); } // Free the array of file paths free(files_array); } else { - msg(ERROR, "Repository %s empty", REPOS[i]); + msg(ERROR, "Path %s empty", path); } } - -// Get all packages from a directory -struct packages get_pkgs_from_repos() -{ - char** REPOS = calloc(512,sizeof(char*)); - int num_repos = get_repos(REPOS) - if(num_repos < 2) - { - msg(FATAL, "No local repositories"); - } - - struct packages pkgs = create_pkgs(0); - for(int i = 1; i < num_repos; i++) - { - char* path = calloc(MAX_PATH, 1); - sprintf(path, "%s/%s", getenv("SOVIET_REPOS_DIR"), REPOS[i]); - struct packages result = get_pkgs(path); - merge_pkgs(&pkgs, &result); - } - - return pkgs; -} diff --git a/src/util.c b/src/util.c index 9454eda..3ff32b3 100644 --- a/src/util.c +++ b/src/util.c @@ -291,4 +291,10 @@ int download(char* url, FILE* fp) { curl_easy_cleanup(curl); } return 0; +} + +// Copy a file +int cp(char* from, char* to) +{ + return 1; } \ No newline at end of file From 305b2febaecc02760e51ed4c8b634541facec0e8 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Mon, 23 Dec 2024 04:36:31 +0100 Subject: [PATCH 05/23] minor fixes --- formats/ecmp/ecmp.c | 42 +++++------- include/libspm.h | 132 ++++++++++++++++------------------- makefile | 5 +- src/check.c | 29 +++++--- src/clean.c | 3 + src/config.c | 45 ++++++------ src/install.c | 151 +++++++++++++--------------------------- src/list_TBD.c | 6 +- src/make.c | 59 ++++------------ src/pkg.c | 98 +++++++++++++++----------- src/repo.c | 13 +++- src/uninstall.c | 2 +- src/update.c | 11 ++- src/util.c | 24 +++---- test/package.c | 40 ----------- test/spm.c | 22 +++--- test/test.c | 163 ++++++++++++++++++++++++++++++++++++++------ test/test.h | 4 -- 18 files changed, 424 insertions(+), 425 deletions(-) delete mode 100644 test/package.c diff --git a/formats/ecmp/ecmp.c b/formats/ecmp/ecmp.c index 2eb2f6b..4e39ece 100644 --- a/formats/ecmp/ecmp.c +++ b/formats/ecmp/ecmp.c @@ -47,37 +47,33 @@ int open(char* path,struct package* pkg) void* parsers[][3] = { {parseinfo,pkg,NULL}, - {parseraw,&pkg->info.make,NULL}, {parseraw,&pkg->info.install,NULL}, - {parseraw,&pkg->info.download,NULL}, {parseraw,&pkg->info.prepare,NULL}, {parseraw,&pkg->info.special,NULL}, {parsenl,&pkg->files,&pkg->filesCount}, {parsenl,&pkg->dependencies,&pkg->dependenciesCount}, {parsenl,&pkg->optional,&pkg->optionalCount}, - {parsenl,&pkg->inputs,&pkg->inputsCount}, + {parsenl,&pkg->locations,&pkg->locationsCount}, - {parseraw,&pkg->info.description,NULL}, - {parsenl,&pkg->exports,&pkg->exportsCount} + {parseraw,&pkg->description,NULL}, + {parsenl,&pkg->config,&pkg->configCount} }; void* pairs[][2] = { {"info",parsers[0]}, - {"make",parsers[1]}, - {"install",parsers[2]}, - {"download",parsers[3]}, - {"prepare",parsers[4]}, - {"special",parsers[5]}, - - {"files",parsers[6]}, - {"dependencies",parsers[7]}, - {"optional",parsers[8]}, - {"inputs",parsers[9]}, - {"locations",parsers[10]}, - {"description",parsers[11]}, - {"exports",parsers[12]}, + {"install",parsers[1]}, + {"prepare",parsers[2]}, + {"special",parsers[3]}, + + {"files",parsers[4]}, + {"dependencies",parsers[5]}, + {"optional",parsers[6]}, + + {"locations",parsers[7]}, + {"description",parsers[8]}, + {"config",parsers[9]}, {NULL,NULL} }; @@ -87,7 +83,6 @@ int open(char* path,struct package* pkg) {"type",&pkg->type}, {"url",&pkg->url}, {"license",&pkg->license}, - {"sha256",&pkg->sha256}, {"environment",&pkg->environment}, {NULL,NULL} }; @@ -221,7 +216,8 @@ unsigned int getsections(char* path,section*** sections) { (void)current; unsigned int alloc = 0; - while ((read = getline(&line,&len,fp)) != EOF) { + while ((read = getline(&line,&len,fp)) != EOF) + { if (line[0] == '#' || line[0] == '\n' || strlen(line) < 2) { continue; } @@ -246,6 +242,7 @@ unsigned int getsections(char* path,section*** sections) { } strcat((*sections)[sectionscount-1]->buff,line); } + free(line); return sectionscount; } @@ -259,15 +256,13 @@ int create(const char* path,struct package* pkg) // i love hashmaps but here we'll use maparray // we have the list[0] = section and list[1] = function to do stuff void* list[][3] = { - {"download",pkg->info.download,NULL}, {"prepare",pkg->info.prepare,NULL}, - {"make",pkg->info.make,NULL}, {"install",pkg->info.install,NULL}, {"special",pkg->info.special,NULL}, {"dependencies",pkg->dependencies,&pkg->dependenciesCount}, {"optional",pkg->optional,&pkg->optionalCount}, - {"description",pkg->info.description,NULL}, + {"description",pkg->description,NULL}, {"locations",pkg->locations,&pkg->locationsCount}, }; @@ -287,7 +282,6 @@ int create(const char* path,struct package* pkg) if (pkg->type != NULL) fprintf(ecmp,"type = %s\n",pkg->type); if (pkg->license != NULL) fprintf(ecmp,"license = %s\n",pkg->license); if (pkg->url != NULL) fprintf(ecmp,"url = %s\n",pkg->url); - if (pkg->sha256 != NULL) fprintf(ecmp,"sha256 = %s\n",pkg->sha256); fprintf(ecmp,"\n"); // for improved readability for (unsigned int i = 0;i < sizeof(list) / sizeof(list[0]);i++ ) diff --git a/include/libspm.h b/include/libspm.h index da4edf0..fbf1211 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -11,13 +11,10 @@ struct cmd { // Commands - char* make; char* test; char* prepare; char* install; char* special; - char* download; - char* description; }; struct package @@ -27,7 +24,6 @@ struct package char* type; // for the type at first i used an enum but im lazy and its stupid; char* version; char* license; - char* sha256; char* url; char* environment; @@ -36,6 +32,8 @@ struct package char* format; // + char* description; + char** files; int filesCount; @@ -44,17 +42,13 @@ struct package char** optional; int optionalCount; + + char ** config; + int configCount; char ** locations; int locationsCount; - - char ** inputs; - int inputsCount; - - char ** exports; - int exportsCount; - - + // cmds struct cmd info; @@ -67,74 +61,47 @@ struct packages struct package* buffer; }; -// List of installed packages -int list_installed(); - -// num. of installed packages -int count_installed(); - -// Serach for a package by term -char** search(char *term, int *num_results); - -// Check what packages need updating -int update(); - -// Upgrade all packages that need updating -int upgrade(); - -// Create links for the package -void create_links(char build_loc[4096], char dest_loc[4096]); - -// Get all repositories currently present -int get_repos(char** list); - -// Clone a git repository -int add_repo(char* name, char* url); - -// Cleanup unneded files after a package is installed -void clean_install(); - -// Function to install a package from source with a specific format -int install_package_source(struct package* pkg); - -// Function to uninstall packages -int uninstall(char* name); - +/*check.c*/ // Function to check if a package is installed and untouched -int check(const char* name); - -// Function to retrieve a package from a data repository -char* get(struct package *i_pkg, const char* repo, const char* out_path); - -// Function to move binaries to the correct locations -void move_binaries(char** locations,long loc_size); - -// build a package from source -int make (char* package_dir,struct package* pkg); - -// execute post install scripts -int exec_special(const char* cmd,const char* package_dir); - -// update the system -int update(); +int check(struct package* pkg); +// Function to check the existence of package locations +int check_locations(char** locations, int locationsCount); +/*clean.c*/ // Function to clean working directories int clean(); +// Function to clean unneeded files after install +void clean_install(); -// Function to synchronize the local repository with a remote repository -int repo_sync(); +/*config.c*/ +// Read a config file +int readConfig(const char* configFilePath, int overwrite); -// init the system +/*globals.c*/ +/*see globals.h*/ + +/*hashtable.c*/ +/*see hashtable.h*/ + +/*init.c*/ +// Function to initialize the Soviet Package Manager void init(); -// Read the soviet config -int readConfig(const char* configFilePath, int overwrite); +/*install.c*/ +// Function to install a package from source +int install_package_source(struct package* pkg); +// Function to write the package configuration file +void write_package_configuration_file(struct package* pkg); +// Function to read the package configuration file +void read_package_configuration_file(struct package* pkg); -// Function to check the existence of package locations -int check_locations(char** locations,int locationsCount); +/*make.c*/ +// Function to build and install a package +int make(struct package* pkg); -// Function to check if a package is already installed -bool is_installed(const char* name); +/*move.c*/ +// Function to move binaries to the correct locations +void move_binaries(char** locations, long loc_size); /*pkg.c*/ // Allocate an array of packages @@ -146,16 +113,34 @@ void push_pkg(struct packages* pkgs, struct package* pkg); // Pop the last added package from the array struct package* pop_pkg(struct packages* pkgs); // Open a package from the given path and populate the package structure -int open_pkg(const char* path, struct package* pkg, const char* format); +int open_pkg(const char* path, struct package* pkg); // Create a package at the given path using the specified format and package structure -int create_pkg(struct package* pkg); +int create_pkg(char* in_path, struct package* pkg); // Function to free memory allocated for a package structure int free_pkg(struct package* pkg); +// Function to check if a given package is already in the file tree +int is_installed_pkg(char* path, struct package* pkg); // Create the database that stores all packages in a directory int create_pkg_db(char* db_path, struct packages* pkgs); // Get all packages from a directory struct packages get_pkgs(char* path); +/*repo.c*/ +// Get currently present repos +int get_repos(char** list); +// Function to synchronize the local repository with a remote repository +int repo_sync(); +// Add a new repository from a git repo +int add_repo(char* name, char* url); + +/*uninstall.c*/ +// Function to uninstall packages +int uninstall(char* name); + +/*update.c*/ +// Function to update a package +int update(); + /*util.c*/ // Recursively remove a directory and its contents int rmrf(char *path); @@ -164,7 +149,7 @@ int rmany(char* path); // Quit the program with the given status code and display an error message if status is not 0 void quit(int status); // Function to recursively retrieve all files in a directory and its subdirectories -char **get_all_files(const char* root, const char *path, int *num_files); +char **get_all_files(const char* root, char *path, int *num_files); // Load a format plugin, execute a specific function, and close the plugin int runFormatLib(const char* format, const char* fn, const char* pkg_path, struct package* pkg); // A function to retrieve the version number of the libspm library. @@ -174,4 +159,5 @@ float version(); int parse_env(char** in); // Download a file from url into FILE int download(char* url, FILE* fp); +// Copy a file int cp(char* from, char* to); \ No newline at end of file diff --git a/makefile b/makefile index 9155b7a..1389c7b 100755 --- a/makefile +++ b/makefile @@ -30,7 +30,7 @@ SDIR = src CFLAGS = -Wall -fPIC -O2 -Wextra -L./bin -Iinclude -DBGFLAGS = -g -fsanitize=address +DBGFLAGS = -g -fsanitize=address -lasan # set local lib to lib/*/*.a LOCAL_LIBS = $(wildcard lib/*/*.a) @@ -72,8 +72,7 @@ $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c test: - $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) - $(CC) $(CFLAGS) -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/package.c ${DEVDIR}/test.c $(LIBS) -o bin/package-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) + $(CC) $(CFLAGS) -lasan -DSTATIC ${FMT_DIR}/*/* ${DEVDIR}/spm.c ${DEVDIR}/test.c $(LIBS) -o bin/spm-test -lspm -L./bin -D MEMCHECK=$(MEMCHECK) @echo "Test binary created" check-all: diff --git a/src/check.c b/src/check.c index 47dc5f1..39be800 100755 --- a/src/check.c +++ b/src/check.c @@ -1,7 +1,9 @@ // Include necessary header files for the code #include "libspm.h" // Custom library for package management -#include "unistd.h" // Standard library for system calls -#include "stdio.h" // Standard I/O library for file operations +#include "cutils.h" + +#include // Standard library for system calls +#include // Standard I/O library for file operations #include // Standard library for general functions // Function to check if a package is installed and untouched @@ -16,30 +18,34 @@ - 2: Package is corrupted (package data file is here but with no location info). - 3: Package is corrupted (Some locations aren't here). */ -int check(const char* name) +int check(struct package* pkg) { - char dataSpmPath[MAX_PATH]; - // Create the path to the package data file using environment variables - sprintf(dataSpmPath, "%s/%s", getenv("SOVIET_SPM_DIR"), name); + dbg(2, "Creating a path to the local package"); + + char dataSpmPath[MAX_PATH]; + sprintf(dataSpmPath, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->path); + dbg(2, "PATH: %s", dataSpmPath); // Checking if the package data file exists if (access(dataSpmPath, F_OK) != 0) { + dbg(2, "PATH does not exist"); return 1; // Exit code 1 indicates the package is not installed } - struct package pkg; - // Open the package data file and load its contents - open_pkg(dataSpmPath, &pkg, getenv("SOVIET_DEFAULT_FORMAT")); + dbg(2, "Opening the package"); + open_pkg(dataSpmPath, pkg); + dbg(2, "Checking package locations"); // If the package data file lacks location information, return exit code 2 - if (pkg.locationsCount == 0) { + if (pkg->locationsCount == 0) { + dbg(2, "The package is corrupted"); return 2; // Exit code 2 indicates the package is corrupted (no location info) } // Check the existence of package locations and return the appropriate exit code - return check_locations(pkg.locations, pkg.locationsCount); + return check_locations(pkg->locations, pkg->locationsCount); } // Function to check the existence of package locations @@ -58,6 +64,7 @@ int check_locations(char** locations, int locationsCount) for (int i = 0; i < locationsCount; i++) { // If a location doesn't exist, return exit code 3 if (access(locations[i], F_OK) != 0) { + dbg(2, "The package is corrupted (some locations are missing)"); return 3; // Exit code 3 indicates the package is corrupted (some locations are missing) } } diff --git a/src/clean.c b/src/clean.c index c05604d..1e630e0 100755 --- a/src/clean.c +++ b/src/clean.c @@ -48,5 +48,8 @@ void clean_install() rmany(full_cleanup_path); } + free(full_cleanup_path); } + free(cleanup_loc); + free(cleanups); } \ No newline at end of file diff --git a/src/config.c b/src/config.c index affa177..ca8c397 100755 --- a/src/config.c +++ b/src/config.c @@ -15,27 +15,27 @@ typedef struct { } ConfigEntry; ConfigEntry configEntries[] = { - { "SOVIET_ROOT", "/" }, - { "SOVIET_USER_ROOT", "~/.local/" }, - { "SOVIET_DEFAULT_FORMAT", "ecmp" }, - { "SOVIET_MAIN_DIR", "/var/cccp" }, - { "SOVIET_WORK_DIR", "/var/cccp/work" }, - { "SOVIET_CONFIG_FILE", "/etc/cccp.conf" }, - { "SOVIET_REPOS_DIR", "/var/cccp/sources" }, - { "SOVIET_SPM_DIR", "/var/cccp/spm" }, - { "SOVIET_LOG_DIR", "/var/cccp/log" }, - { "SOVIET_PLUGIN_DIR", "/var/cccp/plugins" }, - { "SOVIET_BUILD_DIR", "/var/cccp/work/build" }, - { "SOVIET_MAKE_DIR", "/var/cccp/work/make" }, - { "MAKE_FLAGS", "-j1" }, - { "SOVIET_DEFAULT_REPO", "OUR" }, - { "SOVIET_DEFAULT_REPO_URL", "https://github.com/Soviet-Linux/OUR.git" }, - { "SOVIET_FORMATS", "ecmp" }, - { "SOVIET_SOURCE_DIR", "/usr/src/cccp" }, - { "SOVIET_ENV_DIR", "/etc/cccp" }, - { "SOVIET_CLEANUP", "/usr/share/info/dir:/usr/share/doc/" }, - { "SOVIET_ALL_DB", "/var/cccp/all.db" }, - { "SOVIET_INSTALLED_DB", "/var/cccp/installed.db" }, + { "SOVIET_ROOT" , "/" }, + { "SOVIET_USER_ROOT" , "~/.local/" }, + { "SOVIET_DEFAULT_FORMAT" , "ecmp" }, + { "SOVIET_MAIN_DIR" , "/var/cccp" }, + { "SOVIET_WORK_DIR" , "/var/cccp/work" }, + { "SOVIET_CONFIG_FILE" , "/etc/cccp.conf" }, + { "SOVIET_REPOS_DIR" , "/var/cccp/sources" }, + { "SOVIET_SPM_DIR" , "/var/cccp/spm" }, + { "SOVIET_LOG_DIR" , "/var/cccp/log" }, + { "SOVIET_PLUGIN_DIR" , "/var/cccp/plugins" }, + { "SOVIET_BUILD_DIR" , "/var/cccp/work/build" }, + { "SOVIET_MAKE_DIR" , "/var/cccp/work/make" }, + { "SOVIET_DEFAULT_REPO" , "OUR" }, + { "SOVIET_DEFAULT_REPO_URL" , "https://github.com/Soviet-Linux/OUR.git" }, + { "SOVIET_FORMATS" , "ecmp" }, + { "SOVIET_SOURCE_DIR" , "/usr/src/cccp" }, + { "SOVIET_ENV_DIR" , "/etc/cccp" }, + { "SOVIET_CLEANUP" , "/usr/share/info/dir:/usr/share/doc/" }, + { "SOVIET_ALL_DB" , "/var/cccp/all.db" }, + { "SOVIET_INSTALLED_DB" , "/var/cccp/installed.db" }, + { "MAKE_FLAGS" , "-j1" }, // Add more key-value pairs with default values as needed }; @@ -48,7 +48,6 @@ int readConfig(const char* configFilePath, int overwrite) msg(FATAL, "Tried to use non-existing config"); } - dbg(2, "config: %s", configFilePath); dbg(2, "config: %s", configFilePath); FILE* file = fopen(configFilePath, "r"); dbg(2, "file is readed"); @@ -78,7 +77,7 @@ int readConfig(const char* configFilePath, int overwrite) char* line = calloc(1024, 1); while (fgets(line, 1024, file)) { - line[strlen(line) - 1] = 0; + line[strlen(line)] = 0; parse_env(&line); if(((line[0] != '#') && ((line[0] != '/') && (line[1] != '/'))) && (strstr(line, "=") != 0)) diff --git a/src/install.c b/src/install.c index 964b9e5..aee192d 100755 --- a/src/install.c +++ b/src/install.c @@ -62,11 +62,6 @@ int install_package_source(struct package* pkg) { setenv("LICENSE", pkg->license, 1); } - - if (pkg->sha256 != NULL) - { - setenv("SHA256", pkg->sha256, 1); - } } // Check if a package is a collection @@ -74,11 +69,10 @@ int install_package_source(struct package* pkg) { // Legacy directory path for compatibility char legacy_dir[MAX_PATH]; + sprintf(legacy_dir, "%s/%s-%s", getenv("SOVIET_MAKE_DIR"), pkg->name, pkg->version); // Build the package { - sprintf(legacy_dir, "%s/%s-%s", getenv("SOVIET_MAKE_DIR"), pkg->name, pkg->version); - // ... chmod(getenv("SOVIET_MAKE_DIR"), 0777); chmod(getenv("SOVIET_BUILD_DIR"), 0777); @@ -87,31 +81,39 @@ int install_package_source(struct package* pkg) int status = 0; if ( p == 0) { - if (getuid() == 0) + // Ensure that the build is done as a regular user { - /* process is running as root, drop privileges */ - if (setgid(65534) != 0) + if (getuid() == 0) { - msg(ERROR, "setgid: Unable to drop group privileges"); - } - if (setuid(65534) != 0) - { - msg(ERROR, "setuid: Unable to drop user privileges"); + // process is running as root, drop privileges + if (setgid(65534) != 0) + { + msg(ERROR, "setgid: Unable to drop group privileges"); + } + if (setuid(65534) != 0) + { + msg(ERROR, "setuid: Unable to drop user privileges"); + } } } + // Build the package dbg(1, "Making %s", pkg->name); - if (make(legacy_dir, pkg) != 0) { - msg(ERROR, "Failed to make %s", pkg->name); - exit(1); - } + make(pkg); exit(0); } - while(wait(&status) > 0); + else + { + waitpid(p, &status, 0); + } + if(WIFSIGNALED(status)) + { + msg(FATAL, "WIFSIGNALED"); + } if(WEXITSTATUS(status) != 0) { - msg(FATAL, "make exited with error code %d", pkg->name, WEXITSTATUS(status)); + msg(FATAL, "make exited with error code %d", WEXITSTATUS(status)); } dbg(1, "Making %s done", pkg->name); @@ -148,7 +150,7 @@ int install_package_source(struct package* pkg) dbg(1, "Got %d locations for %s", pkg->locationsCount, pkg->name); // Check if the package is already installed - if (is_installed(pkg->name)) { + if (is_installed_pkg(getenv("SOVIET_SPM_DIR"), pkg)) { msg(WARNING, "Package %s is already installed, reinstalling", pkg->name); uninstall(pkg->name); } else { @@ -175,34 +177,20 @@ int install_package_source(struct package* pkg) } } - create_pkg(pkg); + if(create_pkg(getenv("SOVIET_SPM_DIR"), pkg) != 0) return 1; + dbg(1, "Package %s installed", pkg->name); - + // Clean up clean(); - - // Remove the package from the queue - QUEUE_COUNT--; - PACKAGE_QUEUE[QUEUE_COUNT] = NULL; - return 0; } /* Warning: there is something sussy going on beyond this point */ -void configure_package(struct package* pkg) +void write_package_configuration_file(struct package* pkg) { - // Get global environment variables - if (pkg->environment != NULL) - { - dbg(1, "Getting environment variables..."); - char* env_path = calloc(MAX_PATH, 1); - sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->environment); - - readConfig(env_path, 1); - } - // Set global environment variables - if (pkg->exports != NULL && pkg->exportsCount > 0 && strlen(pkg->exports[0]) > 0) + if (pkg->config != NULL && pkg->configCount > 0 && strlen(pkg->config[0]) > 0) { dbg(1, "Setting environment variables..."); char* env_path = calloc(MAX_PATH, 1); @@ -211,79 +199,34 @@ void configure_package(struct package* pkg) FILE *env_file; env_file = fopen(env_path, "w"); - for (int i = 0; i < pkg->exportsCount; i++) + for (int i = 0; i < pkg->configCount; i++) { - fprintf(env_file, "%s\n", pkg->exports[i]); - char* line = strdup(pkg->exports[i]); - parse_env(&line); - - if(((line[0] != '#') && ((line[0] != '/') && (line[1] != '/'))) && (strstr(line, "=") != 0)) - { - char* key = strtok(line, "="); - char* value = strchr(line, '\0') + 1; - - if (key == NULL || value == NULL) - { - msg(ERROR, "Invalid config file"); - } - - dbg(2, "Key: %s Value: %s", key, value); - - // Set environment variables based on the key-value pairs in the config file - setenv(key, value, 1); - } - free(line); + fprintf(env_file, "%s\n", pkg->config[i]); } fclose(env_file); } } -// Function to check if a package is already installed -/* -Accepts: -- const char* name: Name of the package to check. - -Returns: -- bool: A boolean value indicating whether the package is installed. - - true: Package is installed. - - false: Package is not installed. -*/ -bool is_installed(const char* name) +void read_package_configuration_file(struct package* pkg) { - char path[1024]; - char** FORMATS; - int FORMAT_COUNT = splita(strdup(getenv("SOVIET_FORMATS")),' ',&FORMATS); - - char** REPOS = calloc(512,sizeof(char)); - int REPO_COUNT = get_repos(REPOS); - - // loop through all formats - for (int i = 0; i < FORMAT_COUNT; i++) + // Get global environment variables + if (pkg->environment != NULL) { - // loop through all repos - for (int j = 0; j < REPO_COUNT; j++) - { - sprintf(path,"%s/%s/%s.%s",getenv("SOVIET_SPM_DIR"), REPOS[j],name,FORMATS[i]); - if (access(path,F_OK) == 0) - { - free(REPOS); - free(FORMATS); - return true; - } - } + dbg(1, "Getting environment variables..."); + char* env_path = calloc(MAX_PATH, 1); + sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->environment); + + readConfig(env_path, 1); } - return false; -} -void add_to_queue(char* name) -{ - // Add the package name to the queue - PACKAGE_QUEUE[QUEUE_COUNT] = name; - QUEUE_COUNT++; - if (QUEUE_COUNT > QUEUE_MAX) + + // Set global environment variables + if (pkg->config != NULL && pkg->configCount > 0 && strlen(pkg->config[0]) > 0) { - msg(FATAL, "Package tree too large"); - } + dbg(1, "Setting environment variables..."); + char* env_path = calloc(MAX_PATH, 1); + sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->name); - dbg(1, "Added %s to the queue", name); + readConfig(env_path, 1); + } } \ No newline at end of file diff --git a/src/list_TBD.c b/src/list_TBD.c index 0ec889f..9ce7818 100644 --- a/src/list_TBD.c +++ b/src/list_TBD.c @@ -12,7 +12,7 @@ // Function to count the number of installed packages int count_installed() { - const char *path = getenv("SOVIET_SPM_DIR"); + char *path = getenv("SOVIET_SPM_DIR"); int num_files; char **files_array = get_all_files(path, path, &num_files); if (files_array != NULL) { @@ -27,7 +27,7 @@ int count_installed() { // Function to list all installed packages int list_installed() { - const char *path = getenv("SOVIET_SPM_DIR"); + char *path = getenv("SOVIET_SPM_DIR"); int num_files; char **files_array = get_all_files(path, path, &num_files); if (files_array != NULL) { @@ -56,7 +56,7 @@ int list_installed() { // Function to search for a term in installed files char ** search(char *term, int *num_results) { int found = 0; - const char *path = getenv("SOVIET_REPOS_DIR"); + char *path = getenv("SOVIET_REPOS_DIR"); int num_files; char **files_array = get_all_files(path, path, &num_files); char **searched_array = NULL; diff --git a/src/make.c b/src/make.c index 24c062e..ac4f5b6 100755 --- a/src/make.c +++ b/src/make.c @@ -23,9 +23,7 @@ - -2: Failed to install the package. - -3: No install command found. */ -int make(char* package_dir, struct package* pkg) { - char* make_dir = getenv("SOVIET_MAKE_DIR"); - +int make(struct package* pkg) { char* cmd_params; if (QUIET) { cmd_params = "&> /dev/null"; @@ -33,12 +31,6 @@ int make(char* package_dir, struct package* pkg) { cmd_params = ""; } - // TODO: this - // Thinking about putting the package caching here - // Maybe it will check if the installed version matches $VERSION - // If so, it will just copy the dir from /usr/src/$NAME-$VERSION - // Instead of executing the following: - // // Parse the files for (int i = 0; i < pkg->filesCount; i++) { @@ -96,7 +88,7 @@ int make(char* package_dir, struct package* pkg) { if (buffer == NULL) { msg(FATAL, "Could not verify the file's hash"); - return -1; + return 2; } SHA256((unsigned char*) buffer, size, hash); @@ -106,12 +98,12 @@ int make(char* package_dir, struct package* pkg) { msg(FATAL, "Could not verify the file's hash"); return -1; }*/ - dbg(1, "Hash is %s", file_sha256); for(int k = 0; k < SHA256_DIGEST_LENGTH; k++) { char* temp = calloc(8, 1); sprintf(temp, "%02x", hash[k]); strcat(hash_str, temp); + free(temp); } dbg(1, "Got %s", hash_str); @@ -123,70 +115,43 @@ int make(char* package_dir, struct package* pkg) { dbg(1, "Download finished"); - cp(location, source_file_location); + //cp(location, source_file_location); } else { dbg(1, "Loading form %s", source_location); - cp(source_file_location, location); + //cp(source_file_location, location); } - free(files); + free(files); free(location); free(source_location); free(source_file_location); } - // Download package sources - if (pkg->info.download != NULL && strlen(pkg->info.download) > 0) { - char sources_cmd[64 + strlen(make_dir) + strlen(pkg->info.download)]; - - sprintf(sources_cmd, "(cd %s && %s) %s ", make_dir, pkg->info.download, cmd_params); - dbg(2, "Downloading sources with %s", sources_cmd); - int res = system(sources_cmd); - - if (res != 0) { - msg(ERROR, "Failed to download sources for %s", pkg->name); - return -1; - } - } - // Run 'prepare' command if (pkg->info.prepare != NULL && strlen(pkg->info.prepare) > 0) { - char prepare_cmd[64 + strlen(package_dir) + strlen(pkg->info.prepare) + strlen(cmd_params)]; + char prepare_cmd[64 + strlen(getenv("SOVIET_MAKE_DIR")) + strlen(pkg->info.prepare) + strlen(cmd_params)]; - sprintf(prepare_cmd, "( cd %s && %s ) %s", package_dir, pkg->info.prepare, cmd_params); + sprintf(prepare_cmd, "( cd %s && %s ) %s", getenv("SOVIET_MAKE_DIR"), pkg->info.prepare, cmd_params); dbg(2, "Executing prepare command: %s", prepare_cmd); if (system(prepare_cmd) != 0) { msg(FATAL, "Failed to prepare %s", pkg->name); - return -2; + return 2; } dbg(1, "Prepare command executed!"); } - // Run 'make' command - if (pkg->info.make && strlen(pkg->info.make)) { - char make_cmd[64 + strlen(package_dir) + strlen(pkg->info.make) + strlen(cmd_params)]; - sprintf(make_cmd, "( cd %s && %s ) %s", package_dir, pkg->info.make, cmd_params); - - dbg(2, "Executing make command: %s", make_cmd); - if (system(make_cmd) != 0) { - return 1; - } - dbg(1, "Make command executed!"); - } - // Run 'test' command (if in testing mode) if (pkg->info.test != NULL && TESTING && strlen(pkg->info.test) > 0) { - char test_cmd[64 + strlen(package_dir) + strlen(pkg->info.test) + strlen(cmd_params)]; - sprintf(test_cmd, "( cd %s && %s ) %s", package_dir, pkg->info.test, cmd_params); + char test_cmd[64 + strlen(getenv("SOVIET_MAKE_DIR")) + strlen(pkg->info.test) + strlen(cmd_params)]; + sprintf(test_cmd, "( cd %s && %s ) %s", getenv("SOVIET_MAKE_DIR"), pkg->info.test, cmd_params); dbg(2, "Executing test command: %s", test_cmd); if (system(test_cmd) != 0) { - return 1; + return 2; } dbg(1, "Test command executed!"); } - return 0; } \ No newline at end of file diff --git a/src/pkg.c b/src/pkg.c index 6173284..291d7f3 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -52,39 +52,32 @@ struct package* pop_pkg(struct packages* pkgs) } // Open a package from the given path and populate the package structure -int open_pkg(const char* path, struct package* pkg, const char* format) +int open_pkg(const char* path, struct package* pkg) { - dbg(2, "Setting everything to NULL"); - // Set all variables to NULL - memset(pkg, 0, sizeof(struct package)); - - // Print make dependencies count - dbg(3, "make dependencies count: %d", pkg->optionalCount); dbg(3, "path: %s", path); - // Check if the file exists if (access(path, F_OK) != 0) { msg(ERROR, "File %s does not exist\n", path); return 1; } - // Check file extension - if (format == NULL) { - dbg(2, "Getting format from file extension"); - format = strrchr(path, '.') + 1; - dbg(1, "Format: %s\n", format); - } + dbg(2, "Getting format from file extension"); + char* format = strrchr(path, '.') + 1; + dbg(1, "Format: %s", format); char** FORMATS; int FORMAT_COUNT = splita(getenv("SOVIET_FORMATS"), ' ', &FORMATS); if (format != NULL) { // This is experimental - for (int i = 0; i < FORMAT_COUNT; i++) { - dbg(2, "format: %s = %s\n", format, FORMATS[i]); - if (strcmp(format, FORMATS[i]) == 0) { + for (int i = 0; i < FORMAT_COUNT; i++) + { + dbg(2, "format: %s = %s", format, FORMATS[i]); + if (strcmp(format, FORMATS[i]) == 0) + { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "open", path, pkg); + free(FORMATS); return 0; } } @@ -96,12 +89,14 @@ int open_pkg(const char* path, struct package* pkg, const char* format) return 1; } -// Create a package at the given path using the specified format and package structure -int create_pkg(struct package* pkg) +// Create a package at the given path using the specified package structure +int create_pkg(char* in_path, struct package* pkg) { char path[MAX_PATH]; - sprintf(path, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->path); + sprintf(path, "%s/%s", in_path, pkg->path); + // This might seem stupid + // and it is if(isdir(path) != 0) { pmkdir(path); @@ -111,7 +106,7 @@ int create_pkg(struct package* pkg) msg(INFO, "Creating package %s", path); char** FORMATS; - int FORMAT_COUNT = splita(strdup(getenv("SOVIET_FORMATS")),' ',&FORMATS); + int FORMAT_COUNT = splita(getenv("SOVIET_FORMATS"),' ',&FORMATS); if (pkg->format != NULL) { @@ -122,14 +117,14 @@ int create_pkg(struct package* pkg) { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "create", path, pkg); - free(FORMATS[i]); + free(FORMATS); return 0; } } } msg(ERROR,"File %s is not a valid package file, or the format plugin isn't loaded", path); free(FORMATS); - return -1; + return 1; } // Function to free memory allocated for a package structure @@ -140,35 +135,58 @@ int free_pkg(struct package* pkg) if (pkg->license != NULL) free(pkg->license); if (pkg->type != NULL) free(pkg->type); if (pkg->url != NULL) free(pkg->url); - if (pkg->path != NULL) free(pkg->path); + if (pkg->description != NULL) free(pkg->description); - if (pkg->info.make != NULL) free(pkg->info.make); - if (pkg->info.special != NULL) free(pkg->info.special); - if (pkg->info.download != NULL) free(pkg->info.download); if (pkg->info.install != NULL) free(pkg->info.install); + if (pkg->info.special != NULL) free(pkg->info.special); if (pkg->info.prepare != NULL) free(pkg->info.prepare); if (pkg->info.test != NULL) free(pkg->info.test); - if (pkg->locations) { - if (*pkg->locations) free(*pkg->locations); + if (pkg->locations) + { + for(int i = 0; i < pkg->locationsCount; i++) + { + free(pkg->locations[i]); + } free(pkg->locations); } - if (pkg->dependencies) { - if (*pkg->dependencies) free(*pkg->dependencies); + if (pkg->dependencies) + { + for(int i = 0; i < pkg->dependenciesCount; i++) + { + free(pkg->dependencies[i]); + } free(pkg->dependencies); } - if (pkg->optional) { - if (*pkg->optional) free(*pkg->optional); + if (pkg->optional) + { + for(int i = 0; i < pkg->optionalCount; i++) + { + free(pkg->optional[i]); + } free(pkg->optional); } - if (pkg->files) { - if (*pkg->files) free(*pkg->files); + if (pkg->files) + { + for(int i = 0; i < pkg->filesCount; i++) + { + free(pkg->files[i]); + } free(pkg->files); } return 0; } +// Function to check if a given package is already in the file tree +int is_installed_pkg(char* path, struct package* pkg) +{ + (void)path; + (void)pkg; + return 0; +} + // Create the database that stores all packages in a directory +/* int create_pkg_db(char* db_path, struct packages* pkgs) { remove(db_path); @@ -186,10 +204,11 @@ int create_pkg_db(char* db_path, struct packages* pkgs) msg(FATAL, "SQL error when creating pkg_table"); } - char* ins = "INSERT INTO Packages VALUES (?,?)"; + //char* ins = "INSERT INTO Packages VALUES (?,?)"; - sqlite3_close(&db); + sqlite3_close(db); } +*/ // Get all packages from a directory struct packages get_pkgs(char* path) @@ -233,10 +252,13 @@ struct packages get_pkgs(char* path) free(files_array[j]); } // Free the array of file paths + return pkgs; free(files_array); } else { msg(ERROR, "Path %s empty", path); + struct packages pkgs = {0}; + return pkgs; } -} +} \ No newline at end of file diff --git a/src/repo.c b/src/repo.c index 2845eec..b353c4b 100755 --- a/src/repo.c +++ b/src/repo.c @@ -132,8 +132,17 @@ int add_repo(char* name, char* url) // Set clone options unsigned int* status = NULL; - git_submodule_update_options opts = GIT_CLONE_OPTIONS_INIT; - git_fetch_options fopts = GIT_FETCH_OPTIONS_INIT; + git_submodule_update_options opts = {0}; + if(git_submodule_update_options_init(&opts, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION)!= 0) + { + msg(FATAL, "Failed to initialize git submodule options"); + } + git_fetch_options fopts = {0}; + if(git_fetch_options_init(&fopts, GIT_SUBMODULE_UPDATE_OPTIONS_VERSION)!= 0) + { + msg(FATAL, "Failed to initialize git fetch options"); + } + opts.fetch_opts = fopts; opts.fetch_opts.depth = 1; diff --git a/src/uninstall.c b/src/uninstall.c index 95e4bae..ff22565 100755 --- a/src/uninstall.c +++ b/src/uninstall.c @@ -51,7 +51,7 @@ int uninstall(char* name) struct package r_pkg; // Open the package's SPM file and populate the r_pkg struct - open_pkg(dataSpmPath, &r_pkg, NULL); + open_pkg(dataSpmPath, &r_pkg); dbg(3, "Found %d locations", r_pkg.locationsCount); // Remove all the files in the data["locations"] diff --git a/src/update.c b/src/update.c index 711acc2..88a9787 100644 --- a/src/update.c +++ b/src/update.c @@ -7,17 +7,16 @@ #include "libspm.h" #include "cutils.h" -//should probably add there to the header when we are done - +// Function to update a package int update() { msg(INFO, "fetching updates"); int new_version_found = 0; - const char *path = getenv("SOVIET_SPM_DIR"); + char *path = getenv("SOVIET_SPM_DIR"); dbg(2, "path is %s", path); - const char *repo_path = getenv("SOVIET_REPOS_DIR"); + char *repo_path = getenv("SOVIET_REPOS_DIR"); dbg(2, "repo path is %s", repo_path); int num_files; char **files_array = get_all_files(path, path, &num_files); @@ -87,8 +86,8 @@ int update() sprintf(remote_path, "%s/%s/%s", repo_path, remote_repo, remote_package); dbg(2, "remote path is %s", remote_path); - open_pkg(local_path, local, "ecmp"); - open_pkg(remote_path, remote, "ecmp"); + open_pkg(local_path, local); + open_pkg(remote_path, remote); // Compare the versions if(strcmp(local->version, remote->version) != 0) diff --git a/src/util.c b/src/util.c index 3ff32b3..e585f67 100644 --- a/src/util.c +++ b/src/util.c @@ -19,6 +19,10 @@ // Callback function used by nftw to unlink files and directories int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { + (void)sb; + (void)typeflag; + (void)ftwbuf; + int rv = remove(fpath); if (rv) @@ -81,7 +85,7 @@ void quit(int status) } // Function to recursively retrieve all files in a directory and its subdirectories -char **get_all_files(const char* root, const char *path, int *num_files) +char **get_all_files(const char* root, char *path, int *num_files) { DIR *dir; struct dirent *entry; @@ -204,19 +208,14 @@ int parse_env(char** in) char* env = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_"; char* start = strchr(*in, '$'); char* end = NULL; - int i, start_i; + size_t i, start_i; if (start == NULL) { return 0; } - dbg(2, "Start: %s", start); - - start_i = strlen(*in) - strlen(start); - - dbg(2, "Start i: %d, from '%d' and '%d'", start_i, strlen(*in), strlen(start)); - + start_i = strlen(*in) - strlen(start); for (i = 1; i < strlen(start); i++) { end = strchr(env, start[i]); @@ -238,7 +237,7 @@ int parse_env(char** in) if(i + 1 == strlen(start)) { - end = " "; + end = ""; } } @@ -250,8 +249,7 @@ int parse_env(char** in) } var[--i] = '\0'; - dbg(2, "Var: %s", var); - dbg(2, "In: %s", *in); + dbg(2, "Found variable: %s", var); char* full_var = getenv(var); @@ -260,7 +258,7 @@ int parse_env(char** in) return 0; } - dbg(2, "Full var: %s", full_var); + dbg(2, "Substituting for: %s", full_var); char* full_in = calloc(strlen(*in) + strlen(full_var) + strlen(end) + 1, 1); @@ -296,5 +294,7 @@ int download(char* url, FILE* fp) { // Copy a file int cp(char* from, char* to) { + (void)from; + (void)to; return 1; } \ No newline at end of file diff --git a/test/package.c b/test/package.c deleted file mode 100644 index 696902c..0000000 --- a/test/package.c +++ /dev/null @@ -1,40 +0,0 @@ -// Tests disabled for now -#if 0 -// this file will be used by the our to check a package's validity. -// it replaces in this usage the test.c file, now only used for libspm testing. - -#include "test.h" - - -#define STATIC - -char WORKING_DIR[2048]; - -int main(int argc, char const *argv[]) -{ - - - // check for arguments - if (argc < 2) - { - printf("No arguments provided\n"); - return 1; - } - - // set debug level - setenv("SOVIET_DEBUG","3",1); - - char* spm_path = strdup(argv[1]); - - // check if file is a valid package - msg(INFO,"Checking package validity..."); - test_ecmp(spm_path); - msg(INFO,"Package is valid"); - msg(INFO,"Installing package..."); - test_pm(spm_path); - msg(INFO,"Package installed successfully"); - - return 0; -} - -#endif \ No newline at end of file diff --git a/test/spm.c b/test/spm.c index 6022b04..71e0bd9 100644 --- a/test/spm.c +++ b/test/spm.c @@ -1,10 +1,7 @@ -// Tests disabled for now -#if 1 #include "test.h" +#include "../include/libspm.h" #include -char WORKING_DIR[2048]; - int main() { msg(INFO,"Started LibSPM test suite..."); @@ -17,24 +14,19 @@ int main() DEBUG_UNIT = NULL; /* END LIBSPM CONFIG */ - char cwd[2048]; - getcwd(cwd, 2048); - sprintf(WORKING_DIR,"%s/test/assets",cwd); - - char TEST_SPM_PATH[2048]; - sprintf(TEST_SPM_PATH,"%s/vim.ecmp",WORKING_DIR); - // Check for root privileges for all other commands if (geteuid() != 0) { printf("You must have root privileges to run this command.\n"); return 1; } + setenv("SOVIET_TEST_DIR", "/tmp/cccp-test", 1); + rmany(getenv("SOVIET_TEST_DIR")); + pmkdir(getenv("SOVIET_TEST_DIR")); + test_check(); test_clean(); test_config(); - test_globals(); - test_init(); test_install(); test_make(); test_move(); @@ -49,6 +41,10 @@ int main() { msg(WARNING,"Leaks: %d",leaks); } + else + { + msg(INFO, "No leaks detected ;3"); + } msg(INFO,"Done testing LibSPM."); return 0; diff --git a/test/test.c b/test/test.c index cb835ef..e55c6f2 100644 --- a/test/test.c +++ b/test/test.c @@ -1,37 +1,160 @@ -// Tests disabled for now -#if 1 #include "test.h" #include "../include/libspm.h" -void test_check(char* spm_path) +void test_check() { - return; + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test", 1); + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf(ptr, "[locations]\n"); + fprintf(ptr, "/tmp/cccp-test/test.ecmp\n"); + fclose(ptr); + + struct package pkg = {0}; + pkg.path = "test.ecmp"; + int result = check(&pkg); + free_pkg(&pkg); + + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + rmany("/tmp/cccp-test/test.ecmp"); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); } void test_clean() { - return + char TEST_BUILD_DIR[MAX_PATH]; + char TEST_MAKE_DIR[MAX_PATH]; + + sprintf(TEST_BUILD_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_BUILD_DIR"); + sprintf(TEST_MAKE_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_MAKE_DIR"); + + setenv("SOVIET_BUILD_DIR", TEST_BUILD_DIR, 1); + setenv("SOVIET_MAKE_DIR", TEST_MAKE_DIR, 1); + + pmkdir(getenv("SOVIET_BUILD_DIR")); + pmkdir(getenv("SOVIET_MAKE_DIR")); + + int result = clean(); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + rmany(getenv("SOVIET_BUILD_DIR")); + rmany(getenv("SOVIET_MAKE_DIR")); + unsetenv("SOVIET_BUILD_DIR"); + unsetenv("SOVIET_MAKE_DIR"); } void test_config() { - return; -} - -void test_globals() -{ - return; -} - -void test_init() -{ - return; + setenv("SOVIET_TEST_ENV", "TEST", 1); + + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.conf","w"); + fprintf(ptr, "SOVIET_TEST_VAR=$SOVIET_TEST_ENV/TEST"); + fclose(ptr); + + int result = readConfig("/tmp/cccp-test/test.conf", 1); + + if((result != 0) || (strcmp(getenv("SOVIET_TEST_VAR"), "TEST/TEST") != 0)) + { + msg(ERROR, "EXPECTED: TEST/TEST"); + msg(ERROR, "GOT: %s", getenv("SOVIET_TEST_VAR")); + msg(FATAL, "FAILED"); + } + else msg(INFO, "PASSED"); + + unsetenv("SOVIET_TEST_ENV"); + unsetenv("SOVIET_TEST_VAR"); + rmany("/tmp/cccp-test/test.conf"); } void test_install() { - return; + int result = 0; + + // Define variables used during installation + { + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); + setenv("SOVIET_SOURCE_DIR", "/tmp/cccp-test/src_dir", 1); + + pmkdir("/tmp/cccp-test/spm_dir"); + pmkdir("/tmp/cccp-test/src_dir"); + + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + + char TEST_BUILD_DIR[MAX_PATH]; + char TEST_MAKE_DIR[MAX_PATH]; + + sprintf(TEST_BUILD_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_BUILD_DIR"); + sprintf(TEST_MAKE_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_MAKE_DIR"); + + setenv("SOVIET_BUILD_DIR", TEST_BUILD_DIR, 1); + setenv("SOVIET_MAKE_DIR", TEST_MAKE_DIR, 1); + + pmkdir(getenv("SOVIET_BUILD_DIR")); + pmkdir(getenv("SOVIET_MAKE_DIR")); + + } + // Create test package + { + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf( ptr, + "[info]\n" \ + "name = test\n" \ + "version = 0\n" \ + "type = src\n" \ + "[files]\n" \ + "$VERSION-file 127.0.0.1 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" \ + "[description]\n" \ + "test package\n" \ + "[prepare]\n" \ + "mkdir test-0\n" \ + "mv 0-file ./test-0/0-file\n" \ + "[install]\n" \ + "mv 0-file $SOVIET_BUILD_DIR/0-file\n" \ + "[special]\n" \ + "echo special...\n" + ); + + fclose(ptr); + } + + struct package pkg = {0}; + pkg.name = "test"; + pkg.path = "test.ecmp"; + pkg.format = "ecmp"; + + result += open_pkg("/tmp/cccp-test/test.ecmp", &pkg); + result += install_package_source(&pkg); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + // Cleanup + { + free_pkg(&pkg); + rmany(getenv("SOVIET_BUILD_DIR")); + rmany(getenv("SOVIET_MAKE_DIR")); + rmany(getenv("SOVIET_SPM_DIR")); + rmany(getenv("SOVIET_SOURCE_DIR")); + unsetenv("SOVIET_BUILD_DIR"); + unsetenv("SOVIET_MAKE_DIR"); + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + rmany("/tmp/cccp-test/test.ecmp"); + } } void test_make() @@ -41,12 +164,12 @@ void test_make() void test_move() { - return + return; } void test_pkg() { - return + return; } @@ -69,5 +192,3 @@ void test_util() { return; } - -#endif \ No newline at end of file diff --git a/test/test.h b/test/test.h index a1db99b..b207ecc 100644 --- a/test/test.h +++ b/test/test.h @@ -7,8 +7,6 @@ #include "../include/globals.h" #include "../include/cutils.h" -#define STATIC - void test_check(); void test_clean(); void test_config(); @@ -23,5 +21,3 @@ void test_uninstall(); void test_update(); void test_util(); -extern char WORKING_DIR[2048]; - From 80599200f69f5c9bd483e9aefb7576edcf0dc793 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Tue, 24 Dec 2024 01:30:18 +0100 Subject: [PATCH 06/23] minor fixes --- include/libspm.h | 15 +- src/check.c | 2 +- src/config.c | 4 + src/install.c | 12 +- src/pkg.c | 237 +++++++++++++++++++++------- test/test.c | 402 +++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 536 insertions(+), 136 deletions(-) diff --git a/include/libspm.h b/include/libspm.h index fbf1211..04719a3 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -29,7 +29,6 @@ struct package // Internal char* path; - char* format; // char* description; @@ -61,6 +60,8 @@ struct packages struct package* buffer; }; +/*for use examples see test.c*/ + /*check.c*/ // Function to check if a package is installed and untouched int check(struct package* pkg); @@ -105,9 +106,11 @@ void move_binaries(char** locations, long loc_size); /*pkg.c*/ // Allocate an array of packages -struct packages create_pkgs(int reserve); +struct packages* create_pkgs(int reserve); // Merge 2 package arrays void merge_pkgs(struct packages* destination, struct packages* source); +// Free a package array +void free_pkgs(struct packages* pkgs); // Push a package into the array void push_pkg(struct packages* pkgs, struct package* pkg); // Pop the last added package from the array @@ -118,12 +121,14 @@ int open_pkg(const char* path, struct package* pkg); int create_pkg(char* in_path, struct package* pkg); // Function to free memory allocated for a package structure int free_pkg(struct package* pkg); -// Function to check if a given package is already in the file tree -int is_installed_pkg(char* path, struct package* pkg); +// Function to search for packages in the database +struct packages* search_pkgs(char* db_path, char* name); // Create the database that stores all packages in a directory int create_pkg_db(char* db_path, struct packages* pkgs); // Get all packages from a directory -struct packages get_pkgs(char* path); +struct packages* get_pkgs(char* path); +// Dump contents of a database to a package array +struct packages* dump_db(char* db_path); /*repo.c*/ // Get currently present repos diff --git a/src/check.c b/src/check.c index 39be800..1c7477d 100755 --- a/src/check.c +++ b/src/check.c @@ -35,7 +35,7 @@ int check(struct package* pkg) // Open the package data file and load its contents dbg(2, "Opening the package"); - open_pkg(dataSpmPath, pkg); + open_pkg(getenv("SOVIET_SPM_DIR"), pkg); dbg(2, "Checking package locations"); // If the package data file lacks location information, return exit code 2 diff --git a/src/config.c b/src/config.c index ca8c397..d7e1690 100755 --- a/src/config.c +++ b/src/config.c @@ -84,6 +84,10 @@ int readConfig(const char* configFilePath, int overwrite) { char* key = strtok(line, "="); char* value = strchr(line, '\0') + 1; + if(strchr(value, '\n') != NULL) + { + value[strlen(value) - strlen(strchr(value, '\n'))] = '\0'; + } if (key == NULL || value == NULL) { msg(ERROR, "Invalid config file"); diff --git a/src/install.c b/src/install.c index aee192d..955fc5d 100755 --- a/src/install.c +++ b/src/install.c @@ -29,9 +29,7 @@ int install_package_source(struct package* pkg) { char* make_dir = getenv("SOVIET_MAKE_DIR"); char* build_dir = getenv("SOVIET_BUILD_DIR"); - // Temporary for compatibility - setenv("BUILD_ROOT", build_dir, 1); - + if (make_dir == NULL || build_dir == NULL) { msg(ERROR, "SOVIET_MAKE_DIR or SOVIET_BUILD_DIR is not set"); @@ -150,7 +148,7 @@ int install_package_source(struct package* pkg) dbg(1, "Got %d locations for %s", pkg->locationsCount, pkg->name); // Check if the package is already installed - if (is_installed_pkg(getenv("SOVIET_SPM_DIR"), pkg)) { + if (check(pkg) == 0) { msg(WARNING, "Package %s is already installed, reinstalling", pkg->name); uninstall(pkg->name); } else { @@ -167,7 +165,6 @@ int install_package_source(struct package* pkg) { if (pkg->info.special != NULL && strlen(pkg->info.special) > 0) { - msg(WARNING, "Special: %s", pkg->info.special); dbg(1, "Executing post install script for %s", pkg->name); if (system(pkg->info.special) != 0) { @@ -178,7 +175,7 @@ int install_package_source(struct package* pkg) } if(create_pkg(getenv("SOVIET_SPM_DIR"), pkg) != 0) return 1; - + dbg(1, "Package %s installed", pkg->name); // Clean up @@ -204,6 +201,7 @@ void write_package_configuration_file(struct package* pkg) fprintf(env_file, "%s\n", pkg->config[i]); } fclose(env_file); + free(env_path); } } @@ -217,6 +215,7 @@ void read_package_configuration_file(struct package* pkg) sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->environment); readConfig(env_path, 1); + free(env_path); } @@ -228,5 +227,6 @@ void read_package_configuration_file(struct package* pkg) sprintf(env_path, "%s/%s", getenv("SOVIET_ENV_DIR"), pkg->name); readConfig(env_path, 1); + free(env_path); } } \ No newline at end of file diff --git a/src/pkg.c b/src/pkg.c index 291d7f3..d691bea 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -9,24 +9,38 @@ #include "libspm.h" // Allocate an array of packages -struct packages create_pkgs(int reserve) +struct packages* create_pkgs(int reserve) { - struct packages pkgs; - pkgs.size = 1 + reserve; - pkgs.count = 0; - pkgs.buffer = (struct package*)calloc(1 + reserve, sizeof(struct package)); + struct packages* pkgs = calloc(1, sizeof(struct packages)); + pkgs->size = 1 + reserve; + pkgs->count = 0; + pkgs->buffer = (struct package*)calloc(1 + reserve, sizeof(struct package)); return pkgs; } // Merge 2 package arrays void merge_pkgs(struct packages* destination, struct packages* source) { - for(int i = 0; i < source->count; i++) + for(int i = 0; source->count != 0; i++) { struct package* pkg = pop_pkg(source); push_pkg(destination, pkg); + } + free(source->buffer); + free(source); +} + +// Free a package array +void free_pkgs(struct packages* pkgs) +{ + for(int i = 0; pkgs->count != 0; i++) + { + struct package* pkg = pop_pkg(pkgs); free_pkg(pkg); } + + free(pkgs->buffer); + free(pkgs); } // Push a package into the array @@ -37,7 +51,7 @@ void push_pkg(struct packages* pkgs, struct package* pkg) pkgs->buffer = realloc(pkgs->buffer, sizeof(struct package)*(pkgs->count + pkgs->size)); pkgs->size = pkgs->count + pkgs->size; } - memcpy(&(pkgs->buffer[pkgs->count]), pkg, sizeof(struct package)); + (pkgs->buffer[pkgs->count]) = *pkg; pkgs->count++; } @@ -45,24 +59,23 @@ void push_pkg(struct packages* pkgs, struct package* pkg) struct package* pop_pkg(struct packages* pkgs) { pkgs->count--; - struct package* pkg = calloc(1, sizeof(struct package)); - memcpy(pkg, &(pkgs->buffer[pkgs->count]), sizeof(struct package)); - free_pkg(&(pkgs->buffer[pkgs->count])); - return pkg; + return &(pkgs->buffer[pkgs->count]); } // Open a package from the given path and populate the package structure int open_pkg(const char* path, struct package* pkg) { - dbg(3, "path: %s", path); + char full_path[MAX_PATH]; + sprintf(full_path, "%s/%s", path, pkg->path); + dbg(3, "path: %s", full_path); // Check if the file exists if (access(path, F_OK) != 0) { - msg(ERROR, "File %s does not exist\n", path); + msg(ERROR, "File %s does not exist\n", full_path); return 1; } dbg(2, "Getting format from file extension"); - char* format = strrchr(path, '.') + 1; + char* format = strrchr(full_path, '.') + 1; dbg(1, "Format: %s", format); char** FORMATS; @@ -76,16 +89,16 @@ int open_pkg(const char* path, struct package* pkg) if (strcmp(format, FORMATS[i]) == 0) { dbg(2, "Opening package with %s format", FORMATS[i]); - runFormatLib(FORMATS[i], "open", path, pkg); + runFormatLib(FORMATS[i], "open", full_path, pkg); free(FORMATS); return 0; } } } else { - msg(ERROR, "File %s is not a valid package file", path); + msg(ERROR, "File %s is not a valid package file", full_path); return 1; } - msg(ERROR, "File %s is not a valid package file, or the format plugin isn't loaded", path); + msg(ERROR, "File %s is not a valid package file, or the format plugin isn't loaded", full_path); return 1; } @@ -103,17 +116,21 @@ int create_pkg(char* in_path, struct package* pkg) rmany(path); } - msg(INFO, "Creating package %s", path); + dbg(2, "Creating package %s", path); + + dbg(2, "Getting format from file extension"); + char* format = strrchr(path, '.') + 1; + dbg(1, "Format: %s", format); char** FORMATS; int FORMAT_COUNT = splita(getenv("SOVIET_FORMATS"),' ',&FORMATS); - if (pkg->format != NULL) + if (format != NULL) { // this is experimental for (int i = 0; i < FORMAT_COUNT; i++) { - if (strcmp(pkg->format, FORMATS[i]) == 0) + if (strcmp(format, FORMATS[i]) == 0) { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "create", path, pkg); @@ -136,6 +153,8 @@ int free_pkg(struct package* pkg) if (pkg->type != NULL) free(pkg->type); if (pkg->url != NULL) free(pkg->url); if (pkg->description != NULL) free(pkg->description); + if (pkg->environment != NULL) free(pkg->environment); + if (pkg->path != NULL) free(pkg->path); if (pkg->info.install != NULL) free(pkg->info.install); if (pkg->info.special != NULL) free(pkg->info.special); @@ -174,91 +193,187 @@ int free_pkg(struct package* pkg) } free(pkg->files); } + if (pkg->config) + { + for(int i = 0; i < pkg->configCount; i++) + { + free(pkg->config[i]); + } + free(pkg->config); + } return 0; } -// Function to check if a given package is already in the file tree -int is_installed_pkg(char* path, struct package* pkg) +// Function to search for a package in the database +struct packages* search_pkgs(char* db_path, char* term) { - (void)path; - (void)pkg; - return 0; + sqlite3* db; + int result = sqlite3_open(db_path, &db); + if(result) {msg(ERROR, "SQL error when opening SOVIET_DB");} + struct packages* pkgs = create_pkgs(256 /*absolutely random number*/); + + // Prepare the SQL query + // yes, this is a copy-paste from what we had a year ago + sqlite3_stmt* stmt; + result = sqlite3_prepare_v2(db, "SELECT Name, Path FROM Packages", -1, &stmt, NULL); + if (result != SQLITE_OK) { msg(ERROR, "SQL error when preparing to search"); } + + int i = 0; + while ((result = sqlite3_step(stmt)) == SQLITE_ROW) + { + // TODO: + // This very is stupid + const unsigned char* name = sqlite3_column_text(stmt, 0); + const unsigned char* path = sqlite3_column_text(stmt, 1); + if(strstr((const char*)name, term) != 0) + { + dbg(2, "FOUND: %s at %s", name, path); + struct package pkg = {0}; + pkg.name = strdup((const char*)name); + pkg.path = strdup((const char*)path); + push_pkg(pkgs, &pkg); + i++; + } + } + + result = sqlite3_finalize(stmt); + if (result != SQLITE_OK) { msg(ERROR, "SQL error when finalizing statement"); } + + sqlite3_close(db); + return pkgs; } // Create the database that stores all packages in a directory -/* int create_pkg_db(char* db_path, struct packages* pkgs) { - remove(db_path); + rmany(db_path); sqlite3* db; - sqlite3_stmt* pkg_table; int result = sqlite3_open(db_path, &db); - if(result) - { - msg(FATAL, "SQL error when creating SOVIET_DB"); - } + if(result) {msg(ERROR, "SQL error when creating SOVIET_DB"); return result;} result = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Packages (Name TEXT, Path TEXT)", NULL, NULL, NULL); - if (result != SQLITE_OK) + if (result != SQLITE_OK) {msg(ERROR, "SQL error when creating pkg_table"); return result;} + + for(int i = 0; i < pkgs->count; i++) { - msg(FATAL, "SQL error when creating pkg_table"); - } + sqlite3_stmt* stmt; + result = sqlite3_prepare_v2(db, "INSERT INTO Packages VALUES (?,?)", -1, &stmt, NULL); if (result != SQLITE_OK) { msg(ERROR, "SQL error when preparing to insert package"); return result; } + result = sqlite3_bind_text(stmt, 1, pkgs->buffer[i].name, -1, NULL); if (result != SQLITE_OK) { msg(ERROR, "SQL error when binding package name"); return result; } + result = sqlite3_bind_text(stmt, 2, pkgs->buffer[i].path, -1, NULL); if (result != SQLITE_OK) { msg(ERROR, "SQL error when binding package path"); return result; } + result = sqlite3_step(stmt); if (result != SQLITE_DONE) { msg(ERROR, "SQL error when inserting package"); return result; } + result = sqlite3_reset(stmt); if (result != SQLITE_OK) { msg(ERROR, "SQL error when resetting statement"); return result; } + result = sqlite3_finalize(stmt); if (result != SQLITE_OK) { msg(ERROR, "SQL error when finalizing statement"); return result; } - //char* ins = "INSERT INTO Packages VALUES (?,?)"; + } sqlite3_close(db); + return 0; } -*/ // Get all packages from a directory -struct packages get_pkgs(char* path) +struct packages* get_pkgs(char* path) { + // NOTE: + // it only checks the default format + // not sure if that's a good idea int num_files; char **files_array = get_all_files(path, path, &num_files); if (files_array != NULL) { - struct packages pkgs = create_pkgs(num_files); + struct packages* pkgs = create_pkgs(num_files); // Print each file path for (int j = 0; j < num_files; j++) { - if(strstr(files_array[j], ".ecmp") != NULL) - { - char* path = strdup(files_array[j]); - char* name = strdup(files_array[j]); - - while(strtok(name, "/")) + if(strstr(files_array[j], "/.") == NULL) + { + if(strstr(files_array[j], getenv("SOVIET_DEFAULT_FORMAT")) != NULL) { - char* tmp = name; - name = strchr(name, '\0') + 1; - if(*name == '\0') + if(strstr(files_array[j], getenv("SOVIET_DEFAULT_FORMAT"))[strlen(getenv("SOVIET_DEFAULT_FORMAT"))] == '\0') { - name = tmp; - break; - } - } + char path[MAX_PATH]; + sprintf(path, "%s", files_array[j]); + char name[MAX_PATH]; + sprintf(name, "%s", files_array[j]); - dbg(1, "path is %s, name is %s", path, name); + while(strrchr(name, '/') != NULL) + { + strcpy(name, strrchr(name, '/') + 1); + } + name[strlen(name) - (strlen(getenv("SOVIET_DEFAULT_FORMAT")) + 1) /*+1 for the '.'*/] = '\0'; - struct package pkg = {0}; - pkg.name = strdup(name); - pkg.path = strdup(path); + dbg(1, "path is %s, name is %s", path, name); - push_pkg(&pkgs, &pkg); + struct package pkg = {0}; + pkg.name = strdup(name); + pkg.path = strdup(path); - // Free each file path string - free(path); + push_pkg(pkgs, &pkg); + } + // Garbage file + } + // Not "SOVIET_DEFAULT_FORMAT" file } + // "hidden" file free(files_array[j]); } // Free the array of file paths - return pkgs; free(files_array); + if(pkgs->count < 1) + { + msg(ERROR, "Path %s does not contain any packages", path); + struct packages* pkgs = create_pkgs(0); + return pkgs; + } + return pkgs; } else { msg(ERROR, "Path %s empty", path); - struct packages pkgs = {0}; + struct packages* pkgs = create_pkgs(0); return pkgs; } +} + +// Function to search for a package in the database +struct packages* dump_db(char* db_path) +{ + /* + sqlite3* db; + int result = sqlite3_open(db_path, &db); + if(result) {msg(ERROR, "SQL error when opening SOVIET_DB");} + */ + // struct packages* pkgs = create_pkgs(256 /*absolutely random number*/); + + // Prepare the SQL query + // yes, this is a copy-paste from what we had a year ago + /* + sqlite3_stmt* stmt; + result = sqlite3_prepare_v2(db, "SELECT Name, Path FROM Packages", -1, &stmt, NULL); + if (result != SQLITE_OK) { msg(ERROR, "SQL error when preparing to search"); } + + int i = 0; + while ((result = sqlite3_step(stmt)) == SQLITE_ROW) + { + // TODO: + // This very is stupid + const unsigned char* name = sqlite3_column_text(stmt, 0); + const unsigned char* path = sqlite3_column_text(stmt, 1); + if(strstr((const char*)name, term) != 0) + { + dbg(2, "FOUND: %s at %s", name, path); + struct package pkg = {0}; + pkg.name = strdup((const char*)name); + pkg.path = strdup((const char*)path); + push_pkg(pkgs, &pkg); + i++; + } + } + + result = sqlite3_finalize(stmt); + if (result != SQLITE_OK) { msg(ERROR, "SQL error when finalizing statement"); } + + sqlite3_close(db); + return pkgs; + */ } \ No newline at end of file diff --git a/test/test.c b/test/test.c index e55c6f2..09bf0dc 100644 --- a/test/test.c +++ b/test/test.c @@ -4,88 +4,110 @@ void test_check() { - setenv("SOVIET_SPM_DIR", "/tmp/cccp-test", 1); - setenv("SOVIET_FORMATS", "ecmp", 1); - setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + // Necessary prepwork + { + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test", 1); + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); - FILE *ptr; - ptr = fopen("/tmp/cccp-test/test.ecmp","w"); - fprintf(ptr, "[locations]\n"); - fprintf(ptr, "/tmp/cccp-test/test.ecmp\n"); - fclose(ptr); + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf(ptr, "[locations]\n"); + fprintf(ptr, "/tmp/cccp-test/test.ecmp\n"); + fclose(ptr); + } struct package pkg = {0}; - pkg.path = "test.ecmp"; + pkg.path = strdup("test.ecmp"); int result = check(&pkg); free_pkg(&pkg); - unsetenv("SOVIET_SPM_DIR"); - unsetenv("SOVIET_FORMATS"); - unsetenv("SOVIET_PLUGIN_DIR"); - rmany("/tmp/cccp-test/test.ecmp"); - if(result != 0) msg(FATAL, "FAILED"); else msg(INFO, "PASSED"); + + // Cleanup + { + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + rmany("/tmp/cccp-test/test.ecmp"); + } } void test_clean() { - char TEST_BUILD_DIR[MAX_PATH]; - char TEST_MAKE_DIR[MAX_PATH]; - - sprintf(TEST_BUILD_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_BUILD_DIR"); - sprintf(TEST_MAKE_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_MAKE_DIR"); - - setenv("SOVIET_BUILD_DIR", TEST_BUILD_DIR, 1); - setenv("SOVIET_MAKE_DIR", TEST_MAKE_DIR, 1); + // Necessary prepwork + { + char TEST_BUILD_DIR[MAX_PATH]; + char TEST_MAKE_DIR[MAX_PATH]; + + sprintf(TEST_BUILD_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_BUILD_DIR"); + sprintf(TEST_MAKE_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_MAKE_DIR"); + + setenv("SOVIET_BUILD_DIR", TEST_BUILD_DIR, 1); + setenv("SOVIET_MAKE_DIR", TEST_MAKE_DIR, 1); - pmkdir(getenv("SOVIET_BUILD_DIR")); - pmkdir(getenv("SOVIET_MAKE_DIR")); + pmkdir(getenv("SOVIET_BUILD_DIR")); + pmkdir(getenv("SOVIET_MAKE_DIR")); + } int result = clean(); if(result != 0) msg(FATAL, "FAILED"); else msg(INFO, "PASSED"); - rmany(getenv("SOVIET_BUILD_DIR")); - rmany(getenv("SOVIET_MAKE_DIR")); - unsetenv("SOVIET_BUILD_DIR"); - unsetenv("SOVIET_MAKE_DIR"); + // Cleanup + { + rmany(getenv("SOVIET_BUILD_DIR")); + rmany(getenv("SOVIET_MAKE_DIR")); + unsetenv("SOVIET_BUILD_DIR"); + unsetenv("SOVIET_MAKE_DIR"); + } } void test_config() { - setenv("SOVIET_TEST_ENV", "TEST", 1); + // Necessary prepwork + { + setenv("SOVIET_TEST_ENV", "TEST", 1); - FILE *ptr; - ptr = fopen("/tmp/cccp-test/test.conf","w"); - fprintf(ptr, "SOVIET_TEST_VAR=$SOVIET_TEST_ENV/TEST"); - fclose(ptr); + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.conf","w"); + fprintf(ptr, "SOVIET_TEST_VAR=$SOVIET_TEST_ENV/TEST"); + fclose(ptr); + } int result = readConfig("/tmp/cccp-test/test.conf", 1); if((result != 0) || (strcmp(getenv("SOVIET_TEST_VAR"), "TEST/TEST") != 0)) { - msg(ERROR, "EXPECTED: TEST/TEST"); - msg(ERROR, "GOT: %s", getenv("SOVIET_TEST_VAR")); + msg(ERROR, "EXPECTED: 'TEST/TEST'"); + msg(ERROR, "GOT: '%s'", getenv("SOVIET_TEST_VAR")); msg(FATAL, "FAILED"); } else msg(INFO, "PASSED"); - - unsetenv("SOVIET_TEST_ENV"); - unsetenv("SOVIET_TEST_VAR"); - rmany("/tmp/cccp-test/test.conf"); + + // Cleanup + { + unsetenv("SOVIET_TEST_ENV"); + unsetenv("SOVIET_TEST_VAR"); + rmany("/tmp/cccp-test/test.conf"); + } } void test_install() { int result = 0; - // Define variables used during installation + // Necessary prepwork { setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); setenv("SOVIET_SOURCE_DIR", "/tmp/cccp-test/src_dir", 1); + setenv("SOVIET_ROOT", "/tmp/cccp-test/destination/", 1); + setenv("SOVIET_ENV_DIR", "/tmp/cccp-test/src_dir", 1); + setenv("SOVIET_TEST_ENV", "TEST", 1); + pmkdir(getenv("SOVIET_ROOT")); pmkdir("/tmp/cccp-test/spm_dir"); pmkdir("/tmp/cccp-test/src_dir"); @@ -103,27 +125,27 @@ void test_install() pmkdir(getenv("SOVIET_BUILD_DIR")); pmkdir(getenv("SOVIET_MAKE_DIR")); + pmkdir(getenv("SOVIET_ENV_DIR")); - } - // Create test package - { FILE *ptr; ptr = fopen("/tmp/cccp-test/test.ecmp","w"); fprintf( ptr, - "[info]\n" \ - "name = test\n" \ - "version = 0\n" \ - "type = src\n" \ - "[files]\n" \ - "$VERSION-file 127.0.0.1 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" \ - "[description]\n" \ - "test package\n" \ - "[prepare]\n" \ - "mkdir test-0\n" \ - "mv 0-file ./test-0/0-file\n" \ - "[install]\n" \ - "mv 0-file $SOVIET_BUILD_DIR/0-file\n" \ - "[special]\n" \ + "[info]\n" + "name = test\n" + "version = 0\n" + "type = src\n" + "[files]\n" + "$VERSION-file 127.0.0.1 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + "[description]\n" + "test package\n" + "[config]\n" + "SOVIET_TEST_VAR=$SOVIET_TEST_ENV\n" + "[prepare]\n" + "mkdir test-0\n" + "mv 0-file ./test-0/0-file\n" + "[install]\n" + "mv 0-file $SOVIET_BUILD_DIR/0-file\n" + "[special]\n" "echo special...\n" ); @@ -132,10 +154,18 @@ void test_install() struct package pkg = {0}; pkg.name = "test"; - pkg.path = "test.ecmp"; - pkg.format = "ecmp"; + pkg.path = strdup("test.ecmp"); - result += open_pkg("/tmp/cccp-test/test.ecmp", &pkg); + result += open_pkg("/tmp/cccp-test", &pkg); + write_package_configuration_file(&pkg); + read_package_configuration_file(&pkg); + result += strcmp(getenv("SOVIET_TEST_VAR"), "TEST"); + if(result != 0) + { + msg(ERROR, "EXPECTED: 'TEST'"); + msg(ERROR, "GOT: '%s'", getenv("SOVIET_TEST_VAR")); + msg(FATAL, "FAILED"); + } result += install_package_source(&pkg); if(result != 0) msg(FATAL, "FAILED"); @@ -153,24 +183,270 @@ void test_install() unsetenv("SOVIET_SPM_DIR"); unsetenv("SOVIET_FORMATS"); unsetenv("SOVIET_PLUGIN_DIR"); + unsetenv("SOVIET_TEST_ENV"); + unsetenv("SOVIET_TEST_VAR"); rmany("/tmp/cccp-test/test.ecmp"); } } void test_make() { - return; + int result = 0; + + // Necessary prepwork + { + setenv("SOVIET_SOURCE_DIR", "/tmp/cccp-test/src_dir", 1); + pmkdir("/tmp/cccp-test/src_dir"); + + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + + char TEST_MAKE_DIR[MAX_PATH]; + sprintf(TEST_MAKE_DIR, "%s/%s", getenv("SOVIET_TEST_DIR"), "TEST_MAKE_DIR"); + setenv("SOVIET_MAKE_DIR", TEST_MAKE_DIR, 1); + pmkdir(getenv("SOVIET_MAKE_DIR")); + + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf( ptr, + "[info]\n" + "name = test\n" + "version = 0\n" + "type = src\n" + "[files]\n" + "$VERSION-file 127.0.0.1 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + "[prepare]\n" + "mkdir test-0\n" + "mv 0-file ./test-0/0-file\n" + ); + + fclose(ptr); + } + + struct package pkg = {0}; + pkg.name = "test"; + pkg.path = strdup("test.ecmp"); + + result += open_pkg("/tmp/cccp-test", &pkg); + result += make(&pkg); + result += access("/tmp/cccp-test/TEST_MAKE_DIR/test-0/0-file", F_OK); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + // Cleanup + { + free_pkg(&pkg); + rmany(getenv("SOVIET_MAKE_DIR")); + rmany(getenv("SOVIET_SOURCE_DIR")); + unsetenv("SOVIET_MAKE_DIR"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + rmany("/tmp/cccp-test/test.ecmp"); + } } void test_move() { - return; + // Necessary prepwork + { + setenv("SOVIET_BUILD_DIR", "/tmp/cccp-test/source/", 1); + setenv("SOVIET_ROOT", "/tmp/cccp-test/destination/", 1); + pmkdir(getenv("SOVIET_BUILD_DIR")); + pmkdir(getenv("SOVIET_ROOT")); + + FILE *ptr; + ptr = fopen("/tmp/cccp-test/source/test","w"); + fprintf(ptr, "test file"); + fclose(ptr); + } + + int num_files; + char **files_array = get_all_files(getenv("SOVIET_BUILD_DIR"), getenv("SOVIET_BUILD_DIR"), &num_files); + move_binaries(files_array, num_files); + + int result = access("/tmp/cccp-test/destination/test", F_OK); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + // Cleanup + { + for(int i = 0; i < num_files; i++) + { + free(files_array[i]); + } + free(files_array); + rmany(getenv("SOVIET_BUILD_DIR")); + rmany(getenv("SOVIET_ROOT")); + unsetenv("SOVIET_ROOT"); + unsetenv("SOVIET_ROOT"); + } } void test_pkg() { - return; + int result = 0; + // Test package array + { + struct packages* pkgs = create_pkgs(0); + for(int i = 0; i < 5; i++) + { + struct package pkg = {0}; + pkg.name = strdup("test_part_1"); + pkg.description = strdup("test description"); + push_pkg(pkgs, &pkg); + } + result += (pkgs->count - 5); + dbg(2, "size %d - count %d", pkgs->size, pkgs->count); + + struct packages* t_pkgs = create_pkgs(0); + for(int i = 0; i < 5; i++) + { + struct package pkg = {0}; + pkg.name = strdup("test_part_2"); + pkg.description = strdup("test description"); + push_pkg(t_pkgs, &pkg); + } + result += (t_pkgs->count - 5); + dbg(2, "size %d - count %d", t_pkgs->size, t_pkgs->count); + + merge_pkgs(pkgs, t_pkgs); + result += (pkgs->count - 10); + dbg(2, "size %d - count %d", pkgs->size, pkgs->count); + + // Cleanup + { + free_pkgs(pkgs); + } + } + + // Test create and open package + { + // Necessary prepwork + { + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); + pmkdir("/tmp/cccp-test/spm_dir"); + + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf( ptr, + "[info]\n" + "name = test\n" + "version = 0\n" + "type = src\n" + "[files]\n" + "$VERSION-file 127.0.0.1 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + "[description]\n" + "test package\n" + "[config]\n" + "SOVIET_TEST_VAR=$SOVIET_TEST_ENV\n" + "[prepare]\n" + "mkdir test-0\n" + "mv 0-file ./test-0/0-file\n" + "[install]\n" + "mv 0-file $SOVIET_BUILD_DIR/0-file\n" + "[special]\n" + "echo special...\n" + ); + + fclose(ptr); + } + + struct package pkg_0 = {0}; + pkg_0.path = "test-0.ecmp"; + pkg_0.name = "test"; + pkg_0.version = "0"; + pkg_0.type = "src"; + pkg_0.description= "test package\n"; + result += create_pkg("/tmp/cccp-test", &pkg_0); + + struct package pkg_1 = {0}; + pkg_1.path = strdup("test-0.ecmp"); + result += open_pkg("/tmp/cccp-test", &pkg_1); + result += strcmp(pkg_1.name, "test"); + result += strcmp(pkg_1.version, "0"); + result += strcmp(pkg_1.type, "src"); + result += strcmp(pkg_1.description, "test package\n"); + + // Cleanup + { + free_pkg(&pkg_1); + rmany(getenv("SOVIET_SPM_DIR")); + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + rmany("/tmp/cccp-test/test.ecmp"); + rmany("/tmp/cccp-test/test-0.ecmp"); + } + } + // Test package database + { + // Necessary prepwork + { + setenv("SOVIET_REPO_DIR", "/tmp/cccp-test/repo_dir", 1); + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); + setenv("SOVIET_DEFAULT_FORMAT", "ecmp", 1); + + pmkdir(getenv("SOVIET_REPO_DIR")); + pmkdir("/tmp/cccp-test/repo_dir/test_repo/long/repo/file/tree"); + pmkdir(getenv("SOVIET_SPM_DIR")); + for(int i = 0; i < 15; i++) + { + char dir[MAX_PATH]; + sprintf(dir, "%s/%s/%d%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", i, ".ecmp"); + + FILE *ptr; + ptr = fopen(dir,"w"); + fprintf(ptr, "test file"); + fclose(ptr); + } + // Garbage files + for(int i = 0; i < 10; i++) + { + char dir[MAX_PATH]; + sprintf(dir, "%s/%s/%s-%d", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", ".ecmp", i); + + FILE *ptr; + ptr = fopen(dir,"w"); + fprintf(ptr, "test file"); + fclose(ptr); + } + } + + struct packages* pkgs = get_pkgs("/tmp/cccp-test/repo_dir/"); + result += (pkgs->count - 15); + for(int i = 0; i < 15; i++) + { + char str[8]; + sprintf(str, "%d", i); + result += strcmp(pkgs->buffer[i].name, str); + } + result += create_pkg_db("/tmp/cccp-test/test.db", pkgs); + struct packages* search_result = search_pkgs("/tmp/cccp-test/test.db", "1"); + result += ((search_result->count) - 6); + result += strcmp(search_result->buffer[0].path, "test_repo/long/repo/file/tree/1.ecmp"); + result += strcmp(search_result->buffer[1].path, "test_repo/long/repo/file/tree/10.ecmp"); + + // Cleanup + { + free_pkgs(pkgs); + free_pkgs(search_result); + rmany(getenv("SOVIET_REPO_DIR")); + rmany(getenv("SOVIET_SPM_DIR")); + rmany("/tmp/cccp-test/test.db"); + unsetenv("SOVIET_REPO_DIR"); + unsetenv("SOVIET_DEFAULT_FORMAT"); + unsetenv("SOVIET_SPM_DIR"); + } + } + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); } void test_repo() From cc7c4ec8e82a05b495221c895806987810b2a873 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Tue, 24 Dec 2024 03:48:06 +0100 Subject: [PATCH 07/23] minor fixes --- include/globals.h | 11 ++-- include/libspm.h | 10 ++-- src/globals.c | 11 ++-- src/install.c | 2 +- src/list_TBD.c | 128 ---------------------------------------------- src/pkg.c | 50 ++++++++++-------- src/repo.c | 38 ++++++++------ src/uninstall.c | 63 +++++++++-------------- src/update.c | 126 --------------------------------------------- test/spm.c | 3 +- test/test.c | 82 ++++++++++++++++++++++++++--- test/test.h | 1 - 12 files changed, 165 insertions(+), 360 deletions(-) delete mode 100644 src/list_TBD.c delete mode 100644 src/update.c diff --git a/include/globals.h b/include/globals.h index 11b3101..433a149 100755 --- a/include/globals.h +++ b/include/globals.h @@ -15,11 +15,8 @@ extern bool TESTING; extern bool OVERWRITE; // enable verbose mode extern bool QUIET; -// Flag indicating that a user passed either Y or N to be used as default -extern bool OVERWRITE_CHOISE; -// Choise for passing N or Y to a prompt by default -extern char* USER_CHOISE[2]; - -extern char* PACKAGE_QUEUE[QUEUE_MAX]; -extern int QUEUE_COUNT; +// Flag indicating that no inputs are required +extern bool AUTO; +// Package queue +extern struct packages* PACKAGE_QUEUE; diff --git a/include/libspm.h b/include/libspm.h index 04719a3..1b177ea 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -129,10 +129,12 @@ int create_pkg_db(char* db_path, struct packages* pkgs); struct packages* get_pkgs(char* path); // Dump contents of a database to a package array struct packages* dump_db(char* db_path); +// Function returns an array of packages that need updating +struct packages* update(struct package* pkg); /*repo.c*/ // Get currently present repos -int get_repos(char** list); +char** get_repos(int* count); // Function to synchronize the local repository with a remote repository int repo_sync(); // Add a new repository from a git repo @@ -140,11 +142,7 @@ int add_repo(char* name, char* url); /*uninstall.c*/ // Function to uninstall packages -int uninstall(char* name); - -/*update.c*/ -// Function to update a package -int update(); +int uninstall(struct package* pkg); /*util.c*/ // Recursively remove a directory and its contents diff --git a/src/globals.c b/src/globals.c index 1050bff..185fe0f 100644 --- a/src/globals.c +++ b/src/globals.c @@ -1,5 +1,6 @@ // Include necessary headers #include "stdbool.h" +#include "libspm.h" #include #include "cutils.h" #include "globals.h" @@ -18,12 +19,8 @@ bool OVERWRITE = false; // Flag for quiet mode (no verbose output) bool QUIET = true; -// Flag indicating that a user passed either Y or N to be used as default -bool OVERWRITE_CHOISE = false; - -// Choise for passing N or Y to a prompt by default -char* USER_CHOISE[2]; +// Flag indicating that no inputs are required +bool AUTO = false; // Array for package queue and its count -char* PACKAGE_QUEUE[QUEUE_MAX]; -int QUEUE_COUNT = 0; +struct packages* PACKAGE_QUEUE = {0}; diff --git a/src/install.c b/src/install.c index 955fc5d..d68d74e 100755 --- a/src/install.c +++ b/src/install.c @@ -150,7 +150,7 @@ int install_package_source(struct package* pkg) // Check if the package is already installed if (check(pkg) == 0) { msg(WARNING, "Package %s is already installed, reinstalling", pkg->name); - uninstall(pkg->name); + uninstall(pkg); } else { dbg(3, "Package %s is not installed", pkg->name); } diff --git a/src/list_TBD.c b/src/list_TBD.c deleted file mode 100644 index 9ce7818..0000000 --- a/src/list_TBD.c +++ /dev/null @@ -1,128 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -// Include necessary headers -#include "libspm.h" -#include "cutils.h" - -// Function to count the number of installed packages -int count_installed() { - char *path = getenv("SOVIET_SPM_DIR"); - int num_files; - char **files_array = get_all_files(path, path, &num_files); - if (files_array != NULL) { - // Return the number of files - return num_files; - } else { - // If no files found, print a message - printf("No files found.\n"); - } - return 1; -} - -// Function to list all installed packages -int list_installed() { - char *path = getenv("SOVIET_SPM_DIR"); - int num_files; - char **files_array = get_all_files(path, path, &num_files); - if (files_array != NULL) { - // Print each file path - for (int i = 0; i < num_files; i++) { - - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* repo = strtok(files_array[i], "/"); - char* package = strchr(files_array[i], '\0') + 1; - printf("%s from %s\n", package, repo); - - // Free each file path string - free(files_array[i]); - } - // Free the array of file paths - free(files_array); - } else { - // If no files found, print a message - printf("No files found.\n"); - } - return 0; -} - -// Function to search for a term in installed files -char ** search(char *term, int *num_results) { - int found = 0; - char *path = getenv("SOVIET_REPOS_DIR"); - int num_files; - char **files_array = get_all_files(path, path, &num_files); - char **searched_array = NULL; - - if (files_array != NULL) { - // Print each file path - for (int i = 0; i < num_files; i++) - { - - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* repo = strtok(files_array[i], "/"); - char* package = strchr(files_array[i], '\0') + 1; - - char* package_name = calloc(strlen(package) + 2, sizeof(char)); - strcpy(package_name, package); - - while(strtok(package_name, "/")) - { - char* tmp = package_name; - package_name = strchr(package_name, '\0') + 1; - if(*package_name == '\0') - { - package_name = tmp; - break; - } - } - - dbg(1, "repos is %s, package is %s, name is %s",repo, package, package_name); - - if (strstr(package_name, term) != 0) - { - // Compare the filename - printf("Found package: %s in %s \n", package_name, repo); - searched_array = realloc(searched_array, (found + 1) * sizeof(char *)); - // Stupid - char* tmp = calloc(strlen(package_name) + strlen(repo) * 2, 1); - sprintf(tmp, "%s>%s", package_name, repo); - - searched_array[found] = strdup(tmp); - free(tmp); - found++; - } - - // Free each file path string - free(files_array[i]); - } - // Free the array of file paths - free(files_array); - - // Update num_results if it's not NULL - if (num_results != NULL) - *num_results = found; - - return searched_array; - } else { - // If no files found, print a message - printf("All repositories are empty.\n"); - return NULL; - } - - if(found == 0) - { - printf("Package not found: %s\n", term); - } - return 0; -} - diff --git a/src/pkg.c b/src/pkg.c index d691bea..bc2cee3 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -218,7 +218,6 @@ struct packages* search_pkgs(char* db_path, char* term) result = sqlite3_prepare_v2(db, "SELECT Name, Path FROM Packages", -1, &stmt, NULL); if (result != SQLITE_OK) { msg(ERROR, "SQL error when preparing to search"); } - int i = 0; while ((result = sqlite3_step(stmt)) == SQLITE_ROW) { // TODO: @@ -232,7 +231,6 @@ struct packages* search_pkgs(char* db_path, char* term) pkg.name = strdup((const char*)name); pkg.path = strdup((const char*)path); push_pkg(pkgs, &pkg); - i++; } } @@ -290,6 +288,8 @@ struct packages* get_pkgs(char* path) { if(strstr(files_array[j], getenv("SOVIET_DEFAULT_FORMAT"))[strlen(getenv("SOVIET_DEFAULT_FORMAT"))] == '\0') { + dbg(1, "file: %s", files_array[j]); + char path[MAX_PATH]; sprintf(path, "%s", files_array[j]); char name[MAX_PATH]; @@ -297,7 +297,7 @@ struct packages* get_pkgs(char* path) while(strrchr(name, '/') != NULL) { - strcpy(name, strrchr(name, '/') + 1); + memmove(name, strrchr(name, '/') + 1, strlen(strrchr(name, '/') + 1) + 1); } name[strlen(name) - (strlen(getenv("SOVIET_DEFAULT_FORMAT")) + 1) /*+1 for the '.'*/] = '\0'; @@ -335,39 +335,30 @@ struct packages* get_pkgs(char* path) } } -// Function to search for a package in the database +// Function to dump a database into an array of packages struct packages* dump_db(char* db_path) { - /* sqlite3* db; int result = sqlite3_open(db_path, &db); if(result) {msg(ERROR, "SQL error when opening SOVIET_DB");} - */ - // struct packages* pkgs = create_pkgs(256 /*absolutely random number*/); + struct packages* pkgs = create_pkgs(256 /*absolutely random number*/); // Prepare the SQL query // yes, this is a copy-paste from what we had a year ago - /* sqlite3_stmt* stmt; result = sqlite3_prepare_v2(db, "SELECT Name, Path FROM Packages", -1, &stmt, NULL); if (result != SQLITE_OK) { msg(ERROR, "SQL error when preparing to search"); } - int i = 0; while ((result = sqlite3_step(stmt)) == SQLITE_ROW) { - // TODO: - // This very is stupid const unsigned char* name = sqlite3_column_text(stmt, 0); const unsigned char* path = sqlite3_column_text(stmt, 1); - if(strstr((const char*)name, term) != 0) - { - dbg(2, "FOUND: %s at %s", name, path); - struct package pkg = {0}; - pkg.name = strdup((const char*)name); - pkg.path = strdup((const char*)path); - push_pkg(pkgs, &pkg); - i++; - } + + struct package pkg = {0}; + + pkg.name = strdup((const char*)name); + pkg.path = strdup((const char*)path); + push_pkg(pkgs, &pkg); } result = sqlite3_finalize(stmt); @@ -375,5 +366,22 @@ struct packages* dump_db(char* db_path) sqlite3_close(db); return pkgs; - */ +} + +// Function returns an array of packages that need updating +struct packages* update_pkg(struct package* pkg) +{ + msg(INFO, "fetching updates"); + int new_version_found = 0; + + if(access(getenv("SOVIET_INSTALLED_DB"), F_OK) != 0) + { + msg(ERROR, "no installed DB found"); + return -1; + } + + struct packages* installed_packages = dump_db(getenv("SOVIET_INSTALLED_DB")); + + if(new_version_found == 0) { msg(INFO, "all packages are up to date"); } + return 0; } \ No newline at end of file diff --git a/src/repo.c b/src/repo.c index b353c4b..62624b0 100755 --- a/src/repo.c +++ b/src/repo.c @@ -12,54 +12,55 @@ #include "cutils.h" // Get currently present repos -int get_repos(char** list) +char** get_repos(int* count) { + char** list = calloc(512, sizeof(char*)); dbg(3, "checking for repos"); DIR *d; struct dirent *dir; d = opendir(getenv("SOVIET_REPOS_DIR")); - int count = 0; - list[count] = calloc(strlen("local") + 1, 1); - sprintf(list[count], "local"); - count++; + *count = 0; + list[*count] = calloc(strlen("local") + 1, 1); + sprintf(list[*count], "local"); + (*count)++; if (d) { while ((dir = readdir(d)) != NULL) { - if (count > 512) + if (*count > 512) { printf("Error : too many elements in list , reallocating\n"); - list = realloc(list,(count+512) * sizeof(char*)); + list = realloc(list,(*count+512) * sizeof(char*)); } if (dir->d_type != DT_DIR || dir->d_name[0] == '.') continue; - list[count] = calloc(strlen(dir->d_name) + 1, sizeof(char)); - strcpy(list[count], dir->d_name); - count++; + list[*count] = calloc(strlen(dir->d_name) + 1, sizeof(char)); + strcpy(list[*count], dir->d_name); + (*count)++; } } - for (int i = 0; i < count - 1; i++) + for (int i = 0; i < *count - 1; i++) { if (strcmp(list[i], ".") == 0 || strcmp(list[i], "..") == 0) { // Move the . string to the end char* temp = list[i]; dbg(3, "Moving: %s", temp); - for (int k = i; k < count - 1; k++) + for (int k = i; k < *count - 1; k++) { list[k] = list[k + 1]; } - list[count - 1] = temp; + list[*count - 1] = temp; i--; - count--; + (*count)--; } } closedir(d); dbg(3, "done checking for repos"); - return count; + return list; } // Function to synchronize the local repository with a remote repository @@ -100,7 +101,8 @@ int repo_sync() // Initialize a new Git repository if (git_repository_init(&repo_handle, repo_dir, false) != 0) { - msg(FATAL, "Failed to initialize git repository in %s.", repo_dir); + const git_error* error = giterr_last(); + msg(FATAL, "Failed to initialize git repository in %s - %s", repo_dir, error->message); } } @@ -121,6 +123,7 @@ int repo_sync() } git_repository_free(repo_handle); + return 0; } @@ -182,9 +185,10 @@ int add_repo(char* name, char* url) msg(ERROR, "Failed to finalize submodule %s - %s", name, error->message); return -1; } - git_submodule_free(submodule_handle); git_repository_free(temp_handle); + git_repository_free(repo_handle); + return 0; } diff --git a/src/uninstall.c b/src/uninstall.c index ff22565..ad333e3 100755 --- a/src/uninstall.c +++ b/src/uninstall.c @@ -24,53 +24,40 @@ This function is used to uninstall packages. It relies on location data, which c Please avoid making changes to this code unless there's a critical bug or an important missing feature. */ -int uninstall(char* name) +int uninstall(struct package* pkg) { - // Get the SPM directory from the environment variables - char* SPM_DIR = getenv("SOVIET_SPM_DIR"); - dbg(3, "SOVIET_SPM_DIR = %s", SPM_DIR); - char* ROOT = getenv("SOVIET_ROOT"); + char dataSpmPath[MAX_PATH]; + sprintf(dataSpmPath, "%s/%s", getenv("SOVIET_SPM_DIR"), pkg->path); - char** REPOS = calloc(512,sizeof(char*)); - int REPO_COUNT = get_repos(REPOS); - char* dataSpmPath = calloc(MAX_PATH, sizeof(char)); - - for (int j = 0; j < REPO_COUNT; j++) + // Check if the SPM file exists + if (check(pkg) == 0) { - // Generate the path to the package's SPM file - char tmpSpmPath[MAX_PATH]; - sprintf(tmpSpmPath, "%s/%s/%s.%s", (char*)getenv("SOVIET_SPM_DIR"),REPOS[j], name, getenv("SOVIET_DEFAULT_FORMAT")); - - // Verify if the package is installed - msg(INFO, "Verifying if the package is installed at %s", tmpSpmPath); - - // Check if the SPM file exists - if (access(tmpSpmPath, F_OK) == 0) { - sprintf(dataSpmPath, "%s/%s/%s.%s", getenv("SOVIET_SPM_DIR"),REPOS[j], name, getenv("SOVIET_DEFAULT_FORMAT")); - // Create a struct to store package information - struct package r_pkg; + // Create a struct to store package information + struct package r_pkg = {0}; + r_pkg.path = strdup(pkg->path); - // Open the package's SPM file and populate the r_pkg struct - open_pkg(dataSpmPath, &r_pkg); + // Open the package's SPM file and populate the r_pkg struct + open_pkg(getenv("SOVIET_SPM_DIR"), &r_pkg); - dbg(3, "Found %d locations", r_pkg.locationsCount); - // Remove all the files in the data["locations"] - char loc_path[MAX_PATH]; - for (int i = 0; i < r_pkg.locationsCount; i++) { + dbg(3, "Found %d locations", r_pkg.locationsCount); + // Remove all the files in the data["locations"] + char loc_path[MAX_PATH]; + for (int i = 0; i < r_pkg.locationsCount; i++) + { + sprintf(loc_path, "%s%s", getenv("SOVIET_ROOT"), r_pkg.locations[i]); - sprintf(loc_path, "%s%s", ROOT, r_pkg.locations[i]); - - //dbg(3, "Removing %s", loc_path); - if (rmany(loc_path) != 0) { - msg(ERROR,"Failed to remove %s",loc_path); - perror("remove"); - } + dbg(3, "Removing %s", loc_path); + if (rmany(loc_path) != 0) { + msg(ERROR,"Failed to remove %s",loc_path); + perror("remove"); } - // Remove the SPM file from DATA_DIR - remove(dataSpmPath); - return 0; } + // Remove the SPM file from DATA_DIR + remove(dataSpmPath); + free_pkg(&r_pkg); + return 0; } + msg(ERROR, "package not installed"); return -1; } diff --git a/src/update.c b/src/update.c deleted file mode 100644 index 88a9787..0000000 --- a/src/update.c +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include -#include - -// Include necessary headers -#include "libspm.h" -#include "cutils.h" - -// Function to update a package -int update() -{ - msg(INFO, "fetching updates"); - - int new_version_found = 0; - - char *path = getenv("SOVIET_SPM_DIR"); - dbg(2, "path is %s", path); - char *repo_path = getenv("SOVIET_REPOS_DIR"); - dbg(2, "repo path is %s", repo_path); - int num_files; - char **files_array = get_all_files(path, path, &num_files); - - if (files_array == NULL) { - msg(WARNING, "no packages installed"); - return 0; - } - // Print each file path - for (int i = 0; i < num_files; i++) - { - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* local_repo = strtok(files_array[i], "/"); - //dbg(2, "local repo is %s", local_repo); - char* local_package_name = strchr(files_array[i], '\0') + 1; - //dbg(2, "local package name is %s", local_package_name); - - // Allocate the packages to be compared - struct package* local = calloc(1, sizeof(struct package)); - struct package* remote = calloc(1, sizeof(struct package)); - - char* local_path = calloc(MAX_PATH, sizeof(char)); - char* remote_path = calloc(MAX_PATH, sizeof(char)); - - sprintf(local_path, "%s/%s/%s", path, local_repo, local_package_name); - //dbg(2, "local path is %s", local_path); - - int num_searched_files; - char **searched_files_array = get_all_files(repo_path, repo_path, &num_searched_files); - - if (searched_files_array != NULL) - { - // Print each file path - for (int j = 0; j < num_searched_files; j++) - { - // This will break if the files are not separated into repos - // But it doesnt cause a crash, just a visual bug - // I think - char* remote_repo = strtok(searched_files_array[j], "/"); - //dbg(2, "remote repo is %s", remote_repo); - char* remote_package = strchr(searched_files_array[j], '\0') + 1; - //dbg(2, "remote package is %s", remote_package); - char* remote_package_name = calloc(strlen(remote_package) + 2, sizeof(char)); - strcpy(remote_package_name, remote_package); - //dbg(2, "remote package name is %s", remote_package_name); - - while(strtok(remote_package_name, "/")) - { - char* tmp = remote_package_name; - remote_package_name = strchr(remote_package_name, '\0') + 1; - if(strcmp(remote_package_name, "") == 0) - { - remote_package_name = tmp; - break; - } - } - - //printf("%s, %s \n", remote_package_name, local_package_name); - - if (strcmp(remote_repo, local_repo) == 0) - { - if (strcmp(remote_package_name, local_package_name) == 0) - { - // Compare the filename - sprintf(remote_path, "%s/%s/%s", repo_path, remote_repo, remote_package); - dbg(2, "remote path is %s", remote_path); - - open_pkg(local_path, local); - open_pkg(remote_path, remote); - - // Compare the versions - if(strcmp(local->version, remote->version) != 0) - { - msg(INFO, "package %s is at version %s, available version is %s", local->name, local->version, remote->version); - new_version_found = 1; - } - - free(local); - free(remote); - } - } - // Free each file path string - free(searched_files_array[j]); - } - // Free each file path string - free(files_array[i]); - } - // Free the array of file paths - free(searched_files_array); - } - // Free the array of file paths - free(files_array); - - - if(new_version_found != 0) - { - msg(WARNING, "new version found for one or more packages, use --upgrade to upgrade"); - } - else - { - msg(WARNING, "all packages are up to date"); - } - - return 0; -} \ No newline at end of file diff --git a/test/spm.c b/test/spm.c index 71e0bd9..0e4e4dd 100644 --- a/test/spm.c +++ b/test/spm.c @@ -31,9 +31,8 @@ int main() test_make(); test_move(); test_pkg(); - test_repo(); + //test_repo(); test_uninstall(); - test_update(); test_util(); int leaks = check_leaks(); diff --git a/test/test.c b/test/test.c index 09bf0dc..0fed6c8 100644 --- a/test/test.c +++ b/test/test.c @@ -1,6 +1,7 @@ #include "test.h" #include "../include/libspm.h" +#include void test_check() { @@ -432,6 +433,9 @@ void test_pkg() result += strcmp(search_result->buffer[0].path, "test_repo/long/repo/file/tree/1.ecmp"); result += strcmp(search_result->buffer[1].path, "test_repo/long/repo/file/tree/10.ecmp"); + // Test dump_db + // Test update_pkg + // Cleanup { free_pkgs(pkgs); @@ -445,23 +449,89 @@ void test_pkg() } } + // Test updating packages + { + + } + if(result != 0) msg(FATAL, "FAILED"); else msg(INFO, "PASSED"); } void test_repo() { - return; + int result = 0; + // Necessary prepwork + { + setenv("SOVIET_REPOS_DIR", "/tmp/cccp-test/repo_dir", 1); + setenv("SOVIET_DEFAULT_REPO_URL", "https://github.com/Soviet-Linux/OUR.git", 1); + setenv("SOVIET_DEFAULT_REPO", "OUR", 1); + setenv("SOVIET_DEFAULT_FORMAT", "ecmp", 1); + + pmkdir("/tmp/cccp-test/repo_dir/repo-1"); + pmkdir("/tmp/cccp-test/repo_dir/repo-2"); + pmkdir("/tmp/cccp-test/repo_dir/repo-3"); + + git_libgit2_init(); + } + + int repo_count; + char** REPOS = get_repos(&repo_count); + // we expect 3 repos + 1 local; + result += (repo_count - 4); + result += repo_sync(); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + // Cleanup + { + git_libgit2_shutdown(); + + for(int i = 0; i < 4; i++) + { + free(REPOS[i]); + } + free(REPOS); + rmany("/tmp/cccp-test/repo_dir"); + unsetenv("SOVIET_REPOS_DIR"); + unsetenv("SOVIET_DEFAULT_REPO_URL"); + unsetenv("SOVIET_DEFAULT_REPO"); + unsetenv("SOVIET_DEFAULT_FORMAT"); + } } void test_uninstall() { - return; -} + // Necessary prepwork + { + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test", 1); + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + setenv("SOVIET_ROOT", "/", 1); -void test_update() -{ - return; + FILE *ptr; + ptr = fopen("/tmp/cccp-test/test.ecmp","w"); + fprintf(ptr, "[locations]\n"); + fprintf(ptr, "/tmp/cccp-test/test.ecmp\n"); + fclose(ptr); + } + + struct package pkg = {0}; + pkg.path = strdup("test.ecmp"); + int result = uninstall(&pkg); + free_pkg(&pkg); + + if(result != 0) msg(FATAL, "FAILED"); + else msg(INFO, "PASSED"); + + // Cleanup + { + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_ROOT"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + } } void test_util() diff --git a/test/test.h b/test/test.h index b207ecc..1d0e6a7 100644 --- a/test/test.h +++ b/test/test.h @@ -18,6 +18,5 @@ void test_move(); void test_pkg(); void test_repo(); void test_uninstall(); -void test_update(); void test_util(); From 72e971edcbf397ecd14e9dc465d316067fc967c9 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Tue, 24 Dec 2024 20:15:33 +0100 Subject: [PATCH 08/23] minor fixes --- formats/ecmp/ecmp.c | 9 +++ include/globals.h | 3 - include/libspm.h | 4 +- src/globals.c | 3 - src/install.c | 2 + src/move.c | 10 +-- src/pkg.c | 78 +++++++++++++++++------ src/repo.c | 3 +- src/util.c | 48 ++++++++++++++- test/spm.c | 4 +- test/test.c | 146 +++++++++++++++++++++++++++++++++++++++----- 11 files changed, 255 insertions(+), 55 deletions(-) diff --git a/formats/ecmp/ecmp.c b/formats/ecmp/ecmp.c index 4e39ece..01b379e 100644 --- a/formats/ecmp/ecmp.c +++ b/formats/ecmp/ecmp.c @@ -78,6 +78,9 @@ int open(char* path,struct package* pkg) }; void* infodict[][2] = { + // This is very stupid, but basically I assume that the name was obtained from the database + // This is to go around a memory leak caused by overwriting name when opening a package + // This is very stupid {"name",&pkg->name}, {"version",&pkg->version}, {"type",&pkg->type}, @@ -181,6 +184,12 @@ unsigned int parseinfo(char *s, struct package* dest) { // add to corresponding value in dict char** destbuff = hm_get(infohm, key); + + if(strcmp(key, "name") == 0) + { + // This is very stupid + continue; + } if (destbuff == NULL) { msg(WARNING, "Unknown key : '%s'", key); continue; diff --git a/include/globals.h b/include/globals.h index 433a149..b81ac47 100755 --- a/include/globals.h +++ b/include/globals.h @@ -8,11 +8,8 @@ START OF THE (sort of) CONSTANTS DECALRATIONS (They are not mean to be modified a lot) */ - // enable testing mode extern bool TESTING; -// overwrite file when installing -extern bool OVERWRITE; // enable verbose mode extern bool QUIET; // Flag indicating that no inputs are required diff --git a/include/libspm.h b/include/libspm.h index 1b177ea..4a8521b 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -57,6 +57,8 @@ struct packages { int count; int size; + // This should have probably been named 'pkg' or something + // using pkgs->buffer[i].… is not that nice struct package* buffer; }; @@ -130,7 +132,7 @@ struct packages* get_pkgs(char* path); // Dump contents of a database to a package array struct packages* dump_db(char* db_path); // Function returns an array of packages that need updating -struct packages* update(struct package* pkg); +struct packages* update_pkg(); /*repo.c*/ // Get currently present repos diff --git a/src/globals.c b/src/globals.c index 185fe0f..5757902 100644 --- a/src/globals.c +++ b/src/globals.c @@ -13,9 +13,6 @@ // Flag for testing mode bool TESTING = false; -// Flag for overwriting files -bool OVERWRITE = false; - // Flag for quiet mode (no verbose output) bool QUIET = true; diff --git a/src/install.c b/src/install.c index d68d74e..c7462b2 100755 --- a/src/install.c +++ b/src/install.c @@ -41,7 +41,9 @@ int install_package_source(struct package* pkg) // Set the package info section as environment vadiables for make script { + dbg(2, "%s", pkg->name); setenv("NAME", pkg->name, 1); + dbg(2, "%s", pkg->version); setenv("VERSION", pkg->version, 1); if (pkg->url != NULL) diff --git a/src/move.c b/src/move.c index e4eb176..fcb06f3 100755 --- a/src/move.c +++ b/src/move.c @@ -39,14 +39,8 @@ void move_binaries(char** locations, long loc_size) { // Check if the destination location is empty if (!(access(dest_loc, F_OK) != 0)) { - if (OVERWRITE) - { - remove(dest_loc); - } - else - { - msg(FATAL, "%s is already here, use --overwrite?", locations[i]); - } + dbg(1, "%s is already here", locations[i]); + remove(dest_loc); } if (locations[i] == NULL) diff --git a/src/pkg.c b/src/pkg.c index bc2cee3..2545823 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -69,8 +69,8 @@ int open_pkg(const char* path, struct package* pkg) sprintf(full_path, "%s/%s", path, pkg->path); dbg(3, "path: %s", full_path); // Check if the file exists - if (access(path, F_OK) != 0) { - msg(ERROR, "File %s does not exist\n", full_path); + if (access(full_path, F_OK) != 0) { + dbg(1, "File %s does not exist", full_path); return 1; } @@ -95,11 +95,11 @@ int open_pkg(const char* path, struct package* pkg) } } } else { - msg(ERROR, "File %s is not a valid package file", full_path); - return 1; + dbg(1, "File %s is not a valid package file", full_path); + return 2; } - msg(ERROR, "File %s is not a valid package file, or the format plugin isn't loaded", full_path); - return 1; + dbg(1, "File %s is not a valid package file, or the format plugin isn't loaded", full_path); + return 2; } // Create a package at the given path using the specified package structure @@ -220,8 +220,7 @@ struct packages* search_pkgs(char* db_path, char* term) while ((result = sqlite3_step(stmt)) == SQLITE_ROW) { - // TODO: - // This very is stupid + // TODO: This very is stupid const unsigned char* name = sqlite3_column_text(stmt, 0); const unsigned char* path = sqlite3_column_text(stmt, 1); if(strstr((const char*)name, term) != 0) @@ -277,9 +276,9 @@ struct packages* get_pkgs(char* path) int num_files; char **files_array = get_all_files(path, path, &num_files); if (files_array != NULL) - { + { + // TODO: get rid of the nested if's struct packages* pkgs = create_pkgs(num_files); - // Print each file path for (int j = 0; j < num_files; j++) { if(strstr(files_array[j], "/.") == NULL) @@ -297,12 +296,12 @@ struct packages* get_pkgs(char* path) while(strrchr(name, '/') != NULL) { - memmove(name, strrchr(name, '/') + 1, strlen(strrchr(name, '/') + 1) + 1); + memmove(name, strrchr(name, '/') + 1, strlen(strrchr(name, '/') + 1) + 1); /*tbh i just added +1 untill it worked*/ } name[strlen(name) - (strlen(getenv("SOVIET_DEFAULT_FORMAT")) + 1) /*+1 for the '.'*/] = '\0'; - dbg(1, "path is %s, name is %s", path, name); + dbg(1, "name: %s", name); struct package pkg = {0}; pkg.name = strdup(name); @@ -369,19 +368,64 @@ struct packages* dump_db(char* db_path) } // Function returns an array of packages that need updating -struct packages* update_pkg(struct package* pkg) +struct packages* update_pkg() { msg(INFO, "fetching updates"); - int new_version_found = 0; if(access(getenv("SOVIET_INSTALLED_DB"), F_OK) != 0) { msg(ERROR, "no installed DB found"); - return -1; + return create_pkgs(0); } struct packages* installed_packages = dump_db(getenv("SOVIET_INSTALLED_DB")); + if(installed_packages->count < 1) + { + msg(ERROR, "no installed packages"); + return create_pkgs(0); + } - if(new_version_found == 0) { msg(INFO, "all packages are up to date"); } - return 0; + struct packages* pkgs = create_pkgs(installed_packages->count); + + for(int i = 0; i < installed_packages->count; i++) + { + struct package remote_package = {0}; + remote_package.name = strdup(installed_packages->buffer[i].name); + remote_package.path = strdup(installed_packages->buffer[i].path); + // TODO: get rid of the nested if's + if (open_pkg(getenv("SOVIET_REPO_DIR"), &remote_package ) == 0) + { + if (open_pkg(getenv("SOVIET_SPM_DIR"), &(installed_packages->buffer[i])) == 0) + { + if(strcmp(remote_package.version, installed_packages->buffer[i].version) != 0) + { + // We don't actually know if it's older or newer + dbg(2, "package %s version %s differs from remote", installed_packages->buffer[i].name, installed_packages->buffer[i].version); + // I suppose it doens't matter which package we push + push_pkg(pkgs, &remote_package); + } + else + { + dbg(2, "package %s is up to date", installed_packages->buffer[i].name); + free_pkg(&remote_package); + } + } + else + { + // The local package does not exist, the database is corrupt/outdated + msg(ERROR, "package %s does not exist", installed_packages->buffer[i].name); + free_pkg(&remote_package); + } + } + else + { + // The package does not exist on the remote side + dbg(2, "package %s is local", installed_packages->buffer[i].name); + free_pkg(&remote_package); + } + + } + + free_pkgs(installed_packages); + return pkgs; } \ No newline at end of file diff --git a/src/repo.c b/src/repo.c index 62624b0..7969a48 100755 --- a/src/repo.c +++ b/src/repo.c @@ -112,8 +112,7 @@ int repo_sync() if (add_repo(submodule_name, repo_url) != 0) {msg(ERROR, "Failed to create the default repository");} } - // TODO: add a way to get all submodules and update them - // But maybe a single system call isn't too bad... + // TODO: get all submodules and update them without the system call // Update submodules chdir(repo_dir); if (system("git submodule update --depth 1 --remote --init --recursive") != 0) diff --git a/src/util.c b/src/util.c index e585f67..042a52e 100644 --- a/src/util.c +++ b/src/util.c @@ -294,7 +294,49 @@ int download(char* url, FILE* fp) { // Copy a file int cp(char* from, char* to) { - (void)from; - (void)to; - return 1; + struct stat st; + stat(from, &st); + int size = st.st_size; + int permissions = st.st_mode; + int owner = st.st_uid; + int group = st.st_gid; + + char* buffer = malloc(size); + + FILE *old_ptr; + FILE *new_ptr; + + old_ptr = fopen(from,"r"); + if (old_ptr == NULL) { + msg(ERROR,"Error opening file %s",from); + return -1; + } + fread(buffer, sizeof(char), size, old_ptr); + fclose(old_ptr); + + new_ptr = fopen(to,"w"); + if (new_ptr == NULL) { + msg(ERROR,"Error opening file %s",to); + return -2; + } + fwrite(buffer, sizeof(char), size, new_ptr); + int result = fclose(new_ptr); + + if (result != 0) { + msg(ERROR,"Error writing to file %s",to); + return -3; + } + + free(buffer); + + if (chown(to, owner, group) != 0) { + msg(ERROR,"Error changing owner of %s",to); + return -4; + } + if (chmod(to, permissions) != 0) { + msg(ERROR,"Error changing permissions of %s",to); + return -5; + } + + return 0; } \ No newline at end of file diff --git a/test/spm.c b/test/spm.c index 0e4e4dd..47c3c65 100644 --- a/test/spm.c +++ b/test/spm.c @@ -10,7 +10,6 @@ int main() setenv("SOVIET_DEBUG","3",1); DEBUG = 3; QUIET = false; - OVERWRITE = true; DEBUG_UNIT = NULL; /* END LIBSPM CONFIG */ @@ -31,9 +30,8 @@ int main() test_make(); test_move(); test_pkg(); - //test_repo(); + test_repo(); test_uninstall(); - test_util(); int leaks = check_leaks(); if (leaks > 0) diff --git a/test/test.c b/test/test.c index 0fed6c8..c27ce26 100644 --- a/test/test.c +++ b/test/test.c @@ -11,6 +11,7 @@ void test_check() setenv("SOVIET_FORMATS", "ecmp", 1); setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + // I'm heavily abusing the fact that there is no check on the validity of the package FILE *ptr; ptr = fopen("/tmp/cccp-test/test.ecmp","w"); fprintf(ptr, "[locations]\n"); @@ -154,7 +155,7 @@ void test_install() } struct package pkg = {0}; - pkg.name = "test"; + pkg.name = strdup("test"); pkg.path = strdup("test.ecmp"); result += open_pkg("/tmp/cccp-test", &pkg); @@ -225,7 +226,7 @@ void test_make() } struct package pkg = {0}; - pkg.name = "test"; + pkg.name = strdup("test"); pkg.path = strdup("test.ecmp"); result += open_pkg("/tmp/cccp-test", &pkg); @@ -316,6 +317,7 @@ void test_pkg() result += (pkgs->count - 10); dbg(2, "size %d - count %d", pkgs->size, pkgs->count); + dbg(2, "result: %d ", result); // Cleanup { free_pkgs(pkgs); @@ -366,12 +368,15 @@ void test_pkg() result += create_pkg("/tmp/cccp-test", &pkg_0); struct package pkg_1 = {0}; + pkg_1.name = strdup("test"); pkg_1.path = strdup("test-0.ecmp"); result += open_pkg("/tmp/cccp-test", &pkg_1); result += strcmp(pkg_1.name, "test"); result += strcmp(pkg_1.version, "0"); result += strcmp(pkg_1.type, "src"); result += strcmp(pkg_1.description, "test package\n"); + dbg(2, "Finished testing create and open package"); + dbg(2, "result: %d ", result); // Cleanup { @@ -396,7 +401,7 @@ void test_pkg() pmkdir(getenv("SOVIET_REPO_DIR")); pmkdir("/tmp/cccp-test/repo_dir/test_repo/long/repo/file/tree"); pmkdir(getenv("SOVIET_SPM_DIR")); - for(int i = 0; i < 15; i++) + for(int i = 0; i < 10; i++) { char dir[MAX_PATH]; sprintf(dir, "%s/%s/%d%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", i, ".ecmp"); @@ -419,26 +424,36 @@ void test_pkg() } } + // Get packages struct packages* pkgs = get_pkgs("/tmp/cccp-test/repo_dir/"); - result += (pkgs->count - 15); - for(int i = 0; i < 15; i++) + // there should be 10 packages in that directory + result += (pkgs->count - 10); + for(int i = 0; i < 10; i++) { char str[8]; sprintf(str, "%d", i); + // all the found packages should be 0-9 result += strcmp(pkgs->buffer[i].name, str); } + + // Create a database result += create_pkg_db("/tmp/cccp-test/test.db", pkgs); + + // Preform a search struct packages* search_result = search_pkgs("/tmp/cccp-test/test.db", "1"); - result += ((search_result->count) - 6); + // we should find only one '1' + result += (search_result->count - 1); result += strcmp(search_result->buffer[0].path, "test_repo/long/repo/file/tree/1.ecmp"); - result += strcmp(search_result->buffer[1].path, "test_repo/long/repo/file/tree/10.ecmp"); - // Test dump_db - // Test update_pkg + struct packages* db_pkgs = dump_db("/tmp/cccp-test/test.db"); + // there should be 10 packages in the database + result += (db_pkgs->count - 10); + dbg(2, "Finished testing package database"); // Cleanup { free_pkgs(pkgs); + free_pkgs(db_pkgs); free_pkgs(search_result); rmany(getenv("SOVIET_REPO_DIR")); rmany(getenv("SOVIET_SPM_DIR")); @@ -451,7 +466,113 @@ void test_pkg() // Test updating packages { + // Necessary prepwork + { + setenv("SOVIET_REPO_DIR", "/tmp/cccp-test/repo_dir", 1); + setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); + setenv("SOVIET_DEFAULT_FORMAT", "ecmp", 1); + setenv("SOVIET_FORMATS", "ecmp", 1); + setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); + + pmkdir(getenv("SOVIET_REPO_DIR")); + pmkdir("/tmp/cccp-test/repo_dir/test_repo/long/repo/file/tree"); + + pmkdir(getenv("SOVIET_SPM_DIR")); + pmkdir("/tmp/cccp-test/spm_dir/test_repo/long/repo/file/tree"); + // File 1 - outdated + { + char spm_dir[MAX_PATH]; + char repo_dir[MAX_PATH]; + sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", "outdated.ecmp"); + sprintf(spm_dir, "%s/%s/%s", getenv("SOVIET_SPM_DIR"), "test_repo/long/repo/file/tree", "outdated.ecmp"); + + FILE *ptr; + ptr = fopen(repo_dir,"w"); + fprintf(ptr, "[info]\n"); + fprintf(ptr, "name = outdated\n"); + fprintf(ptr, "version = 1\n"); + fclose(ptr); + + ptr = fopen(spm_dir,"w"); + fprintf(ptr, "[info]\n"); + fprintf(ptr, "name = outdated\n"); + fprintf(ptr, "version = 0\n"); + fclose(ptr); + } + + // File 2 - same + { + char spm_dir[MAX_PATH]; + char repo_dir[MAX_PATH]; + sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", "same.ecmp"); + sprintf(spm_dir, "%s/%s/%s", getenv("SOVIET_SPM_DIR"), "test_repo/long/repo/file/tree", "same.ecmp"); + + FILE *ptr; + ptr = fopen(repo_dir,"w"); + fprintf(ptr, "[info]\n"); + fprintf(ptr, "name = same\n"); + fprintf(ptr, "version = 1\n"); + fclose(ptr); + + ptr = fopen(spm_dir,"w"); + fprintf(ptr, "[info]\n"); + fprintf(ptr, "name = same\n"); + fprintf(ptr, "version = 1\n"); + fclose(ptr); + } + + // File 3 - local only + { + char spm_dir[MAX_PATH]; + sprintf(spm_dir, "%s/%s/%s", getenv("SOVIET_SPM_DIR"), "test_repo/long/repo/file/tree", "local.ecmp"); + + FILE *ptr; + ptr = fopen(spm_dir,"w"); + fprintf(ptr, "[info]\n"); + fprintf(ptr, "name = local\n"); + fprintf(ptr, "version = 1\n"); + fclose(ptr); + } + + struct packages* installed = get_pkgs(getenv("SOVIET_SPM_DIR")); + struct packages* remote = get_pkgs(getenv("SOVIET_REPO_DIR")); + + setenv("SOVIET_ALL_DB", "/tmp/cccp-test/all.db", 1); + setenv("SOVIET_INSTALLED_DB", "/tmp/cccp-test/installed.db", 1); + + create_pkg_db(getenv("SOVIET_ALL_DB"), remote); + create_pkg_db(getenv("SOVIET_INSTALLED_DB"), installed); + + free_pkgs(installed); + free_pkgs(remote); + } + + struct packages* need_updating = update_pkg(); + // We expect only one of the packages to need updating + result += (need_updating->count - 1); + dbg(2, "Finished testing package update"); + + result += strcmp(need_updating->buffer[0].name, "outdated"); + result += strcmp(need_updating->buffer[0].version, "1"); + + // Cleanup + { + free_pkgs(need_updating); + + rmany(getenv("SOVIET_REPO_DIR")); + rmany(getenv("SOVIET_SPM_DIR")); + rmany(getenv("SOVIET_ALL_DB")); + rmany(getenv("SOVIET_INSTALLED_DB")); + + unsetenv("SOVIET_REPO_DIR"); + unsetenv("SOVIET_SPM_DIR"); + unsetenv("SOVIET_DEFAULT_FORMAT"); + unsetenv("SOVIET_FORMATS"); + unsetenv("SOVIET_PLUGIN_DIR"); + unsetenv("SOVIET_ALL_DB"); + unsetenv("SOVIET_INSTALLED_DB"); + } } if(result != 0) msg(FATAL, "FAILED"); @@ -532,9 +653,4 @@ void test_uninstall() unsetenv("SOVIET_FORMATS"); unsetenv("SOVIET_PLUGIN_DIR"); } -} - -void test_util() -{ - return; -} +} \ No newline at end of file From d725ac5adf69d7b38a018d7a62a517b0c450dc34 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Tue, 24 Dec 2024 20:43:48 +0100 Subject: [PATCH 09/23] version bump --- include/libspm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libspm.h b/include/libspm.h index 4a8521b..57750b0 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -3,7 +3,7 @@ #include "cutils.h" #include "globals.h" -#define LIBSPM_VERSION 1.000 +#define LIBSPM_VERSION 1.001 #define SOURCE "src" #define BINARY "bin" From 8ea5beee9277959a49c38f30e01f3209735ea5cc Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:42:14 +0100 Subject: [PATCH 10/23] added a yes/no question function --- include/libspm.h | 4 +++- src/util.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/libspm.h b/include/libspm.h index 57750b0..5de63f1 100755 --- a/include/libspm.h +++ b/include/libspm.h @@ -165,4 +165,6 @@ int parse_env(char** in); // Download a file from url into FILE int download(char* url, FILE* fp); // Copy a file -int cp(char* from, char* to); \ No newline at end of file +int cp(char* from, char* to); +// Ask a yes/no queston +int get_input(char* prompt, int def); diff --git a/src/util.c b/src/util.c index 042a52e..d2ec46a 100644 --- a/src/util.c +++ b/src/util.c @@ -338,5 +338,54 @@ int cp(char* from, char* to) return -5; } + return 0; +} + +// Ask a yes/no queston +int get_input(char* prompt, int def) +{ + char* str = calloc(2, sizeof(char)); + + if(def == 0) + { + printf("%s (y/N)\n", prompt); + } + else + { + printf("%s (Y/n)\n", prompt); + } + + + if(AUTO) + { + free(str); + return def; + } + else + { + fgets(str, 2, stdin); + if ( strchr(str, '\n') == NULL ) + { + while ((getchar()) != '\n'); + } + + int i = 0; + + while (str[i] != '\n' && str[i] != '\0') + { + i++; + } + + if (str[i] == '\n') + { + str[i] = '\0'; + } + } + if(str[0] == 'Y' || str[0] == 'y') + { + free(str); + return 1; + } + free(str); return 0; } \ No newline at end of file From c50925376f50e90ba79024dec3fecc317aa0aeee Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 02:12:38 +0100 Subject: [PATCH 11/23] minor fixes --- src/pkg.c | 2 +- test/test.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pkg.c b/src/pkg.c index 2545823..15585e6 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -393,7 +393,7 @@ struct packages* update_pkg() remote_package.name = strdup(installed_packages->buffer[i].name); remote_package.path = strdup(installed_packages->buffer[i].path); // TODO: get rid of the nested if's - if (open_pkg(getenv("SOVIET_REPO_DIR"), &remote_package ) == 0) + if (open_pkg(getenv("SOVIET_REPOS_DIR"), &remote_package ) == 0) { if (open_pkg(getenv("SOVIET_SPM_DIR"), &(installed_packages->buffer[i])) == 0) { diff --git a/test/test.c b/test/test.c index c27ce26..33650fe 100644 --- a/test/test.c +++ b/test/test.c @@ -394,17 +394,17 @@ void test_pkg() { // Necessary prepwork { - setenv("SOVIET_REPO_DIR", "/tmp/cccp-test/repo_dir", 1); + setenv("SOVIET_REPOS_DIR", "/tmp/cccp-test/repo_dir", 1); setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); setenv("SOVIET_DEFAULT_FORMAT", "ecmp", 1); - pmkdir(getenv("SOVIET_REPO_DIR")); + pmkdir(getenv("SOVIET_REPOS_DIR")); pmkdir("/tmp/cccp-test/repo_dir/test_repo/long/repo/file/tree"); pmkdir(getenv("SOVIET_SPM_DIR")); for(int i = 0; i < 10; i++) { char dir[MAX_PATH]; - sprintf(dir, "%s/%s/%d%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", i, ".ecmp"); + sprintf(dir, "%s/%s/%d%s", getenv("SOVIET_REPOS_DIR"), "test_repo/long/repo/file/tree", i, ".ecmp"); FILE *ptr; ptr = fopen(dir,"w"); @@ -415,7 +415,7 @@ void test_pkg() for(int i = 0; i < 10; i++) { char dir[MAX_PATH]; - sprintf(dir, "%s/%s/%s-%d", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", ".ecmp", i); + sprintf(dir, "%s/%s/%s-%d", getenv("SOVIET_REPOS_DIR"), "test_repo/long/repo/file/tree", ".ecmp", i); FILE *ptr; ptr = fopen(dir,"w"); @@ -455,10 +455,10 @@ void test_pkg() free_pkgs(pkgs); free_pkgs(db_pkgs); free_pkgs(search_result); - rmany(getenv("SOVIET_REPO_DIR")); + rmany(getenv("SOVIET_REPOS_DIR")); rmany(getenv("SOVIET_SPM_DIR")); rmany("/tmp/cccp-test/test.db"); - unsetenv("SOVIET_REPO_DIR"); + unsetenv("SOVIET_REPOS_DIR"); unsetenv("SOVIET_DEFAULT_FORMAT"); unsetenv("SOVIET_SPM_DIR"); } @@ -468,13 +468,13 @@ void test_pkg() { // Necessary prepwork { - setenv("SOVIET_REPO_DIR", "/tmp/cccp-test/repo_dir", 1); + setenv("SOVIET_REPOS_DIR", "/tmp/cccp-test/repo_dir", 1); setenv("SOVIET_SPM_DIR", "/tmp/cccp-test/spm_dir", 1); setenv("SOVIET_DEFAULT_FORMAT", "ecmp", 1); setenv("SOVIET_FORMATS", "ecmp", 1); setenv("SOVIET_PLUGIN_DIR", "/var/cccp/plugins", 1); - pmkdir(getenv("SOVIET_REPO_DIR")); + pmkdir(getenv("SOVIET_REPOS_DIR")); pmkdir("/tmp/cccp-test/repo_dir/test_repo/long/repo/file/tree"); pmkdir(getenv("SOVIET_SPM_DIR")); @@ -484,7 +484,7 @@ void test_pkg() { char spm_dir[MAX_PATH]; char repo_dir[MAX_PATH]; - sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", "outdated.ecmp"); + sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPOS_DIR"), "test_repo/long/repo/file/tree", "outdated.ecmp"); sprintf(spm_dir, "%s/%s/%s", getenv("SOVIET_SPM_DIR"), "test_repo/long/repo/file/tree", "outdated.ecmp"); FILE *ptr; @@ -505,7 +505,7 @@ void test_pkg() { char spm_dir[MAX_PATH]; char repo_dir[MAX_PATH]; - sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPO_DIR"), "test_repo/long/repo/file/tree", "same.ecmp"); + sprintf(repo_dir, "%s/%s/%s", getenv("SOVIET_REPOS_DIR"), "test_repo/long/repo/file/tree", "same.ecmp"); sprintf(spm_dir, "%s/%s/%s", getenv("SOVIET_SPM_DIR"), "test_repo/long/repo/file/tree", "same.ecmp"); FILE *ptr; @@ -536,7 +536,7 @@ void test_pkg() } struct packages* installed = get_pkgs(getenv("SOVIET_SPM_DIR")); - struct packages* remote = get_pkgs(getenv("SOVIET_REPO_DIR")); + struct packages* remote = get_pkgs(getenv("SOVIET_REPOS_DIR")); setenv("SOVIET_ALL_DB", "/tmp/cccp-test/all.db", 1); setenv("SOVIET_INSTALLED_DB", "/tmp/cccp-test/installed.db", 1); @@ -560,12 +560,12 @@ void test_pkg() { free_pkgs(need_updating); - rmany(getenv("SOVIET_REPO_DIR")); + rmany(getenv("SOVIET_REPOS_DIR")); rmany(getenv("SOVIET_SPM_DIR")); rmany(getenv("SOVIET_ALL_DB")); rmany(getenv("SOVIET_INSTALLED_DB")); - unsetenv("SOVIET_REPO_DIR"); + unsetenv("SOVIET_REPOS_DIR"); unsetenv("SOVIET_SPM_DIR"); unsetenv("SOVIET_DEFAULT_FORMAT"); unsetenv("SOVIET_FORMATS"); From e93dd93102d85bbc9fb935f1d0df3c1505a047bd Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 02:42:49 +0100 Subject: [PATCH 12/23] minor fixes --- src/repo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/repo.c b/src/repo.c index 7969a48..5c4b7d4 100755 --- a/src/repo.c +++ b/src/repo.c @@ -117,8 +117,11 @@ int repo_sync() chdir(repo_dir); if (system("git submodule update --depth 1 --remote --init --recursive") != 0) { - printf("Failed to update submodules in %s\n", repo_dir); - return 3; + if(system("git submodule foreach --recursive git reset --hard") != 0) + { + printf("Failed to update submodules in %s\n", repo_dir); + } + return system("git submodule update --depth 1 --remote --init --recursive"); } git_repository_free(repo_handle); From eeb0605c9fb42c324b5e30b7bf432e816c11186b Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 02:46:30 +0100 Subject: [PATCH 13/23] minor fixes --- src/repo.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/repo.c b/src/repo.c index 5c4b7d4..79ee30c 100755 --- a/src/repo.c +++ b/src/repo.c @@ -115,13 +115,15 @@ int repo_sync() // TODO: get all submodules and update them without the system call // Update submodules chdir(repo_dir); + if(system("git submodule foreach --recursive git reset --hard") != 0) + { + printf("Failed to update submodules in %s\n", repo_dir); + return 3; + } if (system("git submodule update --depth 1 --remote --init --recursive") != 0) { - if(system("git submodule foreach --recursive git reset --hard") != 0) - { - printf("Failed to update submodules in %s\n", repo_dir); - } - return system("git submodule update --depth 1 --remote --init --recursive"); + printf("Failed to update submodules in %s\n", repo_dir); + return 3; } git_repository_free(repo_handle); From 430a1d1914a612c0abd479db9fe2a07b40f2409d Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 05:11:10 +0100 Subject: [PATCH 14/23] minor foxes --- src/util.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util.c b/src/util.c index d2ec46a..fb32d24 100644 --- a/src/util.c +++ b/src/util.c @@ -345,13 +345,16 @@ int cp(char* from, char* to) int get_input(char* prompt, int def) { char* str = calloc(2, sizeof(char)); + char def_char; if(def == 0) { + def_char = 'N'; printf("%s (y/N)\n", prompt); } else { + def_char = 'Y'; printf("%s (Y/n)\n", prompt); } @@ -381,6 +384,11 @@ int get_input(char* prompt, int def) str[i] = '\0'; } } + if(str[0] == '\0') + { + str[0] = def_char; + str[1] = '\0'; + } if(str[0] == 'Y' || str[0] == 'y') { free(str); From ec21fc1a263de7a02c8c606a7ecaa6710003275a Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 05:18:15 +0100 Subject: [PATCH 15/23] minor fixes --- src/globals.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/globals.c b/src/globals.c index 5757902..65fef89 100644 --- a/src/globals.c +++ b/src/globals.c @@ -5,9 +5,6 @@ #include "cutils.h" #include "globals.h" -// Define a constant for the maximum queue size -#define QUEUE_MAX 256 - // Declare global variables // Flag for testing mode @@ -18,6 +15,3 @@ bool QUIET = true; // Flag indicating that no inputs are required bool AUTO = false; - -// Array for package queue and its count -struct packages* PACKAGE_QUEUE = {0}; From a90b6a1ce667d2e7776c5b0a48b5d95020cbabee Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 05:52:57 +0100 Subject: [PATCH 16/23] minor fixes --- formats/ecmp/ecmp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/formats/ecmp/ecmp.c b/formats/ecmp/ecmp.c index 01b379e..b388aad 100644 --- a/formats/ecmp/ecmp.c +++ b/formats/ecmp/ecmp.c @@ -102,7 +102,7 @@ int open(char* path,struct package* pkg) for (unsigned int i = 0; i < count; i++) { void** options = hm_get(hm,sections[i]->name); if (options == NULL) { - msg(WARNING,"Unknown section : %s",sections[i]->name); + msg(FATAL,"Unknown section : %s",sections[i]->name); free(sections[i]->buff); continue; } @@ -116,7 +116,7 @@ int open(char* path,struct package* pkg) } else { - msg(WARNING,"Unknown parser for section : %s",sections[i]->name); + msg(FATAL,"Unknown parser for section : %s",sections[i]->name); } } dbg(2,"done parsing | returning"); @@ -178,7 +178,7 @@ unsigned int parseinfo(char *s, struct package* dest) { char* key = strtok(nlist[i], "="); char* value = strtok(NULL, "="); if (key == NULL || value == NULL) { - msg(WARNING, "Invalid key-value pair: '%s'", nlist[i]); + msg(FATAL, "Invalid key-value pair: '%s'", nlist[i]); continue; } @@ -191,7 +191,7 @@ unsigned int parseinfo(char *s, struct package* dest) { continue; } if (destbuff == NULL) { - msg(WARNING, "Unknown key : '%s'", key); + msg(FATAL, "Unknown key : '%s'", key); continue; } From 2144c65bdf7de62d1e0eba80ddc15e46e6df6199 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 07:02:06 +0100 Subject: [PATCH 17/23] minor fixes --- src/make.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/make.c b/src/make.c index ac4f5b6..3fa0479 100755 --- a/src/make.c +++ b/src/make.c @@ -56,6 +56,9 @@ int make(struct package* pkg) { sprintf(location, "%s/%s", getenv("SOVIET_MAKE_DIR"), file_name); sprintf(source_location, "%s/%s-%s", getenv("SOVIET_SOURCE_DIR"), getenv("NAME"), getenv("VERSION")); sprintf(source_file_location, "%s/%s-%s/%s", getenv("SOVIET_SOURCE_DIR"), getenv("NAME"), getenv("VERSION"), file_name); + dbg(4,location); + dbg(4,source_location); + dbg(4,source_file_location); dbg(1, "Downloading %s", file_name); @@ -115,11 +118,11 @@ int make(struct package* pkg) { dbg(1, "Download finished"); - //cp(location, source_file_location); + cp(location, source_file_location); } else { dbg(1, "Loading form %s", source_location); - //cp(source_file_location, location); + cp(source_file_location, location); } free(files); From 869d6cfa07492c9414216974ac9e71526f6266a8 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 08:03:29 +0100 Subject: [PATCH 18/23] minor fixes --- makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index 1389c7b..36dff17 100755 --- a/makefile +++ b/makefile @@ -34,6 +34,7 @@ DBGFLAGS = -g -fsanitize=address -lasan # set local lib to lib/*/*.a LOCAL_LIBS = $(wildcard lib/*/*.a) +LOCAL_LIBS_DIRS = $(wildcard lib/*/) LIBS = ${LOCAL_LIBS} -lgit2 -lsqlite3 -lcurl -lm -lcrypto # change these to proper directories where each file should be @@ -90,7 +91,7 @@ debug: libs $(BINDIR)/$(LIBOUT) formats @echo "Build done (debug)" libs: - for i in $(LOCAL_LIBS); do make -C $$(dirname $$i) all; done + for i in $(LOCAL_LIBS_DIRS); do make -C $$i all; done direct: $(CC) $(CFLAGS) $(SRCS) $(LIBS) -g -shared -fPIC -o $(BINDIR)/$(LIBOUT) From bb59a5a4a5fc25bef867bf148c00c796b216a138 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 09:24:22 +0100 Subject: [PATCH 19/23] minor fixes --- lib/cutils | 2 +- src/util.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cutils b/lib/cutils index a91260e..aa5eacf 160000 --- a/lib/cutils +++ b/lib/cutils @@ -1 +1 @@ -Subproject commit a91260eba0df2f622be2389c04ddb0780a703751 +Subproject commit aa5eacfc3067aab375068521ca8cebdc363a1258 diff --git a/src/util.c b/src/util.c index fb32d24..cb2d7ef 100644 --- a/src/util.c +++ b/src/util.c @@ -316,6 +316,7 @@ int cp(char* from, char* to) new_ptr = fopen(to,"w"); if (new_ptr == NULL) { + free(buffer); msg(ERROR,"Error opening file %s",to); return -2; } @@ -323,6 +324,7 @@ int cp(char* from, char* to) int result = fclose(new_ptr); if (result != 0) { + free(buffer); msg(ERROR,"Error writing to file %s",to); return -3; } From ecfca500e98a5e9010d8a39590cfc413c440c508 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:28:56 +0100 Subject: [PATCH 20/23] minor fixes --- formats/ecmp/ecmp.c | 17 ++++++++++------- lib/cutils | 2 +- makefile | 2 +- src/clean.c | 1 + src/config.c | 1 - src/init.c | 1 + src/pkg.c | 5 +++++ test/test.c | 1 + 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/formats/ecmp/ecmp.c b/formats/ecmp/ecmp.c index b388aad..167b607 100644 --- a/formats/ecmp/ecmp.c +++ b/formats/ecmp/ecmp.c @@ -45,7 +45,7 @@ int open(char* path,struct package* pkg) } void* parsers[][3] = { - {parseinfo,pkg,NULL}, + {parseinfo,&pkg,NULL}, {parseraw,&pkg->info.install,NULL}, {parseraw,&pkg->info.prepare,NULL}, @@ -124,6 +124,7 @@ int open(char* path,struct package* pkg) // free sections for (unsigned int i = 0; i < count; i++) { free(sections[i]->name); + free(sections[i]->buff); free(sections[i]); } free(sections); @@ -139,10 +140,10 @@ int open(char* path,struct package* pkg) unsigned int parsenl(char* s,char*** dest) { - char* str; + //char* str; // the parseraw below is useless but i'll keep since in case - parseraw(s,&str); - return splita(str,'\n',dest); + //parseraw(s,&str); + return splita(s,'\n',dest); } unsigned int parseraw(char* s, char** dest) { @@ -151,7 +152,7 @@ unsigned int parseraw(char* s, char** dest) // So we are just going to copy the pointer to it // In the last version , we were copying the string to a new buffer // Because the `s` string was a buffer that was going to be freed by `getline()` - *dest = s; + *dest = strdup(s); return strlen(s); } @@ -188,6 +189,7 @@ unsigned int parseinfo(char *s, struct package* dest) { if(strcmp(key, "name") == 0) { // This is very stupid + free(nlist[i]); continue; } if (destbuff == NULL) { @@ -199,14 +201,15 @@ unsigned int parseinfo(char *s, struct package* dest) { if (*destbuff == NULL) { msg(ERROR, "Error allocating memory for %s value", key); free(nlist); - free(s); + //free(s); return 0; } dbg(3, "Setting destbuff to %p - %s", *destbuff, *destbuff); + free(nlist[i]); } free(nlist); - free(s); + //free(s); return 0; } diff --git a/lib/cutils b/lib/cutils index aa5eacf..733227a 160000 --- a/lib/cutils +++ b/lib/cutils @@ -1 +1 @@ -Subproject commit aa5eacfc3067aab375068521ca8cebdc363a1258 +Subproject commit 733227ab088f486100b0e5172c99dc9126d24cea diff --git a/makefile b/makefile index 36dff17..66c04cd 100755 --- a/makefile +++ b/makefile @@ -91,7 +91,7 @@ debug: libs $(BINDIR)/$(LIBOUT) formats @echo "Build done (debug)" libs: - for i in $(LOCAL_LIBS_DIRS); do make -C $$i all; done + for i in $(LOCAL_LIBS_DIRS); do make -C $$i clean all; done direct: $(CC) $(CFLAGS) $(SRCS) $(LIBS) -g -shared -fPIC -o $(BINDIR)/$(LIBOUT) diff --git a/src/clean.c b/src/clean.c index 1e630e0..58ef710 100755 --- a/src/clean.c +++ b/src/clean.c @@ -48,6 +48,7 @@ void clean_install() rmany(full_cleanup_path); } + free(cleanup_loc[i]); free(full_cleanup_path); } free(cleanup_loc); diff --git a/src/config.c b/src/config.c index d7e1690..b5abaa4 100755 --- a/src/config.c +++ b/src/config.c @@ -111,6 +111,5 @@ int readConfig(const char* configFilePath, int overwrite) setenv(configEntries[i].key, configEntries[i].default_value, overwrite); } } - return 0; } diff --git a/src/init.c b/src/init.c index 87a6059..8b6ffa5 100755 --- a/src/init.c +++ b/src/init.c @@ -51,6 +51,7 @@ void init() { msg(ERROR, "Format plugin %s not found", format); exit(1); } + free(formats[i]); } //free(*formats); diff --git a/src/pkg.c b/src/pkg.c index 15585e6..5c25c9a 100644 --- a/src/pkg.c +++ b/src/pkg.c @@ -90,10 +90,13 @@ int open_pkg(const char* path, struct package* pkg) { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "open", full_path, pkg); + free(FORMATS[i]); free(FORMATS); return 0; } + free(FORMATS[i]); } + free(FORMATS); } else { dbg(1, "File %s is not a valid package file", full_path); return 2; @@ -134,9 +137,11 @@ int create_pkg(char* in_path, struct package* pkg) { dbg(2, "Opening package with %s format", FORMATS[i]); runFormatLib(FORMATS[i], "create", path, pkg); + free(FORMATS[i]); free(FORMATS); return 0; } + free(FORMATS[i]); } } msg(ERROR,"File %s is not a valid package file, or the format plugin isn't loaded", path); diff --git a/test/test.c b/test/test.c index 33650fe..1fd1c45 100644 --- a/test/test.c +++ b/test/test.c @@ -155,6 +155,7 @@ void test_install() } struct package pkg = {0}; + pkg.name = strdup("test"); pkg.path = strdup("test.ecmp"); From fe012f2a541045396eda38277f249f63d1d546c6 Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:30:59 +0100 Subject: [PATCH 21/23] minor fixes --- include/globals.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/globals.h b/include/globals.h index b81ac47..8a3f144 100755 --- a/include/globals.h +++ b/include/globals.h @@ -1,6 +1,7 @@ #include "stdbool.h" -#define QUEUE_MAX 256 +// This is very stupid, but I don't want to work on this right now. +#define QUEUE_MAX 65536 #define MAX_PATH 2048 /* From 102ad2cbd7e76943a712899fe77a65cb732625cf Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:41:21 +0100 Subject: [PATCH 22/23] update cutils --- lib/cutils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cutils b/lib/cutils index 733227a..0d4e262 160000 --- a/lib/cutils +++ b/lib/cutils @@ -1 +1 @@ -Subproject commit 733227ab088f486100b0e5172c99dc9126d24cea +Subproject commit 0d4e2628bc08d3b4a8a25a90375ee1ab561088a5 From a3292ccf959e72fb29cceebc2c454d6cf55c905b Mon Sep 17 00:00:00 2001 From: AleksArt000 <69528329+AleksArt000@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:46:51 +0100 Subject: [PATCH 23/23] fixed CI --- .github/workflows/c-cpp.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 2d3aa6a..53530ce 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -22,6 +22,10 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libcurl4-openssl-dev + - name: Install libsqlite3-dev + run: | + sudo apt-get update + sudo apt-get install -y libsqlite3-dev - name: Install libgit2 run: | curl -L https://codeload.github.com/libgit2/libgit2/tar.gz/refs/tags/v1.8.1 --output libgit2-1.8.1.tar.gz