1if [ ! "$_PACKAGES_PACKAGES_SUBR" ]; then _PACKAGES_PACKAGES_SUBR=1
2#
3# Copyright (c) 2013 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
--- 10 unchanged lines hidden (view full) ---
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/usr.sbin/bsdconfig/share/packages/packages.subr 252745 2013-07-05 01:44:59Z dteske $
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." "$0"
34f_include $BSDCFG_SHARE/dialog.subr
35f_include $BSDCFG_SHARE/device.subr
36f_include $BSDCFG_SHARE/media/common.subr
37f_include $BSDCFG_SHARE/packages/categories.subr
38f_include $BSDCFG_SHARE/packages/index.subr
39f_include $BSDCFG_SHARE/strings.subr
40
41BSDCFG_LIBE="/usr/libexec/bsdconfig"
42f_include_lang $BSDCFG_LIBE/include/messages.subr
43
44############################################################ CONFIGURATION
45
46#
47# How many packages to display (maximum) per dialog menubox.
48#
49: ${PACKAGE_MENU_PAGESIZE:=2000}
50
51############################################################ GLOBALS
52
53#
54# Package extensions to try
55#
56PACKAGE_EXTENSIONS=".tbz .tbz2 .tgz"
57
58#
59# Variables used to track runtime states
60#
61PACKAGES_DETECTED= # Boolean (NULL/non-NULL); detected installed packages?
62PACKAGE_CATEGORIES= # List of package categories parsed from INDEX
63SELECTED_PACKAGES= # Packages selected by user in [X]dialog(1) interface
64
65#
66# Options
67#
68[ "${SHOW_DESC+set}" ] || SHOW_DESC=1
69
--- 562 unchanged lines hidden (view full) ---
632 # + Second, process packages marked for Re-install.
633 # + Finally, process packages marked for Uninstall.
634 #
635 for package in $SELECTED_PACKAGES; do
636 mark=
637 f_str2varname "$package" varpkg
638 f_getvar _mark_$varpkg mark
639 [ "$mark" = "I" ] || continue
640 f_package_add "$package" || continue
641 f_package_deselect "$package"
642 done
643 for package in $SELECTED_PACKAGES; do
644 mark=
645 f_str2varname "$package" varpkg
646 f_getvar _mark_$varpkg mark
647 [ "$mark" = "R" ] || continue
648 # XXX Re-install package
--- 166 unchanged lines hidden (view full) ---
815 ;;
816 esac
817 export _mark_$varpkg="$mark"
818 # NOTE: exported for awk(1) ENVIRON[]
819 done
820 done
821}
822
823# f_package_add $package_name [$depended]
824#
825# Like f_package_extract(), but assumes current media device and chases deps.
826# Note that $package_name should not contain the archive suffix (e.g., `.tbz').
827# If $depended is present and non-NULL, the package is treated as a dependency
828# (in this function, dependencies are not handled any differently, but the
829# f_package_extract() function is passed this value and it displays a different
830# message when installing a dependency versus non-dependency).
831#
832f_package_add()
833{
834 local name="$1" depended="$2" status=$SUCCESS retval
835
836 local alert=f_show_msg no_confirm=
837 f_getvar $VAR_NO_CONFIRM no_confirm
838 [ "$no_confirm" ] && alert=f_show_info
839
840 if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; }
841 then
842 f_dprintf "packageAdd: %s" \
843 "$msg_no_package_name_passed_in_package_variable"
844 return $FAILURE
845 fi
846
847 { # Verify and initialize device media if-defined
848 f_media_verify &&
849 f_device_init media &&
850 f_index_initialize packages/INDEX
851 } || return $FAILURE
852
853 # Now we have (indirectly via f_index_read()):
854 # CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
855 # PACKAGE_CATEGORIES _npkgs
856
857 local varpkg
858 f_str2varname "$name" varpkg
859
860 # Just as-in the user-interface (opposed to scripted-use), only allow
861 # packages with at least one category to be recognized.
862 #
863 local pkgcat=
864 if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then
865 # $pkg may be a partial name, search the index (this is slow)
866 f_index_search PACKAGE_INDEX $name name
867 if [ ! "$name" ]; then
868 f_show_msg \
869 "$msg_sorry_package_was_not_found_in_the_index" \
870 "$name"
871 return $FAILURE
872 fi
873 f_str2varname "$name" varpkg
874 fi
875
876 # If invoked through the scripted interface, we likely have not yet
877 # detected the installed packages -- something we should do only once.
878 #
879 if [ ! "$PACKAGES_DETECTED" ]; then
880 f_package_detect_installed
881 export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[]
882 fi
883 # Now we have: _mark_{varpkg}=X for all installed packages
884
885 #
886 # Since we're maintaining data structures for installed packages,
887 # short-circuit the package dependency checks if the package is already
888 # installed. This prevents wasted cycles, minor delays between package
889 # extractions, and worst-case an infinite loop with a certain faulty
890 # INDEX file.
891 #
892 local mark=
893 f_getvar _mark_$varpkg mark && [ "$mark" = "X" ] && return $SUCCESS
894
895 local dep vardep rundeps=
896 f_getvar _rundeps_$varpkg rundeps
897 for dep in $rundeps; do
898 f_str2varname "$dep" vardep
899
900 # Skip dependency if already installed
901 mark=
902 f_getvar _mark_$vardep mark && [ "$mark" = "X" ] && continue
903
904 # Just as-in the user-interface (opposed to scripted-use), only
905 # allow packages with at least one category to be recognized.
906 #
907 local depcat=
908 if ! f_getvar _categories_$vardep depcat || [ ! "$depcat" ]
909 then
910 $alert "$msg_required_package_not_found" "$dep"
911 [ "$no_confirm" ] && sleep 2
912 fi
913
914 f_package_add "$dep"
915 retval=$?
916 if [ $retval -ne $SUCCESS ]; then
917 status=$(( $status | $retval ))
918
919 # XXX package could be on a future disc volume
920 # XXX (not supporting multiple disc volumes yet)
921
922 $alert "$msg_loading_of_dependent_package_failed" \
923 "$dep"
924 [ "$no_confirm" ] && sleep 2
925 fi
926 done
927 [ $status -eq $SUCCESS ] || return $status
928
929 #
930 # Done with the deps? Try to load the real m'coy.
931 #
932
933 f_package_extract media "$name" "$depended"
934 retval=$?
935 if [ $retval -ne $SUCCESS ]; then
936 status=$(( $status | $retval ))
937 else
938 setvar _mark_$varpkg X
939 fi
940
941 return $status
942}
943
944# f_package_extract $device $name [$depended]
945#
946# Extract a package based on a namespec and media device. If $depended is
947# present and non-NULL, the notification displayed while installing the package
948# has "as a dependency" appended.
949#
950f_package_extract()
951{
952 local device="$1" name="$2" depended="$3"
953
954 # Check to make sure it's not already there
955 local varpkg mark=
956 f_str2varname "$name" varpkg
957 f_getvar _mark_$varpkg mark
958 [ "$mark" = "X" ] && return $SUCCESS
959
960 if ! f_device_init $device; then
961 f_show_msg \
962 "$msg_unable_to_initialize_media_type_for_package_extract"
963 return $FAILURE
964 fi
965
966 # If necessary, initialize the ldconfig hints
967 [ -f "/var/run/ld-elf.so.hints" ] ||
968 f_quietly ldconfig /usr/lib /usr/lib/compat /usr/local/lib
969
970 # Make a couple paranoid locations for temp
971 # files to live if user specified none
972 local tmpdir
973 f_getvar $VAR_PKG_TMPDIR:-/var/tmp tmpdir
974 f_quietly mkdir -p -m 1777 "$tmpdir"
975
976 local path
977 case "$name" in
978 */*) path="$name" ;;
979 *)
980 case "$name" in
981 *-*|*_*) path="packages/All/$name" ;;
982 *) path="packages/Latest/$name"
983 esac
984 esac
985
986 local fname=f_package_extract
987
988 # We have a path, call the device strategy routine to get the file
989 local pkg_ext probe_only=1 found=
990 for pkg_ext in "" $PACKAGE_EXTENSIONS; do
991 if f_device_get $device "$path$pkg_ext" $probe_only; then
992 path="$path$pkg_ext"
993 f_dprintf "%s: found path=[%s] dev=[%s]" \
994 $fname "$path" "$device"
995 found=1
996 break
997 fi
998 done
999
1000 local alert=f_show_msg no_confirm=
1001 f_getvar $VAR_NO_CONFIRM no_confirm
1002 [ "$no_confirm" ] && alert=f_show_info
1003
1004 if [ ! "$found" ]; then
1005 f_dprintf "%s: No such %s file on %s device" \
1006 $fname "$path" "$device"
1007 $alert "$msg_unable_to_fetch_package_from_selected_media" \
1008 "$name"
1009 [ "$no_confirm" ] && sleep 2
1010 return $FAILURE
1011 fi
1012
1013 local devname=
1014 f_struct device_$device get name devname
1015 if [ "$depended" ]; then
1016 f_show_info "$msg_adding_package_as_a_dependency_from_media" \
1017 "$name" "$devname"
1018 else
1019 f_show_info "$msg_adding_package_from_media" "$name" "$devname"
1020 fi
1021
1022 # Get package data and pipe into pkg_add(1) while providing feedback
1023 {
1024 if ! f_device_get $device "$path"; then
1025 $alert "$msg_io_error_while_reading_in_the_package" \
1026 "$name" \
1027 >&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
1028 [ "$no_confirm" ] && sleep 2
1029 else
1030 f_show_info \
1031 "$msg_package_read_successfully_waiting_for_pkg_add" \
1032 "$name" >&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
1033 fi
1034 } | {
1035 if f_debugging; then
1036 /usr/sbin/pkg_add -v -
1037 else
1038 f_quietly /usr/sbin/pkg_add -
1039 fi
1040 }
1041 if [ $? -ne $SUCCESS ]; then
1042 $alert "$msg_pkg_add_apparently_did_not_like_the_package" \
1043 "$name"
1044 [ "$no_confirm" ] && sleep 2
1045 else
1046 f_show_info "$msg_package_was_added_successfully" "$name"
1047 sleep 1
1048 fi
1049
1050 return $SUCCESS
1051}
1052
1053############################################################ MAIN
1054
1055f_dprintf "%s: Successfully loaded." packages/packages.subr
1056
1057fi # ! $_PACKAGES_PACKAGES_SUBR
2#
3# Copyright (c) 2013 Devin Teske
4# All Rights Reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
--- 10 unchanged lines hidden (view full) ---
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/usr.sbin/bsdconfig/share/packages/packages.subr 252745 2013-07-05 01:44:59Z dteske $
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." "$0"
34f_include $BSDCFG_SHARE/dialog.subr
35f_include $BSDCFG_SHARE/device.subr
36f_include $BSDCFG_SHARE/media/common.subr
37f_include $BSDCFG_SHARE/packages/categories.subr
38f_include $BSDCFG_SHARE/packages/index.subr
39f_include $BSDCFG_SHARE/strings.subr
40
41BSDCFG_LIBE="/usr/libexec/bsdconfig"
42f_include_lang $BSDCFG_LIBE/include/messages.subr
43
44############################################################ CONFIGURATION
45
46#
47# How many packages to display (maximum) per dialog menubox.
48#
49: ${PACKAGE_MENU_PAGESIZE:=2000}
50
51############################################################ GLOBALS
52
53#
54# Package extensions to try
55#
56PACKAGE_EXTENSIONS=".tbz .tbz2 .tgz"
57
58#
59# Variables used to track runtime states
60#
61PACKAGES_DETECTED= # Boolean (NULL/non-NULL); detected installed packages?
62PACKAGE_CATEGORIES= # List of package categories parsed from INDEX
63SELECTED_PACKAGES= # Packages selected by user in [X]dialog(1) interface
64
65#
66# Options
67#
68[ "${SHOW_DESC+set}" ] || SHOW_DESC=1
69
--- 562 unchanged lines hidden (view full) ---
632 # + Second, process packages marked for Re-install.
633 # + Finally, process packages marked for Uninstall.
634 #
635 for package in $SELECTED_PACKAGES; do
636 mark=
637 f_str2varname "$package" varpkg
638 f_getvar _mark_$varpkg mark
639 [ "$mark" = "I" ] || continue
640 f_package_add "$package" || continue
641 f_package_deselect "$package"
642 done
643 for package in $SELECTED_PACKAGES; do
644 mark=
645 f_str2varname "$package" varpkg
646 f_getvar _mark_$varpkg mark
647 [ "$mark" = "R" ] || continue
648 # XXX Re-install package
--- 166 unchanged lines hidden (view full) ---
815 ;;
816 esac
817 export _mark_$varpkg="$mark"
818 # NOTE: exported for awk(1) ENVIRON[]
819 done
820 done
821}
822
823# f_package_add $package_name [$depended]
824#
825# Like f_package_extract(), but assumes current media device and chases deps.
826# Note that $package_name should not contain the archive suffix (e.g., `.tbz').
827# If $depended is present and non-NULL, the package is treated as a dependency
828# (in this function, dependencies are not handled any differently, but the
829# f_package_extract() function is passed this value and it displays a different
830# message when installing a dependency versus non-dependency).
831#
832f_package_add()
833{
834 local name="$1" depended="$2" status=$SUCCESS retval
835
836 local alert=f_show_msg no_confirm=
837 f_getvar $VAR_NO_CONFIRM no_confirm
838 [ "$no_confirm" ] && alert=f_show_info
839
840 if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; }
841 then
842 f_dprintf "packageAdd: %s" \
843 "$msg_no_package_name_passed_in_package_variable"
844 return $FAILURE
845 fi
846
847 { # Verify and initialize device media if-defined
848 f_media_verify &&
849 f_device_init media &&
850 f_index_initialize packages/INDEX
851 } || return $FAILURE
852
853 # Now we have (indirectly via f_index_read()):
854 # CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
855 # PACKAGE_CATEGORIES _npkgs
856
857 local varpkg
858 f_str2varname "$name" varpkg
859
860 # Just as-in the user-interface (opposed to scripted-use), only allow
861 # packages with at least one category to be recognized.
862 #
863 local pkgcat=
864 if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then
865 # $pkg may be a partial name, search the index (this is slow)
866 f_index_search PACKAGE_INDEX $name name
867 if [ ! "$name" ]; then
868 f_show_msg \
869 "$msg_sorry_package_was_not_found_in_the_index" \
870 "$name"
871 return $FAILURE
872 fi
873 f_str2varname "$name" varpkg
874 fi
875
876 # If invoked through the scripted interface, we likely have not yet
877 # detected the installed packages -- something we should do only once.
878 #
879 if [ ! "$PACKAGES_DETECTED" ]; then
880 f_package_detect_installed
881 export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[]
882 fi
883 # Now we have: _mark_{varpkg}=X for all installed packages
884
885 #
886 # Since we're maintaining data structures for installed packages,
887 # short-circuit the package dependency checks if the package is already
888 # installed. This prevents wasted cycles, minor delays between package
889 # extractions, and worst-case an infinite loop with a certain faulty
890 # INDEX file.
891 #
892 local mark=
893 f_getvar _mark_$varpkg mark && [ "$mark" = "X" ] && return $SUCCESS
894
895 local dep vardep rundeps=
896 f_getvar _rundeps_$varpkg rundeps
897 for dep in $rundeps; do
898 f_str2varname "$dep" vardep
899
900 # Skip dependency if already installed
901 mark=
902 f_getvar _mark_$vardep mark && [ "$mark" = "X" ] && continue
903
904 # Just as-in the user-interface (opposed to scripted-use), only
905 # allow packages with at least one category to be recognized.
906 #
907 local depcat=
908 if ! f_getvar _categories_$vardep depcat || [ ! "$depcat" ]
909 then
910 $alert "$msg_required_package_not_found" "$dep"
911 [ "$no_confirm" ] && sleep 2
912 fi
913
914 f_package_add "$dep"
915 retval=$?
916 if [ $retval -ne $SUCCESS ]; then
917 status=$(( $status | $retval ))
918
919 # XXX package could be on a future disc volume
920 # XXX (not supporting multiple disc volumes yet)
921
922 $alert "$msg_loading_of_dependent_package_failed" \
923 "$dep"
924 [ "$no_confirm" ] && sleep 2
925 fi
926 done
927 [ $status -eq $SUCCESS ] || return $status
928
929 #
930 # Done with the deps? Try to load the real m'coy.
931 #
932
933 f_package_extract media "$name" "$depended"
934 retval=$?
935 if [ $retval -ne $SUCCESS ]; then
936 status=$(( $status | $retval ))
937 else
938 setvar _mark_$varpkg X
939 fi
940
941 return $status
942}
943
944# f_package_extract $device $name [$depended]
945#
946# Extract a package based on a namespec and media device. If $depended is
947# present and non-NULL, the notification displayed while installing the package
948# has "as a dependency" appended.
949#
950f_package_extract()
951{
952 local device="$1" name="$2" depended="$3"
953
954 # Check to make sure it's not already there
955 local varpkg mark=
956 f_str2varname "$name" varpkg
957 f_getvar _mark_$varpkg mark
958 [ "$mark" = "X" ] && return $SUCCESS
959
960 if ! f_device_init $device; then
961 f_show_msg \
962 "$msg_unable_to_initialize_media_type_for_package_extract"
963 return $FAILURE
964 fi
965
966 # If necessary, initialize the ldconfig hints
967 [ -f "/var/run/ld-elf.so.hints" ] ||
968 f_quietly ldconfig /usr/lib /usr/lib/compat /usr/local/lib
969
970 # Make a couple paranoid locations for temp
971 # files to live if user specified none
972 local tmpdir
973 f_getvar $VAR_PKG_TMPDIR:-/var/tmp tmpdir
974 f_quietly mkdir -p -m 1777 "$tmpdir"
975
976 local path
977 case "$name" in
978 */*) path="$name" ;;
979 *)
980 case "$name" in
981 *-*|*_*) path="packages/All/$name" ;;
982 *) path="packages/Latest/$name"
983 esac
984 esac
985
986 local fname=f_package_extract
987
988 # We have a path, call the device strategy routine to get the file
989 local pkg_ext probe_only=1 found=
990 for pkg_ext in "" $PACKAGE_EXTENSIONS; do
991 if f_device_get $device "$path$pkg_ext" $probe_only; then
992 path="$path$pkg_ext"
993 f_dprintf "%s: found path=[%s] dev=[%s]" \
994 $fname "$path" "$device"
995 found=1
996 break
997 fi
998 done
999
1000 local alert=f_show_msg no_confirm=
1001 f_getvar $VAR_NO_CONFIRM no_confirm
1002 [ "$no_confirm" ] && alert=f_show_info
1003
1004 if [ ! "$found" ]; then
1005 f_dprintf "%s: No such %s file on %s device" \
1006 $fname "$path" "$device"
1007 $alert "$msg_unable_to_fetch_package_from_selected_media" \
1008 "$name"
1009 [ "$no_confirm" ] && sleep 2
1010 return $FAILURE
1011 fi
1012
1013 local devname=
1014 f_struct device_$device get name devname
1015 if [ "$depended" ]; then
1016 f_show_info "$msg_adding_package_as_a_dependency_from_media" \
1017 "$name" "$devname"
1018 else
1019 f_show_info "$msg_adding_package_from_media" "$name" "$devname"
1020 fi
1021
1022 # Get package data and pipe into pkg_add(1) while providing feedback
1023 {
1024 if ! f_device_get $device "$path"; then
1025 $alert "$msg_io_error_while_reading_in_the_package" \
1026 "$name" \
1027 >&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
1028 [ "$no_confirm" ] && sleep 2
1029 else
1030 f_show_info \
1031 "$msg_package_read_successfully_waiting_for_pkg_add" \
1032 "$name" >&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
1033 fi
1034 } | {
1035 if f_debugging; then
1036 /usr/sbin/pkg_add -v -
1037 else
1038 f_quietly /usr/sbin/pkg_add -
1039 fi
1040 }
1041 if [ $? -ne $SUCCESS ]; then
1042 $alert "$msg_pkg_add_apparently_did_not_like_the_package" \
1043 "$name"
1044 [ "$no_confirm" ] && sleep 2
1045 else
1046 f_show_info "$msg_package_was_added_successfully" "$name"
1047 sleep 1
1048 fi
1049
1050 return $SUCCESS
1051}
1052
1053############################################################ MAIN
1054
1055f_dprintf "%s: Successfully loaded." packages/packages.subr
1056
1057fi # ! $_PACKAGES_PACKAGES_SUBR