+++ /dev/null
-/*#############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2013 Pakfire development team #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-# #
-#############################################################################*/
-
-#include <errno.h>
-#include <linux/limits.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <pakfire/archive.h>
-#include <pakfire/constants.h>
-#include <pakfire/db.h>
-#include <pakfire/execute.h>
-#include <pakfire/logging.h>
-#include <pakfire/package.h>
-#include <pakfire/pakfire.h>
-#include <pakfire/private.h>
-#include <pakfire/repo.h>
-#include <pakfire/scriptlet.h>
-#include <pakfire/step.h>
-#include <pakfire/transaction.h>
-#include <pakfire/types.h>
-#include <pakfire/util.h>
-
-#define LDCONFIG "/sbin/ldconfig"
-
-struct _PakfireStep {
- Pakfire pakfire;
- PakfirePackage package;
- PakfireArchive archive;
- pakfire_step_type_t type;
- int nrefs;
-};
-
-int pakfire_step_create(PakfireStep* step, Pakfire pakfire,
- pakfire_step_type_t type, PakfirePackage pkg) {
- PakfireStep s = calloc(1, sizeof(*s));
- if (!s)
- return ENOMEM;
-
- // Store a reference to Pakfire
- s->pakfire = pakfire_ref(pakfire);
-
- // Initialize the reference counter
- s->nrefs = 1;
-
- // Store a reference to the package
- s->package = pakfire_package_ref(pkg);
-
- // Store type
- s->type = type;
-
- *step = s;
- return 0;
-}
-
-PakfireStep pakfire_step_ref(PakfireStep step) {
- step->nrefs++;
-
- return step;
-}
-
-static void pakfire_step_free(PakfireStep step) {
- DEBUG(step->pakfire, "Releasing Step at %p\n", step);
-
- pakfire_package_unref(step->package);
- if (step->archive)
- pakfire_archive_unref(step->archive);
- pakfire_unref(step->pakfire);
- free(step);
-}
-
-PakfireStep pakfire_step_unref(PakfireStep step) {
- if (--step->nrefs > 0)
- return step;
-
- pakfire_step_free(step);
- return NULL;
-}
-
-PakfirePackage pakfire_step_get_package(PakfireStep step) {
- return pakfire_package_ref(step->package);
-}
-
-pakfire_step_type_t pakfire_step_get_type(PakfireStep step) {
- return step->type;
-}
-
-static int pakfire_step_get_downloadtype(PakfireStep step) {
- int type = pakfire_step_get_type(step);
-
- switch (type) {
- case PAKFIRE_STEP_INSTALL:
- case PAKFIRE_STEP_REINSTALL:
- case PAKFIRE_STEP_DOWNGRADE:
- case PAKFIRE_STEP_UPGRADE:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-size_t pakfire_step_get_downloadsize(PakfireStep step) {
- if (pakfire_step_get_downloadtype(step))
- return pakfire_package_get_downloadsize(step->package);
-
- return 0;
-}
-
-int pakfire_step_needs_download(PakfireStep step) {
- if (!pakfire_step_get_downloadtype(step))
- return false;
-
- PakfireRepo repo = pakfire_package_get_repo(step->package);
- if (pakfire_repo_is_installed_repo(repo) == 0)
- return false;
-
- const char* path = pakfire_package_get_path(step->package);
-
- // Does the file exist?
- int r = access(path, R_OK);
- if (r == 0)
- return false;
-
- return true;
-}
-
-static int pakfire_step_verify(PakfireStep step) {
- // The package must have been downloaded
- if (pakfire_step_needs_download(step))
- return 1;
-
- // Fetch the archive
- step->archive = pakfire_package_get_archive(step->package);
- if (!step->archive) {
- const char* nevra = pakfire_package_get_nevra(step->package);
- ERROR(step->pakfire, "Could not open package archive for %s: %s\n",
- nevra, strerror(errno));
-
- return -1;
- }
-
- // Verify the archive
- pakfire_archive_verify_status_t status = pakfire_archive_verify(step->archive);
-
- // Log error
- if (status) {
- const char* error = pakfire_archive_verify_strerror(status);
- ERROR(step->pakfire, "Archive verification failed: %s\n", error);
- }
-
- return status;
-}
-
-static int pakfire_script_check_shell(struct pakfire_scriptlet* scriptlet) {
- const char* interpreter = "#!/bin/sh";
-
- // data must be long enough
- if (scriptlet->size <= strlen(interpreter))
- return 0;
-
- // If the string begins with the interpreter, this is a match
- if (strncmp(scriptlet->data, interpreter, strlen(interpreter)) == 0)
- return 1;
-
- return 0;
-}
-
-static int pakfire_step_run_shell_script(PakfireStep step, struct pakfire_scriptlet* scriptlet) {
- return pakfire_execute_script(step->pakfire, scriptlet->data, scriptlet->size, NULL, 0, NULL, NULL);
-}
-
-static int pakfire_step_run_script(PakfireStep step,
- struct pakfire_db* db, pakfire_scriptlet_type type) {
- struct pakfire_scriptlet* scriptlet = NULL;
-
- // Fetch scriptlet from archive if possible
- if (step->archive)
- scriptlet = pakfire_archive_get_scriptlet(step->archive, type);
- else
- scriptlet = pakfire_db_get_scriptlet(db, step->package, type);
-
- // Nothing to do if there are no scriptlets
- if (!scriptlet)
- return 0;
-
- // Found a script!
- DEBUG(step->pakfire, "Found scriptlet:\n%.*s",
- (int)scriptlet->size, (const char*)scriptlet->data);
-
- // Detect what kind of script this is and run it
- if (pakfire_script_check_shell(scriptlet)) {
- pakfire_step_run_shell_script(step, scriptlet);
- } else {
- ERROR(step->pakfire, "Scriptlet is of an unknown kind\n");
- }
-
- return 0;
-}
-
-static int pakfire_run_ldconfig(PakfireStep step) {
- char path[PATH_MAX];
-
- // Check if ldconfig exists before calling it to avoid overhead
- int r = pakfire_make_path(step->pakfire, path, LDCONFIG);
- if (r < 0)
- return 1;
-
- r = -1;
-
- if (access(path, X_OK) == 0) {
- r = pakfire_execute_command(step->pakfire, LDCONFIG, NULL, 0, NULL, NULL);
-
- DEBUG(step->pakfire, "ldconfig returned %d\n", r);
- }
-
- return r;
-}
-
-static int pakfire_step_extract(PakfireStep step) {
- if (!step->archive) {
- ERROR(step->pakfire, "Archive was not opened\n");
- return -1;
- }
-
- // Extract payload to the root of the Pakfire instance
- int r = pakfire_archive_extract(step->archive, NULL);
- if (r) {
- const char* nevra = pakfire_package_get_nevra(step->package);
- ERROR(step->pakfire, "Could not extract package %s: %d\n", nevra, r);
- }
-
- // Is it necessary to call ldconfig?
- PakfireFilelist filelist = pakfire_archive_get_filelist(step->archive);
- if (filelist) {
- int need_ldconfig = pakfire_filelist_contains(filelist, "*/lib*.so.?");
-
- // Update the runtime linker cache
- if (need_ldconfig)
- pakfire_run_ldconfig(step);
-
- pakfire_filelist_unref(filelist);
- }
-
- return r;
-}
-
-static int pakfire_step_erase(PakfireStep step) {
- // Update the runtime linker cache after all files have been removed
- pakfire_run_ldconfig(step);
-
- return 0; // TODO
-}
-
-
-static const char* pakfire_action_type_string(pakfire_action_type_t type) {
- switch (type) {
- case PAKFIRE_ACTION_NOOP:
- return "NOOP";
-
- case PAKFIRE_ACTION_VERIFY:
- return "VERIFY";
-
- case PAKFIRE_ACTION_EXECUTE:
- return "EXECUTE";
-
- case PAKFIRE_ACTION_PRETRANS:
- return "PRETRANS";
-
- case PAKFIRE_ACTION_POSTTRANS:
- return "POSTTRANS";
- }
-
- return NULL;
-}
-
-int pakfire_step_run(PakfireStep step,
- struct pakfire_db* db, const pakfire_action_type_t action) {
- DEBUG(step->pakfire, "Running Step %p (%s)\n", step, pakfire_action_type_string(action));
-
- pakfire_step_type_t type = pakfire_step_get_type(step);
-
- int r = 0;
- switch (action) {
- // Verify this step
- case PAKFIRE_ACTION_VERIFY:
- r = pakfire_step_verify(step);
- break;
-
- // Run the pre-transaction scripts
- case PAKFIRE_ACTION_PRETRANS:
- switch (type) {
- case PAKFIRE_STEP_INSTALL:
- case PAKFIRE_STEP_REINSTALL:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSIN);
- break;
-
- case PAKFIRE_STEP_UPGRADE:
- case PAKFIRE_STEP_DOWNGRADE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSUP);
- break;
-
- case PAKFIRE_STEP_ERASE:
- case PAKFIRE_STEP_OBSOLETE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSUN);
- break;
-
- case PAKFIRE_STEP_IGNORE:
- break;
- }
- break;
-
- // Run the post-transaction scripts
- case PAKFIRE_ACTION_POSTTRANS:
- switch (type) {
- case PAKFIRE_STEP_INSTALL:
- case PAKFIRE_STEP_REINSTALL:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSIN);
- break;
-
- case PAKFIRE_STEP_UPGRADE:
- case PAKFIRE_STEP_DOWNGRADE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSUP);
- break;
-
- case PAKFIRE_STEP_ERASE:
- case PAKFIRE_STEP_OBSOLETE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSUN);
- break;
-
- case PAKFIRE_STEP_IGNORE:
- break;
- }
- break;
-
- // Execute the action of this script
- case PAKFIRE_ACTION_EXECUTE:
- switch (type) {
- case PAKFIRE_STEP_INSTALL:
- case PAKFIRE_STEP_REINSTALL:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREIN);
- if (r)
- break;
-
- r = pakfire_step_extract(step);
- if (r)
- break;
-
- // Remove package metadata first when reinstalling
- if (type == PAKFIRE_STEP_REINSTALL) {
- r = pakfire_db_remove_package(db, step->package);
- if (r)
- break;
- }
-
- r = pakfire_db_add_package(db, step->package, step->archive);
- if (r)
- break;
-
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTIN);
- break;
-
- case PAKFIRE_STEP_UPGRADE:
- case PAKFIRE_STEP_DOWNGRADE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREUP);
- if (r)
- break;
-
- r = pakfire_step_extract(step);
- if (r)
- break;
-
- r = pakfire_db_add_package(db, step->package, step->archive);
- if (r)
- break;
-
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTUP);
- break;
-
- case PAKFIRE_STEP_ERASE:
- case PAKFIRE_STEP_OBSOLETE:
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREUN);
- if (r)
- break;
-
- r = pakfire_step_erase(step);
- if (r)
- break;
-
- r = pakfire_db_remove_package(db, step->package);
- if (r)
- break;
-
- r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTUN);
- break;
-
- case PAKFIRE_STEP_IGNORE:
- break;
- }
- break;
-
- // Do nothing
- case PAKFIRE_ACTION_NOOP:
- break;
- }
-
- if (r)
- ERROR(step->pakfire, "Step has failed: %s\n", strerror(r));
-
- return r;
-}
#include <solv/transaction.h>
+#include <pakfire/archive.h>
#include <pakfire/db.h>
#include <pakfire/downloader.h>
+#include <pakfire/execute.h>
#include <pakfire/i18n.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
#include <pakfire/pakfire.h>
#include <pakfire/private.h>
#include <pakfire/repo.h>
-#include <pakfire/step.h>
#include <pakfire/transaction.h>
#include <pakfire/types.h>
#include <pakfire/util.h>
Transaction* transaction;
- PakfireStep* steps;
- size_t num_steps;
+ PakfireArchive* archives;
+ PakfirePackage* packages;
+ size_t num;
};
-static pakfire_step_type_t transaction_get_step_type(struct pakfire_transaction* transaction, Id id) {
- int type = transaction_type(transaction->transaction, id, 0);
+static pakfire_step_type_t pakfire_transaction_get_step_type(
+ struct pakfire_transaction* transaction, PakfirePackage pkg) {
+ int type = transaction_type(transaction->transaction, pakfire_package_id(pkg), 0);
// Translate solver types into our own types
switch (type) {
}
}
-static void pakfire_transaction_free(struct pakfire_transaction* transaction) {
- // Release all steps
- if (transaction->steps) {
- for (unsigned int i = 0; i < transaction->num_steps; i++)
- pakfire_step_unref(transaction->steps[i]);
- free(transaction->steps);
+static void pakfire_transaction_free_archives_and_packages(
+ struct pakfire_transaction* transaction) {
+ if (transaction->archives) {
+ for (unsigned int i = 0; i < transaction->num; i++)
+ if (transaction->archives[i])
+ pakfire_archive_unref(transaction->archives[i]);
+ free(transaction->archives);
+
+ transaction->archives = NULL;
}
+ if (transaction->packages) {
+ for (unsigned int i = 0; i < transaction->num; i++)
+ if (transaction->packages[i])
+ pakfire_package_unref(transaction->packages[i]);
+ free(transaction->packages);
+
+ transaction->packages = NULL;
+ }
+}
+
+static void pakfire_transaction_free(struct pakfire_transaction* transaction) {
+ pakfire_transaction_free_archives_and_packages(transaction);
+
transaction_free(transaction->transaction);
pakfire_unref(transaction->pakfire);
free(transaction);
}
-static int pakfire_transaction_add_step(struct pakfire_transaction* transaction, Id id) {
- int type = transaction_get_step_type(transaction, id);
+static int pakfire_transaction_import_transaction(
+ struct pakfire_transaction* transaction, Transaction* t) {
+ // Free any previous content
+ pakfire_transaction_free_archives_and_packages(transaction);
- // Do not add ignored steps
- if (type == PAKFIRE_STEP_IGNORE)
- return 0;
+ // Order the transaction
+ transaction_order(t, 0);
- // Allocate more space
- transaction->steps = reallocarray(transaction->steps, sizeof(*transaction->steps),
- transaction->num_steps + 1);
- if (!transaction->steps)
- return 1;
+ // How many steps?
+ transaction->num = t->steps.count;
- PakfirePackage pkg = pakfire_package_create_from_solvable(transaction->pakfire, id);
- if (!pkg)
+ // Allocate space for packages
+ transaction->packages = calloc(transaction->num, sizeof(*transaction->packages));
+ if (!transaction->packages)
return 1;
- PakfireStep step;
- int r = pakfire_step_create(&step, transaction->pakfire, type, pkg);
- if (r)
- goto ERROR;
-
- transaction->steps[transaction->num_steps++] = step;
-
- // Success
- r = 0;
+ // Allocate space for archives
+ transaction->archives = calloc(transaction->num, sizeof(*transaction->archives));
+ if (!transaction->archives)
+ return 1;
-ERROR:
- if (pkg)
- pakfire_package_unref(pkg);
+ // Create all packages
+ for (unsigned int i = 0; i < transaction->num; i++) {
+ transaction->packages[i] = pakfire_package_create_from_solvable(
+ transaction->pakfire, t->steps.elements[i]);
+ }
- return r;
+ return 0;
}
int pakfire_transaction_create(struct pakfire_transaction** transaction,
if (!t->transaction)
goto ERROR;
- // Order the transaction
- transaction_order(t->transaction, 0);
-
- // Import steps
- for (int i = 0; i < t->transaction->steps.count; i++) {
- int r = pakfire_transaction_add_step(t, t->transaction->steps.elements[i]);
- if (r)
- goto ERROR;
- }
+ // Import transaction
+ int r = pakfire_transaction_import_transaction(t, t->transaction);
+ if (r)
+ goto ERROR;
*transaction = t;
return 0;
return 1;
}
-PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_ref(struct pakfire_transaction* transaction) {
+PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_ref(
+ struct pakfire_transaction* transaction) {
transaction->nrefs++;
return transaction;
}
-PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_unref(struct pakfire_transaction* transaction) {
+PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_unref(
+ struct pakfire_transaction* transaction) {
if (--transaction->nrefs > 0)
return transaction;
}
PAKFIRE_EXPORT size_t pakfire_transaction_count(struct pakfire_transaction* transaction) {
- return transaction->num_steps;
+ return transaction->num;
}
static ssize_t pakfire_transaction_installsizechange(struct pakfire_transaction* transaction) {
PAKFIRE_EXPORT ssize_t pakfire_transaction_downloadsize(struct pakfire_transaction* transaction) {
ssize_t size = 0;
- for (unsigned int i = 0; i < transaction->num_steps; i++)
- size += pakfire_step_get_downloadsize(transaction->steps[i]);
+ for (unsigned int i = 0; i < transaction->num; i++)
+ size += pakfire_package_get_downloadsize(transaction->packages[i]);
return size;
}
return string;
}
+static int pakfire_transaction_verify(struct pakfire_transaction* transaction,
+ PakfirePackage pkg, PakfireArchive archive) {
+ // Nothing to do if this step does not have an archive
+ if (!archive)
+ return 0;
+
+ // Verify the archive
+ pakfire_archive_verify_status_t status = pakfire_archive_verify(archive);
+
+ // Log error
+ if (status) {
+ const char* error = pakfire_archive_verify_strerror(status);
+ ERROR(transaction->pakfire, "Archive verification failed: %s\n", error);
+ }
+
+ return status;
+}
+
+static int pakfire_transaction_run_script(struct pakfire_transaction* transaction,
+ struct pakfire_db* db, pakfire_scriptlet_type type, PakfirePackage pkg, PakfireArchive archive) {
+ struct pakfire_scriptlet* scriptlet = NULL;
+
+ // Fetch scriptlet from archive if possible
+ if (archive)
+ scriptlet = pakfire_archive_get_scriptlet(archive, type);
+ else
+ scriptlet = pakfire_db_get_scriptlet(db, pkg, type);
+
+ // Nothing to do if there are no scriptlets
+ if (!scriptlet)
+ return 0;
+
+ // Found a script!
+ DEBUG(transaction->pakfire, "Found scriptlet:\n%.*s",
+ (int)scriptlet->size, (const char*)scriptlet->data);
+
+ // Detect what kind of script this is and run it
+ if (pakfire_scriptlet_is_shell_script(scriptlet)) {
+ pakfire_execute_script(transaction->pakfire, scriptlet->data, scriptlet->size,
+ NULL, 0, NULL, NULL);
+ } else {
+ ERROR(transaction->pakfire, "Scriptlet is of an unknown kind\n");
+ }
+
+ return 0;
+}
+
+static int pakfire_transaction_extract(struct pakfire_transaction* transaction,
+ PakfirePackage pkg, PakfireArchive archive) {
+ // Extract payload to the root of the Pakfire instance
+ int r = pakfire_archive_extract(archive, NULL);
+ if (r) {
+ ERROR(transaction->pakfire, "Could not extract package %s: %s\n",
+ pakfire_package_get_nevra(pkg), strerror(errno));
+ return r;
+ }
+
+ // Is it necessary to call ldconfig?
+ PakfireFilelist filelist = pakfire_archive_get_filelist(archive);
+ if (filelist) {
+ int need_ldconfig = pakfire_filelist_contains(filelist, "*/lib*.so.?");
+
+ // Update the runtime linker cache
+ if (need_ldconfig)
+ pakfire_execute_ldconfig(transaction->pakfire);
+
+ pakfire_filelist_unref(filelist);
+ }
+
+ return r;
+}
+
+static int pakfire_transaction_erase(struct pakfire_transaction* transaction,
+ PakfirePackage pkg, PakfireArchive archive) {
+ // Update the runtime linker cache after all files have been removed
+ pakfire_execute_ldconfig(transaction->pakfire);
+
+ return 0; // TODO
+}
+
+static const char* pakfire_action_type_string(pakfire_action_type_t type) {
+ switch (type) {
+ case PAKFIRE_ACTION_NOOP:
+ return "NOOP";
+
+ case PAKFIRE_ACTION_VERIFY:
+ return "VERIFY";
+
+ case PAKFIRE_ACTION_EXECUTE:
+ return "EXECUTE";
+
+ case PAKFIRE_ACTION_PRETRANS:
+ return "PRETRANS";
+
+ case PAKFIRE_ACTION_POSTTRANS:
+ return "POSTTRANS";
+ }
+
+ return NULL;
+}
+
+static int pakfire_transaction_run_step(struct pakfire_transaction* transaction,
+ struct pakfire_db* db, const pakfire_action_type_t action, PakfirePackage pkg, PakfireArchive archive) {
+ if (!pkg) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ DEBUG(transaction->pakfire, "Running %s for %s\n",
+ pakfire_action_type_string(action), pakfire_package_get_nevra(pkg));
+
+ pakfire_step_type_t type = pakfire_transaction_get_step_type(transaction, pkg);
+
+ int r = 0;
+ switch (action) {
+ // Verify this step
+ case PAKFIRE_ACTION_VERIFY:
+ r = pakfire_transaction_verify(transaction, pkg, archive);
+ break;
+
+ // Run the pre-transaction scripts
+ case PAKFIRE_ACTION_PRETRANS:
+ switch (type) {
+ case PAKFIRE_STEP_INSTALL:
+ case PAKFIRE_STEP_REINSTALL:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PRETRANSIN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_UPGRADE:
+ case PAKFIRE_STEP_DOWNGRADE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PRETRANSUP, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_ERASE:
+ case PAKFIRE_STEP_OBSOLETE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PRETRANSUN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_IGNORE:
+ break;
+ }
+ break;
+
+ // Run the post-transaction scripts
+ case PAKFIRE_ACTION_POSTTRANS:
+ switch (type) {
+ case PAKFIRE_STEP_INSTALL:
+ case PAKFIRE_STEP_REINSTALL:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTTRANSIN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_UPGRADE:
+ case PAKFIRE_STEP_DOWNGRADE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTTRANSUP, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_ERASE:
+ case PAKFIRE_STEP_OBSOLETE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTTRANSUN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_IGNORE:
+ break;
+ }
+ break;
+
+ // Execute the action of this script
+ case PAKFIRE_ACTION_EXECUTE:
+ switch (type) {
+ case PAKFIRE_STEP_INSTALL:
+ case PAKFIRE_STEP_REINSTALL:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PREIN, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_transaction_extract(transaction, pkg, archive);
+ if (r)
+ break;
+
+ // Remove package metadata first when reinstalling
+ if (type == PAKFIRE_STEP_REINSTALL) {
+ r = pakfire_db_remove_package(db, pkg);
+ if (r)
+ break;
+ }
+
+ r = pakfire_db_add_package(db, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTIN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_UPGRADE:
+ case PAKFIRE_STEP_DOWNGRADE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PREUP, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_transaction_extract(transaction, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_db_add_package(db, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTUP, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_ERASE:
+ case PAKFIRE_STEP_OBSOLETE:
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_PREUN, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_transaction_erase(transaction, pkg, archive);
+ if (r)
+ break;
+
+ r = pakfire_db_remove_package(db, pkg);
+ if (r)
+ break;
+
+ r = pakfire_transaction_run_script(transaction, db,
+ PAKFIRE_SCRIPTLET_POSTUN, pkg, archive);
+ break;
+
+ case PAKFIRE_STEP_IGNORE:
+ break;
+ }
+ break;
+
+ // Do nothing
+ case PAKFIRE_ACTION_NOOP:
+ break;
+ }
+
+ if (r)
+ ERROR(transaction->pakfire, "Step has failed: %s\n", strerror(r));
+
+ return r;
+}
+
static int pakfire_transaction_run_steps(struct pakfire_transaction* transaction,
struct pakfire_db* db, const pakfire_action_type_t action) {
int r = 0;
// Walk through all steps
- for (unsigned int i = 0; i < transaction->num_steps; i++) {
- PakfireStep step = transaction->steps[i];
-
- // Verify the step
- r = pakfire_step_run(step, db, action);
+ for (unsigned int i = 0; i < transaction->num; i++) {
+ r = pakfire_transaction_run_step(transaction, db, action,
+ transaction->packages[i], transaction->archives[i]);
// End loop if action was unsuccessful
if (r) {
- DEBUG(transaction->pakfire, "Step %p failed with code %d\n", step, r);
+ DEBUG(transaction->pakfire, "Step %d failed: %s\n", i, strerror(errno));
break;
}
}
return r;
}
+static int pakfire_transaction_open_archives(struct pakfire_transaction* transaction) {
+ for (unsigned int i = 0; i < transaction->num; i++) {
+ PakfirePackage pkg = transaction->packages[i];
+
+ // Fetch the type
+ pakfire_step_type_t type = pakfire_transaction_get_step_type(transaction, pkg);
+
+ // Do we need the archive?
+ switch (type) {
+ case PAKFIRE_STEP_INSTALL:
+ case PAKFIRE_STEP_REINSTALL:
+ case PAKFIRE_STEP_UPGRADE:
+ case PAKFIRE_STEP_DOWNGRADE:
+ case PAKFIRE_STEP_OBSOLETE:
+ break;
+
+ case PAKFIRE_STEP_ERASE:
+ case PAKFIRE_STEP_IGNORE:
+ continue;
+ }
+
+ transaction->archives[i] = pakfire_package_get_archive(pkg);
+ if (!transaction->archives[i]) {
+ ERROR(transaction->pakfire, "Could not open archive for %s: %s\n",
+ pakfire_package_get_nevra(pkg), strerror(errno));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transaction) {
struct pakfire_db* db;
int r;
DEBUG(transaction->pakfire, "Running Transaction %p\n", transaction);
+ // Open all archives
+ r = pakfire_transaction_open_archives(transaction);
+ if (r)
+ return r;
+
// Open the database
r = pakfire_db_open(&db, transaction->pakfire, PAKFIRE_DB_READWRITE);
if (r) {
}
// Add all packages that need to be downloaded
- for (unsigned int i = 0; i < transaction->num_steps; i++) {
- PakfireStep step = transaction->steps[i];
-
- // Skip all steps that do not require a download
- if (!pakfire_step_needs_download(step))
- continue;
+ for (unsigned int i = 0; i < transaction->num; i++) {
+ PakfirePackage pkg = transaction->packages[i];
+
+ pakfire_step_type_t type = pakfire_transaction_get_step_type(transaction, pkg);
+ switch (type) {
+ case PAKFIRE_STEP_INSTALL:
+ case PAKFIRE_STEP_REINSTALL:
+ case PAKFIRE_STEP_DOWNGRADE:
+ case PAKFIRE_STEP_UPGRADE:
+ break;
- // Fetch the package
- PakfirePackage pkg = pakfire_step_get_package(step);
+ default:
+ continue;
+ }
// Enqueue download
r = pakfire_transaction_download_package(transaction, downloader, pkg);
- pakfire_package_unref(pkg);
-
if (r)
goto ERROR;
}