diff options
| author | Jack Jamison <jackqjamison@gmail.com> | 2026-07-23 15:34:43 -0400 |
|---|---|---|
| committer | Jack Jamison <jackqjamison@gmail.com> | 2026-07-23 15:34:43 -0400 |
| commit | 9282991429a92d6df17213acdc49fe687f42da6c (patch) | |
| tree | 0e7ca7f74ba0c8b445956eab4d47545e0adcf407 /snag/src | |
| parent | d9bc99629dd3f8624df98ead06f400c4ffb3880b (diff) | |
download db is now source db, ready to start build
Diffstat (limited to 'snag/src')
| -rw-r--r-- | snag/src/download_db.h | 12 | ||||
| -rw-r--r-- | snag/src/main.c | 9 | ||||
| -rw-r--r-- | snag/src/package.h | 11 | ||||
| -rw-r--r-- | snag/src/package_db.c | 6 | ||||
| -rw-r--r-- | snag/src/source_db.c (renamed from snag/src/download_db.c) | 120 | ||||
| -rw-r--r-- | snag/src/source_db.h | 10 |
6 files changed, 88 insertions, 80 deletions
diff --git a/snag/src/download_db.h b/snag/src/download_db.h deleted file mode 100644 index d45817f..0000000 --- a/snag/src/download_db.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef DOWNLOAD_DB_H -#define DOWNLOAD_DB_H - -#include "package.h" - -typedef struct { - char* download_path; -} package_download_t; - -bool package_get_download(package_info_t* pkg, package_download_t* download); - -#endif diff --git a/snag/src/main.c b/snag/src/main.c index c5a0736..5835859 100644 --- a/snag/src/main.c +++ b/snag/src/main.c @@ -3,7 +3,7 @@ #include "util.h" #include "package_db.h" #include "build_db.h" -#include "download_db.h" +#include "source_db.h" int cmd_install(char* cmd_name, ArgParser* parser); @@ -46,9 +46,10 @@ int cmd_install(char* cmd_name, ArgParser* parser) { if (load_package_info(pkgid, &info)) { print("Installing %s - %s\n", info.attrs.name, info.attrs.desc); - // download or retrieve package download - package_download_t download; - if (!package_get_download(&info, &download)) continue; + // confirm that package source exists or is downloaded + if (!verify_source(&info.attrs.source) && !download_source(&info.attrs.source)) { + continue; + } // run the package install package_run_build(&info); diff --git a/snag/src/package.h b/snag/src/package.h index a96c5c1..54009c1 100644 --- a/snag/src/package.h +++ b/snag/src/package.h @@ -3,8 +3,12 @@ #include <stdbool.h> -// this struct is the "handle" of a package to be passed into other package -// functions +typedef struct { + char* name; + char* url; + char* checksum; +} source_info_t; + typedef struct { char* script_path; struct { @@ -15,8 +19,7 @@ typedef struct { char* webpage; char* license; char* version; - char* source_url; - char* source_checksum; + source_info_t source; } attrs; } package_info_t; diff --git a/snag/src/package_db.c b/snag/src/package_db.c index 533b66a..036e284 100644 --- a/snag/src/package_db.c +++ b/snag/src/package_db.c @@ -105,10 +105,12 @@ bool load_package_info(char* pkgid, package_info_t* info) { info->attrs.license = &info->attrs.buffer[i]; break; case 'v': info->attrs.version = &info->attrs.buffer[i]; break; + case 's': + info->attrs.source.name = &info->attrs.buffer[i]; break; case 'u': - info->attrs.source_url = &info->attrs.buffer[i]; break; + info->attrs.source.url = &info->attrs.buffer[i]; break; case 'c': - info->attrs.source_checksum = &info->attrs.buffer[i]; break; + info->attrs.source.checksum = &info->attrs.buffer[i]; break; } while(info->attrs.buffer[i] != '\0' && i < bytes_read) i++; i++; diff --git a/snag/src/download_db.c b/snag/src/source_db.c index e0aa85e..ab7ec99 100644 --- a/snag/src/download_db.c +++ b/snag/src/source_db.c @@ -1,4 +1,4 @@ -#include "download_db.h" +#include "source_db.h" #include "util.h" @@ -9,78 +9,52 @@ #include <unistd.h> #include <errno.h> -// note: fixed location of download database for now -const char download_db_path[] = "./var/snag/downloads"; - // libcrpyto context EVP_MD_CTX *mdctx = NULL; const EVP_MD *md = NULL; +void ensure_libcrypto(); // curl context CURL *curl = NULL; +void ensure_libcurl(); -static size_t download_write_callback(char* ptr, size_t size, size_t nmemb, void* usrdata) { - // write the curl data to the file in usr data - size_t written = fwrite(ptr, size, nmemb, (FILE *)usrdata); +// note: fixed location of source database for now +const char source_db_path[] = "./var/snag/sources"; +char* get_source_path(source_info_t* source) { return join_path(source_db_path, source->name); } - // update the hash with the new data - EVP_DigestUpdate(mdctx, ptr, written); +bool verify_source(source_info_t* source) { + // verify source exists + char* source_path = get_source_path(source); + bool verified = access(source_path, F_OK) == 0; - return written; + // todo(jqj): actually verify checksum + free(source_path); + return verified; } -bool package_get_download(package_info_t* pkg, package_download_t* download) { - memset(download, 0, sizeof(*download)); - - // construct path of download - // note(jqj): extension is fixed to tar gz until the switch out download - // attrs for the swenu api download command which will specify - // more information - char* download_path = vastrcat(download_db_path, "/", pkg->attrs.id, "-", pkg->attrs.version, ".tar.gz"); +static size_t download_write_callback(char* ptr, size_t size, size_t nmemb, void* usrdata); +bool download_source(source_info_t* source) { - // return download if it already exists in database - if (access(download_path, F_OK) == 0) { - // todo(jqj): verify checksum anyway - download->download_path = download_path; - return true; - } else { - print("Downloading %s\n", pkg->attrs.source_url); - } + char* source_path = get_source_path(source); + print("Downloading %s\n", source->url); - // initialize curl if it isn't already - if (curl == NULL) { - CURLcode result = curl_global_init(CURL_GLOBAL_ALL); - if (result != CURLE_OK) die("failed to initialize curl: %s", curl_easy_strerror(result)); - curl = curl_easy_init(); // note(jqj): for now we reuse one easy curl object - if (curl == NULL) die("failed to initialize easy curl"); + // initialize libcurl and libcrypto if they aren't already + ensure_libcurl(); + ensure_libcrypto(); - /* come back to this if we have init and deinit */ - /* curl_easy_cleanup(curl); */ - /* curl_global_cleanup(); */ - } - - // initialize libcrypto context if it isn't already - if (mdctx == NULL) { - mdctx = EVP_MD_CTX_new(); - md = EVP_sha256(); - - /* come back to this if we have init and deinit */ - /* EVP_MD_CTX_free(mdctx); */ - } - - // initialize up sha256 hash + // initialize sha256 hash EVP_DigestInit_ex(mdctx, md, NULL); // open file for writing - FILE* download_file = fopen(download_path, "wb"); - if (download_file == NULL) die("failed open download file for writing (%s): %s", download_path, strerror(errno)); + FILE* download_file = fopen(source_path, "wb"); + if (download_file == NULL) die("failed open download file for writing (%s): %s", source_path, strerror(errno)); // make curl request with url and output file // callback writes to the file and feeds the hash - curl_easy_setopt(curl, CURLOPT_URL, pkg->attrs.source_url); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, download_file); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_write_callback); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_URL, source->url); CURLcode result = curl_easy_perform(curl); fclose(download_file); if(result != CURLE_OK) { @@ -102,18 +76,48 @@ bool package_get_download(package_info_t* pkg, package_download_t* download) { hash_hex[SHA256_DIGEST_LENGTH * 2] = '\0'; // confirm that checksum matches - assert(pkg->attrs.source_checksum != NULL); - if (strcmp(pkg->attrs.source_checksum, hash_hex) == 0) { + assert(source->checksum != NULL); + if (strcmp(source->checksum, hash_hex) == 0) { print("checksum verified for download: %s\n", hash_hex); - download->download_path = download_path; return true; } else { print("FAIL: bad checksum for download: %s\n", hash_hex); goto fail; } - fail: - if (access(download_path, F_OK) == 0) remove(download_path); - free(download_path); +fail: + if (access(source_path, F_OK) == 0) remove(source_path); + free(source_path); return false; } + +static size_t download_write_callback(char* ptr, size_t size, size_t nmemb, void* usrdata) { + // write the curl data to the file in usr data + size_t written = fwrite(ptr, size, nmemb, (FILE *)usrdata); + + // update the hash with the new data + EVP_DigestUpdate(mdctx, ptr, written); + + return written; +} + +void ensure_libcrypto() { + if (mdctx == NULL) { + mdctx = EVP_MD_CTX_new(); + md = EVP_sha256(); + /* come back to this if we have init and deinit */ + /* EVP_MD_CTX_free(mdctx); */ + } +} + +void ensure_libcurl() { + if (curl == NULL) { + CURLcode result = curl_global_init(CURL_GLOBAL_ALL); + if (result != CURLE_OK) die("failed to initialize curl: %s", curl_easy_strerror(result)); + curl = curl_easy_init(); // note(jqj): for now we reuse one easy curl object + if (curl == NULL) die("failed to initialize easy curl"); + /* come back to this if we have init and deinit */ + /* curl_easy_cleanup(curl); */ + /* curl_global_cleanup(); */ + } +} diff --git a/snag/src/source_db.h b/snag/src/source_db.h new file mode 100644 index 0000000..e22f221 --- /dev/null +++ b/snag/src/source_db.h @@ -0,0 +1,10 @@ +#ifndef SOURCE_DB_H +#define SOURCE_DB_H + +#include "package.h" + +bool verify_source(source_info_t* source); +bool download_source(source_info_t* source); +bool unpack_source(source_info_t* source, char* dest_path); + +#endif |
