OSDN Git Service

Version 3.1.1+toward_3.2.0_20141228193746
[portsreinstall/current.git] / lib / libpkgsys.sh
index 65e4045..773c43a 100644 (file)
@@ -2,7 +2,7 @@
 # ==============================================================================
 # portsreinstall library script
 # - Wrappers for hiding version differences in the Ports/Packages system -
-# Copyright (C) 2013 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
+# Copyright (C) 2013-2014 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
 # This software is distributed under the 2-Clause BSD License.
 # ==============================================================================
 
@@ -15,6 +15,22 @@ PKGSYS_CMD_PKG_ADD='pkg add' # Corresponding command for pkg_add
 PKGSYS_AVR_REFETCH_TIMES_PER_SITE=1    # Average number (integer) of retrials for retrieving package or distfiles per mirror site
 PKGSYS_AVR_REFETCH_TIMES_FOR_CHKSUMERR=2       #  Number (integer) of retrials for check sum error in retrieving a package
 
+# ============= Check implementation of the ports tree =============
+pkgsys_chk_ports_tree_implementation ()
+{
+       local var tmp_work
+       if [ ! -d "${PORTSDIR}" ]
+       then
+               message_echo "ERROR: Ports directory ${PORTSDIR} is not found." >&2
+               exit 1
+       fi
+       if [ ! -e "${PORTSDIR}/Makefile" -o ! -e "${PORTSDIR}/Mk/bsd.port.mk" ]
+       then
+               message_echo "ERROR: Ports tree ${PORTSDIR} is missing, broken or incompatible." >&2
+               exit 1
+       fi
+}
+
 # ============= System defined value for the ports/packages =============
 pkgsys_sysvar ()
 {
@@ -42,6 +58,12 @@ pkgsys_is_pkgtool ()
        esac
 }
 
+# ============= Check whether a port is indispensable for package operations =============
+pkgsys_is_necessary_pkgtool ()
+{
+       [ x"$WITH_PKGNG" = x'yes' -a "x$1" = x'ports-mgmt/pkg' ]
+}
+
 # ============= Check whether the dialog for selecting port options is dialog4ports =============
 pkgsys_is_dialog4ports_used ()
 {
@@ -147,12 +169,22 @@ pkgsys_fetch_legacy_remote ()
        [ -d "${PKGREPOSITORY}" ] || mkdir -p "${PKGREPOSITORY}"
        if [ -e "${PKGREPOSITORY}/$pkg.tbz" ]
        then
-               fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
-               if [ "x$fetchedMD5" = "x$validMD5" ]
+               if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
+               then
+                       fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
+                       [ "x$fetchedMD5" = "x$validMD5" ] || rm "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
+               fi
+               if [ -e "${PKGREPOSITORY}/$pkg.md5=$validMD5.tbz" ]
                then
-                       needs_fetch=no
+                       ln -f "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz" "${PKGREPOSITORY}/$pkg.tbz"
                else
-                       mv "${PKGREPOSITORY}/$pkg.tbz" "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
+                       fetchedMD5=`md5 "${PKGREPOSITORY}/$pkg.tbz" | sed -E "s/^[^=]*=[[:space:]]*(.*)/\1/"`
+                       if [ "x$fetchedMD5" = "x$validMD5" ]
+                       then
+                               needs_fetch=no
+                       else
+                               mv "${PKGREPOSITORY}/$pkg.tbz" "${PKGREPOSITORY}/$pkg.md5=$fetchedMD5.tbz"
+                       fi
                fi
        fi
        if [ $needs_fetch = yes ]
@@ -266,7 +298,7 @@ pkgsys_def_pkgtools ()
 #              }
                pkg_info_qoX ()
                {
-                       pkg info -qoX "$@" 2> /dev/null
+                       pkg info -qox "$@" 2> /dev/null
                }
                pkg_info_qO ()
                {
@@ -306,9 +338,20 @@ pkgsys_def_pkgtools ()
                }
                pkg_check_sanity ()
                {
-                       local pkg
+                       local pkg tmp_stdout tmp_stderr
                        pkg=$1
-                       pkg check -s "$pkg" 2> /dev/null
+                       tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
+                       tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
+                       pkg check -s "$pkg" > $tmp_stdout 2> $tmp_stderr || :
+                       grep '^[^:]*: checksum mismatch for ' "$tmp_stderr" | sed 's/^[^:]*: checksum mismatch for //' || :
+                       if grep -q '^pkg: .*: No such file or directory$' "$tmp_stderr"
+                       then
+                               pkg info -ql "$pkg" | while read filepath
+                               do
+                                       [ -e "$filepath" ] || echo "$filepath"
+                               done
+                       fi
+                       :
                }
                pkg_which ()
                {
@@ -327,6 +370,8 @@ pkgsys_def_pkgtools ()
                pkg_delete_f ()
                {
                        pkg delete -fqy "$@"
+                       pkg info -e "$@" || return 0    # Countermeasure for a bug found for pkg-1.3.4 (at least not until 1.2.7_4)
+                       pkg delete -fy "$@"
                }
                pkg_add_tools ()
                {
@@ -450,7 +495,8 @@ pkgsys_def_pkgtools ()
                        PKGNG_AUTODEPS=NO
                        PKGNG_PORTAUDIT_SITE='http=//portaudit.FreeBSD.org/auditfile.tbz'
                        # Load configuration for pkg(1)
-                       pkg_conf=`pkg query %Fp pkg | grep '/etc/pkg\.conf\.sample$' | sed 's/\.sample$//'`
+                       pkg_conf=`pkg query %Fp pkg 2> /dev/null | grep '/etc/pkg\.conf\.sample$' | sed 's/\.sample$//'` || :
+                       [ -n "$pkg_conf" ] || pkg_conf=${MYPREFIX}/etc/pkg.conf
                        grep -v -e '^[[:space:]]*#' -e '^[[:space:]]*$' "$pkg_conf" 2> /dev/null \
                                | grep -e '^[[:space:]]*[A-Z0-9_]*[[:space:]]*:[[:space:]]*.*' \
                                | while read srcline
@@ -565,9 +611,13 @@ pkgsys_def_pkgtools ()
                }
                pkg_check_sanity ()
                {
-                       local pkg
+                       local pkg tmp_stdout tmp_stderr
                        pkg=$1
-                       pkg_info -qg "$pkg" 2> /dev/null
+                       tmp_stdout=${TMPDIR}/pkgng:pkg_check_sanity:stdout
+                       tmp_stderr=${TMPDIR}/pkgng:pkg_check_sanity:stderr
+                       pkg_info -qg "$pkg" > $tmp_stdout 2> $tmp_stderr || :
+                       grep ' fails the original MD5 checksum$' "$tmp_stdout" | sed 's/ fails the original MD5 checksum$//' || :
+                       grep "^pkg_info: .* doesn't exist$" "$tmp_stderr" | sed -E "s/^pkg_info: (.*) doesn't exist$/\1/" || :
                }
                pkg_which ()
                {
@@ -649,8 +699,8 @@ pkgsys_pkg_info_qO_init ()
        origin=$1
        tmppkg=${TMPDIR}/pkgsys_pkg_info_qO_init::pkg
        origin_regexp=`str_escape_regexp "$origin"`
-       { sed -n -E "/[[:space:]]$origin_regexp$/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null || :; } \
-               | cut -f 1 > $tmppkg
+       sed -n -E "/[[:space:]]$origin_regexp$/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
+               | cut -f 1 > $tmppkg || :
        npkgs=`wc -l < $tmppkg`
        if [ $npkgs -gt 0 ]
        then
@@ -754,7 +804,7 @@ pkgsys_eval_ports_glob ()
                shift
                expr "x$glob" : '^x-' > /dev/null 2>&1 && continue
                glob_regexp=`str_convert_portsglob_to_regexp_pattern "$glob"`
-               if expr "$glob" : '[^/][^/]*\/[^/][^/]*$' > /dev/null 2>&1
+               if expr "$glob" : '.*/' > /dev/null 2>&1
                then
                        grep -E "$glob_regexp" "$origlist" 2>&1 || :
                        {
@@ -762,7 +812,7 @@ pkgsys_eval_ports_glob ()
                                cut -f 2 "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null
                        } | grep -E "$glob_regexp" 2>&1 || :
                else
-                       if expr "$glob" : '^[a-z][a-zA-Z0-9+-]*[a-zA-Z0-9+]$' > /dev/null 2>&1 && \
+                       if expr "$glob" : '^[a-z][a-zA-Z0-9_.+-]*[a-zA-Z0-9_.+]$' > /dev/null 2>&1 && \
                                [ `expr "$glob" : '.*-[0-9]' 2>&1` -eq 0 ]
                        then
                                glob_regexp2=`expr "$glob_regexp" : '\(.*\)\$$' 2>&1`'-[0-9]'
@@ -775,8 +825,8 @@ pkgsys_eval_ports_glob ()
                                sed -n ${index}p "$origlist"
                        done || :
                        glob_regexp2=`expr "$glob_regexp" : '\(.*\)\$$' 2>&1`'[[:space:]]'
-                       { sed -n -E "/$glob_regexp2/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null || :; } \
-                               | cut -f 2
+                       sed -n -E "/$glob_regexp2/p" "${DBDIR}/installed_ports:pkg_vs_origin.tbl" 2> /dev/null \
+                               | cut -f 2 || :
                        pkg_info_qoX "$glob_regexp" || :
                fi
        done | sort -u
@@ -785,7 +835,7 @@ pkgsys_eval_ports_glob ()
 # ============= Create a back-up package archive =============
 pkgsys_create_backup_pkg ()
 {
-       local pkgname dstdir origin backup_pkg_old origin_regexp pkgname_ptn backup_pkg pkgpath
+       local pkgname dstdir origin backup_pkg_old pkgname_ptn backup_pkg dbpath pkgpath origin_regexp
        pkgname=$1
        dstdir=$2
        rm -rf "${TMPDIR}"/package.tmp
@@ -808,6 +858,9 @@ pkgsys_create_backup_pkg ()
                message_echo "WARNING: Failed to create backup package for $pkgname." >&2
                return 1
        fi
+       dbpath=${DBDIR}/requires/$origin
+       [ -d "$dbpath" ] || dbpath=${DBDIR}/initial/$origin
+       pkg_info_qL > $dbpath/previously_installed_files
        [ -d "$dstdir" ] || mkdir -p "$dstdir"
        mv "${TMPDIR}/package.tmp/$backup_pkg" "$dstdir"
        pkgpath=$dstdir/$backup_pkg
@@ -847,7 +900,7 @@ pkgsys_delete_backup_pkg ()
 # ============= Get an existing package archive path for a port origin =============
 pkgsys_get_backup_pkg ()
 {
-       local origin origin_regexp
+       local origin tmpnewest origin_regexp
        origin=$1
        tmpnewest=${TMPDIR}/pkgsys_get_backup_pkg::newest
        origin_regexp=`str_escape_regexp "$origin"`
@@ -863,6 +916,16 @@ pkgsys_get_backup_pkg ()
        cat "$tmpnewest" 2> /dev/null
 }
 
+# ============= Get a file list to be restored by the current backup package for a port origin =============
+pkgsys_get_restored_files_by_backup_pkg ()
+{
+       local origin dbpath
+       origin=$1
+       dbpath=${DBDIR}/requires/$origin
+       [ -d "$dbpath" ] || dbpath=${DBDIR}/initial/$origin
+       cat "$dbpath/previously_installed_files" 2> /dev/null || :
+}
+
 # ============= Get a package name from a package archive file name =============
 pkgsys_pkgarc_to_pkgname ()
 {
@@ -898,7 +961,7 @@ pkgsys_eval_ports_glob_even_if_nonexistent ()
        glob_pattern=$1
        {
                pkgsys_eval_ports_glob "$glob_pattern" 2> /dev/null || :
-               echo "$glob_pattern" | grep '^[a-z][a-z]*/[a-zA-Z0-9_+-][a-zA-Z0-9_+-]*$' || :
+               echo "$glob_pattern" | grep '^[a-z][a-z]*/[a-zA-Z0-9_.+-][a-zA-Z0-9_.+-]*$' || :
        } | grep -v -e '^$' | sort -u
 }
 
@@ -1003,15 +1066,13 @@ pkgsys_sanitychk_pkgcontents ()
        _is_reinstall_encouraged=no
        while [ $iline -le $nlines ]
        do
-               src=`sed -n ${iline}p "$tmp_sanity"`
+               filename=`sed -n ${iline}p "$tmp_sanity"`
                iline=$(($iline+1))
-               filename=`echo "$src" | cut -d ' ' -f 1`
-               icol=2
-               until [ -e "$filename" -o "$filename" = "$src" ]
-               do
-                       filename="$filename "`echo "$src" | cut -d ' ' -f $icol`
-               done
-               [ -e "$filename" ] || continue
+               if [ ! -e "$filename" ]
+               then
+                       _is_reinstall_encouraged=yes
+                       break
+               fi
                if expr "$filename" : '.*/include/.*' > /dev/null
                then
                        _is_reinstall_encouraged=yes