aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/archive.c3
-rw-r--r--src/deps.c12
-rw-r--r--src/fs.c12
-rw-r--r--src/internal_cmd.c22
-rw-r--r--src/manifest.c78
-rw-r--r--src/spm.c29
6 files changed, 102 insertions, 54 deletions
diff --git a/src/archive.c b/src/archive.c
index e12acf0..c8aad35 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -49,6 +49,9 @@ int tar_extract_file(const char *_archive, const char* _filename, const char *_d
}
status = proc->returncode;
+ if (status != 0) {
+ fprintf(stderr, proc->output);
+ }
shell_free(proc);
free(archive);
diff --git a/src/deps.c b/src/deps.c
index a14432e..3332358 100644
--- a/src/deps.c
+++ b/src/deps.c
@@ -13,7 +13,7 @@ int dep_seen(Dependencies **deps, const char *name) {
if (!deps) {
return -1;
}
- for (size_t i = 0; i != (*deps)->records; i++) {
+ for (size_t i = 0; i < (*deps)->records; i++) {
if (strstr((*deps)->list[i], name) != NULL) {
return 1;
}
@@ -148,10 +148,10 @@ int dep_solve(Dependencies **deps, const char *filename) {
/**
*
* @param deps
- * @param _package
+ * @param _package absolute path to package
* @return
*/
-int dep_all(Dependencies **deps, const char *_package) {
+int dep_all(Dependencies **deps, const char *root, const char *_package) {
static int next = 0;
char *package = NULL;
char depfile[PATH_MAX];
@@ -163,7 +163,7 @@ int dep_all(Dependencies **deps, const char *_package) {
strcpy(suffix, "spm_depends_all_XXXXXX");
// Verify the requested package pattern exists
- package = find_package(_package);
+ package = find_file(root, _package);
if (!package) {
perror(_package);
fprintf(SYSERROR);
@@ -181,7 +181,7 @@ int dep_all(Dependencies **deps, const char *_package) {
free(suffix);
return -1;
}
- if (tar_extract_file(package, ".SPM_DEPENDS", tmpdir) < 0) {
+ if (tar_extract_file(package, "./"SPM_META_DEPENDS, tmpdir) < 0) {
perror(package);
fprintf(SYSERROR);
free(package);
@@ -199,7 +199,7 @@ int dep_all(Dependencies **deps, const char *_package) {
for (int i = next; i < resolved; i++) {
next++;
if (dep_seen(deps, (*deps)->list[i])) {
- dep_all(deps, (*deps)->list[i]);
+ dep_all(deps, root, (*deps)->list[i]);
}
}
diff --git a/src/fs.c b/src/fs.c
index f8a276c..2058720 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -182,6 +182,9 @@ void fstree_free(FSTree *fsdata) {
* @return success=expanded path or original path, failure=NULL
*/
char *expandpath(const char *_path) {
+ if (_path == NULL) {
+ return NULL;
+ }
const char *homes[] = {
"HOME",
"USERPROFILE",
@@ -196,7 +199,7 @@ char *expandpath(const char *_path) {
memset(ptmp, '\0', sizeof(tmp));
memset(result, '\0', sizeof(result));
- strncpy(ptmp, _path, strlen(_path));
+ strncpy(ptmp, _path, PATH_MAX - 1);
// Check whether there's a reason to continue processing the string
if (*ptmp != '~') {
@@ -210,7 +213,7 @@ char *expandpath(const char *_path) {
for (size_t i = 0; i < sizeof(homes); i++) {
char *tmphome;
if ((tmphome = getenv(homes[i])) != NULL) {
- strncpy(home, tmphome, strlen(tmphome));
+ strncpy(home, tmphome, PATH_MAX - 1);
break;
}
}
@@ -227,9 +230,10 @@ char *expandpath(const char *_path) {
}
// Construct the new path
- strncat(result, home, strlen(home));
+ strncat(result, home, PATH_MAX - 1);
if (sep) {
- sprintf(result, "%c%s", DIRSEP, ptmp);
+ strncat(result, DIRSEPS, PATH_MAX - 1);
+ strncat(result, ptmp, PATH_MAX - 1);
}
return strdup(result);
diff --git a/src/internal_cmd.c b/src/internal_cmd.c
index e1344ed..8d91029 100644
--- a/src/internal_cmd.c
+++ b/src/internal_cmd.c
@@ -100,31 +100,39 @@ void mkmanifest_interface_usage(void) {
* @return value of `manifest_write`
*/
int mkmanifest_interface(int argc, char **argv) {
+ Manifest *manifest = NULL;
+ int result = 0;
+ char *pkgdir = NULL;
+
if (argc < 2) {
mkmanifest_interface_usage();
return -1;
}
- Manifest *manifest = NULL;
- int result = 0;
- char *pkgdir = NULL;
- pkgdir = argv[1];
+ if ((pkgdir = expandpath(argv[1])) == NULL) {
+ fprintf(stderr, "bad path\n");
+ return -2;
+ }
if (exists(pkgdir) != 0) {
- return -1;
+ fprintf(stderr, "'%s': does not exist\n", pkgdir);
+ return -3;
}
manifest = manifest_from(pkgdir);
if (manifest == NULL) {
- return -2;
+ fprintf(stderr, "no packages\n");
+ return -4;
}
result = manifest_write(manifest, pkgdir);
if (result != 0) {
+ fprintf(stderr, "an error occurred while writing manifest data\n");
manifest_free(manifest);
- return -3;
+ return -5;
}
+ free(pkgdir);
manifest_free(manifest);
return result;
}
diff --git a/src/manifest.c b/src/manifest.c
index 646e6f3..acc1107 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -37,9 +37,17 @@ void manifest_package_separator_restore(char **name) {
*/
Manifest *manifest_from(const char *package_dir) {
char *package_filter[] = {SPM_PACKAGE_EXTENSION, NULL}; // We only want packages
+ char *template = NULL;
FSTree *fsdata = NULL;
fsdata = fstree(package_dir, package_filter, SPM_FSTREE_FLT_ENDSWITH);
+ template = join((char *[]) {TMP_DIR, "spm_manifest_from_XXXXXX", NULL}, DIRSEPS);
+ if (!template) {
+ perror("Failed to allocate template string");
+ fprintf(SYSERROR);
+ return NULL;
+ }
+
Manifest *info = (Manifest *)calloc(1, sizeof(Manifest));
info->records = fsdata->files_length;
info->packages = (ManifestPackage **) calloc(info->records + 1, sizeof(ManifestPackage *));
@@ -54,41 +62,30 @@ Manifest *manifest_from(const char *package_dir) {
printf("Initializing package manifest:\n");
strncpy(info->origin, package_dir, PACKAGE_MEMBER_ORIGIN_SIZE);
+
+ char *tmpdir = mkdtemp(template);
+ if (exists(tmpdir) != 0) {
+ perror("temporary directory creation failed");
+ fprintf(SYSERROR);
+ free(info);
+ fstree_free(fsdata);
+ return NULL;
+ }
+
for (size_t i = 0; i < fsdata->files_length; i++) {
float percent = (((float)i + 1) / fsdata->files_length) * 100;
printf("[%3.0f%%] %s\n", percent, basename(fsdata->files[i]));
- Dependencies *deps = NULL;
- dep_init(&deps);
- if (dep_all(&deps, basename(fsdata->files[i])) < 0) {
- dep_free(&deps);
- fprintf(stderr, "%s: dependency not found\n", fsdata->files[i]);
- fprintf(SYSERROR);
- return NULL;
- }
// Initialize package record
info->packages[i] = (ManifestPackage *) calloc(1, sizeof(ManifestPackage));
if (info->packages[i] == NULL) {
perror("Failed to allocate package record");
fprintf(SYSERROR);
- dep_free(&deps);
fstree_free(fsdata);
free(info);
return NULL;
}
- // Copy dependencies
- if (deps->records) {
- info->packages[i]->requirements = (char **) calloc(deps->__size, sizeof(char *));
- info->packages[i]->requirements_records = deps->records;
- size_t j;
- for (j = 0; j < deps->records; 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);
-
// Swap extra package separators with a bogus character
manifest_package_separator_swap(&fsdata->files[i]);
@@ -109,10 +106,36 @@ Manifest *manifest_from(const char *package_dir) {
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);
+
+ // Read package requirement specs
+ char *archive = join((char *[]) {info->origin, SPM_GLOBAL.repo_target, info->packages[i]->archive, NULL}, DIRSEPS);
+ char *in_archive = join((char *[]) {".", SPM_META_DEPENDS, NULL}, DIRSEPS);
+ if (tar_extract_file(archive, in_archive, tmpdir) != 0) {
+ // TODO: at this point is the package is invalid? .SPM_DEPENDS should be there...
+ fprintf(stderr, "extraction failure: %s\n", archive);
+ rmdirs(tmpdir);
+ exit(1);
+ }
+ char *depfile = join((char *[]) {tmpdir, SPM_META_DEPENDS, NULL}, DIRSEPS);
+ info->packages[i]->requirements = file_readlines(depfile);
+
+ // Record count of requirement specs
+ if (info->packages[i]->requirements != NULL) {
+ for (size_t rec = 0; info->packages[i]->requirements[rec] != NULL; rec++) {
+ strip(info->packages[i]->requirements[rec]);
+ info->packages[i]->requirements_records++;
+ }
+ }
+
+ unlink(depfile);
+ free(depfile);
+ free(archive);
+ free(in_archive);
split_free(parts);
}
fstree_free(fsdata);
+ rmdirs(tmpdir);
return info;
}
@@ -385,6 +408,7 @@ Manifest *manifest_read(char *file_or_url) {
while (fgets(dptr, BUFSIZ, fp) != NULL) {
total_records++;
}
+ total_records--; // header does not count
rewind(fp);
Manifest *info = (Manifest *)calloc(1, sizeof(Manifest));
@@ -415,6 +439,7 @@ Manifest *manifest_read(char *file_or_url) {
return NULL;
}
+ info->records = total_records;
while (fgets(dptr, BUFSIZ, fp) != NULL) {
dptr = strip(dptr);
char *garbage;
@@ -451,7 +476,6 @@ Manifest *manifest_read(char *file_or_url) {
}
split_free(parts);
- info->records = i;
i++;
}
@@ -475,15 +499,9 @@ ManifestPackage *manifest_search(Manifest *info, const char *_package) {
memset(package, '\0', PATH_MAX);
strncpy(package, _package, PATH_MAX);
- //strcat(package, "*");
- for (size_t i = 0; i < info->records; i++) {
- if ((match = find_by_strspec(info, package)) != NULL) {
- return match;
- }
- //if (fnmatch(package, info->packages[i]->archive, FNM_PATHNAME) == 0) {
- // return info->packages[i];
- //}
+ if ((match = find_by_strspec(info, package)) != NULL) {
+ return match;
}
return NULL;
}
diff --git a/src/spm.c b/src/spm.c
index 24147c8..3535cec 100644
--- a/src/spm.c
+++ b/src/spm.c
@@ -41,7 +41,9 @@ int main(int argc, char *argv[], char *arge[]) {
char root[PATH_MAX];
StrList *packages = strlist_init();
+ ManifestList *mf = NULL;
char package_search_str[PATH_MAX];
+ int override_manifests = 0;
memset(root, '\0', PATH_MAX);
memset(package_search_str, '\0', PATH_MAX);
@@ -51,9 +53,7 @@ int main(int argc, char *argv[], char *arge[]) {
exit(1);
}
- // Populate at least one manifest record
- //manifests[manifests_count] = manifest_read(SPM_GLOBAL.package_dir);
- ManifestList *mf = manifestlist_init();
+ mf = manifestlist_init();
for (int i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -72,6 +72,9 @@ int main(int argc, char *argv[], char *arge[]) {
else if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0) {
SPM_GLOBAL.verbose = 1;
}
+ else if (strcmp(arg, "-M") == 0 || strcmp(arg, "--override-manifests") == 0) {
+ override_manifests = 1;
+ }
else if (strcmp(arg, "-m") == 0 || strcmp(arg, "--manifest") == 0) {
if (arg_next == NULL) {
fprintf(stderr, "-m|--manifest requires a directory path\n");
@@ -145,8 +148,11 @@ int main(int argc, char *argv[], char *arge[]) {
exit(1);
}
}
- // Place the default package location at the bottom of the list
- manifestlist_append(mf, SPM_GLOBAL.package_dir);
+
+ if (override_manifests == 0) {
+ // Place the default package location at the bottom of the list
+ manifestlist_append(mf, SPM_GLOBAL.package_dir);
+ }
// Dump configuration
if (SPM_GLOBAL.verbose) {
@@ -202,7 +208,10 @@ int main(int argc, char *argv[], char *arge[]) {
ManifestPackage *package = NULL;
if ((package = manifestlist_search(mf, strlist_item(packages, i))) == NULL) {
fprintf(stderr, "Package not found: %s\n", strlist_item(packages, i));
- continue;
+ dep_free(&deps);
+ free_global_config();
+ runtime_free(rt);
+ exit(1);
}
// If the package has dependencies listed, append them to `deps` now
@@ -213,7 +222,13 @@ int main(int argc, char *argv[], char *arge[]) {
}
// Process any additional dependencies the package requires
- if (dep_all(&deps, package->archive) < 0) {
+ char root[PATH_MAX];
+ memset(root, '\0', PATH_MAX);
+ strncat(root, package->origin, PATH_MAX - 1);
+ strncat(root, DIRSEPS, PATH_MAX - 1);
+ strncat(root, SPM_GLOBAL.repo_target, PATH_MAX - 1);
+
+ if (dep_all(&deps, root, package->archive) < 0) {
dep_free(&deps);
free_global_config();
runtime_free(rt);