diff options
Diffstat (limited to 'bsdconfig/share/packages/packages.subr')
-rw-r--r-- | bsdconfig/share/packages/packages.subr | 1194 |
1 files changed, 0 insertions, 1194 deletions
diff --git a/bsdconfig/share/packages/packages.subr b/bsdconfig/share/packages/packages.subr deleted file mode 100644 index a22edd8bbb27..000000000000 --- a/bsdconfig/share/packages/packages.subr +++ /dev/null @@ -1,1194 +0,0 @@ -if [ ! "$_PACKAGES_PACKAGES_SUBR" ]; then _PACKAGES_PACKAGES_SUBR=1 -# -# Copyright (c) 2013-2016 Devin Teske -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ INCLUDES - -BSDCFG_SHARE="/usr/share/bsdconfig" -. $BSDCFG_SHARE/common.subr || exit 1 -f_dprintf "%s: loading includes..." "$0" -f_include $BSDCFG_SHARE/dialog.subr -f_include $BSDCFG_SHARE/device.subr -f_include $BSDCFG_SHARE/media/common.subr -f_include $BSDCFG_SHARE/packages/categories.subr -f_include $BSDCFG_SHARE/packages/index.subr -f_include $BSDCFG_SHARE/packages/musthavepkg.subr -f_include $BSDCFG_SHARE/strings.subr - -BSDCFG_LIBE="/usr/libexec/bsdconfig" -f_include_lang $BSDCFG_LIBE/include/messages.subr - -############################################################ CONFIGURATION - -# -# How many packages to display (maximum) per dialog menubox. -# -: ${PACKAGE_MENU_PAGESIZE:=2000} - -############################################################ GLOBALS - -# -# Package extensions to try -# -PACKAGE_EXTENSIONS=".txz .tbz .tbz2 .tgz" - -# -# Variables used to track runtime states -# -PACKAGES_DETECTED= # Boolean (NULL/non-NULL); detected installed packages? -PACKAGE_CATEGORIES= # List of package categories parsed from INDEX -SELECTED_PACKAGES= # Packages selected by user in [X]dialog(1) interface - -# -# Options -# -[ "${SHOW_DESC+set}" ] || SHOW_DESC=1 - -############################################################ FUNCTIONS - -# eval f_package_accent_category_menu $var_to_set $CATEGORY_MENU_LIST -# -# Accent the CATEGORY_MENU_LIST produced by f_index_read() (see -# packages/index.subr). Accented information includes adding an asterisk to the -# category name if its index has been cached, adding the number of installed -# packages for each category, and adding the number _selected_ packages for -# each category. -# -# NOTE: The reason `eval' is recommended/shown for the syntax above is because -# the $CATEGORY_MENU_LIST generated by f_index_read() is meant to be expanded -# prior to execution (it contains a series of pre-quoted strings which act as -# the interpolated command arguments). -# -f_package_accent_category_menu() -{ - local var_to_set="$1" category cat desc help varcat menu_buf n - shift 1 # var_to_set - while [ $# -gt 0 ]; do - category="${1%\*}" desc="${2%%; *}" help="$3" - shift 3 # cat/desc/help - - cat="${category# }" # Trim lead space inserted by sort-method - f_str2varname "$cat" varcat - - # Add number of installed packages for this category (if any) - n=0 - case "$cat" in - "$msg_all") debug= f_getvar "_All_ninstalled" n ;; - *) debug= f_getvar "_${varcat}_ninstalled" n ;; - esac && - [ $n -ge 1 ] && desc="$desc; $n $msg_installed_lc" - - # Add number of selected packages for this category (if any) - n=0 - case "$cat" in - "$msg_all") debug= f_getvar "_All_nselected" n ;; - *) debug= f_getvar "_${varcat}_nselected" n ;; - esac && - [ $n -ge 1 ] && desc="$desc; $n $msg_selected" - - # Re-Add asterisk to the category if its index has been cached - f_isset _index_page_${varcat}_1 && category="$category*" - - # Update buffer with modified elements - menu_buf="$menu_buf - '$category' '$desc' '$help'" # End-Quote - done - setvar "$var_to_set" "$menu_buf" # return our buffer -} - -# f_package_select $package ... -# -# Add $package to the list of tracked/selected packages. If $package is already -# being tracked (already apears in $SELECTED_PACKAGES), this function amounts -# to having no effect. -# -f_package_select() -{ - local package pkgsel - while [ $# -gt 0 ]; do - package="$1" - shift 1 # package - for pkgsel in $SELECTED_PACKAGES; do - [ "$package" = "$pkgsel" ] && return $SUCCESS - done - SELECTED_PACKAGES="$SELECTED_PACKAGES $package" - f_dprintf "Added %s to selection list" "$package" - done - SELECTED_PACKAGES="${SELECTED_PACKAGES# }" # Trim leading space -} - -# f_package_deselect $package ... -# -# Remove $package from the list of tracked/selected packages. If $package is -# not being tracked (doesn't appear in $SELECTED_PACKAGES), this function -# amounts to having no effet. -# -f_package_deselect() -{ - local package pkgsel - while [ $# -gt 1 ]; do - local new_list="" - package="$1" - shift 1 # package - for pkgsel in $SELECTED_PACKAGES; do - [ "$pkgsel" = "$package" ] && continue - new_list="$new_list${new_list:+ }$pkgsel" - done - SELECTED_PACKAGES="$new_list" - f_dprintf "Removed %s from selection list" "$package" - done -} - -# f_package_detect_installed -# -# Detect installed packages. Currently this uses pkg-query(8) for querying -# entries and marks each entry as an installed/selected package. -# -f_package_detect_installed() -{ - local package varpkg - for package in $( pkg query "%n-%v" ); do - f_str2varname $package varpkg - export _mark_$varpkg=X # exported for awk(1) ENVIRON[] - f_package_select $package - done -} - -# f_package_calculate_totals -# -# Calculate number of installed/selected packages for each category listed in -# $PACKAGE_CATEGORIES (the number of installed packages for $category is stored -# as $_${varcat}_ninstalled -- where $varcat is the product of `f_str2varname -# $category varcat' -- and number selected packages as $_${varcat}_nselected). -# Also calculates the total number of installed/selected packages stored as -# $_All_ninstalled and $_All_nselected. -# -# Calculations are performed by checking "marks". A "mark" is stored as -# $_mark_$varpkg -- where $varpkg is the product of `f_str2varname $package -# varpkg'. A mark can be "X" for an installed package, `I' for a package that -# is marked for installation, "R" for a package that is marked for re-install, -# and "U" for a package that is marked for uninstallation. If a package mark is -# NULL or a single space (e.g., " "), the package is considered to be NOT -# selected (and therefore does not increment the counts calculated herein). -# -f_package_calculate_totals() -{ - local pkg varpkg mark cat varcat pkgcat n tselected=0 tinstalled=0 - for cat in $PACKAGE_CATEGORIES; do - f_str2varname $cat varcat - setvar _${varcat}_ninstalled=0 - setvar _${varcat}_nselected=0 - done - for pkg in $SELECTED_PACKAGES; do - f_str2varname $pkg varpkg - mark= - f_getvar _mark_$varpkg mark - case "$mark" in - ""|" ") : ;; - X) tinstalled=$(( $tinstalled + 1 )) ;; - *) tselected=$(( $tselected + 1 )) - esac - f_getvar _categories_$varpkg pkgcat - for cat in $pkgcat; do - f_str2varname $cat varcat - case "$mark" in - ""|" ") : ;; - X) debug= f_getvar _${varcat}_ninstalled n - setvar _${varcat}_ninstalled $(( $n + 1 )) ;; - *) debug= f_getvar _${varcat}_nselected n - setvar _${varcat}_nselected $(( $n + 1 )) - esac - done - done - _All_nselected=$tselected - _All_ninstalled=$tinstalled -} - -# f_package_calculate_rundeps -# -# Update package dependencies by first unmarking all dependencies and then -# re-marking all dependencies of packages marked for either install ("I") or -# re-install ("R"). -# -f_package_calculate_rundeps() -{ - local pkg varpkg mark rundeps dep vardep - - # - # First unmark all the existing run-dependencies - # - f_dprintf "Unselecting package run-dependencies..." - for pkg in $SELECTED_PACKAGES; do - f_str2varname $pkg varpkg - mark= - debug= f_getvar _mark_$varpkg mark - # Only unmark if it's marked as a Dependency - if [ "$mark" = "D" ]; then - f_dprintf "%s unselected" $pkg - unset _mark_$varpkg - f_package_deselect $pkg - fi - done - - # - # Processes selected packages, adding dependencies - # - f_dprintf "Re-selecting package run-dependencies..." - for pkg in $SELECTED_PACKAGES; do - f_str2varname $pkg varpkg - mark= - debug= f_getvar _mark_$varpkg mark - # Skip pkg unless marked for [Re-]Install - [ "$mark" = "I" -o "$mark" = "R" ] || continue - f_getvar _rundeps_$varpkg rundeps - for dep in $rundeps; do - f_str2varname $dep vardep - mark= - debug= f_getvar _mark_$vardep mark - # Skip dep if already marked - [ "${mark:- }" = " " ] || continue - export _mark_$vardep="D" - f_package_select $dep - done - done - - f_dprintf "Finished recalculating dependencies." -} - -# f_package_menu_categories $var_to_set $defaultitem -# -# Dislay the menu of package categories, complete with package counts for each -# category, accents, and other miscellany. If $defaultitem is non-NULL and -# matches one of the existing menu-items, it will be pre-highlighted in the -# menu dialog (HINT: Use f_dialog_menutag_fetch() to populate a local variable -# that is passed as $defaultitem to highlight the user's last selection). -# -f_package_menu_categories() -{ - local var_to_get="$1" defaultitem="$2" - local prompt="$msg_please_select_a_category_to_display" - local menu_list=" - '> $msg_review' '$msg_review_desc' '$msg_review_help' - " # End-Quote - local hline= - - f_package_calculate_rundeps - # updates package mark variables and SELECTED_PACKAGES - f_package_calculate_totals - # creates _{varcat}_ninstalled and _{varcat}_nselected - - local category_list - debug= f_getvar "$var_to_get" category_list || return $DIALOG_CANCEL - - # Accent the category menu list with ninstalled/nselected - eval f_package_accent_category_menu category_list $category_list - - # Add list of categories to menu list - menu_list="$menu_list $category_list" - - local height width rows - eval f_dialog_menu_with_help_size height width rows \ - \"\$DIALOG_TITLE\" \ - \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \ - \"\$hline\" \ - $menu_list - local menu_choice - menu_choice=$( eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --item-help \ - --default-item \"\$defaultitem\" \ - --ok-label \"$msg_select\" \ - --cancel-label \"$msg_cancel\" \ - --menu \"\$prompt\" \ - $height $width $rows \ - $menu_list \ - 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD - ) - local retval=$? - f_dialog_menutag_store -s "$menu_choice" - return $retval -} - -# f_package_index_get_page $category $page [$var_to_set [$var_to_get]] -# -# Obtain a [potentially cached] page of the INDEX file for a given $category. -# If $page is 1 and the cache has not yet been generated, the cache-generating -# function f_index_extract_pages() (above) is called to generate all pages -# (not just the requested page) in cache before returning the requested page. -# If $page is not 1 and there is no cached page, failure status is returned. -# -f_package_index_get_page() -{ - local category="$1" page="$2" var_to_set="$3" var_to_get="$4" varcat - f_str2varname "$category" varcat - if ! debug= f_getvar "_index_page_${varcat}_$page" $var_to_set && - [ "$page" = "1" ] - then - f_show_info "$msg_building_package_menus" - local pagesize="$PACKAGE_MENU_PAGESIZE" - f_index_extract_pages "${var_to_get:-PACKAGE_INDEX}" \ - _index_page_${varcat} "$pagesize" "$category" - debug= f_getvar _index_page_${varcat}_$page $var_to_set - - # Update category default-item because now we're cached - [ $page -eq 1 ] && - category_defaultitem="${category_defaultitem%\*}*" - else - return $FAILURE - fi -} - -# f_package_menu_select $category [$page [$defaultitem]] -# -# Display list of packages for $category, optionally $page N and with a default -# item selected. If $page is omitted, the first page is displayed (but this -# only matters if there are multiple pages; which is determined by the global -# maximum $PACKAGE_MENU_PAGESIZE). -# -# On success, if the user doesn't press ESC or choose Cancel, use -# f_dialog_menuitem_fetch() to populate a local variable with the item (not -# tag) corresponding to the user's selection. The tag portion of the user's -# selection is available through f_dialog_menutag_fetch(). -# -f_package_menu_select() -{ - local category="$1" page="${2:-1}" - local prompt= # Calculated below - local menu_list # Calculated below - local defaultitem="$3" - local hline="$hline_arrows_tab_punc_enter" - - f_isinteger "$page" || return $DIALOG_CANCEL - - local varcat - f_str2varname "$category" varcat - - # Get number of packages for this category - local npkgs=0 - case "$category" in - "$msg_all"|"") npkgs="${_npkgs:-0}" ;; - *) f_getvar _npkgs_$varcat npkgs - esac - - # Calculate number of pages - local npages=$(( ${npkgs:=0} / $PACKAGE_MENU_PAGESIZE )) - - # Add a page to the pagecount if not evenly divisible - [ $(( $npages * $PACKAGE_MENU_PAGESIZE )) -lt $npkgs ] && - npages=$(( $npages + 1 )) - - # Print some debugging information - f_dprintf "f_package_menu_select: category=[%s] npkgs=%u npages=%u" \ - "$category" "$npkgs" "$npages" - - local add_prev="" add_next="" - local previous_page="$msg_previous_page" next_page="$msg_next_page" - if [ $page -gt 1 ]; then - add_prev=1 - # Accent the `Previous Page' item with an asterisk - # if the page-before-previous is loaded/cached - f_isset _index_page_${varcat}_$(( $page - 1 )) && - previous_page="$previous_page*" - fi - if [ $page -lt $npages ]; then - add_next=1 - # Accent the `Next Page' item with an asterisk - # if the page-after-next is loaded/cached - f_isset _index_page_${varcat}_$(( $page + 1 )) && - next_page="$next_page*" - fi - - local index_page - f_package_index_get_page "$category" $page index_page - - menu_list=" - ${add_prev:+'> $previous_page' '' ${SHOW_DESC:+''}} - ${add_next:+'> $next_page' '' ${SHOW_DESC:+''}} - $( - export SHOW_DESC - export VALID_VARNAME_CHARS - echo "$index_page" | awk -F'|' -v view="port" ' - BEGIN { - valid_chars = ENVIRON["VALID_VARNAME_CHARS"] - prefix = "" - } - { - cur_prefix = tolower(substr($1, 1, 1)) - printf "'\''" - if ( prefix != cur_prefix ) - prefix = cur_prefix - else - printf " " - package = $1 - if ( view == "port" ) - desc = $2 - varpkg = package - gsub("[^" valid_chars "]", "_", varpkg) - mark = ENVIRON["_mark_" varpkg] - if ( ! mark ) mark = " " - printf "%s'\'' '\''[%c] %s'\''", - package, mark, desc - if ( ENVIRON["SHOW_DESC"] ) { - help = $4 - gsub(/'\''/, "'\''\\'\'\''", help) - printf " '\''%s'\''", help - } - printf "\n" - }' - ) - ${add_prev:+'> $previous_page' '' ${SHOW_DESC:+''}} - ${add_next:+'> $next_page' '' ${SHOW_DESC:+''}} - " # End-Quote - - # Accept/Translate i18n "All" but other category names must - # match tree definitions from INDEX, ports, FTP, etc. - case "$category" in - "$msg_all"|"") f_category_desc_get "All" prompt ;; - *) f_category_desc_get "$category" prompt ;; - esac - f_sprintf prompt "%s $msg_page_of_npages" "$prompt" "$page" "$npages" - - local mheight mwidth mrows - eval f_dialog_menu${SHOW_DESC:+_with_help}_size mheight mwidth mrows \ - \"\$DIALOG_TITLE\" \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \"\$hline\" $menu_list - local iheight iwidth - f_dialog_infobox_size iheight iwidth \ - "$DIALOG_TITLE" "$DIALOG_BACKTITLE" \ - "$msg_processing_selection" - - local menu_choice - menu_choice=$( eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --keep-tite \ - --ok-label \"$msg_select\" \ - --cancel-label \"$msg_back\" \ - ${SHOW_DESC:+--item-help} \ - --default-item \"\$defaultitem\" \ - --menu \"\$prompt\" \ - $mheight $mwidth $mrows \ - $menu_list \ - --and-widget \ - ${USE_XDIALOG:+--no-buttons} \ - --infobox \"\$msg_processing_selection\" \ - $iheight $iwidth \ - 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD - ) - local retval=$? - f_dialog_data_sanitize menu_choice - f_dialog_menutag_store "$menu_choice" - - if [ $retval -eq $DIALOG_OK ]; then - local item - item=$( eval f_dialog_menutag2item${SHOW_DESC:+_with_help} \ - \"\$menu_choice\" $menu_list ) - f_dialog_menuitem_store "$item" - fi - - return $retval -} - -# f_package_menu_deselect $package -# -# Display a menu, asking the user what they would like to do with $package -# with regard to "deselecting" an already installed package. Choices include -# uninstall, re-install, or cancel (leave $package marked as installed). -# Returns success if the user does not press ESC or choose Cnacel. Use the -# f_dialog_menutag_fetch() function upon success to retrieve the user's choice. -# -f_package_menu_deselect() -{ - local package="$1" - local prompt # Calculated below - local menu_list=" - 'X $msg_installed' '$msg_installed_desc' - 'R $msg_reinstall' '$msg_reinstall_desc' - 'U $msg_uninstall' '$msg_uninstall_desc' - " # End-Quote - local hline="$hline_alnum_arrows_punc_tab_enter" - - f_sprintf prompt "$msg_what_would_you_like_to_do_with" "$package" - - local height width rows - eval f_dialog_menu_size height width rows \ - \"\$DIALOG_TITLE\" \ - \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \ - \"\$hline\" \ - $menu_list - local menu_choice - menu_choice=$( eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --ok-label \"$msg_select\" \ - --cancel-label \"$msg_cancel\" \ - --menu \"\$prompt\" \ - $height $width $rows \ - $menu_list \ - 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD - ) - local retval=$? - f_dialog_menutag_store -s "$menu_choice" - return $retval -} - -# f_package_review -# -# Display a review screen, showing selected packages and what they are marked -# for, before proceeding (if the user does not press ESC or choose Cancel) to -# operate on each selection. Returns error if no packages have been selected, -# or the user has pressed ESC, or if they have chosen Cancel. -# -f_package_review() -{ - local funcname=f_package_review - local prompt # Calculated below - local menu_list # Calculated below - local hline="$hline_alnum_arrows_punc_tab_enter" - - f_dprintf "$funcname: SELECTED_PACKAGES=[%s]" "$SELECTED_PACKAGES" - - f_sprintf prompt "$msg_reviewing_selected_packages" "$_All_nselected" - - local package varpkg mark - for package in $SELECTED_PACKAGES; do - mark= - f_str2varname "$package" varpkg - f_getvar _mark_$varpkg mark - [ "$mark" -a ! "${mark#[IRUD]}" ] || continue - menu_list="$menu_list - '$mark' '$package' - " # End-Quote - done - if [ ! "$menu_list" ]; then - f_show_msg "$msg_no_packages_were_selected_for_extraction" - return $DIALOG_CANCEL # Might have selected this by accident - fi - menu_list=$( echo "$menu_list" | sort ) - - local height width rows - eval f_dialog_menu_size height width rows \ - \"\$DIALOG_TITLE\" \ - \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \ - \"\$hline\" \ - $menu_list - - # Show the review menu (ignore menu choice) - eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --ok-label \"\$msg_proceed\" \ - --cancel-label \"\$msg_cancel\" \ - --menu \"\$prompt\" \ - $height $width $rows \ - $menu_list \ - 2> /dev/null || return $? - # Return if the user pressed ESC or chose Cancel/No - - # - # Process each of the selected packages: - # + First, process packages marked for Install. - # + Second, process packages marked for Re-install. - # + Finally, process packages marked for Uninstall. - # - for package in $SELECTED_PACKAGES; do - mark= - f_str2varname "$package" varpkg - debug= f_getvar _mark_$varpkg mark - [ "$mark" = "I" ] || continue - f_dprintf "$funcname: Installing %s package" "$package" - f_package_add "$package" - done - for package in $SELECTED_PACKAGES; do - mark= - f_str2varname "$package" varpkg - debug= f_getvar _mark_$varpkg mark - [ "$mark" = "R" ] || continue - f_dprintf "$funcname: Reinstalling %s package" "$package" - f_package_reinstall "$package" - done - for package in $SELECTED_PACKAGES; do - mark= - f_str2varname "$package" varpkg - debug= f_getvar _mark_$varpkg mark - [ "$mark" = "U" ] || continue - f_dprintf "$funcname: Uninstalling %s package" "$package" - f_package_delete "$package" || continue - f_package_deselect "$package" - done - - return $DIALOG_OK -} - -# f_package_config -# -# Allow the user to configure packages and install them. Initially, a list of -# package categories is loaded/displayed. When the user selects a category, -# the menus for that category are built (unlike sysinstall which built all -# category menus up-front -- which also took forever, despite the fact that -# few people visit more than a couple of categories each time). -# -f_package_config() -{ - # Did we get an INDEX? - f_index_initialize || return $FAILURE - # Creates following variables (indirectly via f_index_read()) - # CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg} - # PACKAGE_CATEGORIES _npkgs - - f_show_info "$msg_building_package_main_menu" - - # Detect installed packages (updates marks/SELECTED_PACKAGES) - f_package_detect_installed - export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[] - - local retval category varcat defaultitem category_defaultitem="" - while :; do - # Display the list of package categories - f_package_menu_categories \ - CATEGORY_MENU_LIST "$category_defaultitem" - retval=$? - f_dialog_menutag_fetch category - f_dprintf "retval=%u mtag=[%s]" $retval "$category" - category_defaultitem="$category" - - [ $retval -eq $DIALOG_OK ] || break - - # Maybe the user chose an action (like `Review') - case "$category" in - "> $msg_review") - f_package_review && break - continue ;; - "> "*) - continue - esac - - # Anything else is a package category - - category=${category# } # Trim leading space if present - category=${category%\*} # Trim trailing asterisk if present - - f_str2varname "$category" varcat - - local page package varpkg mark menu_choice - while :; do - # Display the list of packages for selected category - page=1 defaultitem="" - f_getvar _defaultitem_$varcat defaultitem - f_getvar _defaultpage_$varcat page - f_package_menu_select \ - "$category" "${page:=1}" "$defaultitem" - retval=$? - f_dialog_menutag_fetch menu_choice - f_dprintf "retval=%u mtag=[%s]" $retval "$menu_choice" - - # NOTE: When --and-widget is used only ESC will cause - # dialog(1) to return without going to the next widget. - # This is alright in our case as we can still detect - # the Cancel button because stdout will be NULL. - # Alternatively, Xdialog(1) will terminate with 1 - # if/when Cancel is chosen on any widget. - if [ $retval -eq $DIALOG_ESC -o ! "$menu_choice" ] - then - break - elif [ $retval -eq $DIALOG_CANCEL ]; then - # Using X11, Xdialog(1) returned 1 for Cancel - f_show_msg "%s" "$menu_choice" - break - elif [ $retval -ne $DIALOG_OK ]; then - # X11-related error occurred using Xdialog(1) - f_show_msg "%s" "$menu_choice" - break - fi - - defaultitem="$menu_choice" - - # NOTE: f_package_menu_select() does not show the - # `Previous Page' or `Next Page' items unless needed - case "$menu_choice" in - "> $msg_previous_page"|"> $msg_previous_page*") - page=$(( $page - 1 )) - setvar _defaultpage_$varcat $page - # Update default-item to match accent that will - # be applied by f_package_menu_select(); if the - # page-before-prev is cached, add an asterisk. - if f_isset \ - _index_page_${varcat}_$(( $page - 1 )) - then - defaultitem="${defaultitem%\*}*" - else - defaultitem="${defaultitem%\*}" - fi - setvar _defaultitem_$varcat "$defaultitem" - continue ;; - "> $msg_next_page"|"> $msg_next_page*") - page=$(( $page + 1 )) - setvar _defaultpage_$varcat $page - # Update default-item to match accent that will - # be applied by f_package_menu_select(); if the - # page-after-next is cached, add an asterisk. - if f_isset \ - _index_page_${varcat}_$(( $page + 1 )) - then - defaultitem="${defaultitem%\*}*" - else - defaultitem="${defaultitem%\*}" - fi - setvar _defaultitem_$varcat "$defaultitem" - continue ;; - "> "*) # Unknown navigation/action item - setvar _defaultpage_$varcat $page - continue ;; # Do not treat as a package - *) - setvar _defaultitem_$varcat "$defaultitem" - esac - - # Treat any other selection as a package - package="${menu_choice# }" # Trim leading space - f_str2varname $package varpkg - f_dialog_menuitem_fetch mark - mark="${mark#?}" - mark="${mark%%\] *}" - case "$mark" in - "I") - mark=" " - f_package_deselect $package - ;; - " "|"D") - mark="I" - f_package_select $package - ;; - "X"|"R"|"U") - f_package_menu_deselect $package || continue - f_dialog_menutag_fetch menu_choice - case "$menu_choice" in - "X $msg_installed") - f_package_deselect "$package" - mark="X" - ;; - "R $msg_reinstall") - f_package_select "$package" - mark="R" - ;; - "U $msg_uninstall") - f_package_select "$package" - mark="U" - ;; - esac - ;; - esac - export _mark_$varpkg="$mark" - # NOTE: exported for awk(1) ENVIRON[] - done - done -} - -# f_package_add $package_name [$depended] -# -# Like f_package_extract(), but assumes current media device and chases deps. -# Note that $package_name should not contain the archive suffix (e.g., `.tbz'). -# If $depended is present and non-NULL, the package is treated as a dependency -# (in this function, dependencies are not handled any differently, but the -# f_package_extract() function is passed this value and it displays a different -# message when installing a dependency versus non-dependency). -# -f_package_add() -{ - local name="$1" depended="$2" status=$SUCCESS retval - - local alert=f_show_msg no_confirm= - f_getvar $VAR_NO_CONFIRM no_confirm - [ "$no_confirm" ] && alert=f_show_info - - if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; } - then - f_dprintf "packageAdd: %s" \ - "$msg_no_package_name_passed_in_package_variable" - return $FAILURE - fi - - { # Verify and initialize device media if-defined - f_media_verify && - f_device_init device_media && - f_index_initialize - } || return $FAILURE - - # Now we have (indirectly via f_index_read()): - # CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg} - # PACKAGE_CATEGORIES _npkgs - - local varpkg - f_str2varname "$name" varpkg - - # Just as-in the user-interface (opposed to scripted-use), only allow - # packages with at least one category to be recognized. - # - local pkgcat= - if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then - # $pkg may be a partial name, search the index (this is slow) - f_index_search PACKAGE_INDEX $name name - if [ ! "$name" ]; then - f_show_msg \ - "$msg_sorry_package_was_not_found_in_the_index" \ - "$name" - return $FAILURE - fi - f_str2varname "$name" varpkg - fi - - # If invoked through the scripted interface, we likely have not yet - # detected the installed packages -- something we should do only once. - # - if [ ! "$PACKAGES_DETECTED" ]; then - f_dprintf "f_package_add: Detecting installed packages" - f_package_detect_installed - export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[] - fi - # Now we have: _mark_{varpkg}=X for all installed packages - - # - # Since we're maintaining data structures for installed packages, - # short-circuit the package dependency checks if the package is already - # installed. This prevents wasted cycles, minor delays between package - # extractions, and worst-case an infinite loop with a certain faulty - # INDEX file. - # - local mark= - f_getvar _mark_$varpkg mark && [ "$mark" = "X" ] && return $SUCCESS - - local dep vardep rundeps= - f_getvar _rundeps_$varpkg rundeps - for dep in $rundeps; do - f_str2varname "$dep" vardep - - # Skip dependency if already installed - mark= - f_getvar _mark_$vardep mark && [ "$mark" = "X" ] && continue - - # Just as-in the user-interface (opposed to scripted-use), only - # allow packages with at least one category to be recognized. - # - local depcat= - if ! f_getvar _categories_$vardep depcat || [ ! "$depcat" ] - then - $alert "$msg_required_package_not_found" "$dep" - [ "$no_confirm" ] && sleep 2 - fi - - f_package_add "$dep" - retval=$? - if [ $retval -ne $SUCCESS ]; then - status=$(( $status | $retval )) - - # XXX package could be on a future disc volume - # XXX (not supporting multiple disc volumes yet) - - $alert "$msg_loading_of_dependent_package_failed" \ - "$dep" - [ "$no_confirm" ] && sleep 2 - fi - done - [ $status -eq $SUCCESS ] || return $status - - # - # Done with the deps? Try to load the real m'coy. - # - - f_package_extract device_media "$name" "$depended" - retval=$? - if [ $retval -ne $SUCCESS ]; then - status=$(( $status | $retval )) - else - setvar _mark_$varpkg X - fi - - return $status -} - -# f_package_extract $device $name [$depended] -# -# Extract a package based on a namespec and media device. If $depended is -# present and non-NULL, the notification displayed while installing the package -# has "as a dependency" appended. -# -f_package_extract() -{ - local funcname=f_package_extract - local device="$1" name="$2" depended="$3" - local devname= - - f_musthavepkg_init # Make sure we have a usable pkg(8) with $PKG_ABI - - $device get name devname - f_dprintf "$funcname: device=[%s] name=[%s] depended=[%s]" \ - "$devname" "$name" "$depended" - - # Check to make sure it's not already there - local varpkg mark= - f_str2varname "$name" varpkg - f_getvar _mark_$varpkg mark - [ "$mark" = "X" ] && return $SUCCESS - - if ! f_device_init $device; then - f_show_msg \ - "$msg_unable_to_initialize_media_type_for_package_extract" - return $FAILURE - fi - - # If necessary, initialize the ldconfig hints - [ -f "/var/run/ld-elf.so.hints" ] || - f_quietly ldconfig /usr/lib /usr/lib/compat /usr/local/lib - - # Make a couple paranoid locations for temp - # files to live if user specified none - local tmpdir - f_getvar $VAR_PKG_TMPDIR:-/var/tmp tmpdir - f_quietly mkdir -p -m 1777 "$tmpdir" - - local path device_type - $device get type device_type - case "$name" in - */*) path="$name" ;; - *) - if [ "$device_type" = "$DEVICE_TYPE_HTTP" ]; then - path="$PKG_ABI/latest/All/$name" - else - path="packages/$PKG_ABI/All/$name" - fi - esac - - # We have a path, call the device strategy routine to check the file - local pkg_ext found= - for pkg_ext in "" $PACKAGE_EXTENSIONS; do - if f_device_get $device "$path$pkg_ext" $PROBE_EXIST; then - path="$path$pkg_ext" - found=1 - break - elif [ "$device_type" = "$DEVICE_TYPE_HTTP" ] && - f_device_get $device \ - "packages/$PKG_ABI/All/$name$pkg_ext" $PROBE_EXIST - then - # Mirroring physical media over HTTP - path="packages/$PKG_ABI/All/$name$pkg_ext" - found=1 - break - fi - done - [ "$found" ] && f_dprintf "$funcname: found path=[%s] dev=[%s]" \ - "$path" "$devname" - - local alert=f_show_msg no_confirm= - f_getvar $VAR_NO_CONFIRM no_confirm - [ "$no_confirm" ] && alert=f_show_info - - if [ ! "$found" ]; then - f_dprintf "$funcname: No such %s file on %s device" \ - "$path" "$devname" - $alert "$msg_unable_to_fetch_package_from_selected_media" \ - "$name" - [ "$no_confirm" ] && sleep 2 - return $FAILURE - fi - - if [ "$depended" ]; then - f_show_info "$msg_adding_package_as_a_dependency_from_media" \ - "$name" "$devname" - else - f_show_info "$msg_adding_package_from_media" "$name" "$devname" - fi - - # Request the package be added via pkg-install(8) - if f_debugging; then - f_eval_catch $funcname pkg \ - 'pkg -d install -${depended:+A}y "%s"' "$name" - else - f_eval_catch $funcname pkg \ - 'pkg install -${depended:+A}y "%s"' "$name" - fi - if [ $? -ne $SUCCESS ]; then - $alert "$msg_pkg_install_apparently_did_not_like_the_package" \ - "$name" - [ "$no_confirm" ] && sleep 2 - else - f_show_info "$msg_package_was_added_successfully" "$name" - sleep 1 - fi - - return $SUCCESS -} - -# f_package_delete $name -# -# Delete package by full $name (lacks archive suffix; e.g., `.tbz'). -# -f_package_delete() -{ - local funcname=f_package_delete - local name="$1" - - if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; } - then - f_dprintf "packageDelete: %s" \ - "$msg_no_package_name_passed_in_package_variable" - return $FAILURE - fi - - f_dprintf "$funcname: name=[%s]" "$name" - - [ "$name" ] || return $FAILURE - - { # Verify and initialize device media if-defined - f_media_verify && - f_device_init device_media && - f_index_initialize - } || return $FAILURE - - # Now we have (indirectly via f_index_read()): - # CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg} - # PACKAGE_CATEGORIES _npkgs - - local varpkg - f_str2varname "$name" varpkg - - # Just as-in the user-interface (opposed to scripted-use), only allow - # packages with at least one category to be recognized. - # - local pkgcat= - if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then - # $pkg may be a partial name, search the index (this is slow) - f_index_search PACKAGE_INDEX "$name" name - if [ ! "$name" ]; then - f_show_msg \ - "$msg_sorry_package_was_not_found_in_the_index" \ - "$name" - return $FAILURE - fi - f_str2varname "$name" varpkg - fi - - # If invoked through the scripted interface, we likely have not yet - # detected the installed packages -- something we should do only once. - # - if [ ! "$PACKAGES_DETECTED" ]; then - f_dprintf "$funcname: Detecting installed packages" - f_package_detect_installed - export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[] - fi - # Now we have: _mark_{varpkg}=X for all installed packages - - # - # Return failure if the package is not already installed. - # - local pkgmark= - f_getvar _mark_$varpkg pkgmark - if ! [ "$pkgmark" -a ! "${pkgmark#[XUR]}" ]; then - f_show_msg "$msg_package_not_installed_cannot_delete" "$name" - return $FAILURE - fi - - # - # Check for dependencies - # - local pkgsel depc=0 udeps= - for pkgsel in $SELECTED_PACKAGES; do - local mark= - f_str2varname $pkgsel varpkg - debug= f_getvar _mark_$varpkg mark - [ "$mark" -a ! "${mark#[XUR]}" ] || continue - local dep rundeps= - debug= f_getvar _rundeps_$varpkg rundeps - for dep in $rundeps; do - if [ "$dep" = "$name" ]; then - # Maybe this package is marked for deletion too - if [ "$mark" = "U" ]; then - udeps="$udeps $pkgsel" - else - depc=$(( $depc + 1 )) - fi - break - fi - done - done - if [ $depc -gt 0 ]; then - local grammatical_s= - [ $depc -gt 1 ] && grammatical_s=s - f_show_msg \ - "$msg_package_is_needed_by_other_installed_packages" \ - "$name" "$depc" "$grammatical_s" - return $FAILURE - fi - - # - # Chase dependencies that are marked for uninstallation - # - for pkgsel in $udeps; do - f_dprintf "$funcname: Uninstalling dependency %s (%s)" \ - "$pkgsel" "marked for delete" - f_package_delete "$pkgsel" - done - - # - # OK to perform the delete (no other packages depend on it)... - # - f_show_info "$msg_uninstalling_package_waiting_for_pkg_delete" "$name" - if f_debugging; then - f_eval_catch $funcname pkg 'pkg -d delete -y "%s"' "$name" - else - f_eval_catch $funcname pkg 'pkg delete -y "%s"' "$name" - fi - if [ $? -ne $SUCCESS ]; then - f_show_msg "$msg_pkg_delete_failed" "$name" - return $FAILURE - else - f_dprintf "$funcname: pkg-delete(8) of %s successful" "$name" - f_str2varname "$name" varpkg - setvar _mark_$varpkg "" - fi -} - -# f_package_reinstall $name -# -# A simple wrapper to f_package_delete() + f_package_add() -# -f_package_reinstall() -{ - f_package_delete "$1" && f_package_add "$1" -} - -############################################################ MAIN - -f_dprintf "%s: Successfully loaded." packages/packages.subr - -fi # ! $_PACKAGES_PACKAGES_SUBR |