]> git.ipfire.org Git - pakfire.git/commitdiff
request: Implement downloading packages and packages from command line
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 26 Apr 2021 17:33:26 +0000 (17:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 26 Apr 2021 17:33:26 +0000 (17:33 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/request.c

index af548c223efb880c91dc0fb3d9eaf6b71e94234f..83f024b508791457c5469d24639f272fc15b1655 100644 (file)
@@ -19,6 +19,7 @@
 #############################################################################*/
 
 #include <errno.h>
+#include <linux/limits.h>
 #include <stdlib.h>
 
 #include <solv/queue.h>
@@ -30,6 +31,7 @@
 # include <solv/solverdebug.h>
 #endif
 
+#include <pakfire/archive.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
 #include <pakfire/pakfire.h>
@@ -228,6 +230,26 @@ PAKFIRE_EXPORT PakfireTransaction pakfire_request_get_transaction(struct pakfire
        return pakfire_transaction_create(request->pakfire, request->transaction);
 }
 
+static int pakfire_request_is_file(const char* what) {
+       return pakfire_string_endswith(what, ".pfm");
+}
+
+static int pakfire_request_is_url(const char* what) {
+       static const char* known_schemas[] = {
+               "https://",
+               "http://",
+               "file://",
+               NULL,
+       };
+
+       for (const char** schema = known_schemas; *schema; schema++) {
+               if (pakfire_string_startswith(what, *schema))
+                       return 1;
+       }
+
+       return 0;
+}
+
 static int pakfire_request_add_package(struct pakfire_request* request, int action,
                PakfirePackage pkg, int flags) {
        // Get the solvable ID
@@ -303,8 +325,108 @@ static int pakfire_request_add_job(struct pakfire_request* request, int action,
        return 0;
 }
 
+static int pakfire_request_add_archive(struct pakfire_request* request, int action,
+               PakfireArchive archive, int extra_flags) {
+       PakfireRepo repo = pakfire_repo_create(request->pakfire, "@commandline");
+       if (!repo)
+               return 1;
+
+       // Add it to the repository
+       PakfirePackage pkg = pakfire_repo_add_archive(repo, archive);
+       if (!pkg)
+               goto ERROR;
+
+       int r = pakfire_request_add_package(request, action, pkg, extra_flags);
+       if (r)
+               goto ERROR;
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (pkg)
+               pakfire_package_unref(pkg);
+       pakfire_repo_unref(repo);
+
+       return r;
+}
+
+static int pakfire_request_add_file(struct pakfire_request* request, int action,
+               const char* path, int extra_flags) {
+       PakfireArchive archive;
+
+       // Open the archive
+       int r = pakfire_archive_open(&archive, request->pakfire, path);
+       if (r)
+               goto ERROR;
+
+       // Add it to the request
+       r = pakfire_request_add_archive(request, action, archive, extra_flags);
+       if (r)
+               goto ERROR;
+
+       // Success
+       r = 0;
+
+ERROR:
+       pakfire_archive_unref(archive);
+
+       return r;
+}
+
+static int pakfire_request_add_url(struct pakfire_request* request, int action,
+               const char* url, int extra_flags) {
+       struct pakfire_downloader* downloader;
+       char path[PATH_MAX] = PAKFIRE_CACHE_PATH "/tmp/XXXXXX";
+
+       // Allocate a temporary file name
+       FILE* f = pakfire_mktemp(path);
+       if (!f)
+               return 1;
+
+       // Create a downloader
+       int r = pakfire_downloader_create(&downloader, request->pakfire);
+       if (r)
+               return r;
+
+       // Download the file
+       r = pakfire_downloader_retrieve(downloader, NULL, NULL, NULL,
+                       url, path, PAKFIRE_TRANSFER_NOTEMP);
+       if (r)
+               goto ERROR;
+
+       // Try adding the archive
+       r = pakfire_request_add_file(request, action, path, extra_flags);
+       if (r)
+               goto ERROR;
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (f)
+               fclose(f);
+       pakfire_downloader_unref(downloader);
+
+       return r;
+}
+
+static int pakfire_request_add(struct pakfire_request* request, int action,
+               const char* what, int extra_flags) {
+       // Download and add any remote files
+       if (pakfire_request_is_url(what))
+               return pakfire_request_add_url(request, action, what, extra_flags);
+
+       // Add any local files
+       if (pakfire_request_is_file(what))
+               return pakfire_request_add_file(request, action, what, extra_flags);
+
+       // Add anything else as a job
+       return pakfire_request_add_job(request, action, what, extra_flags);
+}
+
 PAKFIRE_EXPORT int pakfire_request_install(struct pakfire_request* request, const char* what) {
-       return pakfire_request_add_job(request, SOLVER_INSTALL, what, 0);
+       return pakfire_request_add(request, SOLVER_INSTALL, what, 0);
 }
 
 PAKFIRE_EXPORT int pakfire_request_install_package(
@@ -322,7 +444,7 @@ static int erase_flags(int flags) {
 }
 
 PAKFIRE_EXPORT int pakfire_request_erase(struct pakfire_request* request, const char* what, int flags) {
-       return pakfire_request_add_job(request, SOLVER_ERASE, what, erase_flags(flags));
+       return pakfire_request_add(request, SOLVER_ERASE, what, erase_flags(flags));
 }
 
 PAKFIRE_EXPORT int pakfire_request_erase_package(
@@ -331,7 +453,7 @@ PAKFIRE_EXPORT int pakfire_request_erase_package(
 }
 
 PAKFIRE_EXPORT int pakfire_request_upgrade(struct pakfire_request* request, const char* what) {
-       return pakfire_request_add_job(request, SOLVER_UPDATE, what, 0);
+       return pakfire_request_add(request, SOLVER_UPDATE, what, 0);
 }
 
 PAKFIRE_EXPORT int pakfire_request_upgrade_package(
@@ -352,7 +474,7 @@ PAKFIRE_EXPORT int pakfire_request_distupgrade(struct pakfire_request* request)
 }
 
 PAKFIRE_EXPORT int pakfire_request_lock(struct pakfire_request* request, const char* what) {
-       return pakfire_request_add_job(request, SOLVER_LOCK, what, 0);
+       return pakfire_request_add(request, SOLVER_LOCK, what, 0);
 }
 
 PAKFIRE_EXPORT int pakfire_request_lock_package(struct pakfire_request* request, PakfirePackage package) {