/* callback to handle messages/notifications from libalpm transactions */ void cb_event(alpm_event_t *event) { if(config->print) { return; } switch(event->type) { case ALPM_EVENT_CHECKDEPS_START: printf(_("checking dependencies...\n")); break; case ALPM_EVENT_FILECONFLICTS_START: if(config->noprogressbar) { printf(_("checking for file conflicts...\n")); } break; case ALPM_EVENT_RESOLVEDEPS_START: printf(_("resolving dependencies...\n")); break; case ALPM_EVENT_INTERCONFLICTS_START: printf(_("looking for conflicting packages...\n")); break; case ALPM_EVENT_PACKAGE_OPERATION_START: if(config->noprogressbar) { alpm_event_package_operation_t *e = (alpm_event_package_operation_t *) event; switch(e->operation) { case ALPM_PACKAGE_INSTALL: printf(_("installing %s...\n"), alpm_pkg_get_name(e->newpkg)); break; case ALPM_PACKAGE_UPGRADE: printf(_("upgrading %s...\n"), alpm_pkg_get_name(e->newpkg)); break; case ALPM_PACKAGE_REINSTALL: printf(_("reinstalling %s...\n"), alpm_pkg_get_name(e->newpkg)); break; case ALPM_PACKAGE_DOWNGRADE: printf(_("downgrading %s...\n"), alpm_pkg_get_name(e->newpkg)); break; case ALPM_PACKAGE_REMOVE: printf(_("removing %s...\n"), alpm_pkg_get_name(e->oldpkg)); break; } } break; case ALPM_EVENT_PACKAGE_OPERATION_DONE: { alpm_event_package_operation_t *e = (alpm_event_package_operation_t *) event; switch(e->operation) { case ALPM_PACKAGE_INSTALL: display_optdepends(e->newpkg); break; case ALPM_PACKAGE_UPGRADE: case ALPM_PACKAGE_DOWNGRADE: display_new_optdepends(e->oldpkg, e->newpkg); break; case ALPM_PACKAGE_REINSTALL: case ALPM_PACKAGE_REMOVE: break; } } break; case ALPM_EVENT_INTEGRITY_START: if(config->noprogressbar) { printf(_("checking package integrity...\n")); } break; case ALPM_EVENT_KEYRING_START: if(config->noprogressbar) { printf(_("checking keyring...\n")); } break; case ALPM_EVENT_KEY_DOWNLOAD_START: printf(_("downloading required keys...\n")); break; case ALPM_EVENT_LOAD_START: if(config->noprogressbar) { printf(_("loading package files...\n")); } break; case ALPM_EVENT_DELTA_INTEGRITY_START: printf(_("checking delta integrity...\n")); break; case ALPM_EVENT_DELTA_PATCHES_START: printf(_("applying deltas...\n")); break; case ALPM_EVENT_DELTA_PATCH_START: { alpm_event_delta_patch_t *e = (alpm_event_delta_patch_t *) event; printf(_("generating %s with %s... "), e->delta->to, e->delta->delta); } break; case ALPM_EVENT_DELTA_PATCH_DONE: printf(_("success!\n")); break; case ALPM_EVENT_DELTA_PATCH_FAILED: printf(_("failed.\n")); break; case ALPM_EVENT_SCRIPTLET_INFO: fputs(((alpm_event_scriptlet_info_t *) event)->line, stdout); break; case ALPM_EVENT_RETRIEVE_START: colon_printf(_("Retrieving packages ...\n")); break; case ALPM_EVENT_DISKSPACE_START: if(config->noprogressbar) { printf(_("checking available disk space...\n")); } break; case ALPM_EVENT_OPTDEP_REMOVAL: { alpm_event_optdep_removal_t *e = (alpm_event_optdep_removal_t *) event; colon_printf(_("%s optionally requires %s\n"), alpm_pkg_get_name(e->pkg), alpm_dep_compute_string(e->optdep)); } break; case ALPM_EVENT_DATABASE_MISSING: if(!config->op_s_sync) { pm_printf(ALPM_LOG_WARNING, "database file for '%s' does not exist\n", ((alpm_event_database_missing_t *) event)->dbname); } break; case ALPM_EVENT_LOG: { alpm_event_log_t *e = (alpm_event_log_t *) event; if(!e->fmt || strlen(e->fmt) == 0) { break; } if(on_progress) { char *string = NULL; pm_vasprintf(&string, e->level, e->fmt, e->args); if(string != NULL) { output = alpm_list_add(output, string); } } else { pm_vfprintf(stderr, e->level, e->fmt, e->args); } } break; case ALPM_EVENT_PACNEW_CREATED: { alpm_event_pacnew_created_t *e = (alpm_event_pacnew_created_t *) event; if(on_progress) { char *string = NULL; pm_sprintf(&string, ALPM_LOG_WARNING, _("%s installed as %s.pacnew\n"), e->file, e->file); if(string != NULL) { output = alpm_list_add(output, string); } } else { pm_printf(ALPM_LOG_WARNING, _("%s installed as %s.pacnew\n"), e->file, e->file); } } break; case ALPM_EVENT_PACSAVE_CREATED: { alpm_event_pacsave_created_t *e = (alpm_event_pacsave_created_t *) event; if(on_progress) { char *string = NULL; pm_sprintf(&string, ALPM_LOG_WARNING, _("%s saved as %s.pacsave\n"), e->file, e->file); if(string != NULL) { output = alpm_list_add(output, string); } } else { pm_printf(ALPM_LOG_WARNING, _("%s saved as %s.pacsave\n"), e->file, e->file); } } break; case ALPM_EVENT_PACORIG_CREATED: { alpm_event_pacorig_created_t *e = (alpm_event_pacorig_created_t *) event; if(on_progress) { char *string = NULL; pm_sprintf(&string, ALPM_LOG_WARNING, _("%s saved as %s.pacorig\n"), e->file, e->file); if(string != NULL) { output = alpm_list_add(output, string); } } else { pm_printf(ALPM_LOG_WARNING, _("%s saved as %s.pacorig\n"), e->file, e->file); } } break; /* all the simple done events, with fallthrough for each */ case ALPM_EVENT_FILECONFLICTS_DONE: case ALPM_EVENT_CHECKDEPS_DONE: case ALPM_EVENT_RESOLVEDEPS_DONE: case ALPM_EVENT_INTERCONFLICTS_DONE: case ALPM_EVENT_INTEGRITY_DONE: case ALPM_EVENT_KEYRING_DONE: case ALPM_EVENT_KEY_DOWNLOAD_DONE: case ALPM_EVENT_LOAD_DONE: case ALPM_EVENT_DELTA_INTEGRITY_DONE: case ALPM_EVENT_DELTA_PATCHES_DONE: case ALPM_EVENT_DISKSPACE_DONE: case ALPM_EVENT_RETRIEVE_DONE: case ALPM_EVENT_RETRIEVE_FAILED: /* we can safely ignore those as well */ case ALPM_EVENT_PKGDOWNLOAD_START: case ALPM_EVENT_PKGDOWNLOAD_DONE: case ALPM_EVENT_PKGDOWNLOAD_FAILED: /* nothing */ break; } fflush(stdout); }
/* TODO this is one of the worst ever functions written. void *data ? wtf */ void cb_question(alpm_question_t event, void *data1, void *data2, void *data3, int *response) { if(config->print) { if(event == ALPM_QUESTION_INSTALL_IGNOREPKG) { *response = 1; } else { *response = 0; } return; } switch(event) { case ALPM_QUESTION_INSTALL_IGNOREPKG: if(!config->op_s_downloadonly) { *response = yesno(_("%s is in IgnorePkg/IgnoreGroup. Install anyway?"), alpm_pkg_get_name(data1)); } else { *response = 1; } break; case ALPM_QUESTION_REPLACE_PKG: *response = yesno(_("Replace %s with %s/%s?"), alpm_pkg_get_name(data1), (char *)data3, alpm_pkg_get_name(data2)); break; case ALPM_QUESTION_CONFLICT_PKG: /* data parameters: target package, local package, conflict (strings) */ /* print conflict only if it contains new information */ if(strcmp(data1, data3) == 0 || strcmp(data2, data3) == 0) { *response = noyes(_("%s and %s are in conflict. Remove %s?"), (char *)data1, (char *)data2, (char *)data2); } else { *response = noyes(_("%s and %s are in conflict (%s). Remove %s?"), (char *)data1, (char *)data2, (char *)data3, (char *)data2); } break; case ALPM_QUESTION_REMOVE_PKGS: { alpm_list_t *unresolved = data1; alpm_list_t *namelist = NULL, *i; size_t count = 0; for(i = unresolved; i; i = i->next) { namelist = alpm_list_add(namelist, (char *)alpm_pkg_get_name(i->data)); count++; } colon_printf(_n( "The following package cannot be upgraded due to unresolvable dependencies:\n", "The following packages cannot be upgraded due to unresolvable dependencies:\n", count)); list_display(" ", namelist, getcols(fileno(stdout))); printf("\n"); *response = noyes(_n( "Do you want to skip the above package for this upgrade?", "Do you want to skip the above packages for this upgrade?", count)); alpm_list_free(namelist); } break; case ALPM_QUESTION_SELECT_PROVIDER: { alpm_list_t *providers = data1; size_t count = alpm_list_count(providers); char *depstring = alpm_dep_compute_string((alpm_depend_t *)data2); colon_printf(_("There are %zd providers available for %s:\n"), count, depstring); free(depstring); select_display(providers); *response = select_question(count); } break; case ALPM_QUESTION_CORRUPTED_PKG: *response = yesno(_("File %s is corrupted (%s).\n" "Do you want to delete it?"), (char *)data1, alpm_strerror(*(alpm_errno_t *)data2)); break; case ALPM_QUESTION_IMPORT_KEY: { alpm_pgpkey_t *key = data1; char created[12]; time_t time = (time_t)key->created; strftime(created, 12, "%Y-%m-%d", localtime(&time)); if(key->revoked) { *response = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s (revoked)?"), key->length, key->pubkey_algo, key->fingerprint, key->uid, created); } else { *response = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s?"), key->length, key->pubkey_algo, key->fingerprint, key->uid, created); } } break; } if(config->noask) { if(config->ask & event) { /* inverse the default answer */ *response = !*response; } } }
/** * @brief Remove a specified list of packages. * * @param targets a list of packages (as strings) to remove from the system * * @return 0 on success, 1 on failure */ int pacman_remove(alpm_list_t *targets) { int retval = 0; alpm_list_t *i, *data = NULL; if(targets == NULL) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } /* Step 0: create a new transaction */ if(trans_init(config->flags, 0) == -1) { return 1; } /* Step 1: add targets to the created transaction */ for(i = targets; i; i = alpm_list_next(i)) { char *target = i->data; char *targ = strchr(target, '/'); if(targ && strncmp(target, "local", 5) == 0) { targ++; } else { targ = target; } if(remove_target(targ) == -1) { retval = 1; } } if(retval == 1) { goto cleanup; } /* Step 2: prepare the transaction based on its type, targets and flags */ if(alpm_trans_prepare(config->handle, &data) == -1) { alpm_errno_t err = alpm_errno(config->handle); pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"), alpm_strerror(err)); switch(err) { case ALPM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { alpm_depmissing_t *miss = i->data; char *depstring = alpm_dep_compute_string(miss->depend); printf(_(":: %s: requires %s\n"), miss->target, depstring); free(depstring); } break; default: break; } FREELIST(data); retval = 1; goto cleanup; } /* Search for holdpkg in target list */ int holdpkg = 0; for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) { alpm_pkg_t *pkg = i->data; if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) { pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"), alpm_pkg_get_name(pkg)); holdpkg = 1; } } if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) { retval = 1; goto cleanup; } /* Step 3: actually perform the removal */ alpm_list_t *pkglist = alpm_trans_get_remove(config->handle); if(pkglist == NULL) { printf(_(" there is nothing to do\n")); goto cleanup; /* we are done */ } if(config->print) { print_packages(pkglist); goto cleanup; } /* print targets and ask user confirmation */ display_targets(); printf("\n"); if(yesno(_("Do you want to remove these packages?")) == 0) { retval = 1; goto cleanup; } if(alpm_trans_commit(config->handle, &data) == -1) { pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"), alpm_strerror(alpm_errno(config->handle))); retval = 1; } FREELIST(data); /* Step 4: release transaction resources */ cleanup: if(trans_release() == -1) { retval = 1; } return retval; }