]> git.ipfire.org Git - pakfire.git/commitdiff
repo: Add function to scan repos for archives
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 12 Feb 2021 16:43:08 +0000 (16:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 12 Feb 2021 16:43:08 +0000 (16:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/repo.h
src/libpakfire/include/pakfire/util.h
src/libpakfire/libpakfire.sym
src/libpakfire/repo.c
src/libpakfire/util.c
tests/libpakfire/repo.c

index 58ede26ad1e7ecf99e33a8382b001dbbb2a28a79..73944ef94a7ef57eb418c5c3d5696bc547b9835c 100644 (file)
@@ -80,6 +80,10 @@ FILE* pakfire_repo_cache_open(PakfireRepo repo, const char* path, const char* mo
 int pakfire_repo_cache_access(PakfireRepo repo, const char* path, int mode);
 time_t pakfire_repo_cache_age(PakfireRepo repo, const char* path);
 
+// Scan
+
+int pakfire_repo_scan(PakfireRepo repo, int flags);
+
 #ifdef PAKFIRE_PRIVATE
 
 #include <solv/repo.h>
index 3952cec29433f133b6459eda3b8eb01999880e23..83700d5a8fc5222caff378006ee20c8aab7ab388 100644 (file)
@@ -53,4 +53,10 @@ size_t pakfire_string_to_size(const char* s);
 char** pakfire_split_string(const char* s, char delim);
 void pakfire_partition_string(const char* s, const char* delim, char** s1, char** s2);
 
+#ifdef PAKFIRE_PRIVATE
+
+int pakfire_string_endswith(const char* s, const char* suffix);
+
+#endif
+
 #endif /* PAKFIRE_UTIL_H */
index 9450119edf15d76de970e2d52b1ff27b13cfdca0..86a7b6249af8d389d76c4ff1170d0da820af6e86 100644 (file)
@@ -294,6 +294,7 @@ global:
        pakfire_repo_read_solv;
        pakfire_repo_read_solv_fp;
        pakfire_repo_ref;
+       pakfire_repo_scan;
        pakfire_repo_set_baseurl;
        pakfire_repo_set_description;
        pakfire_repo_set_enabled;
index 3ee2f9604f7897c7c2c6833314d55649b190129c..1f438db8019514153d2d9a0abb8f65ae15545c7c 100644 (file)
@@ -19,6 +19,8 @@
 #############################################################################*/
 
 #include <assert.h>
+#include <errno.h>
+#include <fts.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -297,6 +299,18 @@ PAKFIRE_EXPORT int pakfire_repo_set_baseurl(PakfireRepo repo, const char* baseur
        return 0;
 }
 
+static char* pakfire_repo_get_path(PakfireRepo repo) {
+       const char* baseurl = pakfire_repo_get_baseurl(repo);
+       if (!baseurl)
+               return NULL;
+
+       // Must be a local repository
+       if (!pakfire_string_startswith(baseurl, "dir://"))
+               return NULL;
+
+       return strdup(baseurl + strlen("dir://"));
+}
+
 PAKFIRE_EXPORT const char* pakfire_repo_get_keyfile(PakfireRepo repo) {
        return repo->appdata->keyfile;
 }
@@ -629,3 +643,60 @@ PAKFIRE_EXPORT time_t pakfire_repo_cache_age(PakfireRepo repo, const char* path)
 
        return t;
 }
+
+static int pakfire_repo_scan_file(PakfireRepo repo, const char* path) {
+       PakfireArchive archive = pakfire_archive_open(repo->pakfire, path);
+       if (!archive)
+               return errno;
+
+       // Import package into the repository
+       PakfirePackage pkg = pakfire_archive_make_package(archive, repo);
+       if (!pkg) {
+               pakfire_archive_unref(archive);
+               return errno;
+       }
+
+       pakfire_package_unref(pkg);
+       pakfire_archive_unref(archive);
+
+       return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_repo_scan(PakfireRepo repo, int flags) {
+       char* path = pakfire_repo_get_path(repo);
+       if (!path)
+               return EINVAL;
+
+       int r = 1;
+
+       char* paths[] = {
+               path, NULL,
+       };
+
+       FTS* tree = fts_open(paths, FTS_NOCHDIR|FTS_NOSTAT, 0);
+       if (!tree)
+               return errno;
+
+       FTSENT* node;
+
+       while ((node = fts_read(tree))) {
+               // Skip anything that isn't a file
+               if (!(node->fts_info & FTS_F))
+                       continue;
+
+               // Skip any files that do not end in "pfm"
+               if (!pakfire_string_endswith(node->fts_name, ".pfm"))
+                       continue;
+
+               // Scan the file
+               r = pakfire_repo_scan_file(repo, node->fts_path);
+               if (r)
+                       goto ERROR;
+       }
+
+ERROR:
+       fts_close(tree);
+       free(path);
+
+       return r;
+}
index 8d20ad4b619351ba9b0c19be2c874bde7716c561..38c0a71ba758f9e8f6c7766f0ebf0a59294ef517 100644 (file)
@@ -39,6 +39,10 @@ PAKFIRE_EXPORT int pakfire_string_startswith(const char* s, const char* prefix)
        return !strncmp(s, prefix, strlen(prefix));
 }
 
+int pakfire_string_endswith(const char* s, const char* suffix) {
+       return !strcmp(s + strlen(s) - strlen(suffix), suffix);
+}
+
 char* pakfire_format_size(double size) {
        char string[STRING_SIZE];
        const char* units[] = {" ", "k", "M", "G", "T", NULL};
index c882ec5b3b6cdf7be42bf4d3bfab526040e56cf9..e9a9a464baedd670eaf2bea3f7a9e851d047dbf2 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <pakfire/repo.h>
+#include <pakfire/util.h>
+
 #include "../testsuite.h"
 
+static int test_scan(const struct test* t) {
+       char baseurl[1024];
+       snprintf(baseurl, sizeof(baseurl) - 1, "dir://%s/data", TEST_SRC_PATH);
+
+       PakfireRepo repo = pakfire_repo_create(t->pakfire, "test");
+       ASSERT(repo);
+
+       pakfire_repo_set_baseurl(repo, baseurl);
+
+       int r = pakfire_repo_scan(repo, 0);
+       ASSERT(r == 0);
+
+       // There should be one package in this repository now
+       ASSERT(pakfire_repo_count(repo) == 1);
+
+       pakfire_repo_unref(repo);
+
+       return 0;
+}
+
 int main(int argc, char** argv) {
+       testsuite_add_test(test_scan);
+
        return testsuite_run();
 }