From 351f7c076f78a09336ba42ada03cf7529f54f1cc Mon Sep 17 00:00:00 2001 From: Tristan Smith Date: Sat, 31 Aug 2024 15:45:10 -0400 Subject: [PATCH] Downloads, unpacks, doesn't get the right directory currently. --- .gitignore | 3 ++ src/build.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/caur.h | 19 ++++++++++- src/config.c | 21 ++++++++++++ src/download.c | 26 +++++++++----- src/main.c | 25 +++++++++----- src/unpack.c | 28 +++++++++++++++ 7 files changed, 198 insertions(+), 17 deletions(-) create mode 100644 src/build.c create mode 100644 src/config.c create mode 100644 src/unpack.c diff --git a/.gitignore b/.gitignore index a9e97e5..785910d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ src/*.o *.o caur +*.tar.gz +*.bak +cleanup.sh diff --git a/src/build.c b/src/build.c new file mode 100644 index 0000000..9c5be70 --- /dev/null +++ b/src/build.c @@ -0,0 +1,93 @@ +#include "caur.h" +#include +#include +#include +#include +#include +#include +#include + +int setup_cache_directory(char *cache_dir, size_t size) { + const char *home = getenv("HOME"); + if (home == NULL) { + fprintf(stderr, "Could not determine the user's home directory.\n"); + return 1; + } + + snprintf(cache_dir, size, "%s/.config/caur", home); + + struct stat st = {0}; + if (stat(cache_dir, &st) == -1) { + if (mkdir(cache_dir, 0755) == -1) { + fprintf(stderr, "Failed to create cache directory: %s\n", strerror(errno)); + return 1; + } else { + printf("Cache directory created: %s\n", cache_dir); + } + } else { + printf("Cache directory already exists: %s\n", cache_dir); + } + + return 0; +} + +int build_package(const char *package_name) { + char cache_dir[1024]; + char tar_file[1024]; + char unpack_dir[1024]; + char build_command[1024]; + + int ret; + + // Set up the cache directory + if (setup_cache_directory(cache_dir, sizeof(cache_dir)) != 0) { + return 1; + } + + // Path to the downloaded .tar.gz file + ret = snprintf(tar_file, sizeof(tar_file), "%s/%s.tar.gz", cache_dir, package_name); + if ((size_t)ret >= sizeof(tar_file)) { + fprintf(stderr, "Warning: tar_file path was truncated.\n"); + return 1; + } + + // Check if the tar.gz file exists + struct stat st; + if (stat(tar_file, &st) != 0) { + fprintf(stderr, "Error: The file %s does not exist. Please check the download process.\n", tar_file); + return 1; + } + + // Create directory to unpack the files into + ret = snprintf(unpack_dir, sizeof(unpack_dir), "%s/%s", cache_dir, package_name); + if ((size_t)ret >= sizeof(unpack_dir)) { + fprintf(stderr, "Warning: unpack_dir path was truncated.\n"); + return 1; + } + mkdir(unpack_dir, 0755); + + // Unpack the downloaded .tar.gz file + if (unpack_tar_gz(tar_file, unpack_dir) != 0) { + return 1; + } + + // Change directory to unpacked location and build the package + ret = snprintf(build_command, sizeof(build_command), "cd %s && makepkg -si", unpack_dir); + if ((size_t)ret >= sizeof(build_command)) { + fprintf(stderr, "Warning: build_command was truncated.\n"); + return 1; + } + + int result = system(build_command); + if (result == -1) { + fprintf(stderr, "Failed to execute build command\n"); + return 1; + } else if (WIFEXITED(result) && WEXITSTATUS(result) != 0) { + fprintf(stderr, "Build failed with exit status %d.\n", WEXITSTATUS(result)); + return 1; + } + + printf("Package %s built and installed successfully.\n", package_name); + return 0; +} + diff --git a/src/caur.h b/src/caur.h index 150fb08..151f603 100644 --- a/src/caur.h +++ b/src/caur.h @@ -4,13 +4,30 @@ #include #include +// Define the URL for the AUR package and the file extension +#define AUR_PACKAGE_URL "https://aur.archlinux.org/cgit/aur.git/snapshot/" +#define AUR_PACKAGE_URL_END ".tar.gz" + // Function to write data to file size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream); // Function to download a package from the AUR -int download_package(const char *package_name); +int download_package(const char *package_name, const char *cache_dir); // Function to perform a system upgrade int perform_system_upgrade(); +// Function to create cache/build directory +int setup_cache_directory(char *cache_dir, size_t size); + +// Function to unpack archived .tar.gz file +// TODO: Look into seeing if other archive formats are used +int unpack_tar_gz(const char *filename, const char *destination); + +// Function to build package +int build_package(const char *package_name); + +// Reading user config file +FILE *open_config_file(const char *cache_dir); + #endif // CAUR_H diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..150cc18 --- /dev/null +++ b/src/config.c @@ -0,0 +1,21 @@ +#include +#include + +FILE *open_config_file(const char *cache_dir) { + char config_file[512]; + + // Construct the full path to the config file + if ((size_t)snprintf(config_file, sizeof(config_file), "%s/config", cache_dir) >= sizeof(config_file)) { + fprintf(stderr, "config_file was truncated\n"); + return NULL; + } + + // Attempt to open the config file + FILE *file = fopen(config_file, "r"); + if (file == NULL) { + fprintf(stderr, "Could not open config file: %s\n", config_file); + return NULL; + } + + return file; +} \ No newline at end of file diff --git a/src/download.c b/src/download.c index 77c1224..d55b18a 100644 --- a/src/download.c +++ b/src/download.c @@ -1,23 +1,24 @@ #include "caur.h" -#include - -#define AUR_PACKAGE_URL "https://aur.archlinux.org/cgit/aur.git/snapshot/" -#define AUR_PACKAGE_URL_END ".tar.gz" +#include +#include +#include +#include size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t written = fwrite(ptr, size, nmemb, stream); return written; } -int download_package(const char *package_name) { +int download_package(const char *package_name, const char *cache_dir) { CURL *curl; FILE *fp; CURLcode res; char url[256]; - char outfilename[256]; + char outfilename[512]; + // Construct the URL and output file path snprintf(url, sizeof(url), "%s%s%s", AUR_PACKAGE_URL, package_name, AUR_PACKAGE_URL_END); - snprintf(outfilename, sizeof(outfilename), "%s%s", package_name, AUR_PACKAGE_URL_END); + snprintf(outfilename, sizeof(outfilename), "%s/%s%s", cache_dir, package_name, AUR_PACKAGE_URL_END); curl = curl_easy_init(); if (curl) { @@ -38,10 +39,19 @@ int download_package(const char *package_name) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); return 1; } + + // Check if the file was downloaded correctly + struct stat st; + if (stat(outfilename, &st) != 0) { + fprintf(stderr, "Downloaded file %s not found.\n", outfilename); + return 1; + } + + printf("Downloaded file %s successfully, size: %ld bytes\n", outfilename, st.st_size); } else { fprintf(stderr, "Failed to init curl\n"); return 1; } return 0; -} \ No newline at end of file +} diff --git a/src/main.c b/src/main.c index e97422e..df347f6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -// Version: 0.1.1 +// Version: 0.1.5 // date created 8-31-24 #include "caur.h" @@ -12,7 +12,14 @@ // #include // Parsing packing information from the AUR packages int main(int argc, char *argv[]) { + char cache_dir[1024]; + // Setup cache directory + if (setup_cache_directory(cache_dir, sizeof(cache_dir)) != 0) { + return 1; + } + + // Perform system upgrade if fewer characters than 1 are entered. if (argc < 2) { printf("Performing system upgrade...\n"); return perform_system_upgrade(); @@ -22,18 +29,20 @@ int main(int argc, char *argv[]) { const char *package_name = argv[1]; // Call download function with provided package name - if (download_package(package_name) == 0) { + if (download_package(package_name, cache_dir) == 0) { printf("Package %s downloaded successfully\n", package_name); + + // Build and install the package + if (build_package(package_name) == 0) { + printf("Successfully built and installed %s!\n", package_name); + } else { + printf("Building package %s failed.\n", package_name); + } } else { printf("Failed to download package %s\n", package_name); } return 0; - /* const char *package_name = "neofetch"; - if (download_package(package_name) == 0) { - printf("Package downloaded successfully\n"); - } else { - printf("Failed to download package"); - } */ + } diff --git a/src/unpack.c b/src/unpack.c new file mode 100644 index 0000000..0e9cd1e --- /dev/null +++ b/src/unpack.c @@ -0,0 +1,28 @@ +#include // For system() +#include // For printf(), fprintf() +#include // System calls need to CTFD + +#include "caur.h" + +int unpack_tar_gz(const char *filename, const char *destination) { + char command[1024]; + int ret = snprintf(command, sizeof(command), "tar -xzf %s --strip-components=1 -C %s", filename, destination); + + if ((size_t)ret >= sizeof(command)) { + fprintf(stderr, "Warning: tar command was truncated.\n"); + return 1; + } + + int result = system(command); + if (result == -1) { + fprintf(stderr, "Failed to execute tar command\n"); + return 1; + } else if (WIFEXITED(result) && WEXITSTATUS(result) != 0) { + fprintf(stderr, "Unpacking failed with exit status %d.\n", WEXITSTATUS(result)); + return 1; + } + + printf("Successfully unpacked %s to %s\n", filename, destination); + return 0; +} +