int pacman_files(alpm_list_t *targets) { alpm_list_t *files_dbs = NULL; if(check_syncdbs(1, 0)) { return 1; } files_dbs = alpm_get_syncdbs(config->handle); if(config->op_s_sync) { /* grab a fresh package list */ colon_printf(_("Synchronizing package databases...\n")); alpm_logaction(config->handle, PACMAN_CALLER_PREFIX, "synchronizing package lists\n"); if(!sync_syncdbs(config->op_s_sync, files_dbs)) { return 1; } } if(targets == NULL && (config->op_q_owns | config->op_s_search)) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } /* determine the owner of a file */ if(config->op_q_owns) { return files_fileowner(files_dbs, targets); } /* search for a file */ if(config->op_s_search) { return files_search(files_dbs, targets, config->op_f_regex); } /* get a listing of files in sync DBs */ if(config->op_q_list) { return files_list(files_dbs, targets); } if(targets != NULL) { pm_printf(ALPM_LOG_ERROR, _("no options specified (use -h for help)\n")); return 1; } return 0; }
/* callback to handle questions from libalpm transactions (yes/no) */ void cb_question(alpm_question_t *question) { if(config->print) { if(question->type == ALPM_QUESTION_INSTALL_IGNOREPKG) { question->any.answer = 1; } else { question->any.answer = 0; } return; } switch(question->type) { case ALPM_QUESTION_INSTALL_IGNOREPKG: { alpm_question_install_ignorepkg_t *q = &question->install_ignorepkg; if(!config->op_s_downloadonly) { q->install = yesno(_("%s is in IgnorePkg/IgnoreGroup. Install anyway?"), alpm_pkg_get_name(q->pkg)); } else { q->install = 1; } } break; case ALPM_QUESTION_REPLACE_PKG: { alpm_question_replace_t *q = &question->replace; q->replace = yesno(_("Replace %s with %s/%s?"), alpm_pkg_get_name(q->oldpkg), alpm_db_get_name(q->newdb), alpm_pkg_get_name(q->newpkg)); } break; case ALPM_QUESTION_CONFLICT_PKG: { alpm_question_conflict_t *q = &question->conflict; /* print conflict only if it contains new information */ if(strcmp(q->conflict->package1, q->conflict->reason->name) == 0 || strcmp(q->conflict->package2, q->conflict->reason->name) == 0) { q->remove = noyes(_("%s and %s are in conflict. Remove %s?"), q->conflict->package1, q->conflict->package2, q->conflict->package2); } else { q->remove = noyes(_("%s and %s are in conflict (%s). Remove %s?"), q->conflict->package1, q->conflict->package2, q->conflict->reason->name, q->conflict->package2); } } break; case ALPM_QUESTION_REMOVE_PKGS: { alpm_question_remove_pkgs_t *q = &question->remove_pkgs; alpm_list_t *namelist = NULL, *i; size_t count = 0; for(i = q->packages; 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()); printf("\n"); q->skip = 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_question_select_provider_t *q = &question->select_provider; size_t count = alpm_list_count(q->providers); char *depstring = alpm_dep_compute_string(q->depend); colon_printf(_n("There is %zd provider available for %s\n", "There are %zd providers available for %s:\n", count), count, depstring); free(depstring); select_display(q->providers); q->use_index = select_question(count); } break; case ALPM_QUESTION_CORRUPTED_PKG: { alpm_question_corrupted_t *q = &question->corrupted; q->remove = yesno(_("File %s is corrupted (%s).\n" "Do you want to delete it?"), q->filepath, alpm_strerror(q->reason)); } break; case ALPM_QUESTION_IMPORT_KEY: { alpm_question_import_key_t *q = &question->import_key; char created[12]; time_t time = (time_t)q->key->created; strftime(created, 12, "%Y-%m-%d", localtime(&time)); if(q->key->revoked) { q->import = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s (revoked)?"), q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created); } else { q->import = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s?"), q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created); } } break; } if(config->noask) { if(config->ask & question->type) { /* inverse the default answer */ question->any.answer = !question->any.answer; } } }
/* 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 = &event->package_operation; 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 = &event->package_operation; 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: printf(_("generating %s with %s... "), event->delta_patch.delta->to, event->delta_patch.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(event->scriptlet_info.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 = &event->optdep_removal; char *dep_string = alpm_dep_compute_string(e->optdep); colon_printf(_("%s optionally requires %s\n"), alpm_pkg_get_name(e->pkg), dep_string); free(dep_string); } break; case ALPM_EVENT_DATABASE_MISSING: if(!config->op_s_sync) { pm_printf(ALPM_LOG_WARNING, "database file for '%s' does not exist\n", event->database_missing.dbname); } break; case ALPM_EVENT_PACNEW_CREATED: { alpm_event_pacnew_created_t *e = &event->pacnew_created; 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 = &event->pacsave_created; 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; /* 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); }
/** * @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; if(strncmp(target, "local/", 6) == 0) { target += 6; } if(remove_target(target) == -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); colon_printf(_("%s: requires %s\n"), miss->target, depstring); free(depstring); alpm_depmissing_free(miss); } break; default: break; } alpm_list_free(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; }
/* 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; } } }