struct pakfire* pakfire,
int transaction_flags,
int solver_flags,
- int (*action)(struct pakfire_request* request, const char* what, int flags),
+ const enum pakfire_request_action action,
const char** packages,
const char** locks,
int job_flags,
// Lock anything that should be locked
if (locks) {
for (const char** lock = locks; *lock; lock++) {
- r = pakfire_request_lock(request, *lock);
+ r = pakfire_request_add(request, PAKFIRE_REQ_LOCK, *lock, 0);
if (r) {
ERROR(pakfire, "Could not lock '%s': %m\n", *lock);
goto ERROR;
// Perform action on all packages
for (const char** package = packages; *package; package++) {
- r = action(request, *package, job_flags);
+ r = pakfire_request_add(request, action, *package, job_flags);
if (r) {
ERROR(pakfire, "Could not find '%s': %m\n", *package);
goto ERROR;
pakfire,
transaction_flags,
solver_flags,
- pakfire_request_install,
+ PAKFIRE_REQ_INSTALL,
packages,
locks,
flags,
pakfire,
transaction_flags,
solver_flags,
- pakfire_request_erase,
+ PAKFIRE_REQ_ERASE,
packages,
locks,
flags,
}
static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solver_flags,
- int (*action)(struct pakfire_request* request, int flags),
- int job_flags, int* changed,
+ const enum pakfire_request_action action, int job_flags, int* changed,
pakfire_status_callback status_callback, void* status_callback_data) {
struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
goto ERROR;
// Perform action
- r = action(request, job_flags);
+ r = pakfire_request_add(request, action, NULL, job_flags);
if (r)
goto ERROR;
// XXX add locks
if (!packages)
return pakfire_perform_transaction_simple(
- pakfire, solver_flags, pakfire_request_update_all, flags, changed,
+ pakfire, solver_flags, PAKFIRE_REQ_UPDATE_ALL, flags, changed,
status_callback, status_callback_data);
return pakfire_perform_transaction(pakfire, transaction_flags, solver_flags,
- pakfire_request_update, packages, locks, flags, changed,
+ PAKFIRE_REQ_UPDATE, packages, locks, flags, changed,
status_callback, status_callback_data);
}
static int pakfire_verify(struct pakfire* pakfire, int *changed) {
- return pakfire_perform_transaction_simple(pakfire, 0, pakfire_request_verify,
+ return pakfire_perform_transaction_simple(pakfire, 0, PAKFIRE_REQ_VERIFY,
0, changed, NULL, NULL);
}
PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags,
int* changed, pakfire_status_callback status_callback, void* status_callback_data) {
return pakfire_perform_transaction_simple(pakfire, solver_flags,
- pakfire_request_sync, flags, changed, status_callback, status_callback_data);
+ PAKFIRE_REQ_SYNC, flags, changed, status_callback, status_callback_data);
}
if (flags & PAKFIRE_REQUEST_ESSENTIAL)
solver_flags |= SOLVER_ESSENTIAL;
+ // Keep any dependencies
+ if (!(flags & PAKFIRE_REQUEST_KEEP_DEPS))
+ solver_flags |= SOLVER_CLEANDEPS;
+
+ // Drop orphans
+ if (!(flags & PAKFIRE_REQUEST_KEEP_ORPHANED))
+ solver_flags |= SOLVER_DROP_ORPHANED;
+
return solver_flags;
}
return pakfire_string_endswith(what, ".pfm");
}
-static int pakfire_request_add_package(struct pakfire_request* request, int action,
- struct pakfire_package* pkg, int flags) {
- // Get the solvable ID
- Id id = pakfire_package_id(pkg);
+static int __pakfire_request_add(struct pakfire_request* request,
+ const enum pakfire_request_action action, const Id type, const Id id, int flags) {
+ Id _action = ID_NULL;
+ int permitted_flags = PAKFIRE_REQUEST_ESSENTIAL;
+
+ // Check if type/ID is not set for actions that don't support it
+ switch (action) {
+ case PAKFIRE_REQ_INSTALL:
+ case PAKFIRE_REQ_ERASE:
+ case PAKFIRE_REQ_UPDATE:
+ case PAKFIRE_REQ_LOCK:
+ break;
+
+ default:
+ if (type || id) {
+ errno = EINVAL;
+ return 1;
+ }
+ }
+
+ // Select the correct action
+ switch (action) {
+ case PAKFIRE_REQ_INSTALL:
+ _action = SOLVER_INSTALL;
+ break;
+
+ case PAKFIRE_REQ_ERASE:
+ _action = SOLVER_ERASE;
+
+ permitted_flags |= PAKFIRE_REQUEST_KEEP_DEPS;
+ break;
+
+ case PAKFIRE_REQ_UPDATE:
+ _action = SOLVER_UPDATE;
+ break;
+
+ case PAKFIRE_REQ_UPDATE_ALL:
+ _action = SOLVER_UPDATE|SOLVER_SOLVABLE_ALL;
+ break;
+
+ case PAKFIRE_REQ_SYNC:
+ _action = SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL;
+
+ permitted_flags |= PAKFIRE_REQUEST_KEEP_ORPHANED;
+ break;
+
+ case PAKFIRE_REQ_LOCK:
+ _action = SOLVER_LOCK;
+ break;
+
+ case PAKFIRE_REQ_VERIFY:
+ _action = SOLVER_VERIFY|SOLVER_SOLVABLE_ALL;
+ break;
+ }
+
+ // Filter out any unsupported flags for the selected action
+ flags &= permitted_flags;
// Translate flags
flags = pakfire_request_job_flags(flags);
+ // XXX reset flags because the translation is broken
+ flags = 0;
+
// Add it to the job queue
- queue_push2(&request->jobs, SOLVER_SOLVABLE|action|flags, id);
+ queue_push2(&request->jobs, _action|type|flags, id);
return 0;
}
-static int pakfire_request_add_job(struct pakfire_request* request, int action,
- const char* what, int extra_flags) {
+static int pakfire_request_add_job(struct pakfire_request* request,
+ const enum pakfire_request_action action, const char* what, int extra_flags) {
Pool* pool = pakfire_get_solv_pool(request->pakfire);
// Make the pool ready
DEBUG(request->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what);
- // Translate flags
- const int job_flags = pakfire_request_job_flags(extra_flags);
-
// Set action and global flags
for (int i = 0; i < jobs.count; i += 2)
- jobs.elements[i] |= action | job_flags;
+ __pakfire_request_add(request, action, jobs.elements[i], jobs.elements[i+1], extra_flags);
- // Merge jobs into the main job queue
- queue_insertn(&request->jobs, request->jobs.count, jobs.count, jobs.elements);
queue_free(&jobs);
return 0;
}
-static int pakfire_request_add_archive(struct pakfire_request* request, int action,
- struct pakfire_archive* archive, int extra_flags) {
+int pakfire_request_add(struct pakfire_request* request,
+ const enum pakfire_request_action action, const char* what, int flags) {
struct pakfire_package* package = NULL;
int r;
- struct pakfire_repo* repo = pakfire_get_repo(request->pakfire, PAKFIRE_REPO_COMMANDLINE);
- if (!repo)
- return 1;
+ // Remove leading whitespace
+ if (what) {
+ while (*what && isspace(*what))
+ what++;
+ }
- // Add it to the repository
- r = pakfire_repo_add_archive(repo, archive, &package);
- if (r)
- goto ERROR;
+ if (!what) {
+ r = __pakfire_request_add(request, action, ID_NULL, ID_NULL, flags);
+ if (r)
+ goto ERROR;
- r = pakfire_request_add_package(request, action, package, extra_flags);
- if (r)
- goto ERROR;
+ // Check if we got given a URL or some file
+ } else if (pakfire_string_is_url(what) || pakfire_request_is_file(what)) {
+ // Add them to the commandline repository
+ r = pakfire_commandline_add(request->pakfire, what, &package);
+ if (r)
+ goto ERROR;
- // Success
- r = 0;
+ // Then add the package
+ r = pakfire_request_add_package(request, action, package, flags);
+ if (r)
+ goto ERROR;
+
+ // Otherwise try adding this as a job
+ } else {
+ r = pakfire_request_add_job(request, action, what, flags);
+ if (r)
+ goto ERROR;
+ }
ERROR:
if (package)
pakfire_package_unref(package);
- pakfire_repo_unref(repo);
-
- return r;
-}
-
-static int pakfire_request_add_file(struct pakfire_request* request, int action,
- const char* path, int extra_flags) {
- struct pakfire_archive* archive = NULL;
-
- // 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:
- if (archive)
- 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_TMP_DIR "/pakfire-download.XXXXXX";
-
- // Allocate a temporary file name
- FILE* f = pakfire_mktemp(path, 0);
- 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, 0, NULL, 0, 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) {
- if (!what) {
- errno = EINVAL;
- return 1;
- }
-
- // Remove leading whitespace
- while (*what && isspace(*what))
- what++;
-
- // Download and add any remote files
- if (pakfire_string_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);
-}
-
-int pakfire_request_install(struct pakfire_request* request,
- const char* what, int flags) {
- return pakfire_request_add(request, SOLVER_INSTALL, what, flags);
-}
-
-int pakfire_request_install_package(
- struct pakfire_request* request, struct pakfire_package* package) {
- return pakfire_request_add_package(request, SOLVER_INSTALL, package, 0);
-}
-
-static int erase_flags(int flags) {
- int additional = 0;
-
- // Keep dependencies
- if (!(flags & PAKFIRE_REQUEST_KEEP_DEPS))
- additional |= SOLVER_CLEANDEPS;
-
- return additional;
-}
-
-int pakfire_request_erase(struct pakfire_request* request, const char* what, int flags) {
- return pakfire_request_add(request, SOLVER_ERASE, what, erase_flags(flags));
-}
-
-int pakfire_request_erase_package(
- struct pakfire_request* request, struct pakfire_package* package, int flags) {
- return pakfire_request_add_package(request, SOLVER_ERASE, package, erase_flags(flags));
-}
-
-int pakfire_request_update(struct pakfire_request* request, const char* what, int flags) {
- return pakfire_request_add(request, SOLVER_UPDATE, what, flags);
-}
-
-int pakfire_request_update_package(
- struct pakfire_request* request, struct pakfire_package* package) {
- return pakfire_request_add_package(request, SOLVER_UPDATE, package, 0);
-}
-
-int pakfire_request_update_all(struct pakfire_request* request, int flags) {
- queue_push2(&request->jobs, SOLVER_SOLVABLE_ALL|SOLVER_UPDATE|erase_flags(flags), 0);
-
- return 0;
-}
-
-int pakfire_request_sync(struct pakfire_request* request, int flags) {
- int solver_flags = SOLVER_SOLVABLE_ALL|SOLVER_DISTUPGRADE;
-
- // Drop orphans
- if (!(flags & PAKFIRE_REQUEST_KEEP_ORPHANED))
- solver_flags |= SOLVER_DROP_ORPHANED;
-
- queue_push2(&request->jobs, solver_flags, 0);
-
- return 0;
-}
-
-int pakfire_request_lock(struct pakfire_request* request, const char* what) {
- return pakfire_request_add(request, SOLVER_LOCK, what, 0);
-}
-
-int pakfire_request_lock_package(struct pakfire_request* request, struct pakfire_package* package) {
- return pakfire_request_add_package(request, SOLVER_LOCK, package, 0);
-}
-
-int pakfire_request_verify(struct pakfire_request* request, int flags) {
- queue_push2(&request->jobs, SOLVER_SOLVABLE_ALL|SOLVER_VERIFY, 0);
+int pakfire_request_add_package(struct pakfire_request* request,
+ const enum pakfire_request_action action, struct pakfire_package* package, int flags) {
+ // Get the solvable ID
+ Id id = pakfire_package_id(package);
- return 0;
+ // Add it to the job queue
+ return __pakfire_request_add(request, action, SOLVER_SOLVABLE, id, flags);
}
int pakfire_request_next_problem(