diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/archive.c | 12 | ||||
-rw-r--r-- | src/find.c | 2 | ||||
-rw-r--r-- | src/fs.c | 15 | ||||
-rw-r--r-- | src/install.c | 20 | ||||
-rw-r--r-- | src/internal_cmd.c | 15 | ||||
-rw-r--r-- | src/manifest.c | 40 | ||||
-rw-r--r-- | src/mime.c | 2 | ||||
-rw-r--r-- | src/relocation.c | 115 | ||||
-rw-r--r-- | src/rpath.c | 8 | ||||
-rw-r--r-- | src/shlib.c | 2 | ||||
-rw-r--r-- | src/spm.c | 40 | ||||
-rw-r--r-- | src/str.c | 4 |
12 files changed, 160 insertions, 115 deletions
diff --git a/src/archive.c b/src/archive.c index ef89c3a..e12acf0 100644 --- a/src/archive.c +++ b/src/archive.c @@ -31,9 +31,9 @@ int tar_extract_file(const char *_archive, const char* _filename, const char *_d return -1; } - strchrdel(archive, "&;|"); - strchrdel(destination, "&;|"); - strchrdel(filename, "&;|"); + strchrdel(archive, SHELL_INVALID); + strchrdel(destination, SHELL_INVALID); + strchrdel(filename, SHELL_INVALID); sprintf(cmd, "tar xf \"%s\" -C \"%s\" \"%s\" 2>&1", archive, destination, filename); if (exists(archive) != 0) { @@ -69,7 +69,7 @@ int tar_extract_archive(const char *_archive, const char *_destination) { char cmd[PATH_MAX]; if (exists(_archive) != 0) { - fprintf(SYSERROR); + //fprintf(SYSERROR); return -1; } @@ -85,9 +85,9 @@ int tar_extract_archive(const char *_archive, const char *_destination) { } // sanitize archive - strchrdel(archive, "&;|"); + strchrdel(archive, SHELL_INVALID); // sanitize destination - strchrdel(destination, "&;|"); + strchrdel(destination, SHELL_INVALID); sprintf(cmd, "tar xf %s -C %s 2>&1", archive, destination); shell(&proc, SHELL_OUTPUT, cmd); @@ -110,7 +110,7 @@ int find_in_file(const char *filename, const char *pattern) { fclose(fp); for (size_t i = 0; i < (size_t) file_len; i++) { - if (!memcmp(&buffer[i], pattern, pattern_len)) { + if (memcmp(&buffer[i], pattern, pattern_len) == 0) { result = 0; // found break; } @@ -13,7 +13,14 @@ FSTree *fstree(const char *_path, char **filter_by, unsigned int filter_mode) { FTSENT *node = NULL; FSTree *fsdata = NULL; int no_filter = 0; - char *path = realpath(_path, NULL); + char *path = NULL; + + if (filter_mode & SPM_FSTREE_FLT_RELATIVE) { + path = strdup(_path); + } else { + path = realpath(_path, NULL); + } + if (path == NULL) { perror(_path); fprintf(SYSERROR); @@ -326,9 +333,9 @@ int rsync(const char *_args, const char *_source, const char *_destination) { strcat(args_combined, _args); } - strchrdel(args_combined, "&;|"); - strchrdel(source, "&;|"); - strchrdel(destination, "&;|"); + strchrdel(args_combined, SHELL_INVALID); + strchrdel(source, SHELL_INVALID); + strchrdel(destination, SHELL_INVALID); snprintf(cmd, PATH_MAX, "rsync %s \"%s\" \"%s\" 2>&1", args_combined, source, destination); shell(&proc, SHELL_OUTPUT, cmd); diff --git a/src/install.c b/src/install.c index 24725f8..c1d0f8c 100644 --- a/src/install.c +++ b/src/install.c @@ -3,6 +3,8 @@ */ #include "spm.h" +extern const char *METADATA_FILES[]; + /** * SPM packages contain metadata files that are not useful post-install and would amount to a lot of clutter. * This function removes these data files from a directory tree @@ -10,23 +12,15 @@ * @return success=0, error=-1 */ int metadata_remove(const char *_path) { - char *metadata[] = { - SPM_META_DEPENDS, - SPM_META_PREFIX_BIN, - SPM_META_PREFIX_TEXT, - SPM_META_MANIFEST, - NULL, - }; - if (exists(_path) != 0) { perror(_path); fprintf(SYSERROR); return -1; } - for (int i = 0; metadata[i] != NULL; i++) { + for (int i = 0; METADATA_FILES[i] != NULL; i++) { char path[PATH_MAX]; - sprintf(path, "%s%c%s", _path, DIRSEP, metadata[i]); + sprintf(path, "%s%c%s", _path, DIRSEP, METADATA_FILES[i]); if (exists(path) != 0) { continue; } @@ -71,6 +65,7 @@ int install(const char *destroot, const char *_package) { if (!suffix) { perror("suffix"); fprintf(SYSERROR); + return -1; } strcpy(suffix, "spm_destroot_XXXXXX"); snprintf(template, PATH_MAX, "%s%c%s", TMP_DIR, DIRSEP, suffix); @@ -87,7 +82,10 @@ int install(const char *destroot, const char *_package) { if (SPM_GLOBAL.verbose) { printf("Extracting archive: %s\n", package); } - tar_extract_archive(package, tmpdir); + if (tar_extract_archive(package, tmpdir) != 0) { + fprintf(stderr, "%s: %s\n", package, strerror(errno)); + return -1; + } // Relocate temporary directory relocate_root(destroot, tmpdir); diff --git a/src/internal_cmd.c b/src/internal_cmd.c index 3583073..e1344ed 100644 --- a/src/internal_cmd.c +++ b/src/internal_cmd.c @@ -100,24 +100,15 @@ void mkmanifest_interface_usage(void) { * @return value of `manifest_write` */ int mkmanifest_interface(int argc, char **argv) { - if (argc < 1 || argc > 3) { + if (argc < 2) { mkmanifest_interface_usage(); return -1; } Manifest *manifest = NULL; int result = 0; char *pkgdir = NULL; - char path[PATH_MAX]; - memset(path, '\0', PATH_MAX); - if (argc < 3) { - pkgdir = SPM_GLOBAL.package_dir; - strcpy(path, SPM_MANIFEST_FILENAME); - } - else { - pkgdir = argv[1]; - strcpy(path, argv[2]); - } + pkgdir = argv[1]; if (exists(pkgdir) != 0) { return -1; @@ -128,7 +119,7 @@ int mkmanifest_interface(int argc, char **argv) { return -2; } - result = manifest_write(manifest, path); + result = manifest_write(manifest, pkgdir); if (result != 0) { manifest_free(manifest); return -3; diff --git a/src/manifest.c b/src/manifest.c index 30e5856..646e6f3 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -52,6 +52,8 @@ Manifest *manifest_from(const char *package_dir) { } printf("Initializing package manifest:\n"); + strncpy(info->origin, package_dir, PACKAGE_MEMBER_ORIGIN_SIZE); + 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])); @@ -101,6 +103,7 @@ Manifest *manifest_from(const char *package_dir) { // Populate `ManifestPackage` record info->packages[i]->size = (size_t) get_file_size(fsdata->files[i]); + strncpy(info->packages[i]->origin, info->origin, PACKAGE_MEMBER_ORIGIN_SIZE); 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); @@ -139,27 +142,33 @@ void manifest_package_free(ManifestPackage *info) { /** * Write a `Manifest` to the configuration directory * @param info - * @param outfile + * @param pkgdir * @return */ -int manifest_write(Manifest *info, const char *outfile) { +int manifest_write(Manifest *info, const char *pkgdir) { char *reqs = NULL; char path[PATH_MAX]; + char path_manifest[PATH_MAX]; + memset(path, '\0', sizeof(path)); + memset(path_manifest, '\0', sizeof(path)); - if (outfile == NULL) { - strcpy(path, SPM_GLOBAL.package_manifest); - } - else { - strcpy(path, outfile); - } + strcpy(path, pkgdir); - if (endswith(path, SPM_MANIFEST_FILENAME) != 0) { + // Append the repo target if its missing + if (strstr(path, SPM_GLOBAL.repo_target) == NULL) { strcat(path, DIRSEPS); - strcat(path, SPM_MANIFEST_FILENAME); + strcat(path, SPM_GLOBAL.repo_target); } + strcpy(path_manifest, path); - FILE *fp = fopen(path, "w+"); + // Append the manifest filename if its missing + if (endswith(path_manifest, SPM_MANIFEST_FILENAME) != 0) { + strcat(path_manifest, DIRSEPS); + strcat(path_manifest, SPM_MANIFEST_FILENAME); + } + + FILE *fp = fopen(path_manifest, "w+"); #ifdef _DEBUG if (SPM_GLOBAL.verbose) { for (size_t i = 0; i < info->records; i++) { @@ -184,7 +193,7 @@ int manifest_write(Manifest *info, const char *outfile) { } #endif - printf("Generating manifest file: %s\n", path); + 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++) { @@ -196,7 +205,7 @@ int manifest_write(Manifest *info, const char *outfile) { printf("[%3.0f%%] %s\n", percent, info->packages[i]->archive); } reqs = join(info->packages[i]->requirements, ","); - char *archive = join((char *[]) {SPM_GLOBAL.package_dir, SPM_GLOBAL.repo_target, info->packages[i]->archive, NULL}, DIRSEPS); + char *archive = join((char *[]) {path, info->packages[i]->archive, NULL}, DIRSEPS); char *checksum_sha256 = sha256sum(archive); sprintf(dptr, "%s|" // archive @@ -447,6 +456,7 @@ Manifest *manifest_read(char *file_or_url) { } if (tmpdir != NULL) { + rmdirs(tmpdir); free(tmpdir); } fclose(fp); @@ -484,6 +494,10 @@ ManifestPackage *manifest_search(Manifest *info, const char *_package) { * @return `ManifestPackage` */ ManifestPackage *manifest_package_copy(ManifestPackage *manifest) { + if (manifest == NULL) { + return NULL; + } + ManifestPackage *result = calloc(1, sizeof(ManifestPackage)); memcpy(result, manifest, sizeof(ManifestPackage)); @@ -20,7 +20,7 @@ Process *file_command(const char *_filename) { const char *fmt_cmd = "file -E -i \"%s\" 2>&1"; #endif - strchrdel(filename, "&;|"); + strchrdel(filename, SHELL_INVALID); sprintf(sh_cmd, fmt_cmd, filename); shell(&proc_info, SHELL_OUTPUT, sh_cmd); diff --git a/src/relocation.c b/src/relocation.c index ce6a896..7c9f5d6 100644 --- a/src/relocation.c +++ b/src/relocation.c @@ -3,6 +3,14 @@ */ #include "spm.h" +const char *METADATA_FILES[] = { + SPM_META_DEPENDS, + SPM_META_PREFIX_BIN, + SPM_META_PREFIX_TEXT, + SPM_META_MANIFEST, + NULL, +}; + /** * Replace all occurrences of `spattern` with `sreplacement` in `data` * @@ -26,7 +34,7 @@ int replace_text(char *data, const char *spattern, const char *sreplacement) { size_t sreplacement_len = strlen(sreplacement); if (sreplacement_len > spattern_len) { - fprintf(stderr, "replacement string too long\n"); + fprintf(stderr, "replacement string too long: %zu > %zu\n '%s'\n '%s'\n", sreplacement_len, spattern_len, sreplacement, spattern); return -1; } @@ -134,10 +142,11 @@ RelocationEntry **prefixes_read(const char *filename) { } RelocationEntry **entry = NULL; char line[BUFSIZ]; - memset(line, '\0', BUFSIZ); + char *lptr = line; + memset(lptr, '\0', BUFSIZ); - while (fgets(line, BUFSIZ, fp) != NULL) { - if (isempty(line)) { + while (fgets(lptr, BUFSIZ, fp) != NULL) { + if (isempty(lptr)) { continue; } record_count++; @@ -170,11 +179,11 @@ RelocationEntry **prefixes_read(const char *filename) { int do_prefix = 0; int do_path = 0; size_t i = 0; - while (fgets(line, BUFSIZ, fp) != NULL) { - if (isempty(line)) { + while (fgets(lptr, BUFSIZ, fp) != NULL) { + if (isempty(lptr)) { continue; } - if (startswith(line, "#") == 0) { + if (startswith(lptr, "#") == 0) { do_prefix = 1; } else { @@ -190,12 +199,12 @@ RelocationEntry **prefixes_read(const char *filename) { if (do_prefix) { // Populate prefix data (a prefix starts with a #) - entry[i]->prefix = (char *) calloc(strlen(line) + 1, sizeof(char)); + entry[i]->prefix = (char *) calloc(strlen(lptr) + 1, sizeof(char)); if (!entry[i]->prefix) { fclose(fp); return NULL; } - strncpy(entry[i]->prefix, line, strlen(line)); + strncpy(entry[i]->prefix, lptr, strlen(lptr)); // Remove prefix delimiter and whitespace strchrdel(entry[i]->prefix, "#"); entry[i]->prefix = strip(entry[i]->prefix); @@ -205,12 +214,12 @@ RelocationEntry **prefixes_read(const char *filename) { else if (do_path) { // Populate path data - entry[i]->path = (char *) calloc(strlen(line) + 1, sizeof(char)); + entry[i]->path = (char *) calloc(strlen(lptr) + 1, sizeof(char)); if (!entry[i]->path) { fclose(fp); return NULL; } - strncpy(entry[i]->path, line, strlen(line)); + strncpy(entry[i]->path, lptr, strlen(lptr)); entry[i]->path = strip(entry[i]->path); do_path = 0; } @@ -221,6 +230,35 @@ RelocationEntry **prefixes_read(const char *filename) { } /** + * Determine if `filename` is a SPM metadata file + * + * Example: + * + * ~~~{.c} + * #include "spm.h" + * + * int main() { + * if (file_is_metadata("./.SPM_DEPENDS")) { + * // file is metadata + * } else { + * // file is not metadata + * } + * } + * ~~~ + * + * @param filename + * @return 0=no, 1=yes + */ +int file_is_metadata(const char *filename) { + for (size_t i = 0; METADATA_FILES[i] != NULL; i++) { + if (strstr(filename, METADATA_FILES[i]) != NULL) { + return 1; + } + } + return 0; +} + +/** * Scan `tree` for files containing `prefix`. Matches are recorded in `output_file` with the following format: * * ~~~ @@ -253,30 +291,39 @@ int prefixes_write(const char *output_file, int mode, char **prefix, const char return -1; } - FSTree *fsdata = fstree(tree, NULL, SPM_FSTREE_FLT_NONE); - if (!fsdata) { - fclose(fp); - fprintf(SYSERROR); - return -1; - } - for (size_t i = 0; i < fsdata->files_length; i++) { - for (int p = 0; prefix[p] != NULL; p++) { - if (find_in_file(fsdata->files[i], prefix[p]) == 0) { - int proceed = 0; - if (mode == PREFIX_WRITE_BIN) { - proceed = file_is_binary(fsdata->files[i]); - } else if (mode == PREFIX_WRITE_TEXT) { - proceed = file_is_text(fsdata->files[i]); - } + char *cwd = getcwd(NULL, PATH_MAX); + chdir(tree); + { + FSTree *fsdata = fstree(".", NULL, SPM_FSTREE_FLT_RELATIVE); + if (!fsdata) { + fclose(fp); + fprintf(SYSERROR); + return -1; + } + for (size_t i = 0; i < fsdata->files_length; i++) { + if (file_is_metadata(fsdata->files[i])) { + continue; + } + for (int p = 0; prefix[p] != NULL; p++) { + if (find_in_file(fsdata->files[i], prefix[p]) == 0) { + int proceed = 0; + if (mode == PREFIX_WRITE_BIN) { + proceed = file_is_binary(fsdata->files[i]); + } else if (mode == PREFIX_WRITE_TEXT) { + proceed = file_is_text(fsdata->files[i]); + } - if (!proceed) { - continue; + // file_is_* functions return NULL when they encounter anything but a regular file + if (!proceed) { + continue; + } + // Record in file + fprintf(fp, "#%s\n%s\n", prefix[p], fsdata->files[i]); } - - fprintf(fp, "#%s\n%s\n", prefix[p], fsdata->files[i]); } } - } + } chdir(cwd); + free(cwd); fclose(fp); return 0; } @@ -297,9 +344,9 @@ int relocate(const char *_filename, const char *_oldstr, const char *_newstr) { char cmd[PATH_MAX]; // sanitize command - strchrdel(oldstr, "&;|"); - strchrdel(newstr, "&;|"); - strchrdel(filename, "&;|"); + strchrdel(oldstr, SHELL_INVALID); + strchrdel(newstr, SHELL_INVALID); + strchrdel(filename, SHELL_INVALID); memset(cmd, '\0', sizeof(cmd)); sprintf(cmd, "reloc \"%s\" \"%s\" \"%s\" \"%s\" 2>&1", oldstr, newstr, filename, filename); diff --git a/src/rpath.c b/src/rpath.c index 5758939..2976ed8 100644 --- a/src/rpath.c +++ b/src/rpath.c @@ -16,8 +16,8 @@ Process *patchelf(const char *_filename, const char *_args) { char sh_cmd[PATH_MAX]; sh_cmd[0] = '\0'; - strchrdel(args, "&;|"); - strchrdel(filename, "&;|"); + strchrdel(args, SHELL_INVALID); + strchrdel(filename, SHELL_INVALID); sprintf(sh_cmd, "patchelf %s %s 2>&1", args, filename); shell(&proc_info, SHELL_OUTPUT, sh_cmd); @@ -44,7 +44,7 @@ int has_rpath(const char *_filename) { } // sanitize input path - strchrdel(filename, "&;|"); + strchrdel(filename, SHELL_INVALID); Process *pe = patchelf(filename, "--print-rpath"); strip(pe->output); @@ -87,7 +87,7 @@ char *rpath_get(const char *_filename) { char *rpath = NULL; // sanitize input path - strchrdel(path, "&;|"); + strchrdel(path, SHELL_INVALID); Process *pe = patchelf(filename, "--print-rpath"); if (pe->returncode != 0) { diff --git a/src/shlib.c b/src/shlib.c index b9cb3d7..1a427f6 100644 --- a/src/shlib.c +++ b/src/shlib.c @@ -14,7 +14,7 @@ char *shlib_deps_objdump(const char *_filename) { return NULL; } - strchrdel(filename, "&;|"); + strchrdel(filename, SHELL_INVALID); snprintf(cmd, sizeof(cmd), "%s %s '%s'", "objdump", "-p", filename); shell(&proc, SHELL_OUTPUT, cmd); @@ -9,8 +9,6 @@ int RUNTIME_INSTALL = 0; int RUNTIME_ROOTDIR = 0; int RUNTIME_LIST = 0; int RUNTIME_SEARCH = 0; -const int MANIFESTS_MAX = 25; -int manifests_count = 0; void usage(const char *program_name) { printf("usage: %s [-hVvBIrLS]\n" @@ -31,9 +29,6 @@ int main(int argc, char *argv[], char *arge[]) { memset(program_name, '\0', sizeof(program_name) + 1); strcpy(program_name, basename(argv[0])); - Manifest *manifests[MANIFESTS_MAX]; - memset(manifests, '\0', MANIFESTS_MAX * sizeof(Manifest *)); - // not much to see here yet // at the moment this will all be random tests, for better or worse // everything here is subject to change without notice @@ -150,6 +145,8 @@ 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); // Dump configuration if (SPM_GLOBAL.verbose) { @@ -194,17 +191,7 @@ int main(int argc, char *argv[], char *arge[]) { Dependencies *deps = NULL; dep_init(&deps); - printf("Reading package manifest... "); - Manifest *manifest = manifest_read(manifests[manifests_count]->origin); //manifest_read(NULL); - if (!manifest) { - fprintf(stderr, "Package manifest is missing or corrupt\n"); - runtime_free(rt); - exit(1); - } - printf("done\n"); - printf("Installation root: %s\n", root); - printf("Requested packages:\n"); for (size_t i = 0; i < strlist_count(packages); i++) { printf(" -> %s\n", strlist_item(packages, i)); @@ -242,12 +229,12 @@ int main(int argc, char *argv[], char *arge[]) { printf("Installing package requirements:\n"); for (size_t i = 0; i < deps->records; i++) { - printf(" -> %s\n", deps->list[i]); ManifestPackage *package = manifestlist_search(mf, deps->list[i]); - char *package_path = join((char *[]) {SPM_GLOBAL.package_dir, package->archive, NULL}, DIRSEPS); + printf(" -> %-30s %s\n", deps->list[i], package->origin); + char *package_path = join((char *[]) {package->origin, SPM_GLOBAL.repo_target, package->archive, NULL}, DIRSEPS); if (install(root, package_path) < 0) { - fprintf(SYSERROR); + fprintf(stderr, "Installation failed: %s\n", package_path); runtime_free(rt); exit(errno); } @@ -263,19 +250,18 @@ int main(int argc, char *argv[], char *arge[]) { char *package = NULL; if ((match = manifestlist_search(mf, strlist_item(packages, i))) == NULL) { - fprintf(SYSERROR); runtime_free(rt); exit(1); } - package = join((char *[]) {SPM_GLOBAL.package_dir, match->archive, NULL}, DIRSEPS); + package = join((char *[]) {match->origin, SPM_GLOBAL.repo_target, match->archive, NULL}, DIRSEPS); // If the package was installed as a requirement of another dependency, skip it if (dep_seen(&deps, package)) { continue; } - printf(" -> %s\n", basename(package)); + printf(" -> %-30s %s\n", basename(package), match->origin); if (install(root, package) < 0) { fprintf(SYSERROR); runtime_free(rt); @@ -283,7 +269,7 @@ int main(int argc, char *argv[], char *arge[]) { } free(package); } - manifest_free(manifest); + //manifest_free(manifest); dep_free(&deps); } @@ -331,7 +317,7 @@ int main(int argc, char *argv[], char *arge[]) { int banner_size = 79; putchar('#'); print_banner("-", banner_size); - printf("# %-20s %-20s %-20s %-20s\n", "name", "version", "revision", "size"); + printf("# %-20s %-10s %-10s %-10s %-20s\n", "name", "version", "revision", "size", "origin"); putchar('#'); print_banner("-", banner_size); @@ -341,15 +327,15 @@ int main(int argc, char *argv[], char *arge[]) { ManifestPackage **package = find_by_spec(info, name, op, ver); for (int p = 0; package[p] != NULL; p++) { char *package_hsize = human_readable_size(package[p]->size); - printf(" %-20s %-20s %-20s %-20s\n", package[p]->name, package[p]->version, package[p]->revision, - package_hsize); + printf(" %-20s %-10s %-10s %-10s %20s\n", package[p]->name, package[p]->version, package[p]->revision, + package_hsize, info->packages[p]->origin); free(package_hsize); } } else if (RUNTIME_LIST) { for (size_t p = 0; p < info->records; p++) { char *package_hsize = human_readable_size(info->packages[p]->size); - printf(" %-20s %-20s %-20s %-20s\n", info->packages[p]->name, info->packages[p]->version, - info->packages[p]->revision, package_hsize); + printf(" %-20s %-10s %-10s %-10s %20s\n", info->packages[p]->name, info->packages[p]->version, + info->packages[p]->revision, package_hsize, info->packages[p]->origin); free(package_hsize); } } @@ -53,9 +53,11 @@ int endswith(const char *sptr, const char *pattern) { size_t pattern_size = strlen(pattern); for (size_t s = sptr_size - pattern_size, p = 0 ; s < sptr_size; s++, p++) { if (sptr[s] != pattern[p]) { + // sptr does not end with pattern return 1; } } + // sptr ends with pattern return 0; } @@ -452,7 +454,7 @@ char *lstrip(char *sptr) { */ char *strip(char *sptr) { size_t len = strlen(sptr) - 1; - if (len < 1) { + if (len < 1 && isblank(*sptr)) { *sptr = '\0'; return sptr; } |