aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config_global.c43
-rw-r--r--src/manifest.c157
-rw-r--r--src/spm.c28
3 files changed, 181 insertions, 47 deletions
diff --git a/src/config_global.c b/src/config_global.c
index bbce6ef..d4e7e69 100644
--- a/src/config_global.c
+++ b/src/config_global.c
@@ -42,7 +42,7 @@ char *get_user_config_file(void) {
char *get_user_tmp_dir(void) {
char template[PATH_MAX];
char *ucd = get_user_conf_dir();
- sprintf(template, "%s%ctmp", ucd, DIRSEP);
+ sprintf(template, "%s%c%s", ucd, DIRSEP, "tmp");
if (access(template, F_OK) != 0) {
if (mkdirs(template, 0755) != 0) {
@@ -57,7 +57,7 @@ char *get_user_tmp_dir(void) {
char *get_user_package_dir(void) {
char template[PATH_MAX];
char *ucd = get_user_conf_dir();
- sprintf(template, "%s%cpkgs", ucd, DIRSEP);
+ sprintf(template, "%s%c%s", ucd, DIRSEP, "pkgs");
if (access(template, F_OK) != 0) {
if (mkdirs(template, 0755) != 0) {
@@ -69,6 +69,23 @@ char *get_user_package_dir(void) {
return strdup(template);
}
+char *get_package_manifest(void) {
+ char template[PATH_MAX];
+ char *ucd = get_user_conf_dir();
+
+ sprintf(template, "%s%c%s", ucd, DIRSEP, "manifest.dat");
+ char *wtf = template;
+
+ if (access(template, F_OK) != 0) {
+ fprintf(stderr, "Package manifest not found: %s\n", template);
+ Manifest *manifest = manifest_from(PKG_DIR);
+ manifest_write(manifest);
+ manifest_free(manifest);
+ }
+
+ free(ucd);
+ return strdup(template);
+}
/**
* Check whether SPM has access to external programs it needs
*/
@@ -95,13 +112,12 @@ void check_runtime_environment(void) {
}
}
-
-
void init_config_global(void) {
SPM_GLOBAL.user_config_basedir = NULL;
SPM_GLOBAL.user_config_file = NULL;
SPM_GLOBAL.package_dir = NULL;
SPM_GLOBAL.tmp_dir = NULL;
+ SPM_GLOBAL.package_manifest = NULL;
SPM_GLOBAL.config = NULL;
SPM_GLOBAL.verbose = 0;
@@ -149,6 +165,21 @@ void init_config_global(void) {
else {
SPM_GLOBAL.package_dir = get_user_package_dir();
}
+
+ // Initialize package manifest
+ item = config_get(SPM_GLOBAL.config, "package_manifest");
+ if (item) {
+ SPM_GLOBAL.package_manifest = item->value;
+ if (access(SPM_GLOBAL.package_manifest, F_OK) != 0) {
+ fprintf(stderr, "Package manifest not found: %s\n", SPM_GLOBAL.package_manifest);
+ Manifest *manifest = manifest_from(PKG_DIR);
+ manifest_write(manifest);
+ manifest_free(manifest);
+ }
+ }
+ else {
+ SPM_GLOBAL.package_manifest = get_package_manifest();
+ }
}
void free_global_config(void) {
@@ -158,6 +189,9 @@ void free_global_config(void) {
if (SPM_GLOBAL.tmp_dir) {
free(SPM_GLOBAL.tmp_dir);
}
+ if (SPM_GLOBAL.package_manifest) {
+ free(SPM_GLOBAL.package_manifest);
+ }
if (SPM_GLOBAL.user_config_basedir) {
free(SPM_GLOBAL.user_config_basedir);
}
@@ -183,5 +217,6 @@ void show_global_config(void) {
}
printf("# package storage: %s\n", SPM_GLOBAL.package_dir);
printf("# temp storage: %s\n", SPM_GLOBAL.tmp_dir);
+ printf("# package manifest: %s\n", SPM_GLOBAL.package_manifest);
printf("\n");
}
diff --git a/src/manifest.c b/src/manifest.c
index 5193c3d..e60599d 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -2,20 +2,16 @@
// Created by jhunk on 12/20/19.
//
#include "spm.h"
+#include <fnmatch.h>
-int manifest_create(const char *package_dir) {
- const char *filename = "manifest.dat";
- char path[PATH_MAX];
- int total_records = 0;
+Manifest *manifest_from(const char *package_dir) {
FSTree *fsdata = NULL;
fsdata = fstree(package_dir);
- ManifestPackage **info = (ManifestPackage **)calloc(fsdata->files_length + 1, sizeof(ManifestPackage *));
-
- memset(path, '\0', sizeof(path));
- memset(info, '\0', sizeof(ManifestPackage *));
- sprintf(path, "%s%c%s", SPM_GLOBAL.user_config_basedir, DIRSEP, filename);
+ Manifest *info = (Manifest *)calloc(1, sizeof(Manifest));
+ info->records = fsdata->files_length;
+ info->packages = (ManifestPackage **) calloc(info->records + 1, sizeof(ManifestPackage *));
- printf("Gathering package data:\n");
+ printf("Initializing package manifest:\n");
for (int i = 0; i < fsdata->files_length && i < 0xffff; i++) {
float percent = (((float)i + 1) / fsdata->files_length) * 100;
printf("[%3.0f%%] %s\n", percent, basename(fsdata->files[i]));
@@ -26,71 +22,156 @@ int manifest_create(const char *package_dir) {
}
// Initialize package record
- info[i] = (ManifestPackage *)calloc(1, sizeof(ManifestPackage));
+ info->packages[i] = (ManifestPackage *) calloc(1, sizeof(ManifestPackage));
// Copy dependencies
if (deps->records) {
- info[i]->requirements = (char **) calloc(deps->__size, sizeof(char *));
+ info->packages[i]->requirements = (char **) calloc(deps->__size, sizeof(char *));
for (int j = 0; j < deps->records; j++) {
- info[i]->requirements[j] = (char *) calloc(strlen(deps->list[j]) + 1, sizeof(char));
- strncpy(info[i]->requirements[j], deps->list[j], strlen(deps->list[j]));
+ info->packages[i]->requirements[j] = (char *) calloc(strlen(deps->list[j]) + 1, sizeof(char));
+ strncpy(info->packages[i]->requirements[j], deps->list[j], strlen(deps->list[j]));
}
}
dep_free(&deps);
char **parts = split(fsdata->files[i], "-");
- info[i]->size = get_file_size(fsdata->files[i]);
- strncpy(info[i]->archive, basename(fsdata->files[i]), PACKAGE_MEMBER_SIZE);
- strncpy(info[i]->name, basename(parts[0]), PACKAGE_MEMBER_SIZE);
- strncpy(info[i]->version, parts[1], PACKAGE_MEMBER_SIZE);
- strncpy(info[i]->revision, parts[2], PACKAGE_MEMBER_SIZE);
- strdelsuffix(info[i]->revision, SPM_PACKAGE_EXTENSION);
+ info->packages[i]->size = get_file_size(fsdata->files[i]);
+ strncpy(info->packages[i]->archive, basename(fsdata->files[i]), PACKAGE_MEMBER_SIZE);
+ strncpy(info->packages[i]->name, basename(parts[0]), PACKAGE_MEMBER_SIZE);
+ strncpy(info->packages[i]->version, parts[1], PACKAGE_MEMBER_SIZE);
+ strncpy(info->packages[i]->revision, parts[2], PACKAGE_MEMBER_SIZE);
+ strdelsuffix(info->packages[i]->revision, SPM_PACKAGE_EXTENSION);
split_free(parts);
- total_records++;
}
- printf("\n");
+ //printf("\n");
+ return info;
+}
+
+void manifest_free(Manifest *info) {
+ for (int i = 0; i < info->records; i++) {
+ if (info->packages[i]->requirements) {
+ for (int j = 0; info->packages[i]->requirements[j] != NULL; j++) {
+ free(info->packages[i]->requirements[j]);
+ }
+ free(info->packages[i]->requirements);
+ }
+ free(info->packages[i]);
+ }
+ free(info->packages);
+ free(info);
+}
+int manifest_write(Manifest *info) {
+ const char *filename = "manifest.dat";
+ char path[PATH_MAX];
+ memset(path, '\0', sizeof(path));
+ sprintf(path, "%s%c%s", SPM_GLOBAL.user_config_basedir, DIRSEP, filename);
FILE *fp = fopen(path, "w+");
- char *reqs;
- for (int i = 0; i < total_records; i++) {
- if (SPM_GLOBAL.verbose) {
+ char *reqs = NULL;
+
+ if (SPM_GLOBAL.verbose) {
+ for (int i = 0; i < info->records; i++) {
printf("%-20s: %s\n"
"%-20s: %lu\n"
"%-20s: %s\n"
"%-20s: %s\n"
"%-20s: %s\n",
- "archive", info[i]->archive,
- "size", info[i]->size,
- "name", info[i]->name,
- "version", info[i]->version,
- "revision", info[i]->revision
+ "archive", info->packages[i]->archive,
+ "size", info->packages[i]->size,
+ "name", info->packages[i]->name,
+ "version", info->packages[i]->version,
+ "revision", info->packages[i]->revision
);
- reqs = join(info[i]->requirements, ", ");
+ reqs = join(info->packages[i]->requirements, ", ");
printf("%-20s: %s\n", "requirements", reqs ? reqs : "NONE");
free(reqs);
printf("\n");
}
-
}
- printf("Generating manifest: %s\n", path);
- for (int i = 0; i < total_records; i++) {
+ printf("Generating manifest file: %s\n", path);
+ for (int i = 0; i < info->records; i++) {
// write CSV-like manifest
char data[BUFSIZ];
memset(data, '\0', BUFSIZ);
char *dptr = data;
- float percent = (((float)i + 1) / total_records) * 100;
- printf("[%3.0f%%] %s\n", percent, info[i]->archive);
- reqs = join(info[i]->requirements, ",");
+ float percent = (((float)i + 1) / info->records) * 100;
+ printf("[%3.0f%%] %s\n", percent, info->packages[i]->archive);
+ reqs = join(info->packages[i]->requirements, ",");
sprintf(dptr, "%s|" // archive
"%lu|" // size
"%s|" // name
"%s|" // version
"%s|" // revision
"%s" // requirements
- , info[i]->archive, info[i]->size, info[i]->name, info[i]->version, info[i]->revision, reqs ? reqs : "*");
+ , info->packages[i]->archive, info->packages[i]->size, info->packages[i]->name, info->packages[i]->version, info->packages[i]->revision, reqs ? reqs : "*");
fprintf(fp, "%s\n", dptr);
free(reqs);
}
fclose(fp);
+ return 0;
+}
+
+Manifest *manifest_read(void) {
+ const char *filename = "manifest.dat";
+ char path[PATH_MAX];
+ memset(path, '\0', sizeof(path));
+ sprintf(path, "%s%c%s", SPM_GLOBAL.user_config_basedir, DIRSEP, filename);
+ FILE *fp = fopen(path, "r+");
+ if (!fp) {
+ perror(filename);
+ return NULL;
+ }
+ int total_records = 0;
+ char data[BUFSIZ];
+ char *dptr = data;
+ memset(dptr, '\0', BUFSIZ);
+
+ while (fgets(dptr, BUFSIZ, fp) != NULL) {
+ total_records++;
+ }
+ rewind(fp);
+
+ Manifest *info = (Manifest *)calloc(1, sizeof(Manifest));
+ info->packages = (ManifestPackage **)calloc(total_records + 1, sizeof(ManifestPackage *));
+
+ int i = 0;
+ while (fgets(dptr, BUFSIZ, fp) != NULL) {
+ dptr = strip(dptr);
+ char *garbage;
+ char **parts = split(dptr, "|");
+
+ info->packages[i] = (ManifestPackage *)calloc(1, sizeof(ManifestPackage));
+ strncpy(info->packages[i]->archive, parts[0], strlen(parts[0]));
+ info->packages[i]->size = strtoul(parts[1], &garbage, 10);
+ strncpy(info->packages[i]->name, parts[2], strlen(parts[2]));
+ strncpy(info->packages[i]->version, parts[3], strlen(parts[3]));
+ strncpy(info->packages[i]->revision, parts[4], strlen(parts[4]));
+
+ info->packages[i]->requirements = NULL;
+ if (strncmp(parts[5], "*", 2) != 0) {
+ info->packages[i]->requirements = split(parts[5], ",");
+ }
+ split_free(parts);
+ info->records = i;
+ i++;
+ }
+
+ fclose(fp);
+ return info;
}
+
+ManifestPackage *manifest_search(Manifest *info, const char *_package) {
+ char package[PATH_MAX];
+
+ memset(package, '\0', PATH_MAX);
+ strncpy(package, _package, PATH_MAX);
+ strcat(package, "*");
+
+ for (int i = 0; i < info->records; i++) {
+ if (fnmatch(package, info->packages[i]->archive, FNM_PATHNAME) == 0) {
+ return info->packages[i];
+ }
+ }
+ return NULL;
+} \ No newline at end of file
diff --git a/src/spm.c b/src/spm.c
index c737ea1..ada7840 100644
--- a/src/spm.c
+++ b/src/spm.c
@@ -64,7 +64,9 @@ int main(int argc, char *argv[]) {
SPM_GLOBAL.verbose = 1;
}
else if (strcmp(arg, "--reindex") == 0) {
- manifest_create(SPM_GLOBAL.package_dir);
+ Manifest *info = manifest_from(SPM_GLOBAL.package_dir);
+ manifest_write(info);
+ manifest_free(info);
exit(0);
}
else if (strcmp(arg, "-r") == 0 || strcmp(arg, "--root") == 0) {
@@ -115,6 +117,14 @@ int main(int argc, char *argv[]) {
Dependencies *deps = NULL;
dep_init(&deps);
+ printf("Reading package manifest... ");
+ Manifest *manifest = manifest_read();
+ if (!manifest) {
+ fprintf(stderr, "Package manifest is missing or corrupt\n");
+ exit(1);
+ }
+ printf("done\n");
+
if (isempty(root)) {
printf("Using default installation root\n");
sprintf(root, "%s%c%s", getenv("HOME"), DIRSEP, "spm_root");
@@ -132,13 +142,20 @@ int main(int argc, char *argv[]) {
printf("Resolving package requirements...\n");
for (int i = 0; i < PACKAGE_MAX; i++) {
- char *match = NULL;
- char *package = NULL;
-
+ ManifestPackage *package = NULL;
if (packages[i] == NULL) {
break;
}
+ package = manifest_search(manifest, packages[i]);
+
+ // If the package has dependencies listed, append them to `deps` now
+ if (package && package->requirements) {
+ for (int p = 0; package->requirements[p] != NULL; p++) {
+ dep_append(&deps, package->requirements[p]);
+ }
+ }
+ /*
if ((match = find_package(packages[i])) == NULL) {
fprintf(SYSERROR);
exit(1);
@@ -148,8 +165,9 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Unable to derive package name from package path:\n\t-> %s\n", match);
exit(1);
}
+ */
- if (dep_all(&deps, package) < 0) {
+ if (dep_all(&deps, package->archive) < 0) {
dep_free(&deps);
free_global_config();
exit(1);