int _alpm_upgrade_packages(alpm_handle_t *handle) { size_t pkg_count, pkg_current; int skip_ldconfig = 0, ret = 0; alpm_list_t *targ; alpm_trans_t *trans = handle->trans; if(trans->add == NULL) { return 0; } pkg_count = alpm_list_count(trans->add); pkg_current = 1; /* loop through our package list adding/upgrading one at a time */ for(targ = trans->add; targ; targ = targ->next) { alpm_pkg_t *newpkg = targ->data; if(handle->trans->state == STATE_INTERRUPTED) { return ret; } if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) { /* something screwed up on the commit, abort the trans */ trans->state = STATE_INTERRUPTED; handle->pm_errno = ALPM_ERR_TRANS_ABORT; /* running ldconfig at this point could possibly screw system */ skip_ldconfig = 1; ret = -1; } pkg_current++; } if(!skip_ldconfig) { /* run ldconfig if it exists */ _alpm_ldconfig(handle); } return ret; }
/** Displays the list in table format * * @param title the tables title * @param header the column headers. column count is determined by the nr * of headers * @param rows the rows to display as a list of lists of strings. the outer * list represents the rows, the inner list the cells (= columns) * @param cols the number of columns available in the terminal * @return -1 if not enough terminal cols available, else 0 */ static int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows, unsigned short cols) { const unsigned short padding = 2; const alpm_list_t *i; size_t *widths = NULL, totalcols, totalwidth; int *has_data = NULL; if(rows == NULL || header == NULL) { return 0; } totalcols = alpm_list_count(header); totalwidth = table_calc_widths(header, rows, padding, totalcols, &widths, &has_data); /* return -1 if terminal is not wide enough */ if(totalwidth > cols) { pm_printf(ALPM_LOG_WARNING, _("insufficient columns available for table display\n")); return -1; } if(!totalwidth || !widths || !has_data) { return -1; } if(title != NULL) { printf("%s\n\n", title); } table_print_line(header, padding, totalcols, widths, has_data); printf("\n"); for(i = rows; i; i = alpm_list_next(i)) { table_print_line(i->data, padding, totalcols, widths, has_data); } free(widths); free(has_data); return 0; }
/* Search sync db for packages. Only works for 1 package now. */ static int sync_search(CURL *curl, alpm_list_t *targets) { alpm_list_t *i, *j, *search_results; alpm_db_t *db; alpm_pkg_t *spkg; struct aurpkg_t *pkg; size_t listsz; search_results = query_aur(curl, targets->data, AUR_QUERY_SEARCH); if (search_results == NULL) { printf("Sorry, no results for %s\n", targets->data); return 0; } listsz = alpm_list_count(search_results); /* Sort by alphabetical order first */ search_results = alpm_list_msort(search_results, listsz, aurpkg_name_cmp); /* Sort by votes */ if (config->sort_votes) { search_results = alpm_list_msort(search_results, listsz, aurpkg_vote_cmp); } for (i = search_results; i; i = i->next) { pkg = (struct aurpkg_t *) i->data; printf("%saur/%s%s%s %s%s %s(%d)%s\n", color.bmag, color.nocolor, color.bold, pkg->name, color.bgreen, pkg->version, color.votecol, pkg->votes, color.nocolor); printf(" %s\n", pkg->desc); } alpm_list_free_inner(search_results, (alpm_list_fn_free) aurpkg_free); alpm_list_free(search_results); return 0; }
void show_results () { alpm_list_t *i_first; alpm_list_t *i; alpm_list_nav fn_nav=NULL;; alpm_list_fn_cmp fn_cmp=NULL; if (results!=NULL) { switch (config.sort) { case S_NAME: fn_cmp = (alpm_list_fn_cmp) results_cmp; break; case S_VOTE: fn_cmp = (alpm_list_fn_cmp) results_votes_cmp; break; case S_IDATE: fn_cmp = (alpm_list_fn_cmp) results_installdate_cmp; break; case S_ISIZE: fn_cmp = (alpm_list_fn_cmp) results_isize_cmp; break; } if (fn_cmp) results = alpm_list_msort (results, alpm_list_count (results), fn_cmp); if (config.rsort) { fn_nav = (alpm_list_nav) alpm_list_previous; i_first = alpm_list_last (results); } else { fn_nav = (alpm_list_nav) alpm_list_next; i_first = results; } for(i = i_first; i; i = fn_nav(i)) { results_t *r = i->data; if (r->type == R_ALPM_PKG) print_package ("", r->ele, alpm_pkg_get_str); else if (r->type == R_AUR_PKG) print_package ("", r->ele, aur_get_str); } alpm_list_free_inner (results, (alpm_list_fn_free) results_free); alpm_list_free (results); results = NULL; } }
/* prepare a list of pkgs to display */ static void _display_targets(alpm_list_t *targets, int verbose) { char *str; const char *label; double size; off_t isize = 0, rsize = 0, dlsize = 0; unsigned short cols; alpm_list_t *i, *rows = NULL, *names = NULL; if(!targets) { return; } /* gather package info */ for(i = targets; i; i = alpm_list_next(i)) { pm_target_t *target = i->data; if(target->install) { dlsize += alpm_pkg_download_size(target->install); isize += alpm_pkg_get_isize(target->install); } if(target->remove) { /* add up size of all removed packages */ rsize += alpm_pkg_get_isize(target->remove); } } /* form data for both verbose and non-verbose display */ for(i = targets; i; i = alpm_list_next(i)) { pm_target_t *target = i->data; rows = alpm_list_add(rows, create_verbose_row(target)); if(target->install) { pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install), alpm_pkg_get_version(target->install)); } else if(isize == 0) { pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->remove), alpm_pkg_get_version(target->remove)); } else { pm_asprintf(&str, "%s-%s [removal]", alpm_pkg_get_name(target->remove), alpm_pkg_get_version(target->remove)); } names = alpm_list_add(names, str); } /* print to screen */ pm_asprintf(&str, _("Packages (%d):"), alpm_list_count(targets)); printf("\n"); cols = getcols(fileno(stdout)); if(verbose) { alpm_list_t *header = create_verbose_header(); if(table_display(str, header, rows, cols) != 0) { /* fallback to list display if table wouldn't fit */ list_display(str, names, cols); } alpm_list_free(header); } else { list_display(str, names, cols); } printf("\n"); /* rows is a list of lists of strings, free inner lists here */ for(i = rows; i; i = alpm_list_next(i)) { alpm_list_t *lp = i->data; FREELIST(lp); } alpm_list_free(rows); FREELIST(names); free(str); if(dlsize > 0 || config->op_s_downloadonly) { size = humanize_size(dlsize, 'M', 2, &label); printf(_("Total Download Size: %.2f %s\n"), size, label); } if(!config->op_s_downloadonly) { if(isize > 0) { size = humanize_size(isize, 'M', 2, &label); printf(_("Total Installed Size: %.2f %s\n"), size, label); } if(rsize > 0 && isize == 0) { size = humanize_size(rsize, 'M', 2, &label); printf(_("Total Removed Size: %.2f %s\n"), size, label); } /* only show this net value if different from raw installed size */ if(isize > 0 && rsize > 0) { size = humanize_size(isize - rsize, 'M', 2, &label); printf(_("Net Upgrade Size: %.2f %s\n"), size, label); } } }
/** * pacman_list_length: * @list: A #PacmanList. * * Gets the number of items in @list. * * Returns: The length of @list. */ guint pacman_list_length (const PacmanList *list) { return alpm_list_count (list); }
alpm_list_t* alpm_list_sort_data (alpm_list_t *list, alpm_list_fn_cmp fn) { list = alpm_list_msort (list, alpm_list_count (list), fn); return list; }
int _alpm_check_diskspace(alpm_handle_t *handle) { alpm_list_t *mount_points, *i; alpm_mountpoint_t *root_mp; size_t replaces = 0, current = 0, numtargs; int error = 0; alpm_list_t *targ; alpm_trans_t *trans = handle->trans; numtargs = alpm_list_count(trans->add); mount_points = mount_point_list(handle); if(mount_points == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not determine filesystem mount points\n")); return -1; } root_mp = match_mount_point(mount_points, handle->root); if(root_mp == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not determine root mount point %s\n"), handle->root); error = 1; goto finish; } replaces = alpm_list_count(trans->remove); if(replaces) { numtargs += replaces; for(targ = trans->remove; targ; targ = targ->next, current++) { alpm_pkg_t *local_pkg; int percent = (current * 100) / numtargs; PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", percent, numtargs, current); local_pkg = targ->data; calculate_removed_size(handle, mount_points, local_pkg); } } for(targ = trans->add; targ; targ = targ->next, current++) { alpm_pkg_t *pkg, *local_pkg; int percent = (current * 100) / numtargs; PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", percent, numtargs, current); pkg = targ->data; /* is this package already installed? */ local_pkg = _alpm_db_get_pkgfromcache(handle->db_local, pkg->name); if(local_pkg) { calculate_removed_size(handle, mount_points, local_pkg); } calculate_installed_size(handle, mount_points, pkg); for(i = mount_points; i; i = i->next) { alpm_mountpoint_t *data = i->data; if(data->blocks_needed > data->max_blocks_needed) { data->max_blocks_needed = data->blocks_needed; } } } PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", 100, numtargs, current); for(i = mount_points; i; i = i->next) { alpm_mountpoint_t *data = i->data; if(data->used && data->read_only) { _alpm_log(handle, ALPM_LOG_ERROR, _("Partition %s is mounted read only\n"), data->mount_dir); error = 1; } else if(data->used & USED_INSTALL && check_mountpoint(handle, data)) { error = 1; } } finish: mount_point_list_free(mount_points); if(error) { RET_ERR(handle, ALPM_ERR_DISK_SPACE, -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; } } }
int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data) { alpm_list_t *i; alpm_list_t *deltas = NULL; size_t numtargs, current = 0, replaces = 0; int errors; alpm_trans_t *trans = handle->trans; if(download_files(handle, &deltas)) { alpm_list_free(deltas); return -1; } if(validate_deltas(handle, deltas, data)) { alpm_list_free(deltas); return -1; } alpm_list_free(deltas); /* Check integrity of packages */ numtargs = alpm_list_count(trans->add); EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_START, NULL, NULL); errors = 0; for(i = trans->add; i; i = i->next, current++) { alpm_pkg_t *spkg = i->data; int percent = (current * 100) / numtargs; const char *filename; char *filepath; alpm_siglevel_t level; PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", percent, numtargs, current); if(spkg->origin == PKG_FROM_FILE) { continue; /* pkg_load() has been already called, this package is valid */ } filename = alpm_pkg_get_filename(spkg); filepath = _alpm_filecache_find(handle, filename); alpm_db_t *sdb = alpm_pkg_get_db(spkg); level = alpm_db_get_siglevel(sdb); /* load the package file and replace pkgcache entry with it in the target list */ /* TODO: alpm_pkg_get_db() will not work on this target anymore */ _alpm_log(handle, ALPM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name); alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum, spkg->base64_sig, level); if(!pkgfile) { errors++; *data = alpm_list_add(*data, strdup(filename)); FREE(filepath); continue; } FREE(filepath); pkgfile->reason = spkg->reason; /* copy over install reason */ i->data = pkgfile; _alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */ } PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", 100, numtargs, current); EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL); if(errors) { RET_ERR(handle, ALPM_ERR_PKG_INVALID, -1); } if(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY) { return 0; } trans->state = STATE_COMMITING; replaces = alpm_list_count(trans->remove); /* fileconflict check */ if(!(trans->flags & ALPM_TRANS_FLAG_FORCE)) { EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n"); alpm_list_t *conflict = _alpm_db_find_fileconflicts(handle, trans->add, trans->remove); if(conflict) { if(data) { *data = conflict; } else { alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free); alpm_list_free(conflict); } RET_ERR(handle, ALPM_ERR_FILE_CONFLICTS, -1); } EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL); } /* check available disk space */ if(handle->checkspace) { EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_START, NULL, NULL); _alpm_log(handle, ALPM_LOG_DEBUG, "checking available disk space\n"); if(_alpm_check_diskspace(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, "%s\n", _("not enough free disk space")); return -1; } EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_DONE, NULL, NULL); } /* remove conflicting and to-be-replaced packages */ if(replaces) { _alpm_log(handle, ALPM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n"); /* we want the frontend to be aware of commit details */ if(_alpm_remove_packages(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not commit removal transaction\n")); return -1; } } /* install targets */ _alpm_log(handle, ALPM_LOG_DEBUG, "installing packages\n"); if(_alpm_upgrade_packages(handle) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not commit transaction\n")); return -1; } return 0; }
/** * @brief Upgrade a specified list of packages. * * @param targets a list of packages (as strings) to upgrade * * @return 0 on success, 1 on failure */ int pacman_upgrade(alpm_list_t *targets) { int retval = 0, *file_is_remote; alpm_list_t *i; unsigned int n, num_targets; if(targets == NULL) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } num_targets = alpm_list_count(targets); /* Check for URL targets and process them */ file_is_remote = malloc(num_targets * sizeof(int)); if(file_is_remote == NULL) { pm_printf(ALPM_LOG_ERROR, _("memory exhausted\n")); return 1; } for(i = targets, n = 0; i; i = alpm_list_next(i), n++) { if(strstr(i->data, "://")) { char *str = alpm_fetch_pkgurl(config->handle, i->data); if(str == NULL) { pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", (char *)i->data, alpm_strerror(alpm_errno(config->handle))); retval = 1; } else { free(i->data); i->data = str; file_is_remote[n] = 1; } } else { file_is_remote[n] = 0; } } if(retval) { goto fail_free; } /* Step 1: create a new transaction */ if(trans_init(config->flags, 1) == -1) { retval = 1; goto fail_free; } printf(_("loading packages...\n")); /* add targets to the created transaction */ for(i = targets, n = 0; i; i = alpm_list_next(i), n++) { const char *targ = i->data; alpm_pkg_t *pkg; int siglevel; if(file_is_remote[n]) { siglevel = alpm_option_get_remote_file_siglevel(config->handle); } else { siglevel = alpm_option_get_local_file_siglevel(config->handle); } if(alpm_pkg_load(config->handle, targ, 1, siglevel, &pkg) != 0) { pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); retval = 1; continue; } if(alpm_add_pkg(config->handle, pkg) == -1) { pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); alpm_pkg_free(pkg); retval = 1; continue; } config->explicit_adds = alpm_list_add(config->explicit_adds, pkg); } if(retval) { goto fail_release; } free(file_is_remote); /* now that targets are resolved, we can hand it all off to the sync code */ return sync_prepare_execute(); fail_release: trans_release(); fail_free: free(file_is_remote); return retval; }
int powaur_backup(alpm_list_t *targets) { int ret = 0; char localdb[PATH_MAX]; struct archive *a; struct archive_entry *entry; struct stat st; char cwd[PATH_MAX]; char backup_dest[PATH_MAX]; char backup[MINI_BUFSZ]; time_t time_now; struct tm tm_st; if (targets != NULL && alpm_list_count(targets) != 1) { pw_fprintf(PW_LOG_ERROR, stderr, "-B only takes 1 argument.\n"); return -1; } a = archive_write_new(); if (!a) { return error(PW_ERR_ARCHIVE_CREATE); } archive_write_set_compression_bzip2(a); archive_write_set_format_pax_restricted(a); /* Filename = pacman-YYYY-MM-DD_HHhMM.tar.bz2 */ time(&time_now); localtime_r(&time_now, &tm_st); strftime(backup, MINI_BUFSZ, "pacman-%Y-%m-%d_%Hh%M.tar.bz2", &tm_st); if (!getcwd(cwd, PATH_MAX)) { error(PW_ERR_GETCWD); ret = -1; goto cleanup; } /* Get full path */ if (targets) { snprintf(backup_dest, PATH_MAX, "%s/%s", targets->data, backup); } else { snprintf(backup_dest, PATH_MAX, "%s/%s", cwd, backup); } if (archive_write_open_filename(a, backup_dest) != ARCHIVE_OK) { PW_SETERRNO(PW_ERR_ARCHIVE_OPEN); ret = -1; goto cleanup; } if (ret = chdir(pacman_dbpath)) { error(PW_ERR_CHDIR, pacman_dbpath); goto restore_cwd; } /* Create entry for the current directory. */ entry = archive_entry_new(); if (!entry) { error(PW_ERR_ARCHIVE_ENTRY); goto restore_cwd; } snprintf(localdb, PATH_MAX, "%s", "local"); if (ret = stat(localdb, &st)) { error(PW_ERR_STAT, localdb); goto free_entry; } archive_entry_set_pathname(entry, localdb); archive_entry_copy_stat(entry, &st); archive_write_header(a, entry); pw_printf(PW_LOG_INFO, "Saving pacman database in %s\n", backup_dest); ret = write_dir_archive(localdb, a); if (!ret) { pw_printf(PW_LOG_INFO, "Pacman database successfully saved in %s\n", backup_dest); } else { pw_fprintf(PW_LOG_ERROR, stderr, "Pacman database not saved.\n"); } free_entry: archive_entry_free(entry); restore_cwd: if (chdir(cwd)) { PW_SETERRNO(PW_ERR_RESTORECWD); ret = -1; } cleanup: archive_write_finish(a); return ret; }
static int sync_db_populate(alpm_db_t *db) { const char *dbpath; size_t est_count; int count = 0; struct stat buf; struct archive *archive; struct archive_entry *entry; alpm_pkg_t *pkg = NULL; if(db->status & DB_STATUS_INVALID) { RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1); } if(db->status & DB_STATUS_MISSING) { RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1); } if((archive = archive_read_new()) == NULL) { RET_ERR(db->handle, ALPM_ERR_LIBARCHIVE, -1); } archive_read_support_compression_all(archive); archive_read_support_format_all(archive); dbpath = _alpm_db_path(db); if(!dbpath) { /* pm_errno set in _alpm_db_path() */ return -1; } _alpm_log(db->handle, ALPM_LOG_DEBUG, "opening database archive %s\n", dbpath); if(archive_read_open_filename(archive, dbpath, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath, archive_error_string(archive)); archive_read_finish(archive); RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } if(stat(dbpath, &buf) != 0) { RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } est_count = estimate_package_count(&buf, archive); /* initialize hash at 66% full */ db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2); if(db->pkgcache == NULL) { RET_ERR(db->handle, ALPM_ERR_MEMORY, -1); } while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { mode_t mode = archive_entry_mode(entry); if(S_ISDIR(mode)) { continue; } else { /* we have desc, depends or deltas - parse it */ if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); continue; } } } count = alpm_list_count(db->pkgcache->list); if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } archive_read_finish(archive); _alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", count, db->treename); return count; }
/* Find file conflicts that may occur during the transaction with two checks: * 1: check every target against every target * 2: check every target against the filesystem */ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *root) { alpm_list_t *i, *conflicts = NULL; alpm_list_t *targets = trans->packages; int numtargs = alpm_list_count(targets); int current; ALPM_LOG_FUNC; if(db == NULL || targets == NULL || root == NULL) { return(NULL); } /* TODO this whole function needs a huge change, which hopefully will * be possible with real transactions. Right now we only do half as much * here as we do when we actually extract files in add.c with our 12 * different cases. */ for(current = 1, i = targets; i; i = i->next, current++) { alpm_list_t *j, *k, *tmpfiles = NULL; pmpkg_t *p1, *p2, *dbpkg; char path[PATH_MAX+1]; p1 = i->data; if(!p1) { continue; } double percent = (double)current / numtargs; PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", (percent * 100), numtargs, current); /* CHECK 1: check every target against every target */ _alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s\n", alpm_pkg_get_name(p1)); for(j = i->next; j; j = j->next) { p2 = j->data; if(!p2) { continue; } tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); if(tmpfiles) { for(k = tmpfiles; k; k = k->next) { snprintf(path, PATH_MAX, "%s%s", root, (char *)k->data); conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_TARGET, path, alpm_pkg_get_name(p1), alpm_pkg_get_name(p2)); } FREELIST(tmpfiles); } } /* declarations for second check */ struct stat lsbuf, sbuf; char *filestr = NULL; /* CHECK 2: check every target against the filesystem */ _alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name); dbpkg = _alpm_db_get_pkgfromcache(db, p1->name); /* Do two different checks here. f the package is currently installed, * then only check files that are new in the new package. If the package * is not currently installed, then simply stat the whole filelist */ if(dbpkg) { /* older ver of package currently installed */ tmpfiles = chk_filedifference(alpm_pkg_get_files(p1), alpm_pkg_get_files(dbpkg)); } else { /* no version of package currently installed */ tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1)); } /* loop over each file to be installed */ for(j = tmpfiles; j; j = j->next) { int skip_conflict = 0; filestr = j->data; snprintf(path, PATH_MAX, "%s%s", root, filestr); /* stat the file - if it exists, do some checks */ if(_alpm_lstat(path, &lsbuf) != 0) { continue; } stat(path, &sbuf); if(path[strlen(path)-1] == '/') { if(S_ISDIR(lsbuf.st_mode)) { _alpm_log(PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); skip_conflict = 1; } else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) { _alpm_log(PM_LOG_DEBUG, "%s is a symlink to a dir, hopefully not a conflict\n", path); skip_conflict = 1; } } if(!skip_conflict) { _alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s\n", path); /* Look at all the targets to see if file has changed hands */ int resolved_conflict = 0; /* have we acted on this conflict? */ for(k = targets; k; k = k->next) { p2 = k->data; if(!p2 || strcmp(p1->name, p2->name) == 0) { continue; } pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name); /* Check if it used to exist in a package, but doesn't anymore */ alpm_list_t *pkgfiles, *localfiles; /* added for readability */ pkgfiles = alpm_pkg_get_files(p2); localfiles = alpm_pkg_get_files(localp2); if(localp2 && !alpm_list_find_str(pkgfiles, filestr) && alpm_list_find_str(localfiles, filestr)) { /* skip removal of file, but not add. this will prevent a second * package from removing the file when it was already installed * by its new owner (whether the file is in backup array or not */ trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(path)); _alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s\n", filestr); resolved_conflict = 1; break; } } if(!resolved_conflict) { _alpm_log(PM_LOG_DEBUG, "file found in conflict: %s\n", path); conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_FILESYSTEM, path, p1->name, NULL); } } } FREELIST(tmpfiles); } return(conflicts); }
/* 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; } } }
static alpm_list_t *mount_point_list(alpm_handle_t *handle) { alpm_list_t *mount_points = NULL, *ptr; alpm_mountpoint_t *mp; #if defined(HAVE_GETMNTENT) && defined(HAVE_MNTENT_H) /* Linux */ struct mntent *mnt; FILE *fp; fp = setmntent(MOUNTED, "r"); if(fp == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not open file: %s: %s\n"), MOUNTED, strerror(errno)); return NULL; } while((mnt = getmntent(fp))) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); mount_points = alpm_list_add(mount_points, mp); } endmntent(fp); #elif defined(HAVE_GETMNTENT) && defined(HAVE_MNTTAB_H) /* Solaris, Illumos */ struct mnttab mnt; FILE *fp; int ret; fp = fopen("/etc/mnttab", "r"); if(fp == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), "/etc/mnttab", strerror(errno)); return NULL; } while((ret = getmntent(fp, &mnt)) == 0) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, mnt->mnt_mountp, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); mount_points = alpm_list_add(mount_points, mp); } /* -1 == EOF */ if(ret != -1) { _alpm_log(handle, ALPM_LOG_WARNING, _("could not get filesystem information\n")); } fclose(fp); #elif defined(HAVE_GETMNTINFO) /* FreeBSD (statfs), NetBSD (statvfs), OpenBSD (statfs), OS X (statfs) */ int entries; FSSTATSTYPE *fsp; entries = getmntinfo(&fsp, MNT_NOWAIT); if(entries < 0) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not get filesystem information\n")); return NULL; } for(; entries-- > 0; fsp++) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); memcpy(&(mp->fsp), fsp, sizeof(FSSTATSTYPE)); #if defined(HAVE_GETMNTINFO_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FLAG) mp->read_only = fsp->f_flag & ST_RDONLY; #elif defined(HAVE_GETMNTINFO_STATFS) && defined(HAVE_STRUCT_STATFS_F_FLAGS) mp->read_only = fsp->f_flags & MNT_RDONLY; #endif /* we don't support lazy loading on this platform */ mp->fsinfo_loaded = MOUNT_FSINFO_LOADED; mount_points = alpm_list_add(mount_points, mp); } #endif mount_points = alpm_list_msort(mount_points, alpm_list_count(mount_points), mount_point_cmp); for(ptr = mount_points; ptr != NULL; ptr = ptr->next) { mp = ptr->data; _alpm_log(handle, ALPM_LOG_DEBUG, "discovered mountpoint: %s\n", mp->mount_dir); } return mount_points; }
/* Lists detailed information about targets */ static int sync_info(CURL *curl, alpm_list_t *targets) { int found, ret, pkgcount; alpm_list_t *i, *j, *results; alpm_list_t *free_list = NULL; alpm_list_t *syncdbs = alpm_option_get_syncdbs(config->handle); alpm_pkg_t *spkg; char cwd[PATH_MAX]; char filename[PATH_MAX]; char url[PATH_MAX]; FILE *fp = NULL; int fd; struct aurpkg_t *pkg; if (!getcwd(cwd, PATH_MAX)) { return error(PW_ERR_GETCWD); } if (chdir(powaur_dir)) { return error(PW_ERR_CHDIR, powaur_dir); } found = ret = pkgcount = 0; for (i = targets; i; i = i->next, ++pkgcount) { /* Search sync dbs first */ spkg = search_syncdbs(syncdbs, i->data); if (spkg) { if (found++){ printf("\n"); } pacman_pkgdump(spkg, PKG_FROM_SYNC); spkg = NULL; continue; } results = query_aur(curl, i->data, AUR_QUERY_INFO); if (alpm_list_count(results) != 1) { if (pkgcount > 0) { printf("\n"); } pw_printf(PW_LOG_ERROR, "package %s not found\n", i->data); goto garbage_collect; } snprintf(filename, PATH_MAX, "%s.PKGBUILDXXXXXX", i->data); fd = mkstemp(filename); if (fd < 0) { error(PW_ERR_FOPEN, filename); goto garbage_collect; } fp = fdopen(fd, "w+"); if (!fp) { printf("NO\n"); error(PW_ERR_FOPEN, filename); goto garbage_collect; } snprintf(url, PATH_MAX, AUR_PKGBUILD_URL, i->data); /* Download the PKGBUILD and parse it */ ret = download_single_file(curl, url, fp); if (ret) { goto destroy_remnants; } /* Parse PKGBUILD and get detailed info */ fseek(fp, 0L, SEEK_SET); pkg = results->data; parse_pkgbuild(pkg, fp); if (found++) { printf("\n"); } printf("%s%s %saur%s\n", color.bold, REPO, color.bmag, color.nocolor); printf("%s%s %s%s\n", color.bold, NAME, pkg->name, color.nocolor); printf("%s%s %s%s%s\n", color.bold, VERSION, color.bgreen, pkg->version, color.nocolor); printf("%s%s %s%s%s\n", color.bold, URL, color.bcyan, pkg->url, color.nocolor); printf("%s%s%s ", color.bold, A_URL, color.bcyan); printf(AUR_PKG_URL, pkg->id); printf("%s\n", color.nocolor); printf("%s%s %s%s\n", color.bold, LICENSES, color.nocolor, pkg->license); printf("%s%s %s%d\n", color.bold, A_VOTES, color.nocolor, pkg->votes); printf("%s%s ", color.bold, A_OUTOFDATE); if (pkg->outofdate) { printf("%s%s", color.bred, "Yes"); } else { printf("%s%s", color.nocolor, "No"); } printf("%s\n", color.nocolor); print_list_prefix(pkg->provides, PROVIDES); print_list_prefix(pkg->depends, DEPS); print_list_prefix(pkg->optdepends, OPTDEPS); print_list_prefix(pkg->conflicts, CONFLICTS); print_list_prefix(pkg->replaces, REPLACES); print_list_prefix(pkg->arch, ARCH); printf("%s%s%s %s\n", color.bold, DESC, color.nocolor, pkg->desc); destroy_remnants: fclose(fp); fp = NULL; unlink(filename); garbage_collect: free_list = alpm_list_add(free_list, results); } cleanup: for (i = free_list; i; i = i->next) { alpm_list_free_inner(i->data, (alpm_list_fn_free) aurpkg_free); alpm_list_free(i->data); } alpm_list_free(free_list); if (chdir(cwd)) { return error(PW_ERR_RESTORECWD); } return found ? 0 : -1; }
static int sync_db_populate(alpm_db_t *db) { const char *dbpath; size_t est_count; int count, fd; struct stat buf; struct archive *archive; struct archive_entry *entry; alpm_pkg_t *pkg = NULL; if(db->status & DB_STATUS_INVALID) { RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1); } if(db->status & DB_STATUS_MISSING) { RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1); } dbpath = _alpm_db_path(db); if(!dbpath) { /* pm_errno set in _alpm_db_path() */ return -1; } fd = _alpm_open_archive(db->handle, dbpath, &buf, &archive, ALPM_ERR_DB_OPEN); if(fd < 0) { return -1; } est_count = estimate_package_count(&buf, archive); db->pkgcache = _alpm_pkghash_create(est_count); if(db->pkgcache == NULL) { db->handle->pm_errno = ALPM_ERR_MEMORY; count = -1; goto cleanup; } while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { mode_t mode = archive_entry_mode(entry); if(S_ISDIR(mode)) { continue; } else { /* we have desc, depends or deltas - parse it */ if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); continue; } } } count = alpm_list_count(db->pkgcache->list); if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } _alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", count, db->treename); cleanup: archive_read_finish(archive); if(fd >= 0) { CLOSE(fd); } return count; }
/** * helper function for resolvedeps: search for dep satisfier in dbs * * @param handle the context handle * @param dep is the dependency to search for * @param dbs are the databases to search * @param excluding are the packages to exclude from the search * @param prompt if true, will cause an unresolvable dependency to issue an * interactive prompt asking whether the package should be removed from * the transaction or the transaction aborted; if false, simply returns * an error code without prompting * @return the resolved package **/ static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt) { alpm_list_t *i, *j; int ignored = 0; alpm_list_t *providers = NULL; int count; /* 1. literals */ for(i = dbs; i; i = i->next) { pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(handle, pkg)) { int install = 0; if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { _alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); } if(!install) { ignored = 1; continue; } } return pkg; } } /* 2. satisfiers (skip literals here) */ for(i = dbs; i; i = i->next) { for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) { pmpkg_t *pkg = j->data; if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(handle, pkg)) { int install = 0; if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { _alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); } if(!install) { ignored = 1; continue; } } _alpm_log(handle, PM_LOG_DEBUG, "provider found (%s provides %s)\n", pkg->name, dep->name); providers = alpm_list_add(providers, pkg); /* keep looking for other providers in the all dbs */ } } } /* first check if one provider is already installed locally */ for(i = providers; i; i = i->next) { pmpkg_t *pkg = i->data; if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { alpm_list_free(providers); return pkg; } } count = alpm_list_count(providers); if(count >= 1) { /* default to first provider if there is no QUESTION callback */ int index = 0; if(count > 1) { /* if there is more than one provider, we ask the user */ QUESTION(handle->trans, PM_TRANS_CONV_SELECT_PROVIDER, providers, dep, NULL, &index); } if(index >= 0 && index < count) { pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index)); alpm_list_free(providers); return pkg; } alpm_list_free(providers); providers = NULL; } if(ignored) { /* resolvedeps will override these */ handle->pm_errno = PM_ERR_PKG_IGNORED; } else { handle->pm_errno = PM_ERR_PKG_NOT_FOUND; } return NULL; }
/* TODO this is one of the worst ever functions written. void *data ? wtf */ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, void *data3, int *response) { switch(event) { case PM_TRANS_CONV_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 PM_TRANS_CONV_REPLACE_PKG: *response = yesno(_(":: Replace %s with %s/%s?"), alpm_pkg_get_name(data1), (char *)data3, alpm_pkg_get_name(data2)); break; case PM_TRANS_CONV_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 PM_TRANS_CONV_REMOVE_PKGS: { alpm_list_t *unresolved = (alpm_list_t *) 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++; } 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); 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 PM_TRANS_CONV_SELECT_PROVIDER: { alpm_list_t *providers = (alpm_list_t *)data1; int count = alpm_list_count(providers); char *depstring = alpm_dep_compute_string((pmdepend_t *)data2); printf(_(":: There are %d providers available for %s:\n"), count, depstring); free(depstring); select_display(providers); *response = select_question(count); } break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), alpm_pkg_get_name(data1), alpm_pkg_get_version(data1)); } else { *response = 1; } break; case PM_TRANS_CONV_CORRUPTED_PKG: *response = yesno(_(":: File %s is corrupted. Do you want to delete it?"), (char *)data1); break; } if(config->noask) { if(config->ask & event) { /* inverse the default answer */ *response = !*response; } } }
/** Display usage/syntax for the specified operation. * @param op the operation code requested * @param myname basename(argv[0]) */ static void usage(int op, const char * const myname) { #define addlist(s) (list = alpm_list_add(list, s)) alpm_list_t *list = NULL, *i; /* prefetch some strings for usage below, which moves a lot of calls * out of gettext. */ char const *const str_opt = _("options"); char const *const str_file = _("file(s)"); char const *const str_pkg = _("package(s)"); char const *const str_usg = _("usage"); char const *const str_opr = _("operation"); /* please limit your strings to 80 characters in width */ if(op == PM_OP_MAIN) { printf("%s: %s <%s> [...]\n", str_usg, myname, str_opr); printf(_("operations:\n")); printf(" %s {-h --help}\n", myname); printf(" %s {-V --version}\n", myname); printf(" %s {-D --database} <%s> <%s>\n", myname, str_opt, str_pkg); printf(" %s {-Q --query} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-R --remove} [%s] <%s>\n", myname, str_opt, str_pkg); printf(" %s {-S --sync} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-T --deptest} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-U --upgrade} [%s] <%s>\n", myname, str_opt, str_file); printf(_("\nuse '%s {-h --help}' with an operation for available options\n"), myname); } else { if(op == PM_OP_REMOVE) { printf("%s: %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --cascade remove packages and all packages that depend on them\n")); addlist(_(" -n, --nosave remove configuration files\n")); addlist(_(" -s, --recursive remove unnecessary dependencies\n" " (-ss includes explicitly installed dependencies)\n")); addlist(_(" -u, --unneeded remove unneeded packages\n")); } else if(op == PM_OP_UPGRADE) { printf("%s: %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file); addlist(_(" --needed do not reinstall up to date packages\n")); printf("%s:\n", str_opt); } else if(op == PM_OP_QUERY) { printf("%s: %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --changelog view the changelog of a package\n")); addlist(_(" -d, --deps list packages installed as dependencies [filter]\n")); addlist(_(" -e, --explicit list packages explicitly installed [filter]\n")); addlist(_(" -g, --groups view all members of a package group\n")); addlist(_(" -i, --info view package information (-ii for backup files)\n")); addlist(_(" -k, --check check that package files exist (-kk for file properties)\n")); addlist(_(" -l, --list list the files owned by the queried package\n")); addlist(_(" -m, --foreign list installed packages not found in sync db(s) [filter]\n")); addlist(_(" -n, --native list installed packages only found in sync db(s) [filter]\n")); addlist(_(" -o, --owns <file> query the package that owns <file>\n")); addlist(_(" -p, --file <package> query a package file instead of the database\n")); addlist(_(" -q, --quiet show less information for query and search\n")); addlist(_(" -s, --search <regex> search locally-installed packages for matching strings\n")); addlist(_(" -t, --unrequired list packages not (optionally) required by any\n" " package (-tt to ignore optdepends) [filter]\n")); addlist(_(" -u, --upgrades list outdated packages [filter]\n")); } else if(op == PM_OP_SYNC) { printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --clean remove old packages from cache directory (-cc for all)\n")); addlist(_(" -g, --groups view all members of a package group\n" " (-gg to view all groups and members)\n")); addlist(_(" -i, --info view package information (-ii for extended information)\n")); addlist(_(" -l, --list <repo> view a list of packages in a repo\n")); addlist(_(" -q, --quiet show less information for query and search\n")); addlist(_(" -s, --search <regex> search remote repositories for matching strings\n")); addlist(_(" -u, --sysupgrade upgrade installed packages (-uu enables downgrades)\n")); addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n")); addlist(_(" -y, --refresh download fresh package databases from the server\n" " (-yy to force a refresh even if up to date)\n")); addlist(_(" --needed do not reinstall up to date packages\n")); } else if(op == PM_OP_DATABASE) { printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" --asdeps mark packages as non-explicitly installed\n")); addlist(_(" --asexplicit mark packages as explicitly installed\n")); addlist(_(" -k, --check test local database for validity (-kk for sync databases)\n")); } else if(op == PM_OP_DEPTEST) { printf("%s: %s {-T --deptest} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); } switch(op) { case PM_OP_SYNC: case PM_OP_UPGRADE: addlist(_(" --force force install, overwrite conflicting files\n")); addlist(_(" --asdeps install packages as non-explicitly installed\n")); addlist(_(" --asexplicit install packages as explicitly installed\n")); addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n")); addlist(_(" --ignoregroup <grp>\n" " ignore a group upgrade (can be used more than once)\n")); /* pass through */ case PM_OP_REMOVE: addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n")); addlist(_(" --assume-installed <package=version>\n" " add a virtual package to satisfy dependencies\n")); addlist(_(" --dbonly only modify database entries, not package files\n")); addlist(_(" --noprogressbar do not show a progress bar when downloading files\n")); addlist(_(" --noscriptlet do not execute the install scriptlet if one exists\n")); addlist(_(" -p, --print print the targets instead of performing the operation\n")); addlist(_(" --print-format <string>\n" " specify how the targets should be printed\n")); break; } addlist(_(" -b, --dbpath <path> set an alternate database location\n")); addlist(_(" -r, --root <path> set an alternate installation root\n")); addlist(_(" -v, --verbose be verbose\n")); addlist(_(" --arch <arch> set an alternate architecture\n")); addlist(_(" --cachedir <dir> set an alternate package cache location\n")); addlist(_(" --color <when> colorize the output\n")); addlist(_(" --config <path> set an alternate configuration file\n")); addlist(_(" --debug display debug messages\n")); addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n")); addlist(_(" --logfile <path> set an alternate log file\n")); addlist(_(" --noconfirm do not ask for any confirmation\n")); addlist(_(" --confirm always ask for confirmation\n")); } list = alpm_list_msort(list, alpm_list_count(list), options_cmp); for(i = list; i; i = alpm_list_next(i)) { fputs((const char *)i->data, stdout); } alpm_list_free(list); #undef addlist }
/* prepare a list of pkgs to display */ static void _display_targets(alpm_list_t *targets, int verbose) { char *str; off_t isize = 0, rsize = 0, dlsize = 0; unsigned short cols; alpm_list_t *i, *names = NULL, *header = NULL, *rows = NULL; if(!targets) { return; } /* gather package info */ for(i = targets; i; i = alpm_list_next(i)) { pm_target_t *target = i->data; if(target->install) { dlsize += alpm_pkg_download_size(target->install); isize += alpm_pkg_get_isize(target->install); } if(target->remove) { /* add up size of all removed packages */ rsize += alpm_pkg_get_isize(target->remove); } } /* form data for both verbose and non-verbose display */ for(i = targets; i; i = alpm_list_next(i)) { pm_target_t *target = i->data; if(verbose) { rows = alpm_list_add(rows, create_verbose_row(target)); } if(target->install) { pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install), alpm_pkg_get_version(target->install)); } else if(isize == 0) { pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->remove), alpm_pkg_get_version(target->remove)); } else { pm_asprintf(&str, "%s-%s [%s]", alpm_pkg_get_name(target->remove), alpm_pkg_get_version(target->remove), _("removal")); } names = alpm_list_add(names, str); } /* print to screen */ pm_asprintf(&str, "%s (%zd)", _("Packages"), alpm_list_count(targets)); printf("\n"); cols = getcols(fileno(stdout)); if(verbose) { header = create_verbose_header(alpm_list_count(targets)); if(table_display(header, rows, cols) != 0) { /* fallback to list display if table wouldn't fit */ list_display(str, names, cols); } } else { list_display(str, names, cols); } printf("\n"); table_free(header, rows); FREELIST(names); free(str); rows = NULL; if(dlsize > 0 || config->op_s_downloadonly) { add_transaction_sizes_row(&rows, _("Total Download Size:"), dlsize); } if(!config->op_s_downloadonly) { if(isize > 0) { add_transaction_sizes_row(&rows, _("Total Installed Size:"), isize); } if(rsize > 0 && isize == 0) { add_transaction_sizes_row(&rows, _("Total Removed Size:"), rsize); } /* only show this net value if different from raw installed size */ if(isize > 0 && rsize > 0) { add_transaction_sizes_row(&rows, _("Net Upgrade Size:"), isize - rsize); } } table_display(NULL, rows, cols); table_free(NULL, rows); }