diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/archive.c | 3 | ||||
-rw-r--r-- | src/deps.c | 12 | ||||
-rw-r--r-- | src/fs.c | 12 | ||||
-rw-r--r-- | src/internal_cmd.c | 22 | ||||
-rw-r--r-- | src/manifest.c | 78 | ||||
-rw-r--r-- | src/spm.c | 29 |
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); @@ -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]); } } @@ -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; } @@ -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); |