diff options
-rw-r--r-- | src/config_global.c | 26 | ||||
-rw-r--r-- | src/install.c | 111 | ||||
-rw-r--r-- | src/manifest.c | 47 | ||||
-rw-r--r-- | src/spm.c | 8 |
4 files changed, 132 insertions, 60 deletions
diff --git a/src/config_global.c b/src/config_global.c index ee42935..c4e4dc8 100644 --- a/src/config_global.c +++ b/src/config_global.c @@ -94,21 +94,14 @@ char *get_user_package_dir(void) { * @return */ char *get_package_manifest(void) { - char template[PATH_MAX]; + Manifest *manifest = NULL; + char *template = NULL; char *ucd = get_user_conf_dir(); - sprintf(template, "%s%c%s", ucd, DIRSEP, "manifest.dat"); - - free(ucd); - return strdup(template); - - /* - Manifest *manifest; - manifest = manifest_read(NULL); - if (manifest != NULL) { - manifest_free(manifest); - } + //free(ucd); + //return strdup(template); + template = join_ex(DIRSEPS, SPM_GLOBAL.package_dir, SPM_GLOBAL.repo_target, SPM_MANIFEST_FILENAME, NULL); if (access(template, F_OK) != 0) { fprintf(stderr, "Package manifest not found: %s\n", template); manifest = manifest_from(PKG_DIR); @@ -117,13 +110,12 @@ char *get_package_manifest(void) { fprintf(SYSERROR); return NULL; } - manifest_write(manifest); + manifest_write(manifest, PKG_DIR); manifest_free(manifest); } free(ucd); - return strdup(template); - */ + return template; } @@ -298,14 +290,12 @@ void init_config_global(void) { item = config_get(SPM_GLOBAL.config, "package_manifest"); if (item) { SPM_GLOBAL.package_manifest = strdup(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_write(manifest, SPM_GLOBAL.package_manifest); manifest_free(manifest); } - */ } else { SPM_GLOBAL.package_manifest = get_package_manifest(); diff --git a/src/install.c b/src/install.c index 93d07b0..ebbab4a 100644 --- a/src/install.c +++ b/src/install.c @@ -42,35 +42,6 @@ int spm_install(SPM_Hierarchy *fs, const char *tmpdir, const char *_package) { printf("Extracting archive: %s\n", package); } - if (strstr(package, "://") != NULL) { - if (exists(fs->tmpdir) != 0) { - mkdirs(fs->tmpdir, 0755); - } - long response = 0; - char *url = strdup(package); - char *tmp_package = join_ex(DIRSEPS, fs->tmpdir, basename(package), NULL); - size_t tmp_package_len = strlen(tmp_package); - - if (tmp_package_len > strlen(package)) { - char *tmp = realloc(package, (strlen(package) + 1) * sizeof(char)); - if (tmp == NULL) { - perror("cannot realloc package path"); - return -1; - } - package = tmp; - } - strcpy(package, tmp_package); - - if (exists(tmp_package) != 0) { - if ((response = fetch(url, package)) >= 400) { - fprintf(stderr, "HTTP(%ld): %s\n", response, http_response_str(response)); - return -1; - } - } - free(url); - free(tmp_package); - } - if (tar_extract_archive(package, tmpdir) != 0) { fprintf(stderr, "%s: %s\n", package, strerror(errno)); free(package); @@ -160,6 +131,45 @@ int spm_check_installed(SPM_Hierarchy *fs, char *package_name) { } /** + * + * @return + */ +char *spm_install_fetch(const char *pkgdir, const char *_package) { + char *package = strdup(_package); + if (package == NULL) { + perror("could not allocate memory for package name"); + fprintf(SYSERROR); + return NULL; + } + + long response = 0; + char *url = strdup(package); + char *payload = join_ex(DIRSEPS, pkgdir, basename(package), NULL); + size_t tmp_package_len = strlen(payload); + + if (tmp_package_len > strlen(package)) { + char *tmp = realloc(package, (strlen(package) + 1) * sizeof(char)); + if (tmp == NULL) { + perror("cannot realloc package path"); + return NULL; + } + package = tmp; + } + strcpy(package, payload); + + if (exists(payload) != 0) { + if ((response = fetch(url, package)) >= 400) { + fprintf(stderr, "HTTP(%ld): %s\n", response, http_response_str(response)); + return NULL; + } + } + free(url); + free(payload); + + return package; +} + +/** * Perform a full package installation * @param mf * @param rootdir @@ -184,7 +194,8 @@ int spm_do_install(SPM_Hierarchy *fs, ManifestList *mf, StrList *packages) { // Produce a dependency tree from requested package(s) for (size_t i = 0; i < strlist_count(packages); i++) { - requirements = resolve_dependencies(mf, strlist_item(packages, i)); + char *item = strlist_item(packages, i); + requirements = resolve_dependencies(mf, item); if (requirements != NULL) { for (size_t c = 0; requirements[c] != NULL; c++) { num_requirements++; @@ -211,10 +222,47 @@ int spm_do_install(SPM_Hierarchy *fs, ManifestList *mf, StrList *packages) { } } + int fetched = 0; + char *package_dir = join_ex(DIRSEPS, SPM_GLOBAL.package_dir, SPM_GLOBAL.repo_target, NULL); + for (size_t i = 0; requirements != NULL && requirements[i] != NULL; i++) { + char *package_path = join((char *[]) {requirements[i]->origin, SPM_GLOBAL.repo_target, requirements[i]->archive, NULL}, DIRSEPS); + char *package_localpath = join_ex(DIRSEPS, package_dir, requirements[i]->archive, NULL); + + // Download the archive if necessary + if (strstr(package_path, "://") != NULL && exists(package_localpath) != 0) { + printf("Fetching: %s\n", package_path); + package_path = spm_install_fetch(package_dir, package_path); + if (package_path == NULL) { + exit(1); + } + fetched = 1; + } + // Or copy the archive if necessary + else { + // You have another local manifest in use. Copy any used packages from there into the local package directory. + // TODO: Possibly an issue down the road, but not at the moment + if (exists(package_localpath) != 0) { + printf("Copying: %s\n", package_path); + rsync(NULL, package_path, package_dir); + fetched = 1; + } + } + free(package_path); + free(package_localpath); + } + + // Update the package manifest + if (fetched) { + printf("Updating package manifest...\n"); + Manifest *tmp_manifest = manifest_from(SPM_GLOBAL.package_dir); + manifest_write(tmp_manifest, package_dir); + manifest_free(tmp_manifest); + } + printf("Installing package(s):\n"); size_t num_installed = 0; for (size_t i = 0; requirements != NULL && requirements[i] != NULL; i++) { - char *package_path = join((char *[]) {requirements[i]->origin, SPM_GLOBAL.repo_target, requirements[i]->archive, NULL}, DIRSEPS); + char *package_path = join((char *[]) {package_dir, requirements[i]->archive, NULL}, DIRSEPS); if (spm_check_installed(fs, requirements[i]->name)) { printf(" -> %s is already installed\n", requirements[i]->name); @@ -233,6 +281,7 @@ int spm_do_install(SPM_Hierarchy *fs, ManifestList *mf, StrList *packages) { for (size_t i = 0; requirements != NULL && requirements[i] != NULL; i++) { manifest_package_free(requirements[i]); } + free(package_dir); if (num_installed != 0) { // Relocate installation root diff --git a/src/manifest.c b/src/manifest.c index e971bb7..9ea7db4 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -76,7 +76,9 @@ Manifest *manifest_from(const char *package_dir) { return NULL; } - printf("Initializing package manifest:\n"); + if (SPM_GLOBAL.verbose) { + printf("Initializing package manifest:\n"); + } strncpy(info->origin, package_dir, SPM_PACKAGE_MEMBER_ORIGIN_SIZE); @@ -91,7 +93,10 @@ Manifest *manifest_from(const char *package_dir) { 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])); + + if (SPM_GLOBAL.verbose) { + printf("[%3.0f%%] %s\n", percent, basename(fsdata->files[i])); + } // Initialize package record info->packages[i] = (ManifestPackage *) calloc(1, sizeof(ManifestPackage)); @@ -231,7 +236,9 @@ int manifest_write(Manifest *info, const char *pkgdir) { } #endif - printf("Generating manifest file: %s\n", path_manifest); + if (SPM_GLOBAL.verbose) { + printf("Generating manifest file: %s\n", path_manifest); + } fprintf(fp, "%s\n", SPM_MANIFEST_HEADER); char data[BUFSIZ]; for (size_t i = 0; i < info->records; i++) { @@ -367,11 +374,13 @@ Manifest *manifest_read(char *file_or_url) { char *filename = SPM_MANIFEST_FILENAME; char *tmpdir = NULL; char path[PATH_MAX]; + char *pathptr = path; + memset(path, '\0', PATH_MAX); // When file_or_url is NULL we want to use the global manifest if (file_or_url == NULL) { // TODO: move this out - strcpy(path, SPM_GLOBAL.package_manifest); + strcpy(path, SPM_GLOBAL.package_dir); } else { char *template = join((char *[]) {TMP_DIR, "spm_manifest_read_XXXXXX", NULL}, DIRSEPS); @@ -382,15 +391,18 @@ Manifest *manifest_read(char *file_or_url) { return NULL; } - snprintf(path, PATH_MAX, "%s%c%s", template, DIRSEP, filename); + snprintf(pathptr, PATH_MAX - 1, "%s%c%s", template, DIRSEP, filename); + //strncpy(pathptr, template, PATH_MAX - 1); } // Handle receiving a path without the manifest filename // by appending the manifest to the path + /* if (startswith(path, "http") != 0 && endswith(path, filename) != 0) { strcat(path, DIRSEPS); strcat(path, filename); } + */ char *remote_manifest = join((char *[]) {file_or_url, SPM_GLOBAL.repo_target, filename, NULL}, DIRSEPS); if (exists(path) != 0) { @@ -562,6 +574,13 @@ void manifestlist_free(ManifestList *pManifestList) { * @param str */ void manifestlist_append(ManifestList *pManifestList, char *path) { + Manifest *manifest = manifest_read(path); + if (manifest == NULL) { + fprintf(stderr, "Failed to create manifest in memory\n"); + fprintf(SYSERROR); + exit(1); + } + Manifest **tmp = realloc(pManifestList->data, (pManifestList->num_alloc + 1) * sizeof(Manifest *)); if (tmp == NULL) { manifestlist_free(pManifestList); @@ -569,17 +588,29 @@ void manifestlist_append(ManifestList *pManifestList, char *path) { exit(1); } pManifestList->data = tmp; - pManifestList->data[pManifestList->num_inuse] = manifest_read(path); + pManifestList->data[pManifestList->num_inuse] = manifest; pManifestList->num_inuse++; pManifestList->num_alloc++; } ManifestPackage *manifestlist_search(ManifestList *pManifestList, const char *_package) { + ManifestPackage *found[255] = {0,}; ManifestPackage *result = NULL; + ssize_t offset = -1; + for (size_t i = 0; i < manifestlist_count(pManifestList); i++) { - result = manifest_search(manifestlist_item(pManifestList, i), _package); + Manifest *item = manifestlist_item(pManifestList, i); + result = manifest_search(item, _package); + if (result != NULL) { + offset++; + found[offset] = result; + } } - return result; + + if (offset < 0) { + return NULL; + } + return found[offset]; } /** @@ -136,7 +136,8 @@ int main(int argc, char *argv[], char *arge[]) { RUNTIME_REMOVE = 1; for (int p = 0; i < argc; p++) { i++; - if (startswith(argv[i], "-") == 0 || startswith(argv[i], "--") == 0) { + char *next = argv[i]; + if (next == NULL || (startswith(next, "-") == 0 || startswith(next, "--") == 0)) { i--; break; } @@ -152,7 +153,8 @@ int main(int argc, char *argv[], char *arge[]) { RUNTIME_INSTALL = 1; for (int p = 0; i < argc; p++) { i++; - if (startswith(argv[i], "-") == 0 || startswith(argv[i], "--") == 0) { + char *next = argv[i]; + if (next == NULL || (startswith(next, "-") == 0 || startswith(next, "--") == 0)) { i--; break; } @@ -161,7 +163,7 @@ int main(int argc, char *argv[], char *arge[]) { usage(program_name); exit(1); } - strlist_append(packages, argv[i]); + strlist_append(packages, next); } } } |