aboutsummaryrefslogtreecommitdiff
path: root/snag/src
diff options
context:
space:
mode:
Diffstat (limited to 'snag/src')
-rw-r--r--snag/src/download_db.h12
-rw-r--r--snag/src/main.c9
-rw-r--r--snag/src/package.h11
-rw-r--r--snag/src/package_db.c6
-rw-r--r--snag/src/source_db.c (renamed from snag/src/download_db.c)120
-rw-r--r--snag/src/source_db.h10
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