#!/bin/sh -e # ================================================================================== # portsreinstall main script # Copyright (C) 2010-2012 Mamoru Sakaue, MwGhennndo, All Rights Reserved. # This software is distributed under the 2-Clause BSD License. # ================================================================================== # ================================================ # ================ PREPARATION =================== # ================================================ APPNAME=`basename "$0"` MYVERSION=1.1.0+toward_2.0.0_20120811170759 PREFIX=${PREFIX:-/usr/local} CONFFILE=${PREFIX}/etc/${APPNAME}.conf DBDIR=/var/tmp/${APPNAME}.db PKGTOOLSCONF=${PREFIX}/etc/pkgtools.conf # ============= Creation of temporary work directories ============= terminate_process () { } warn_update_ports () { } { until TMPDIR=`mktemp -dq /tmp/"${APPNAME}".XXXXXX 2> /dev/null` ; do : ; done ; } trap 'errno=$?; warn_update_ports; terminate_process; rm -r'`[ \`uname -s\` = FreeBSD ] && echo -n P`' "${TMPDIR}" 2> /dev/null; [ $errno -gt 0 -a $errno -ne 130 ] && echo "(Error exit by $errno)" >&2; exit $errno' 0 1 2 3 9 15 17 18 # ============= Save arguments for updated restart ============= restart_command () { echo -n "exec `echo "$0" | sed -E 's/(.)/\\\\\\1/g'`" while [ $# -ge 1 ] do echo -n " `echo "$1" | sed -E 's/(.)/\\\\\\1/g'`" shift done } restart_command "$@" > ${TMPDIR}/restart_command.sh # ============= Option check ============= help_mode=0 option_err=0 target_dependent_ports= target_required_ports= target_dependent_ports_form2= target_required_ports_form2= taboo_ports= taboo_ports_form2= load_pkgtoolsconf=undef show_version=no avoid_vulner=no skip_unchanged=no keep_distfiles=no renew_options=no supress_self_upadte=no supress_obsolete_db_clean=no while : do if [ "$1" = "-h" ] then help_mode=1 shift elif [ "$1" = "-H" ] then help_mode=2 shift elif [ "$1" = "-t" ] then target_dependent_ports=$target_dependent_ports,$2 shift 2 elif [ "$1" = "-T" ] then target_required_ports=$target_required_ports,$2 shift 2 elif [ "$1" = "-r" ] then target_dependent_ports_form2="$target_dependent_ports_form2 $2" shift 2 elif [ "$1" = "-R" ] then target_required_ports_form2="$target_required_ports_form2 $2" shift 2 elif [ "$1" = "-x" ] then taboo_ports=$taboo_ports,$2 shift 2 elif [ "$1" = "-X" ] then taboo_ports_form2="$taboo_ports_form2 $2" shift 2 elif [ "$1" = "-p" ] then load_pkgtoolsconf=default shift elif [ "$1" = "-P" ] then load_pkgtoolsconf=override shift elif [ "$1" = "-Q" ] then load_pkgtoolsconf=no shift elif [ "$1" = "-V" ] then show_version=yes shift elif [ "$1" = "-s" ] then avoid_vulner=yes shift elif [ "$1" = "-q" ] then skip_unchanged=yes shift elif [ "$1" = "-d" ] then keep_distfiles=yes shift elif [ "$1" = "-N" ] then renew_options=yes shift elif [ "$1" = "-k" ] then supress_self_upadte=yes shift elif [ "$1" = "-c" ] then supress_obsolete_db_clean=yes shift else break fi done # if [ $# -gt 0 ] # then # option_err=1 # fi credit () { echo "${APPNAME} version ${MYVERSION}" echo " -- Ports upgrading utility for massive forced reinstallation" echo " -- And for those who are pursuing the perfect packages environment" echo "Copyright (C) 2010 - 2012 Mamoru Sakaue, MwGhennndo, All Rights Reserved." echo "Email: " echo "Homepage: " } # Usage if [ $help_mode -eq 1 -o $option_err -eq 1 ] then echo "USAGE: ${APPNAME} [OPTIONS] [command]" echo echo "[OPTIONS]" echo " -h : Show this short help." echo " -H : Show long help." echo " -V : Show the current version." echo " -t glob1[,glob2,...] : Reinstall only target ports and their dependents." echo " -r glob : Reinstall only the target port and their dependents." echo " -T glob1[,glob2,...] : Reinstall only target ports and their requirements." echo " -R glob : Reinstall only target ports and their requirements." echo " -x glob1[,glob2,...] : Set the port glob(s) to be taboo." echo " -X glob : Set a port glob to be taboo." echo " -p : Import settings from pkgtools.conf(5) as the primary if exists (default)." echo " -P : Import settings from pkgtools.conf(5) as the secondary if exists." echo " -Q : Ignore pkgtools.conf(5) even if it exists." echo " -s : Build of vulnerable ports are avoided by triggering errors." echo " -q : Ports whose all requirements and themselves are not new are skipped." echo " -d : Do not clean up obsolete or unused distfiles." echo " -N : Renew option settings (only for redo command)." echo " -k : Keep ${APPNAME} itself untouched." echo " -c : Suppress cleaning the temporal database even if its obsolete." echo echo "[ARGUMENTS]" echo " command: do (default) | prepare | redo | clean | ok add globs..." echo " | ok del globs... | taboo add globs... | taboo del globs..." echo " | save [dir] | load path" echo " | show todo | show done | show resolved | show failure | show taboo" echo " | show deleted | show requirements glob... | show dependents glob..." echo echo "[DESCRIPTIONS]" echo " This utility is an alternative to portupgrade(1) and portmaster(8), and" echo "designed to be suitable for reinstallation of all packages after major version" echo "upgrade of the system or very long absence of ports upgrade." echo " Usually, you can execute with no option nor argument. If portupgrade(1) is" echo "installed, compatibility with it is taken into account by importing" echo "pkgtools.conf(5) and rebuilding the package database." exit $option_err elif [ $help_mode -eq 2 ] then credit echo echo "USAGE: ${APPNAME} [OPTIONS] [command]" echo echo "[OPTIONS]" echo " -h : Show short help." echo " -H : Show this long help." echo " -V : Show the current version." echo " -t glob1[,glob2,...] : Reinstall only target ports and their dependents." echo " Target ports which are not installed yet are newly installed." echo " Target ports which are obsolete are deinstalled." echo " This option can be given multiply." echo " This option is recognized in the first 'do' or 'redo' runs, and" echo " transferred to the restarted runs." echo " Dependency relations are inspected for all installed packages as well." echo " Combination with options '-T', '-r' and '-R' is available." echo " -r glob : Reinstall only the target port and their dependents." echo " This option can be given multiply." echo " The difference from '-t' is that only one port glob can be specified." echo " Thus a package name with commas is available." echo " Combination with options '-t', '-T' and '-R' is available." echo " -T glob1[,glob2,...] : Reinstall only target ports and their requirements." echo " Target ports which are not installed yet are newly installed." echo " Target ports which are obsolete are deinstalled." echo " This option can be given multiply." echo " This option is recognized in the first 'do' or 'redo' runs, and" echo " transferred to the restarted runs." echo " Dependency relations are inspected for all installed packages as well." echo " Combination with options '-t', '-r' and '-R' is available." echo " -R glob : Reinstall only target ports and their requirements." echo " This option can be given multiply." echo " The difference from '-T' is that only one port glob can be specified." echo " Thus a package name with commas is available." echo " Combination with options '-t', '-r' and '-T' is available." echo " -x glob1[,glob2,...] : Set the port glob(s) to be taboo." echo " This option registers a port to be ignored as taboo." echo " This option can be given multiply." echo " Mainly for ports that show terrible behaviors resulting in system crash." echo " This option is recognized in the first 'do' or 'redo' runs, and" echo " transferred to the restarted runs." echo " Alternatively you can do the same thing by 'taboo' command." echo " If you want to register permanently, set to the configuration file." echo " Combination with options '-X' is available." echo " -X glob : Set a port glob to be taboo." echo " This option can be given multiply." echo " The difference from '-x' is that only one port glob can be specified." echo " Thus a package name with commas is available." echo " Combination with options '-x' is available." echo " -p : Import settings from pkgtools.conf(5) as the primary." echo " For duplicated configurations, values in pkgtools.conf are applied" echo " first and then those in ${APPNAME}.conf are." echo " This option is ignored when you restart a terminated process." echo " (Default; ignored if ports-mgmt/portupgrade* is not installed)" echo " -P : Import settings from pkgtools.conf(5) as the secondary." echo " For duplicated configurations, values in ${APPNAME}.conf are applied" echo " first and then those in pkgtools.conf are." echo " This option is ignored when you restart a terminated process." echo " (Ignored if ports-mgmt/portupgrade* is not installed)" echo " -Q : Ignore pkgtools.conf(5) even if it exists." echo " This option is ignored when you restart a terminated process." echo " -s : Build of vulnerable ports are avoided by triggering errors." echo " Note that already installed vulnerable packages are untouched." echo " If you desire to uninstall them, do it manually." echo " This specification will be reasonable for the practical situations." echo " This option is fixed at the first 'do' run, and transferred to the" echo " following runs." echo " If you want to continue the reinstallation process by resetting" echo " this option, execute by 'redo' command with '-N' option." echo " -q : Ports whose all requirements and themselves are not new are skipped." echo " This option is safe and useful when the all of the major version of" echo " the system, configuration options of each ports, pkgtools.conf(5)," echo " ${APPNAME}.conf are unchanged." echo " This option is fixed at the first 'do' run, and transferred to the" echo " following runs." echo " If you want to continue the reinstallation process by resetting" echo " this option, execute by 'redo' command with '-N' option." echo " -d : Do not clean up obsolete or unused distfiles." echo " This option is fixed at the first 'do' run, and transferred to the" echo " following runs." echo " If you want to continue the reinstallation process by resetting" echo " this option, execute by 'redo' command with '-N' option." echo " -N : Renew option settings." echo " This option is effective only with 'redo' command." echo " Option settings for '-s', '-q' and '-d' are reset according to" echo " the simultaneously given ones." echo " -k : Keep ${APPNAME} itself untouched." echo " This option supresses update, deinstallation and reinstallation of" echo " the currently installed ${APPNAME}." echo " -c : Suppress cleaning the temporal database even if its obsolete." echo " By default, the temporal database is automatically cleaned up if" echo " it is older than the ports tree or ${APPNAME} itself is to be" echo " updated." echo " This option replace this behavior with termination with warnings." echo " This option should not be used unless the user has special" echo " intentions." echo echo "[ARGUMENTS]" echo " command: (For optional operations or confirmation)" echo " {one of the following commands}" echo " do : full execution (default)" echo " prepare : stop before the actual operations to the ports/packages" echo " redo : execute again for failed ports and their dependents" echo " clean : clean up the temporal database" echo " ok add glob1 [glob2 ...] : register manually resolved ports" echo " ok del glob1 [glob2 ...] : deregister manually resolved ports" echo " taboo add glob1 [glob2 ...]: register taboo ports" echo " taboo del glob1 [glob2 ...]: deregister taboo ports" echo " save [dir] : save the current temporal database as a .tar.gz archive" echo " load path : load a temporal database archive" echo " show [args] : show the list of ports to be reinstalled" echo " todo : ports to be reinstalled (default)" echo " done : already reinstalled ports" echo " resolved : manually reinstalled ports" echo " failure : failed ports" echo " taboo : taboo ports" echo " deleted : obsolete ports to be or have been deleted" echo " requirements glob1 [glob2 ...] : ports required by matching ports" echo " dependents glob1 [glob2 ...] : ports depending on matching ports" echo echo "[CONFIGURATION FILE]" echo " ${CONFFILE}" echo echo "[NOTATIONS]" echo " The 'glob' is either of pkgname_glob or portorigin_glob explained in the man" echo "page of portsdb(1) and ports_glob(1): for example, zip-3.0, zip-*, and archivers" echo "/zip. Here the wild card symbol '*' must be quoted or escaped. In evaluation of" echo "globs, ports_glob(1) is used if it is installed for better compatibility," echo "otherwise an alternative internal function is used." echo echo "[DESCRIPTIONS]" echo " This utility realizes smart reinstallation of a large number of ports by" echo "allowing you to run when when the machine is free and terminate when busy." echo " Concretely, you can stop the process by CTRL+C anytime and restart quickly." echo " This functionality allows you, for example, to start this utility before lunch," echo "terminate after lunch, restart before dinner, terminate after dinner, restart" echo "before going to bed, terminate after breakfast, restart before lunch, ..., and" echo "finally complete." echo echo " The policy of this utility is to complete the job by the most automatic and" echo "finally successful way even if it will take a long time in total." echo " All missing build- and run-time dependencies are newly installed if any." echo " All reinstallation processes are tried to be proceeded forcibly by ignoring" echo "errors or vulnerabilities as possible." echo " This utility pursues the consistency of the dependency relations in the latest" echo "version of the ports tree by on-the-fly entire reconstruction of the relations" echo "while portupgrade(1) and portmaster(8) believe the existing relations of the" echo "installed packages to reduce the total work time as much as possible." echo echo " In the simplest case, all a user has to do toward complete reinstallation is" echo "execute this utility without any arguments (corresponding to 'do' command). If" echo "the run completes with notations on failures for any ports, after resolving the" echo "errors manually, register the resolved ports by executing this utility with" echo "'ok add' command and then execute with 'redo' command. This task is continued" echo "until successful completion." echo echo " The algorithms of this utility are customized for massive reinstallation to" echo "be invoked after major upgrade of the system where rebuild of all third-party" echo "applications are encouraged before cleaning up obsolete system libraries." echo " Nevertheless, the all functionalities of this utility is applicable to any" echo "situations where complete reinstallation of the all or parts of ports is" echo "preferred, e.g., when you have been lazy in upgrade of ports for too long time." echo " For the usual purposes of upgrading packages installed by ports, you are" echo "recommended to use ports-mgmt/portupgrade or ports-mgmt/portmaster instead." echo echo " If this utility has been installed by ports/packages and the corresponding port" echo "is renewed, update of this utility is carried out first and then the following" echo "processes are continued by the new version after cleaning up the temporal" echo "database." echo echo " The scheme of this utility is divided into the temporal database construction" echo "phase and the reinstallation phase." echo " Execution by 'portsreinstall prepare' procedes to the end the first phase, and" echo "that without any argument procedes to the end of the second phase." echo " Each of these two major phases is divided into minor phases." echo " When the previously terminated process is restarted, completed minor phases are" echo "skipped.">&2 echo echo " The massive minor phases belong to 'collecting dependencies of installed/" echo "missing packages', 'ordering dependencies' for the first major phase and" echo "'reinstallation' 'package database update' for the second." echo " Most of them are divided into more minor phases except for 'package database" echo "update'." echo echo " When option(s) '-t', '-r', '-T' or '-R' is/are given in the first run of 'do'" echo "or 'redo' commands, only the targets and their required or dependent ports are" echo "reinstalled (or deleted if obsolete)." echo " This specification is effective until the completion of the run." echo " Run by 'redo' command without the options inherits the previous settings." echo " Meanwhile, run by 'redo' command with the options resets the previous settings," echo "and inspects the dependencies again if new ports are to be installed." echo echo " The user is encouraged to run this utility under script(1) so as to record all" echo "logs in order to resolve problems that you may (rather 'will', practically)" echo "encounter." echo " The solutions depend on the individual cases." echo " If the problem will be resolved by reconfiguration of the port option, execute" echo "'make config' at the corresponding port directory, and then restart this" echo "utility." echo " If the problem will be resolved by manual fetch of tarballs, do it and then" echo "restart this utility." echo " If the problem will be resolved by deleting a concerned package, do it by" echo "pkg_delete(1) with '-f' option or execute 'make deinstall' at the corresponding" echo "port directory, execute '${APPNAME} ok add \$glob' where '\$glob' is the ports" echo "glob of the concerned port, and then restart this utility." echo " If the problem will be resolved by manual reinstallation using pkg_add(1) or so" echo "on, do it and execute '${APPNAME} ok add \$glob' where '\$glob' is the ports" echo "glob of the concerned port, and then restart this utility by 'redo' command." echo echo " If you are familiar to the mechanism of Ports Collections system, in order to" echo "minimize package conflictions, it may be a good idea to delete packages which " echo "you don't think necessary before starting to use this utility." echo "Don't be afraid to delete necessary dependencies because all required ports are" echo "automatically installed." echo echo " If you run into confusion, it may be a good idea to clean up the temporal" echo "database by executing '${APPNAME} clean' and start again from the first." exit fi if [ $show_version = yes ] then echo "${APPNAME} version ${MYVERSION}" exit fi command=$1 [ -z "$command" ] || shift # ==================================================== # ================== FUNCTIONS ======================= # ==================================================== PORTSDIR=${PORTSDIR:-/usr/ports} PORTS_MOVED_DB=${PORTSDIR}/MOVED PORTS_INDEX_DB=${PORTSDIR}/INDEX-`uname -r | cut -d . -f 1` str_escape_regexp_filter () { sed 's/\\/\\\\/g;s/|/\\|/g;s/\./\\./g;s|/|\\/|g;s/\[/\\[/g;s/\]/\\]/g;s/[(]/\\(/g;s/[)]/\\)/g;s/\+/\\+/g;s/\?/\\?/g;s/\*/\\*/g' } convert_glob_to_regexp_pattern () { sed 's/\+/\\+/g;s/\./\\./g;s|/|\\/|g;s/\*/.*/g;s/\?/g./;s/\[\!/[^/g;s/^/^/;s/$/$/' } convert_portsglob_to_regexp_pattern () { local glob_pattern regexp_pattern glob_pattern=$1 if expr "$glob_pattern" : '^:' > /dev/null 2>&1 then regexp_pattern=`echo $glob_pattern | sed 's/^://'` else regexp_pattern=`echo $glob_pattern | convert_glob_to_regexp_pattern` fi echo $regexp_pattern } if which -s ports_glob then : else ports_glob () { local glob index glob=`convert_portsglob_to_regexp_pattern "$1"` [ -f "${DBDIR}/ports_glob:pkg.lst" ] || cut -d \| -f 1 "${PORTS_INDEX_DB}" > ${DBDIR}/ports_glob:pkg.lst [ -f "${DBDIR}/ports_glob:origin.lst" ] || cut -d \| -f 2 "${PORTS_INDEX_DB}" | sed -E "s/^`str_escape_regexp "${PORTSDIR}"`\///" > ${DBDIR}/ports_glob:origin.lst if expr "$glob" : '[^\/][^\/]*\/[^\/][^\/]*$' 2> /dev/null > /dev/null then grep -E "$glob" "${DBDIR}/ports_glob:origin.lst" > ${TMPDIR}/ports_glob:matched pkg_info -aoq | grep -E "$glob" >> ${TMPDIR}/ports_glob:matched else grep -n -E "$glob" "${DBDIR}/ports_glob:pkg.lst" | cut -d : -f 1 | while read index do sed -n ${index}p "${DBDIR}/ports_glob:origin.lst" done > ${TMPDIR}/ports_glob:matched pkg_info -oqx "$glob" >> ${TMPDIR}/ports_glob:matched fi sort -u "${TMPDIR}"/ports_glob:matched } fi str_escape_regexp () { echo $* | str_escape_regexp_filter } rm_a_line () { local item dstpath pattern item=$1 dstpath=$2 pattern=`str_escape_regexp $item` grep -v -E "^$pattern$" "$dstpath" 2> /dev/null > ${TMPDIR}/rm_a_line || : mv "${TMPDIR}/rm_a_line" "$dstpath" } add_a_line_if_new () { local item dstpath pattern item=$1 dstpath=$2 pattern=`str_escape_regexp $item` grep -m 1 -E "^$pattern$" "$dstpath" 2> /dev/null > /dev/null || echo $item >> $dstpath } record_success () { local origin clean recurse origin=$1 str_escape_regexp_filter < ${DBDIR}/failed.list | sed "s|^|^|; s|$|$|" > ${TMPDIR}/record_success.grep_failed.list.tmp if [ `grep -m 1 -E -f "${TMPDIR}/record_success.grep_failed.list.tmp" "${DBDIR}/requires/$origin/requires" | wc -l` -eq 0 ] then add_a_line_if_new "$origin" "${DBDIR}/success.list" rm_a_line "$origin" "${DBDIR}/success_but_dependencies_failed.list" [ ! -e "${DBDIR}/requires/$origin/necessary_update" ] || mv "${DBDIR}/requires/$origin/necessary_update" "${DBDIR}/requires/$origin/necessary_update_completed" else rm_a_line "$origin" "${DBDIR}/success.list" add_a_line_if_new "$origin" "${DBDIR}/success_but_dependencies_failed.list" fi rm_a_line "$origin" "${DBDIR}/failed.list" rm -f "${DBDIR}/requires/$origin/note_failtre" } record_failure () { local origin clean origin=$1 clean=$2 add_a_line_if_new "$origin" "${DBDIR}/failed.list" rm_a_line "$origin" "${DBDIR}/success.list" rm_a_line "$origin" "${DBDIR}/success_but_dependencies_failed.list" if [ -z "$clean" -o "@$clean" = @clean ] then echo "*** Trying to clean the failed build... (Ignore failures)" env ${MAKE_ENVS} make clean ${MAKE_ARGS} || : fi echo "*** Skipping this port and proceeding to the next one forcibly..." echo } add_a_line_to_files_if_new () { local item item=$1 while read filepath do add_a_line_if_new "$item" "$filepath" done } add_lines_if_new () { local filepath origin advance filepath=$1 advance=$2 while read origin do grep -m 1 -E "^`str_escape_regexp $origin`$" "$filepath" 2> /dev/null > /dev/null || echo $origin done > ${TMPDIR}/add_lines_if_new if [ "@$advance" = @advance ] then mv "$filepath" ${TMPDIR}/add_lines_if_new.bak cat "${TMPDIR}/add_lines_if_new" "${TMPDIR}/add_lines_if_new.bak" > $filepath else cat "${TMPDIR}/add_lines_if_new" >> $filepath fi } register_globs () { local globlist listpath mode dirpath origin globlist1=$1 globlist2=$2 listpath=$3 mode=$4 dirpath=`dirname "$listpath"` echo "`echo "$globlist1" | sed 's/,/ /g'`" "$globlist2" | sed -E 's/ +/\ /g' | grep -v '^$' | while read glob do if expr "@$glob" : '^@[^/][^/]*/[^/][^/]*$' > /dev/null 2> /dev/null then [ ! -d "${PORTSDIR}/$glob" ] || { echo $glob; continue; } fi ports_glob "$glob" > ${TMPDIR}/register_globs:ports_glob origin=`ports_glob "$glob"` [ `cat "${TMPDIR}"/register_globs:ports_glob | wc -l` -ge 1 ] || \ { echo "WARNING: No matching ports/package glob [$glob]" >&2 continue } cat "${TMPDIR}"/register_globs:ports_glob done | while read origin do [ -d "$dirpath" ] || mkdir -p "$dirpath" if [ "@$mode" = @remove ] then rm_a_line "$origin" "$listpath" elif grep -m 1 -E "^`str_escape_regexp $origin`$" "$listpath" > /dev/null 2> /dev/null then : else echo $origin >> "$listpath" fi done } expand_glob_pattern_to_origins () { local glob_pattern include_nonexistent regexp_pattern glob_pattern=$1 include_nonexistent=$2 { ports_glob "$glob_pattern" 2> /dev/null || : if expr "$glob_pattern" : '^[a-z][a-z]*\/[a-zA-Z0-9_+-][a-zA-Z0-9_+-]*$' > /dev/null 2>&1 then if [ "x$include_nonexistent" = xyes ] then echo $glob_pattern else pkg_info -qO "$glob_pattern" | xargs pkg_info -qo fi elif expr "$glob_pattern" : '^[a-zA-Z0-9.,_+-][a-zA-Z0-9.,_+-]*$' > /dev/null 2>&1 then pkg_info -qo "$glob_pattern" 2> /dev/null || : else regexp_pattern=`convert_portsglob_to_regexp_pattern "$glob_pattern"` if expr "$glob_pattern" : '.*\/' > /dev/null 2>&1 then pkg_info -aqo | grep -E "$regexp_pattern" 2> /dev/null || : else pkg_info -qoX "$regexp_pattern" 2> /dev/null || : fi fi } | grep -v -e '^$' | sort -u } build_conflist_target_list () { local section section=$1 if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_${section}" ] then echo "-- ${section}_*" set | grep -e "^_CONF_${section}_" | cut -d = -f 1 | while read var do eval glob_pattern=\${$var} expand_glob_pattern_to_origins "$glob_pattern" done > ${DBDIR}/${section}_PORTS.conflist touch "${DBDIR}/COMPLETE_REFLECTCONF_${section}" fi } build_conflist_target_val_pair () { local section tag_target tag_val section=$1 tag_target=$2 tag_val=$3 if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_${section}" ] then echo "-- ${section}_*" set | grep -e "^_CONF_${section}_${tag_target}_" | cut -d = -f 1 | while read var do eval glob_pattern=\${$var} eval val=\$\{`echo $var | sed "s/^_CONF_${section}_${tag_target}_/_CONF_${section}_${tag_val}_/"`\} expand_glob_pattern_to_origins "$glob_pattern" | while read origin do path=${DBDIR}/requires_conflist/$origin [ -d "$path" ] || mkdir -p "$path" echo $val > $path/${section}.conflist done done touch "${DBDIR}/COMPLETE_REFLECTCONF_${section}" fi } add_to_obsolete_if_not_yet () { local origin pkgtag origin=$1 add_a_line_if_new "$origin" "${DBDIR}/moved_or_lost.list" if [ ! -e "${DBDIR}/obsolete/$origin/pkgtag" ] then [ -d "${DBDIR}/obsolete/$origin" ] || mkdir -p "${DBDIR}/obsolete/$origin" pkgtag=`pkg_info -qO "$origin"` [ -n "$pkgtag" ] || pkgtag='[not installed]' echo $pkgtag > ${DBDIR}/obsolete/$origin/pkgtag fi } convert_origin_if_moved () { local origin_src recursedb_in recursedb iline_db date_moved why_moved # input/output origin origin_src=$1 recursedb_in=$2 recursedb=${recursedb_in:-${PORTS_MOVED_DB}} [ ! -d "${PORTSDIR}/$origin" ] || return 0 add_to_obsolete_if_not_yet "$origin" grep -n -m 1 -E "^`str_escape_regexp $origin`\|" "$recursedb" 2> /dev/null > ${TMPDIR}/moved.info || : if [ `cat "${TMPDIR}/moved.info" | wc -l` -eq 0 ] then if [ -n "$recursedb_in" ] then echo "${DEPTH_INDEX} ===> Disappeared port (MOVED broken?)" else echo "${DEPTH_INDEX} ===> Nonexistent port (your original?)" fi [ -z "$origin_src" ] || add_to_obsolete_if_not_yet "$origin_src" return 1 else iline_db=`cut -d : -f 1 "${TMPDIR}/moved.info"` sed 1,${iline_db}d "${PORTS_MOVED_DB}" > ${TMPDIR}/MOVED.DB origin=`sed -E 's/^[0-9]+://' "${TMPDIR}/moved.info" | cut -d '|' -f 2 || :` date_moved=`cut -d '|' -f 3 "${TMPDIR}/moved.info" || :` why_moved=`cut -d '|' -f 4 "${TMPDIR}/moved.info" || :` if [ -n "$origin" ] then echo "${DEPTH_INDEX} ===> Moved to $origin at $date_moved because \"$why_moved\"" convert_origin_if_moved "$origin_src" "${TMPDIR}/MOVED.DB" || return 1 else echo "${DEPTH_INDEX} ===> Deleted at $date_moved because \"$why_moved\"" [ -n "$origin_src" ] || return 1 origin=$origin_src echo "${DEPTH_INDEX} ===> Going back to the original port $origin_src" convert_origin_if_moved || return 1 fi fi } inspect_dependencies () { local origin origin_orig pkg origin_id origin_src port_exists origin_dependency DEPTH_INDEX_orig nlines iline is_suppressed origin=$1 origin_orig=$origin DEPTH_INDEX_orig=${DEPTH_INDEX} DEPTH_INDEX="${DEPTH_INDEX}--" echo "${DEPTH_INDEX} $origin" origin_id=`echo $origin | tr / :` pkg=`pkg_info -qO "$origin"` if [ -n "$pkg" ] then target_dir=${DBDIR}/initial/$origin [ -d "$target_dir" ] || mkdir -p "$target_dir" echo $pkg > $target_dir/installed_version pkg_info -qr "$pkg" | grep '^@pkgdep ' | sed 's/^@pkgdep[[:space:]]*//' | while read requirement do pkg_info -e "$requirement" || continue pkg_info -qo "$requirement" >> $target_dir/requires done pkg_info -qR "$pkg" | grep -v '^$' | while read dependent do pkg_info -e "$dependent" || continue pkg_info -qo "$dependent" >> $target_dir/dependents done fi if [ $supress_self_upadte = yes -a `expr "$pkg" : "^${APPNAME}-[0-9].*"` -gt 0 ] then is_supressed=yes else is_supressed=no fi origin_src= if [ `echo $origin | grep -m 1 -E -f "${DBDIR}/REPLACE.grep_from_pattern.conflist" | wc -l` -eq 1 ] then origin_src=$origin origin=`echo $origin_src | sed -E -f "${DBDIR}/REPLACE.replace_pattern.conflist"` if [ $is_supressed = yes ] then if [ -n "$origin" ] then echo "${DEPTH_INDEX} ===> Replaced with $origin by user configuration (ignored)" else echo "${DEPTH_INDEX} ===> Deleted by user configuration (ignored)" fi else add_to_obsolete_if_not_yet "$origin_src" if [ -n "$origin" ] then add_a_line_if_new "$origin" "${DBDIR}/replaced_target.inspected.list" echo "${DEPTH_INDEX} ===> Replaced with $origin by user configuration" else echo "${DEPTH_INDEX} ===> Deleted by user configuration" fi fi fi if [ -n "$origin" ] then if convert_origin_if_moved "$origin_src" '' then port_exists=yes else port_exists=no fi if [ $port_exists = yes ] then rm_a_line "$origin" "${DBDIR}/moved_or_lost.list" cd "${PORTSDIR}/$origin" target_dir=${DBDIR}/requires/$origin [ -d "$target_dir/status" ] || mkdir -p "$target_dir/status" [ $is_supressed = no ] || touch "$target_dir/SUPPRESSED" if [ -d "${DBDIR}/requires_conflist/$origin" ] then cp -R "${DBDIR}/requires_conflist/$origin/"* "$target_dir/" > /dev/null 2> /dev/null || : fi MAKE_ARGS="FORCE_PKG_REGISTER=yes DISABLE_VULNERABILITIES=yes `cat "$target_dir/MARG.conflist" 2> /dev/null || :`" MAKE_ENVS=`cat "$target_dir/MENV.conflist" 2> /dev/null || :` env ${MAKE_ENVS} make config-conditional ${MAKE_ARGS} pkg=`pkg_info -qO "$origin"` [ -z "$pkg" ] || echo $pkg > $target_dir/installed_version pkg_new=`(cd "${PORTSDIR}/$origin" && env ${MAKE_ENVS} make package-name ${MAKE_ARGS})` pkgtag=$pkg [ -n "$pkgtag" ] || pkgtag=$pkg_new if [ -z "$pkgtag" ] then pkgtag='?' elif [ "z$pkg" != "z$pkg_new" ] then echo $pkg_new > $target_dir/new_version if [ -n "$pkg" ] then pkgtag="$pkg => $pkg_new" else pkgtag="[new] $pkg_new" fi fi echo $pkgtag > $target_dir/pkgtag env ${MAKE_ENVS} make all-depends-list ${MAKE_ARGS} | sed "s|^${PORTSDIR}/||" > "$target_dir/requires" || : grep -E -f "${DBDIR}/REPLACE.grep_from_pattern.conflist" "$target_dir/requires" | grep -v -E "^`str_escape_regexp $origin`$" > ${TMPDIR}/replaced_target.tmp || : mv "$target_dir/requires" "$target_dir/requires.orig" sed -E -f "${DBDIR}/REPLACE.replace_pattern.conflist" "$target_dir/requires.orig" | grep -v '^$' > $target_dir/requires || : add_lines_if_new "${DBDIR}/replaced_target.list" < ${TMPDIR}/replaced_target.tmp grep -v -E -f "${DBDIR}/installed_ports.grep_pattern" "$target_dir/requires" > ${TMPDIR}/missing.$origin_id || : nlines=`cat "${TMPDIR}/missing.$origin_id" | wc -l` iline=1 while [ $iline -le $nlines ] do origin_dependency=`sed -n ${iline}p "${TMPDIR}/missing.$origin_id"` iline=$(($iline+1)) if grep -m 1 -E "^`str_escape_regexp $origin_dependency`$" "${DBDIR}/target.inspected.list" > /dev/null 2> /dev/null then : else inspect_dependencies "$origin_dependency" fi done rm "${TMPDIR}/missing.$origin_id" env ${MAKE_ENVS} make fetch-urlall-list ${MAKE_ARGS} | sed -E 's|.*/([^/]+)$|\1|' | sort | uniq >> ${DBDIR}/distfiles.list fi fi [ "$origin_orig" = "$origin" ] || echo "s|^`str_escape_regexp $origin_orig`$|$origin|" >> ${DBDIR}/REPLACE.complete_replace_pattern.tmp add_a_line_if_new "$origin" "${DBDIR}/target.inspected.list" rm_a_line "$origin" "${DBDIR}/target_ports.remain" if [ -n "$origin_src" ] then add_a_line_if_new "$origin_src" "${DBDIR}/target.inspected.list" rm_a_line "$origin_src" "${DBDIR}/target_ports.remain" fi echo "${DEPTH_INDEX} ===> ok" DEPTH_INDEX=${DEPTH_INDEX_orig} } cmt_fail_reinst () { local origin origin=$1 echo "*** Giving up for this port $origin and proceeding to the next one forcibly..." echo } timestamp () { env LANG= date } warn_update_ports () { [ ${_STATUS_DB_OBSOLETE} = yes ] || return 0 echo "WARNING: The Ports tree was updated after construction of the temporal database for ${APPNAME}." >&2 echo " You should consider executing " >&2 echo " ${APPNAME} clean" >&2 echo " to reset the temporal database unless you have special purposes." >&2 } linear_list () { echo $* | sed -E 's/^ +//; s/ +$//; s/ +/, /; s/, ([^ ]+)$/ and \1/' } chk_privilege () { [ `id -u` -eq 0 ] || { echo "ERROR: Only the superuser can execute this command." >&2; exit 1; } } combine_lists () { local src_conf src_opt dst src_conf=$1 src_opt=$2 dst=$3 cat "${DBDIR}/$src_conf" "${DBDIR}/$src_opt" 2> /dev/null | sort | uniq > ${DBDIR}/$dst || : } show_list_failure () { [ -e "${DBDIR}"/failed.list ] || return 0 while read origin do note=`cat "${DBDIR}/requires/$origin/note_failtre"` if grep -m 1 -E "^`str_escape_regexp $origin`$" "${DBDIR}/manually_done.list" > /dev/null 2>&1 then resolved=', resolved' else resolved= fi if [ -e "${DBDIR}/requires/$origin/pkgtag" ] then pkgtag=' ('`cat "${DBDIR}/requires/$origin/pkgtag"`')' else pkgtag= fi echo "$origin$pkgtag (error while [$note]$resolved)" done < ${DBDIR}/failed.list } chk_if_target () { local prefix _is_all _is_target _is_required _is_former_required _is_dependent _is_former_dependent _is_relevant prefix=$1 origin=$2 if [ -e "${DBDIR}/all/$origin/chk_if_target.param" ] then . "${DBDIR}/all/$origin/chk_if_target.param" else _is_all=y _is_target= _is_required= _is_former_required= _is_dependent= _is_former_dependent= _is_relevant=y if [ `cat "${DBDIR}/target_required_ports.specified" 2> /dev/null | wc -l` -gt 0 ] then _is_all= if grep -m 1 -E "^`str_escape_regexp $origin`$" "${DBDIR}/target_required_ports.specified" > /dev/null 2> /dev/null then _is_target=y elif [ -e "${DBDIR}/requires/$origin/dependents.pattern" ] && grep -m 1 -E -f "${DBDIR}/requires/$origin/dependents.pattern" "${DBDIR}/target_required_ports.specified" > /dev/null 2> /dev/null then _is_required=y elif [ -e "${DBDIR}/initial/$origin/dependents.pattern" ] && grep -m 1 -E -f "${DBDIR}/initial/$origin/dependents.pattern" "${DBDIR}/target_required_ports.specified" > /dev/null 2> /dev/null then _is_former_required=y fi fi if [ `cat "${DBDIR}/target_dependent_ports.specified" 2> /dev/null | wc -l` -gt 0 ] then _is_all= if [ -n "${_is_target}" ] || grep -m 1 -E "^`str_escape_regexp $origin`$" "${DBDIR}/target_dependent_ports.specified" > /dev/null 2> /dev/null then _is_target=y elif [ -e "${DBDIR}/requires/$origin/requires.pattern" ] && grep -m 1 -E -f "${DBDIR}/requires/$origin/requires.pattern" "${DBDIR}/target_dependent_ports.specified" > /dev/null 2> /dev/null then _is_dependent=y elif [ -e "${DBDIR}/initial/$origin/requires.pattern" ] && grep -m 1 -E -f "${DBDIR}/initial/$origin/requires.pattern" "${DBDIR}/target_dependent_ports.specified" > /dev/null 2> /dev/null then _is_former_dependent=y fi fi [ -n "${_is_all}${_is_target}${_is_required}${_is_former_required}${_is_dependent}${_is_former_dependent}" ] || _is_relevant= echo _is_all=${_is_all} > ${TMPDIR}/chk_if_target:results echo _is_target=${_is_target} >> ${TMPDIR}/chk_if_target:results echo _is_required=${_is_required} >> ${TMPDIR}/chk_if_target:results echo _is_former_required=${_is_former_required} >> ${TMPDIR}/chk_if_target:results echo _is_dependent=${_is_dependent} >> ${TMPDIR}/chk_if_target:results echo _is_former_dependent=${_is_former_dependent} >> ${TMPDIR}/chk_if_target:results echo _is_relevant=${_is_relevant} >> ${TMPDIR}/chk_if_target:results [ -d "${DBDIR}/all/$origin" ] || mkdir -p "${DBDIR}/all/$origin" mv "${TMPDIR}"/chk_if_target:results "${DBDIR}/all/$origin/chk_if_target.param" fi eval ${prefix}_is_all=\$\{_is_all\} eval ${prefix}_is_target=\$\{_is_target\} eval ${prefix}_is_required=\$\{_is_required\} eval ${prefix}_is_former_required=\$\{_is_former_required\} eval ${prefix}_is_dependent=\$\{_is_dependent\} eval ${prefix}_is_former_dependent=\$\{_is_former_dependent\} eval ${prefix}_is_relevant=\$\{_is_relevant\} } register_globs_only_installed () { local src1 src2 src1=$1 src2=$2 rm -f "${TMPDIR}/register_globs_only_installed:origins" register_globs "$src1" "$src2" "${TMPDIR}/register_globs_only_installed:origins" [ -e "${TMPDIR}/register_globs_only_installed:origins" ] || return 0 while read origin do [ -z `pkg_info -qO "$origin"` ] || echo $origin done < ${TMPDIR}/register_globs_only_installed:origins } # ================================================== # ==================== MAIN ======================== # ================================================== # Title credit echo echo " Don't hesitate to terminate by CTRL+C anytime you feel the system is heavy to" echo "use because you can restart the operation from the terminated point quickly." echo echo "The current time is `timestamp`" echo # Check of conflicting option [ -z "$target_dependent_ports" -o ! -e "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" ] || echo "WARNING: -t option is specified but ignored because we are restarting the previous run." >&2 [ -z "$target_required_ports" -o ! -e "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" ] || echo "WARNING: -T option is specified but ignored because we are restarting the previous run." >&2 [ -z "$target_dependent_ports_form2" -o ! -e "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" ] || echo "WARNING: -r option is specified but ignored because we are restarting the previous run." >&2 [ -z "$target_required_ports_form2" -o ! -e "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" ] || echo "WARNING: -R option is specified but ignored because we are restarting the previous run." >&2 [ "$load_pkgtoolsconf" = undef -o ! -e "${DBDIR}/COMPLETE_IMPORT_PKGTOOLS_CONF" ] || echo "WARNING: -p, -P or -Q option is specified but ignored by following the previous settings." >&2 # Check whether the temporal database is newer than the ports tree if [ "${PORTS_INDEX_DB}" -nt "${DBDIR}"/MYVERSION ] then if [ $supress_obsolete_db_clean = no ] then _STATUS_DB_OBSOLETE=no if [ "z${command}" != zclean ] then echo "INFO: The temporal database is cleaned up because it is older than the ports tree." echo rm -rf "${DBDIR}" fi else _STATUS_DB_OBSOLETE=yes fi else _STATUS_DB_OBSOLETE=no fi # Update portsreinstall itself if it is newer in the ports tree if [ $supress_self_upadte = no -a `id -u` -eq 0 -a \( ! -e "${DBDIR}" -o ${_STATUS_DB_OBSOLETE} = yes \) ] then pkg_info -Ex "${APPNAME}-[0-9].*" > ${TMPDIR}/self_version || : num_self_versions=`cat "${TMPDIR}"/self_version | wc -l` if [ $num_self_versions -gt 1 ] then echo "ERROR: Multiple versions of ${APPNAME} are installed. This is unexpected." >&2 exit 1 elif [ $num_self_versions -eq 1 ] then self_origin=`pkg_info -qo "\`cat \"${TMPDIR}\"/self_version\`"` [ -d "${PORTSDIR}/$self_origin" ] || { echo "ERROR: ${PORTSDIR}/$self_origin does not exist" >&2; exit 1; } self_pkg_current=`cat "${TMPDIR}"/self_version` self_pkg_new=`( cd "${PORTSDIR}/$self_origin" && make package-name )` if [ -n "$self_pkg_new" ] then if [ "$self_pkg_new" != `cat "${TMPDIR}"/self_version` ] then echo "INFO: The ports tree has a new version of ${APPNAME}. It will be updated first." echo "Updating $self_origin ($self_pkg_current => $self_pkg_new)..." echo "Backing up the installed package..." [ -d "${PORTSDIR}"/packages/All ] || mkdir -p "${PORTSDIR}"/packages/All ( cd "${PORTSDIR}"/packages/All/ && pkg_create -b "$self_pkg_current" ) echo "Reinstalling ${APPNAME}..." pkg_delete -f "$self_pkg_current" if ( cd "${PORTSDIR}/$self_origin" && make reinstall ) then ( cd "${PORTSDIR}/$self_origin" && make clean ) if [ $supress_obsolete_db_clean = yes -a -d "${DBDIR}" ] then echo "INFO: Cleaning the temporal database..." rm -rf "${DBDIR}" echo fi echo "INFO: Restarting with the new version..." echo . "${TMPDIR}"/restart_command.sh echo "ERROR: Failed to launch the new version" >&2 exit 1 else echo "WARNING: Reinstallation failed. Restoring the old package..." >&2 ( cd "${PORTSDIR}/$self_origin" && make deinstall ) || : ( cd "${PORTSDIR}/$self_origin" && make clean ) || : pkg_add -f "${PORTSDIR}"/packages/All/"$self_pkg_current.tbz" echo "INFO: Continuing with the old version..." fi fi else echo "WARNING: No port for ${APPNAME} exists in the current ports tree" >&2 fi else echo "INFO: This version of ${APPNAME} has been installed not by ports/packages mechanism." echo "Thus any updates on ${APPNAME} will be ignored." fi fi # Creation of temporal database directory if [ -d "${DBDIR}" ] then DBVERSION=`cat "${DBDIR}"/MYVERSION 2> /dev/null || :` # Reserved for compatibility check else mkdir -p "${DBDIR}" echo ${MYVERSION} > ${DBDIR}/MYVERSION fi # Taboo list given by options register_globs "$taboo_ports" "$taboo_ports_form2" "${DBDIR}/taboo.list" # ------- Commands ------- # Special modes case ${command:-do} in clean) chk_privilege echo "Starting to clean up the temporal database..." rm -rf "${DBDIR}" echo "Done" exit ;; ok) chk_privilege warn_update_ports opr=$1 shift case $opr in add) register_globs '' "$*" "${DBDIR}/manually_done.list" echo "`linear_list $*` is/are registered to the list of manually resolved ports" ;; del) register_globs '' "$*" "${DBDIR}/manually_done.list" remove echo "`linear_list $*` is/are deregistered from the list of manually resolved ports" ;; esac echo "Now the following ports have been manually resolved:" [ ! -r "${DBDIR}/manually_done.list" ] || cat "${DBDIR}/manually_done.list" exit ;; taboo) chk_privilege warn_update_ports opr=$1 shift case $opr in add) register_globs '' "$*" "${DBDIR}/taboo.list" echo "`linear_list $*` is/are registered to the list of ports to be ignored." ;; del) register_globs '' "$*" "${DBDIR}/taboo.list" remove echo "`linear_list $*` is/are deregistered from the list of ports to be ignored." ;; esac combine_lists TABOO_PORTS.conflist taboo.list taboo.all.list echo "Now the following ports are registered to be ignored:" cat "${DBDIR}/taboo.all.list" exit ;; save) echo $* chk_privilege [ -d "${DBDIR}" ] || { echo "ERROR: Database has not been built up yet." >&2; exit 1; } savedir=$1 [ -n "$savedir" ] || { echo "ERROR: Directory to save the temporal database archive is not specified." >&2; exit 1; } [ -d "$savedir" ] || { echo "ERROR: Directory [$savedir] is not found." >&2; exit 1; } srcdir=`dirname "${DBDIR}"` srcnode=`basename "${DBDIR}"` savefile=`realpath "$savedir"`/${APPNAME}_`date +%Y%m%d_%H%M%S`.tar.gz echo "Starting to save the temporal database as [$savefile]..." ( cd "$srcdir" && tar czf "$savefile" "$srcnode" ) echo "Done" exit ;; load) chk_privilege loadfile=$1 [ -n "$loadfile" ] || { echo "ERROR: Database archive is not specified." >&2; exit 1; } [ -f "$loadfile" ] || { echo "ERROR: Database archive is not found." >&2; exit 1; } loadfile=`realpath "$loadfile"` echo "Starting to load the temporal database..." rm -rf "${DBDIR}" srcdir=`dirname "${DBDIR}"` srcnode=`basename "${DBDIR}"` [ -d "$srcdir" ] || mkdir -p "$srcdir" ( cd "$srcdir" && tar xzf "$loadfile" ) echo "Done" exit ;; show) [ -e "${DBDIR}/COMPLETE_PREPARATION" ] || { echo "ERROR: Database has not built yet." >&2; exit 1; } warn_update_ports _filter_skip_unchanged= _filter_only_target= _for_each_matching_port= pkgnamedb=requires case ${1:-todo} in todo) echo "The following ports are to be reinstalled or newly installed:" list=reinst_todo.list [ -e "${DBDIR}/reinst_todo.list" ] || list=reinst_order.list _filter_skip_unchanged=necessary_update _filter_only_target=y ;; done) echo "The following ports have been successfully reinstalled or newly installed:" list=success.list _filter_skip_unchanged=necessary_update_completed _filter_only_target=y ;; redo) echo "The following ports themselves have been successfully reinstalled or newly installed," echo "but are to be reinstalled again because their dependencies were failed:" list=success_but_dependencies_failed.list _filter_skip_unchanged=necessary_update _filter_only_target=y ;; resolved) echo "The following ports had problems which have been manually resolved:" list=manually_done.list ;; failure) echo "The following ports experienced failures and kept to be old:" show_list_failure exit ;; taboo) echo "The following ports are registered as taboo:" list=taboo.all.list ;; deleted) echo "The following ports are to be or have been deleted:" list=moved_or_lost.actual.list pkgnamedb=obsolete _filter_only_target=y ;; requirements) grandtitle="Dependencies based on the latest ports tree" title="The following ports are required by %s:" list=requires _for_each_matching_port=y ;; dependents) grandtitle="Dependencies based on the latest ports tree" title="The following ports depend on %s:" list=dependents _for_each_matching_port=y ;; *) echo "ERROR: Invalid show argument [$1]" >&2 exit 1 ;; esac [ -n "${_for_each_matching_port}" -o -r "${DBDIR}/$list" ] || exit 0 [ ! -e "${DBDIR}"/saved_options.sh ] || . "${DBDIR}"/saved_options.sh if [ -n "${_for_each_matching_port}" ] then shift [ $# -gt 0 ] || { echo "ERROR: the argument as port glob is missing" >&2; exit 1; } echo "[$grandtitle]" echo isfirst=y for origin_target in `ports_glob "$@"` do [ -e "${DBDIR}/requires/$origin_target/pkgtag" ] || continue [ "$isfirst" = y ] || echo isfirst=n pkg_target=`cat "${DBDIR}/$pkgnamedb/$origin_target/pkgtag"` printf "$title\n" "$origin_target ($pkg_target)" [ -e "${DBDIR}/requires/$origin_target/$list" ] || continue while read origin do if [ -e "${DBDIR}/$pkgnamedb/$origin/pkgtag" ] then echo $origin '('`cat "${DBDIR}/$pkgnamedb/$origin/pkgtag"`')' else echo $origin fi done < ${DBDIR}/requires/$origin_target/$list done [ "$isfirst" = n ] || { echo "ERROR: no matching port for the glob" >&2; exit 1; } elif [ -n "${_filter_skip_unchanged}" -a $skip_unchanged = yes ] then while read origin do [ -e "${DBDIR}/requires/$origin/${_filter_skip_unchanged}" ] || continue if [ -n "${_filter_only_target}" ] then chk_if_target currentorigin "$origin" [ -n "${currentorigin_is_relevant}" ] || continue [ ! -e "${DBDIR}/requires/$origin/SUPPRESSED" ] || continue fi if [ -e "${DBDIR}/$pkgnamedb/$origin/pkgtag" ] then echo $origin '('`cat "${DBDIR}/$pkgnamedb/$origin/pkgtag"`')' else echo $origin fi done < ${DBDIR}/$list else while read origin do if [ -n "${_filter_only_target}" ] then chk_if_target currentorigin "$origin" [ -n "${currentorigin_is_relevant}" ] || continue [ ! -e "${DBDIR}/requires/$origin/SUPPRESSED" ] || continue fi if [ -e "${DBDIR}/$pkgnamedb/$origin/pkgtag" ] then echo $origin '('`cat "${DBDIR}/$pkgnamedb/$origin/pkgtag"`')' else echo $origin fi done < ${DBDIR}/$list fi exit ;; redo) chk_privilege warn_update_ports touch "${DBDIR}/MODE_REDO" rm -f "${DBDIR}/COMPLETE_CLEANUP_REINST_STATUS" [ $renew_options = no ] || rm -f "${DBDIR}/COMPLETE_SAVE_OPTIONS" if [ -n "$target_required_ports$target_dependent_ports$target_required_ports_form2$target_dependent_ports_form2" ] then rm -f "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" touch "${DBDIR}/REQUIRE_CHK_NEW_TARGET" fi echo "[REDO mode]" ;; prepare) chk_privilege warn_update_ports ;; do) chk_privilege ;; *) echo "ERROR: Invalid command [$command]" >&2 exit 1 ;; esac # ------- Termination messages during construction of the temporal database ------- terminate_process_common () { local msg_where [ -z "${_MSG_CURRENT_STAGE}" ] || msg_where=" during ${_MSG_CURRENT_STAGE}" echo if [ $errno -eq 130 ] then echo "INFO: Terminated at `timestamp`$msg_where" echo echo " You can restart this process from the terminated point by" else echo "INFO: Aborted at `timestamp`$msg_where" echo echo " You may restart this process from the aborted point by" fi echo "executing without options or arguments as:" echo " ${APPNAME}" } terminate_process () { terminate_process_common echo " Instead, if you only want to construct the temporal database so as to stop" echo "before the actual reinstallation, execute as:" echo " ${APPNAME} prepare" terminate_process () { } } # ------- Load from pkgtools.conf(5) ------- if [ ! -e "${DBDIR}/COMPLETE_SAVE_OPTIONS" ] then [ ! -e "${DBDIR}"/saved_options.sh ] || echo "(Previous option settings for '-s', '-q' and '-d' are reset.)" cat > ${DBDIR}/saved_options.sh << eof target_dependent_ports=$target_dependent_ports target_required_ports=$target_required_ports target_dependent_ports_form2=$target_dependent_ports_form2 target_required_ports_form2=$target_required_ports_form2 taboo_ports=$taboo_ports taboo_ports_form2=$taboo_ports_form2 load_pkgtoolsconf=$load_pkgtoolsconf avoid_vulner=$avoid_vulner skip_unchanged=$skip_unchanged keep_distfiles=$keep_distfiles renew_options=$renew_options supress_self_upadte=$supress_self_upadte supress_obsolete_db_clean=$supress_obsolete_db_clean eof touch "${DBDIR}/COMPLETE_SAVE_OPTIONS" else t_avoid_vulner=$avoid_vulner t_skip_unchanged=$skip_unchanged t_keep_distfiles=$keep_distfiles . "${DBDIR}"/saved_options.sh [ $t_avoid_vulner = no -o $t_avoid_vulner = $avoid_vulner ] || echo "WARNING: -s option is specified but ignored by transferring the settings from the previous run." >&2 [ $t_skip_unchanged = no -o $t_skip_unchanged = $skip_unchanged ] || echo "WARNING: -q option is specified but ignored by transferring the settings from the previous run." >&2 [ $t_keep_distfiles = no -o $t_keep_distfiles = $keep_distfiles ] || echo "WARNING: -d option is specified but ignored by transferring the settings from the previous run." >&2 fi echo "INFO: List of option values:" echo "-----------------------------------------" cat "${DBDIR}"/saved_options.sh echo "-----------------------------------------" echo if [ ! -e "${DBDIR}/COMPLETE_IMPORT_PKGTOOLS_CONF" ] then PORTUPGRADE=`which portupgrade | head -n 1 || :` if [ $load_pkgtoolsconf = undef ] then if [ -n "${PORTUPGRADE}" -a -e /usr/local/etc/pkgtools.conf ] then load_pkgtoolsconf=default else load_pkgtoolsconf=no fi elif [ $load_pkgtoolsconf != undef -a `which portupgrade | wc -l` -eq 0 ] then echo "WARNING: pkgtools.conf is ignored because portupgrade is not installed" >&2 load_pkgtoolsconf=no fi if [ $load_pkgtoolsconf != no ] then echo "-- Starting to parse pkgtools.conf at `timestamp` (by using installed portupgrade)" portupgrade_pkg=`pkg_info -qO ports-mgmt/portupgrade` [ -n "$portupgrade_pkg" ] || portupgrade_pkg=`pkg_info -qO ports-mgmt/portupgrade-devel` [ `expr "$portupgrade_pkg" : '^portupgrade-devel-'` -eq 0 ] || echo "WARNING: Combination with portupgrade-devel-* has not tested." istart=`grep -m 1 -n -e '^def init_global$' "${PORTUPGRADE}" | cut -d : -f 1` || : [ -n "$istart" ] || { echo "ERROR: The current installed version of portupgrade is unsupported." >&2; } sed 1,$(($istart-1))d "${PORTUPGRADE}" > ${TMPDIR}/portupgrade.0 iend=`grep -m 1 -n -e '^end$' "${TMPDIR}"/portupgrade.0 | cut -d : -f 1` sed -n 1,${iend}p "${TMPDIR}"/portupgrade.0 > ${TMPDIR}/portupgrade.init_global ruby > ${DBDIR}/pkgtools.conf.converted << eof MYNAME = 'portupgrade' require 'pkgtools' `cat "${TMPDIR}"/portupgrade.init_global` init_global init_pkgtools_global load_config alt_moved = config_value(:ALT_MOVED) hold_pkgs = config_value(:HOLD_PKGS) ignore_moved = config_value(:IGNORE_MOVED) alt_pkgdep = config_value(:ALT_PKGDEP) make_args = config_value(:MAKE_ARGS) make_env = config_value(:MAKE_ENV) beforebuild = config_value(:BEFOREBUILD) beforedeinstall = config_value(:BEFOREDEINSTALL) afterinstall = config_value(:AFTERINSTALL) printf("ENV_PORTSDIR=%s\n", ENV['PORTSDIR']) i = 0 alt_moved.each do |val| printf("ALT_MOVED_pkgtoolsconf_%d_='%s'\n", i, val) i = i + 1 end i = 0 hold_pkgs.each do |val| printf("HOLD_pkgtoolsconf_%d_='%s'\n", i, val) i = i + 1 end ignore_moved.each do |val| printf("HOLD_pkgtoolsconf_%d_='%s'\n", i, val) i = i + 1 end i = 0 alt_pkgdep.each do |pat, alt| printf("REPLACE_FROM_pkgtoolsconf_%d_='%s'\n", i, pat) printf("REPLACE_TO_pkgtoolsconf_%d_='%s'\n", i, alt) i = i + 1 end i = 0 make_args.each do |target, definition| printf("MARG_TARGET_pkgtoolsconf_%d_='%s'\n", i, target) printf("MARG_DEF_pkgtoolsconf_%d_='%s'\n", i, definition) i = i + 1 end i = 0 make_env.each do |target, definition| printf("MENV_TARGET_pkgtoolsconf_%d_='%s'\n", i, target) printf("MENV_DEF_pkgtoolsconf_%d_='%s'\n", i, definition) i = i + 1 end i = 0 beforebuild.each do |target, command| printf("BEFOREBUILD_TARGET_pkgtoolsconf_%d_='%s'\n", i, target) printf("BEFOREBUILD_COMMAND_pkgtoolsconf_%d_='%s'\n", i, command) i = i + 1 end i = 0 beforedeinstall.each do |target, command| printf("BEFOREDEINSTALL_TARGET_pkgtoolsconf_%d_='%s'\n", i, target) printf("BEFOREDEINSTALL_COMMAND_pkgtoolsconf_%d_='%s'\n", i, command) i = i + 1 end i = 0 afterinstall.each do |target, command| printf("AFTERINSTALL_TARGET_pkgtoolsconf_%d_='%s'\n", i, target) printf("AFTERINSTALL_COMMAND_pkgtoolsconf_%d_='%s'\n", i, command) i = i + 1 end eof if [ $load_pkgtoolsconf = default ] then cat "${DBDIR}"/pkgtools.conf.converted "${CONFFILE}" > ${DBDIR}/setup.conf elif [ $load_pkgtoolsconf = override ] then cat "${CONFFILE}" "${DBDIR}"/pkgtools.conf.converted > ${DBDIR}/setup.conf fi echo "===> ok" echo else ln -s "${CONFFILE}" "${DBDIR}"/setup.conf fi touch "${DBDIR}/COMPLETE_IMPORT_PKGTOOLS_CONF" fi # ------- Configurations ------- if [ -n "$taboo_ports$taboo_ports_form2" ] then echo "INFO: (Re-)installation of the following ports are avoided as taboo:" echo "----------------------------------------" [ ! -e "${DBDIR}"/taboo.list ] || cat "${DBDIR}"/taboo.list echo "----------------------------------------" echo fi if [ ! -e "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" ] then rm -f "${DBDIR}/target_dependent_ports.specified" "${DBDIR}/target_required_ports.specified" register_globs_only_installed "$target_dependent_ports" "$target_dependent_ports_form2" > ${DBDIR}/target_dependent_ports.specified register_globs_only_installed "$target_required_ports" "$target_required_ports_form2" > ${DBDIR}/target_required_ports.specified touch "${DBDIR}/COMPLETE_PARSE_OPTION_TARGET_PORTS" fi if [ -n "$target_dependent_ports$target_dependent_ports_form2$target_required_ports$target_required_ports_form2" ] then echo "INFO: Operations will be applied only to the targets:" if [ `cat "${DBDIR}"/target_dependent_ports.specified | wc -l` -gt 0 -a `cat "${DBDIR}"/target_required_ports.specified | wc -l` -gt 0 ] then echo "----------------------------------------" cat "${DBDIR}"/target_dependent_ports.specified echo "----------------------------------------" echo "and their dependents;" echo "----------------------------------------" cat "${DBDIR}"/target_required_ports.specified echo "----------------------------------------" echo "and their requirements." echo elif [ `cat "${DBDIR}"/target_dependent_ports.specified | wc -l` -gt 0 ] then echo "----------------------------------------" cat "${DBDIR}"/target_dependent_ports.specified echo "----------------------------------------" echo "and their dependents." echo elif [ `cat "${DBDIR}"/target_required_ports.specified | wc -l` -gt 0 ] then echo "----------------------------------------" cat "${DBDIR}"/target_required_ports.specified echo "----------------------------------------" echo "and their requirements." echo else echo "ERROR: Target ports are specified but none of them is valid." >&2 exit 1 fi fi # Parse configuration file if [ ! -e "${DBDIR}/COMPLETE_PARSE_CONF" ] then echo "Start to parse configuration file [${APPNAME}.conf] at `timestamp`" ( set -e _CONFVARS='ENV ALT_MOVED HOLD TABOO REPLACE_FROM REPLACE_TO MARG_TARGET MARG_DEF MENV_TARGET MENV_DEF BEFOREBUILD BEFOREDEINSTALL AFTERINSTALL' for item in ${_CONFVARS} do set | grep -e "^${item}_" | cut -d = -f 1 | sed 's/^/unset /' done > ${TMPDIR}/unsetvars.sh . "${TMPDIR}"/unsetvars.sh . "${DBDIR}"/setup.conf for item in ${_CONFVARS} do set | grep -e "^${item}_" | sed 's/^/_CONF_/' done > ${DBDIR}/confvars.sh ) || { echo "ERROR: Invalid syntax in [${CONFFILE}]" >&2; exit 1; } touch "${DBDIR}/COMPLETE_PARSE_CONF" fi . "${DBDIR}/confvars.sh" if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_1" ] then echo "Starting to reflect settings of replacement defined in the configuration file at `timestamp`" echo PORTSDIR=${_CONF_ENV_PORTSDIR:-${PORTSDIR}} > "${DBDIR}/setenv.sh" echo DISTDIR=${_CONF_ENV_DISTDIR:-${DISTDIR:-${PORTSDIR}/distfiles}} >> "${DBDIR}/setenv.sh" if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_ALT_MOVED" ] then echo "-- ALT_MOVED_*" cp -p "${PORTS_MOVED_DB}" "${TMPDIR}/MOVED.conflist" set | grep -e '^_CONF_ALT_MOVED_' | cut -d = -f 1 | while read var do eval movedsb_path=\${$var} cat "$movedsb_path" >> ${DBDIR}/MOVED.conflist done touch "${DBDIR}/COMPLETE_REFLECTCONF_ALT_MOVED" fi if [ "${DBDIR}/MOVED.conflist" -nt "${PORTS_MOVED_DB}" ] then PORTS_MOVED_DB=${DBDIR}/MOVED.conflist fi build_conflist_target_list HOLD build_conflist_target_list TABOO combine_lists TABOO_PORTS.conflist taboo.list taboo.all.list if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_REPLACE" ] then echo "-- REPLACE_*" cp /dev/null "${DBDIR}/REPLACE.grep_from_pattern.conflist" cp /dev/null "${DBDIR}/REPLACE.replace_pattern.conflist" set | grep -e '^_CONF_REPLACE_FROM_' | cut -d = -f 1 | while read var do eval glob_pattern=\${$var} eval to=\${`echo $var | sed 's/^_CONF_REPLACE_FROM_/_CONF_REPLACE_TO_/'`} expand_glob_pattern_to_origins "$glob_pattern" yes > ${TMPDIR}/origins.2.tmp || : if [ `cat "${TMPDIR}/origins.2.tmp" | wc -l` -eq 0 ] then echo "WARNING: Original package to be replaced [$glob_pattern] is obsolete." >&2 echo " If still required, use a pattern for port origins instead." >&2 continue fi str_escape_regexp_filter < ${TMPDIR}/origins.2.tmp | sed "s|^|^|; s|$|$|" >> ${DBDIR}/REPLACE.grep_from_pattern.conflist if [ -z "$to" -o "$to" = delete ] then to= else [ -d "${PORTSDIR}/$to" ] || echo "WARNING: replacement port [$to] is obsolete" >&2 fi str_escape_regexp_filter < ${TMPDIR}/origins.2.tmp | sed "s|^|s:^|; s|$|$:$to:|" >> ${DBDIR}/REPLACE.replace_pattern.conflist done touch "${DBDIR}/COMPLETE_REFLECTCONF_REPLACE" fi touch "${DBDIR}/COMPLETE_REFLECTCONF_1" fi . "${DBDIR}/setenv.sh" if [ ! -e "${DBDIR}/COMPLETE_REFLECTCONF_2" ] then echo "Starting to reflect settings for each port defined in the configuration file at `timestamp`" build_conflist_target_val_pair MARG TARGET DEF build_conflist_target_val_pair MENV TARGET DEF build_conflist_target_val_pair BEFOREBUILD TARGET COMMAND build_conflist_target_val_pair BEFOREDEINSTALL TARGET COMMAND build_conflist_target_val_pair AFTERINSTALL TARGET COMMAND touch "${DBDIR}/COMPLETE_REFLECTCONF_2" echo fi # ------- Database construction ------- # Target ports if [ ! -e "${DBDIR}/COMPLETE_INSTALLED_PORTS" ] then echo "Starting to collect installed packages at `timestamp`" pkg_info -aoq 2> /dev/null > ${DBDIR}/installed_ports str_escape_regexp_filter < "${DBDIR}/installed_ports" | sed 's/^/^/; s/$/$/' > ${DBDIR}/installed_ports.grep_pattern touch "${DBDIR}/COMPLETE_INSTALLED_PORTS" echo fi if [ ! -e "${DBDIR}/COMPLETE_TARGETS" ] then echo "Starting to check newly installing ports at `timestamp`" cp "${DBDIR}/installed_ports" "${DBDIR}/target_ports" cat "${DBDIR}/target_dependent_ports.specified" "${DBDIR}/target_required_ports.specified" 2> /dev/null | sort -u | add_lines_if_new "${DBDIR}"/target_ports touch "${DBDIR}/COMPLETE_TARGETS" echo elif [ -e "${DBDIR}/REQUIRE_CHK_NEW_TARGET" ] then echo "Starting to check newly installing ports at `timestamp`" cp "${DBDIR}/target_ports" "${DBDIR}/target_ports.new" sort -u "${DBDIR}/target_dependent_ports.specified" "${DBDIR}/target_required_ports.specified" | add_lines_if_new "${DBDIR}"/target_ports.new if [ `cat "${DBDIR}/target_ports" | wc -l` -ne `cat "${DBDIR}/target_ports.new" | wc -l` ] then echo "WARNING: The temporal database will be refreshed so as to reinstall the all failed ports and their dependents." rm -f "${DBDIR}/COMPLETE_COLLECED_ALL_DEPENDENCIES" \ "${DBDIR}/COMPLETE_DISTFILES_LIST" \ "${DBDIR}/COMPLETE_CONVERT_REQUIRES_LIST" \ "${DBDIR}/COMPLETE_INSPECT_DEPENDENTS" \ "${DBDIR}/COMPLETE_COPY_DEPENDENCY_TMPFILES" \ "${DBDIR}/COMPLETE_ORDERED_ALL_DEPENDENCIES" \ "${DBDIR}/COMPLETE_CHECKED_UNSATISFIED_DEPENDENCIES" \ "${DBDIR}/COMPLETE_REFLECTCONF_2" fi echo fi rm -f "${DBDIR}/REQUIRE_CHK_NEW_TARGET" # Inspection of all dependencies if [ ! -e "${DBDIR}/COMPLETE_COLLECED_ALL_DEPENDENCIES" ] then echo "Starting to inspect dependencies of the all installed packages at `timestamp`" [ -z "$target_dependent_ports$target_dependent_ports_form2$target_required_ports$target_required_ports_form2" ] || \ echo "INFO: Ports irrelevant to the targets are also inspected in order to get complete information." [ -d "${DBDIR}/requires" ] || mkdir -p "${DBDIR}/requires" touch "${DBDIR}/moved_or_lost.list" touch "${DBDIR}/target.inspected.list" if [ -f "${DBDIR}/target_ports.remain" ] then echo "INFO: Restarting from the previously terminated point" else cp -p "${DBDIR}/target_ports" "${DBDIR}/target_ports.remain" fi cp "${DBDIR}/target_ports.remain" "${TMPDIR}/target_ports" DEPTH_INDEX='--' nlines=`cat "${TMPDIR}/target_ports" | wc -l` iline=1 while [ $iline -le $nlines ] do origin=`sed -n ${iline}p "${TMPDIR}/target_ports"` iline=$(($iline+1)) inspect_dependencies "$origin" continue done touch "${DBDIR}/REPLACE.complete_replace_pattern.tmp" sort "${DBDIR}/REPLACE.complete_replace_pattern.tmp" | uniq > ${DBDIR}/REPLACE.complete_replace_pattern touch "${DBDIR}/COMPLETE_COLLECED_ALL_DEPENDENCIES" echo fi # Inspection of all required distfiles if [ ! -e "${DBDIR}/COMPLETE_DISTFILES_LIST" -a $keep_distfiles = no ] then echo "Starting to summarize distfiles list at `timestamp`" sort "${DBDIR}/distfiles.list" 2> /dev/null | uniq | str_escape_regexp_filter | sed 's|^|/|; s|$|$|' > ${DBDIR}/distfiles.grep.pattern || : touch "${DBDIR}/COMPLETE_DISTFILES_LIST" echo fi # Convert requires-lists to actual ones if [ ! -e "${DBDIR}/COMPLETE_CONVERT_REQUIRES_LIST" ] then echo "Starting conversion of requires-lists to actual ones at `timestamp`" if [ -f "${DBDIR}/convert_requires_lists.remain" ] then echo "INFO: Restarting from the previously terminated point" else find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/convert_requires_lists.remain fi cp "${DBDIR}/convert_requires_lists.remain" "${TMPDIR}/convert_requires_lists" while read dbpath do portname=`basename "$dbpath"` catpath=`dirname "$dbpath"` catname=`basename "$catpath"` origin=$catname/$portname sed -E -f "${DBDIR}/REPLACE.complete_replace_pattern" "$dbpath/requires" | grep -v '^$' | sort | uniq > $dbpath/requires.new mv "$dbpath/requires.new" "$dbpath/requires" sed -i '' 1d "${DBDIR}/convert_requires_lists.remain" done < ${TMPDIR}/convert_requires_lists touch "${DBDIR}/COMPLETE_CONVERT_REQUIRES_LIST" echo fi # Inspection of dependents if [ ! -e "${DBDIR}/COMPLETE_INSPECT_DEPENDENTS" ] then echo "Starting inspection of dependents at `timestamp`" if [ -f "${DBDIR}/inspect_dependent.remain" ] then echo "INFO: Restarting from the previously terminated point" else find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/inspect_dependent.remain fi cp "${DBDIR}/inspect_dependent.remain" "${TMPDIR}/inspect_dependent" while read dbpath do portname=`basename "$dbpath"` catpath=`dirname "$dbpath"` catname=`basename "$catpath"` origin=$catname/$portname sed "s|^|${DBDIR}/requires/|; s|$|/dependents|" "$dbpath/requires" | add_a_line_to_files_if_new "$origin" sed -i '' 1d "${DBDIR}/inspect_dependent.remain" done < ${TMPDIR}/inspect_dependent touch "${DBDIR}/COMPLETE_INSPECT_DEPENDENTS" echo fi # Preparation of matching patterns of dependencies if [ ! -e "${DBDIR}/COMPLETE_PREPARATION_OF_MATCHING_PATTERNS_OF_DEPENDENCIES" ] then echo "Starting preparation of matching patterns of dependencies at `timestamp`" if [ -f "${DBDIR}/prepare_matching_patterns_dependencies.remain" ] then echo "INFO: Restarting from the previously terminated point" else find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/prepare_matching_patterns_dependencies.remain fi cp "${DBDIR}/prepare_matching_patterns_dependencies.remain" "${DBDIR}/prepare_matching_patterns_dependencies" while read dbpath do portname=`basename "$dbpath"` catpath=`dirname "$dbpath"` catname=`basename "$catpath"` origin=$catname/$portname [ ! -e "${DBDIR}/requires/$origin/dependents" ] || str_escape_regexp_filter < ${DBDIR}/requires/$origin/dependents | sed 's/^/^/;s/$/$/' > ${DBDIR}/requires/$origin/dependents.pattern [ ! -e "${DBDIR}/initial/$origin/dependents" ] || str_escape_regexp_filter < ${DBDIR}/initial/$origin/dependents | sed 's/^/^/;s/$/$/' > ${DBDIR}/initial/$origin/dependents.pattern [ ! -e "${DBDIR}/requires/$origin/requires" ] || str_escape_regexp_filter < ${DBDIR}/requires/$origin/requires | sed 's/^/^/;s/$/$/' > ${DBDIR}/requires/$origin/requires.pattern [ ! -e "${DBDIR}/initial/$origin/requires" ] || str_escape_regexp_filter < ${DBDIR}/initial/$origin/requires | sed 's/^/^/;s/$/$/' > ${DBDIR}/initial/$origin/requires.pattern chk_if_target currentorigin "$origin" sed -i '' 1d "${DBDIR}/prepare_matching_patterns_dependencies.remain" done < ${DBDIR}/prepare_matching_patterns_dependencies touch "${DBDIR}/COMPLETE_PREPARATION_OF_MATCHING_PATTERNS_OF_DEPENDENCIES" echo fi # Preparation of matching patterns of obsolete ports to be deleted if [ ! -e "${DBDIR}/COMPLETE_PREPARATION_OF_MATCHING_PATTERNS_OF_OBSOLETE_PORTS" ] then echo "Starting preparation of matching patterns of obsolete ports to be deleted at `timestamp`" if [ -f "${DBDIR}/prepare_matching_patterns_obsolete_ports.remain" ] then echo "INFO: Restarting from the previously terminated point" else cp -p "${DBDIR}/moved_or_lost.list" "${DBDIR}/prepare_matching_patterns_obsolete_ports.remain" fi cp "${DBDIR}/prepare_matching_patterns_obsolete_ports.remain" "${DBDIR}/prepare_matching_patterns_obsolete_ports" while read origin do chk_if_target currentorigin "$origin" sed -i '' 1d "${DBDIR}/prepare_matching_patterns_obsolete_ports.remain" done < ${DBDIR}/prepare_matching_patterns_obsolete_ports touch "${DBDIR}/COMPLETE_PREPARATION_OF_MATCHING_PATTERNS_OF_OBSOLETE_PORTS" echo fi # Inspection of necessary updates if [ ! -e "${DBDIR}/COMPLETE_NECESSARY_UPDATES" ] then echo "Starting inspection of necessary updates at `timestamp`" if [ -f "${DBDIR}/necessary_updates.remain" ] then echo "INFO: Restarting from the previously terminated point" else find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/necessary_updates.remain fi cp "${DBDIR}/necessary_updates.remain" "${TMPDIR}/necessary_updates" while read dbpath do portname=`basename "$dbpath"` catpath=`dirname "$dbpath"` catname=`basename "$catpath"` origin=$catname/$portname if [ -e "${DBDIR}/requires/$origin/new_version" ] then touch "${DBDIR}/requires/$origin/necessary_update" if [ -e "${DBDIR}/requires/$origin/dependents" ] then while read origin_dependent do touch "${DBDIR}/requires/$origin_dependent/necessary_update" done < ${DBDIR}/requires/$origin/dependents fi fi sed -i '' 1d "${DBDIR}/necessary_updates.remain" done < ${TMPDIR}/necessary_updates touch "${DBDIR}/COMPLETE_NECESSARY_UPDATES" echo fi # Copying dependencies for preparation if [ ! -e "${DBDIR}/COMPLETE_COPY_DEPENDENCY_TMPFILES" ] then echo "Starting preparation for order of dependencies at `timestamp`" find "${DBDIR}/requires" -depth 3 -name requires -exec cp -p {} {}.remained \; touch "${DBDIR}/COMPLETE_COPY_DEPENDENCY_TMPFILES" echo fi # Clean up of reinstallation status for preparation if [ -e "${DBDIR}/MODE_REDO" -a ! -e "${DBDIR}/COMPLETE_CLEANUP_REINST_STATUS" ] then echo "Starting preparation for order of dependencies at `timestamp`" find "${DBDIR}/requires" -depth 3 -type d -name status -exec rm -rf {} \; -exec mkdir {} \; touch "${DBDIR}/COMPLETE_CLEANUP_REINST_STATUS" echo fi # Order the ports considering dependencies if [ ! -e "${DBDIR}/COMPLETE_ORDERED_ALL_DEPENDENCIES" ] then echo "Starting ordering of dependencies at `timestamp`" [ ! -f "${DBDIR}/reinst_order.list.tmp" ] || echo "INFO: Restarting from the previously terminated point" touch "${DBDIR}/reinst_order.list.tmp" cd "${DBDIR}/requires" cat > ${TMPDIR}/order_dependencies.awk << eof BEGIN { it = 0; i = 0; } { if (NF == 0) { i = 0; } else { if (i == 0) { target = \$0; sub (/\/requires\.remained$/, "", target); sub (/^\.\//, "", target); srcikey[it] = target; srckeyi[target] = it; it++; } else { src[it-1,i-1] = \$0; srcimax[it-1] = srcsize[it-1] = i; } i++; } } END { ntargets = it; norder = 0; order_str = ""; icycle = 0; lf_order_str = ""; while (1) { is_operated = 0; for (it = 0; it < ntargets; it++) { if (!(it in srcikey)) continue; if (srcsize[it] > 0) continue; is_operated = 1; target = srcikey[it]; # print "[" icycle "]-- " target; delete srcikey[it]; order[norder++] = target; order_str = order_str lf_order_str; order_str = sprintf ("%s%s", order_str, target); lf_order_str = "\n"; for (jt = 0; jt < ntargets; jt++) { for (j = 0; j < srcimax[jt]; j++) { if ((jt,j) in src && src[jt,j] == target) { delete src[jt,j]; srcsize[jt]--; break; } } } } if (is_operated == 0) break; icycle++; } reinst_order_list = sprintf ("%s%s", ENVIRON["DBDIR"], "/reinst_order.list.tmp"); print order_str > reinst_order_list; unsatisfied = ""; for (it = 0; it < ntargets; it++) { if (srcsize[it] == 0) continue; reqs = ""; sp_reqs = ""; for (i = 0; i < srcimax[it]; i++) { if ((it,i) in src) { reqs = reqs ", " src[it,i]; sp_reqs = ", "; } } unsatisfied = sprintf ("%s%s [%d] (%s)\n", unsatisfied, srcikey[it], srcsize[it], reqs); } if (unsatisfied != "") { unsatisfied_list = sprintf ("%s%s", ENVIRON["DBDIR"], "/unsatisfied.list"); print unsatisfied > unsatisfied_list; exit 1; } } eof find . -depth 3 -name requires.remained -exec echo {} \; -exec cat {} \; -exec echo \; | \ env DBDIR=${DBDIR} awk -f "${TMPDIR}"/order_dependencies.awk || { \ echo "ERROR: Unsatisfied dependencies are remained" >&2 cat "${DBDIR}/unsatisfied.list" echo "*** Aborted by ${APPNAME}" echo "The ports tree seems broken. You might have caught an incomplete version." echo "You are encouraged to update the ports tree by portsnap(8)." echo "Then execute" echo " ${APPNAME} clean" echo "before restart." terminate_process () { } exit 1 } cp "${DBDIR}/reinst_order.list.tmp" "${DBDIR}/reinst_order.list" touch "${DBDIR}/COMPLETE_ORDERED_ALL_DEPENDENCIES" rm -f "${TMPDIR}/targets" echo fi # Deinstallation of obsolete packages if [ ! -e "${DBDIR}/COMPLETE_LIST_DEINST_OBS_PKGS" ] then echo "Starting to compose a list of deinstallation of obsolete packages at `timestamp`" while read origin do origin_ptn=`str_escape_regexp ${origin}` [ `grep -m 1 -E "^${origin_ptn}$" "${DBDIR}/HOLD_PORTS.conflist" 2> /dev/null | wc -l` -gt 0 ] || echo $origin done < ${DBDIR}/moved_or_lost.list > ${DBDIR}/moved_or_lost.actual.list.tmp mv "${DBDIR}"/moved_or_lost.actual.list.tmp "${DBDIR}"/moved_or_lost.actual.list touch "${DBDIR}/COMPLETE_LIST_DEINST_OBS_PKGS" echo fi # ------- Main operations ------- if [ ! -e "${DBDIR}/COMPLETE_PREPARATION" ] then touch "${DBDIR}/COMPLETE_PREPARATION" fi if [ "$command" = prepare ] then echo "Done (skipped reinstallation) at `timestamp`" echo echo " You can restart this process from the aborted/terminated point by" echo "executing without options or arguments as:" echo " ${APPNAME}" terminate_process () { } exit fi terminate_process () { terminate_process_common terminate_process () { } } # Deinstallation of obsolete packages if [ ! -e "${DBDIR}/COMPLETE_DEINST_OBS_PKGS" ] then _MSG_CURRENT_STAGE_general="deinstallation of obsolete packages" _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} echo "Starting deinstallation of obsolete packages at `timestamp`" [ -d "${DBDIR}/backup_obsolete" ] || mkdir -p "${DBDIR}/backup_obsolete" [ -d "${DBDIR}/status_deinst" ] || mkdir -p "${DBDIR}/status_deinst" if [ `cat "${DBDIR}/moved_or_lost.list" | wc -l` -gt 0 ] then savedir=`pwd` if [ -f "${DBDIR}/moved_or_lost.list.remained" ] then echo "INFO: Restarting from the previously terminated point" else cp -p "${DBDIR}/moved_or_lost.list" "${DBDIR}/moved_or_lost.list.remained" fi cp -p "${DBDIR}/moved_or_lost.list.remained" "${TMPDIR}/moved_or_lost.tmp" nlines=`cat "${TMPDIR}/moved_or_lost.tmp" | wc -l` iline=1 cd "${DBDIR}/backup_obsolete" while [ $iline -le $nlines ] do origin=`sed -n ${iline}p "${TMPDIR}/moved_or_lost.tmp"` iline=$(($iline+1)) currentpkg=`pkg_info -qO "$origin" 2> /dev/null` [ -n "$currentpkg" ] || continue chk_if_target currentorigin "$origin" if [ -z "${currentorigin_is_relevant}" ] then echo "-- (Skipping an irrelevant package for obsolete port $origin as $currentpkg)" continue fi origin_ptn=`str_escape_regexp ${origin}` if [ `grep -m 1 -E "^${origin_ptn}$" "${DBDIR}/HOLD_PORTS.conflist" 2> /dev/null | wc -l` -gt 0 ] then echo "-- (Skipping a hold package for obsolete port $origin as $currentpkg)" continue fi _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} echo "========== Starting deinstallation process for obsolete port $origin as $currentpkg ==========" if [ -z "${currentorigin_is_all}" -a -n "${currentorigin_is_relevant}" ] then [ -z "${currentorigin_is_target}" ] || echo "(Target port)" [ -z "${currentorigin_is_dependent}" ] || echo "(Dependent of the target port(s))" [ -z "${currentorigin_is_required}" ] || echo "(Requirement of the target port(s))" [ -z "${currentorigin_is_former_dependent}" ] || echo "(Former dependent of the target port(s))" [ -z "${currentorigin_is_former_required}" ] || echo "(Former requirement of the target port(s))" fi echo "-- (Creating backup package for $origin as $currentpkg)" tag=`echo $origin | sed 's|/|.|'` if [ ! -e "${DBDIR}/status_deinst/$tag.backup" ] then pkg_create -b "$currentpkg" || { echo "*** Continuating forcibly by hoping success..."; continue; } touch "${DBDIR}/status_deinst/$tag.backup" fi echo "-- (Deleting package for $origin as $currentpkg)" pkg_delete -f "$currentpkg" || { echo "*** Continuating forcibly by hoping success..."; continue; } rm_a_line "$origin" "${DBDIR}/moved_or_lost.list.remained" _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} echo done cd "$savedir" fi touch "${DBDIR}/COMPLETE_DEINST_OBS_PKGS" _MSG_CURRENT_STAGE= echo fi # Reinstallation of remained ports [ ! -e "${DBDIR}/MODE_REDO" ] || rm -f "${DBDIR}/COMPLETE_REINSTALLATION" "${DBDIR}/COMPLETE_CLEANUP_OBSLETE_DISTFILES" "${DBDIR}/COMPLETE_REBUILD_PKGDB" if [ ! -e "${DBDIR}/COMPLETE_REINSTALLATION" ] then _MSG_CURRENT_STAGE_general="reinstallation" _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} echo "Starting reinstallation at `timestamp`" savedir=`pwd` mkdir "${TMPDIR}/backup" [ -d "${DBDIR}/backup_failure" ] || mkdir -p "${DBDIR}/backup_failure" if [ ! -e "${DBDIR}/MODE_REDO" -a -f "${DBDIR}/reinst_todo.list" ] then echo "INFO: Restarting from the previously terminated point" else cp -p "${DBDIR}/reinst_order.list" "${DBDIR}/reinst_todo.list" fi rm -f "${DBDIR}/MODE_REDO" cp -p "${DBDIR}/reinst_todo.list" "${TMPDIR}/reinst_todo.tmp" touch "${DBDIR}/failed.list" touch "${DBDIR}/success_but_dependencies_failed.list" touch "${DBDIR}/success.list" nlines_tot=$((`cat "${DBDIR}/reinst_order.list" | wc -l`)) nlines=`cat "${TMPDIR}/reinst_todo.tmp" | wc -l` icount=$(($nlines_tot-$nlines)) iline=1 while [ $iline -le $nlines ] do _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} origin=`sed -n ${iline}p "${TMPDIR}/reinst_todo.tmp"` iline=$(($iline+1)) icount=$(($icount+1)) MAKE_ARGS="FORCE_PKG_REGISTER=yes `[ $avoid_vulner = yes ] || echo DISABLE_VULNERABILITIES=yes` `cat "${DBDIR}/requires/$origin/MARG.conflist" 2> /dev/null || :`" MAKE_ENVS=`cat "${DBDIR}/requires/$origin/MENV.conflist" 2> /dev/null || :` counter="[$icount/$nlines_tot $(($icount*100/$nlines_tot))%]" if [ -e "${DBDIR}"/requires/$origin/new_version ] then newpkg=`cat "${DBDIR}"/requires/$origin/new_version` else newpkg= fi currentpkg=`pkg_info -qO "$origin" 2> /dev/null || :` pkgtag=$currentpkg [ -n "$pkgtag" ] || pkgtag=$newpkg if [ -z "$pkgtag" ] then pkgtag='?' elif [ -n "$newpkg" -a "x$currentpkg" != "x$newpkg" ] then if [ -n "$currentpkg" ] then pkgtag="$currentpkg => $newpkg" else pkgtag="[new] $newpkg" fi fi echo $pkgtag > ${DBDIR}/requires/$origin/pkgtag position_msg="$origin ($pkgtag)" if grep -m 1 -E "^`str_escape_regexp ${origin}`$" "${DBDIR}/success.list" 2> /dev/null > /dev/null then echo "========== $counter (Skipping an already reinstalled package for port $position_msg at `timestamp`) ==========" echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi if [ $skip_unchanged = yes -a ! -e "${DBDIR}/requires/$origin/necessary_update" ] then echo "========== $counter (Skipping a port, $position_msg, because itself and the all of its requirements are already latest at `timestamp`) ==========" echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi chk_if_target currentorigin "$origin" cp /dev/null "${TMPDIR}"/msg_if_target if [ -z "${currentorigin_is_all}" ] then if [ -n "${currentorigin_is_relevant}" ] then [ -z "${currentorigin_is_target}" ] || echo "(Target port)" > ${TMPDIR}/msg_if_target [ -z "${currentorigin_is_dependent}" ] || echo "(Dependent of the target port(s))" >> ${TMPDIR}/msg_if_target [ -z "${currentorigin_is_required}" ] || echo "(Requirement of the target port(s))" >> ${TMPDIR}/msg_if_target [ -z "${currentorigin_is_former_dependent}" ] || echo "(Former dependent of the target port(s))" >> ${TMPDIR}/msg_if_target [ -z "${currentorigin_is_former_required}" ] || echo "(Former requirement of the target port(s))" >> ${TMPDIR}/msg_if_target else echo "========== $counter (Skipping an irrelevant package for port $position_msg at `timestamp`) ==========" echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi fi if grep -m 1 -E "^`str_escape_regexp ${origin}`$" "${DBDIR}/HOLD_PORTS.conflist" 2> /dev/null > /dev/null then echo "========== $counter (Skipping a hold package for port $position_msg at `timestamp`) ==========" cat ${TMPDIR}/msg_if_target echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi if grep -m 1 -E "^`str_escape_regexp $origin`$" "${DBDIR}/taboo.all.list" 2> /dev/null > /dev/null then echo "========== $counter (Ignored a taboo port $position_msg at `timestamp`) ==========" cat ${TMPDIR}/msg_if_target echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi if grep -m 1 -E "^`str_escape_regexp $origin`$" "${DBDIR}/manually_done.list" 2> /dev/null > /dev/null then echo "========== $counter (Marking a manually-done port $position_msg as success at `timestamp`) ==========" cat ${TMPDIR}/msg_if_target echo record_success $origin rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi if [ -e "${DBDIR}/requires/$origin/SUPPRESSED" ] then echo "========== $counter (Skipping a suppressed port $position_msg as success at `timestamp`) ==========" cat ${TMPDIR}/msg_if_target echo rm_a_line "$origin" "${DBDIR}/reinst_todo.list" continue fi if [ -e "${DBDIR}/requires/$origin/installed_version" ] then insttarget=reinstall instdesc='a reinstallation' else insttarget=install instdesc='an installation' fi _MSG_CURRENT_STAGE="$instdesc process for $position_msg $counter" echo "========== $counter Starting $instdesc process for $position_msg at `timestamp` ==========" cat ${TMPDIR}/msg_if_target cd "${PORTSDIR}/$origin" if [ -e "${DBDIR}/requires/$origin/status/in_build" ] then echo "(Restarting the previously terminated build process...)" else touch "${DBDIR}/requires/$origin/status/in_build" fi if [ -e "${DBDIR}/requires/$origin/BEFOREBUILD.conflist" -a ! -e "${DBDIR}/requires/$origin/status/COMPLETE_BEFOREBUILD" ] then echo "-- BEFOREBUILD operations (start)" sh -e "${DBDIR}/requires/$origin/BEFOREBUILD.conflist" || \ { echo "ERROR: while BEFOREBUILD operations for ${PORTSDIR}/$position_msg." >&2 echo 'BEFOREBUILD operations' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin noclean rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } echo "-- BEFOREBUILD operations (end)" touch "${DBDIR}/requires/$origin/status/COMPLETE_BEFOREBUILD" fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE_CLEAN_BEFORE_BUILD" ] then env ${MAKE_ENVS} make clean ${MAKE_ARGS} || \ { echo "ERROR: Check the permission of directory ${PORTSDIR}/$position_msg." >&2 echo 'clean before build' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin noclean rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } echo touch "${DBDIR}/requires/$origin/status/COMPLETE_CLEAN_BEFORE_BUILD" fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE_FETCH" ] then if [ ! -e "${DBDIR}/requires/$origin/status/FAILED_FETCH" ] then if env ${MAKE_ENVS} make checksum ${MAKE_ARGS} then : else touch "${DBDIR}/requires/$origin/status/FAILED_FETCH" fi fi if [ -e "${DBDIR}/requires/$origin/status/FAILED_FETCH" ] then echo "WARNING: Refetching distfiles for ${PORTSDIR}/$position_msg." >&2 # if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE.FAILED_FETCH.DISTCLEAN" ] # then # env ${MAKE_ENVS} make distclean NOCLEANDEPENDS=yes ${MAKE_ARGS} || \ # { # echo "ERROR: Failed in distclean for ${PORTSDIR}/$position_msg." >&2 # echo 'distclean for refetch' > ${DBDIR}/requires/$origin/note_failtre # record_failure $origin # rm_a_line "$origin" "${DBDIR}/reinst_todo.list" # cmt_fail_reinst "$origin" # continue # } # touch "${DBDIR}/requires/$origin/status/COMPLETE.FAILED_FETCH.DISTCLEAN" # fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE.FAILED_FETCH.REFETCH" ] then env ${MAKE_ENVS} make fetch ${MAKE_ARGS} FETCH_ARGS=-Ap || \ { echo "ERROR: Failed in fetch for ${PORTSDIR}/$position_msg." >&2 echo 'fetch' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } env ${MAKE_ENVS} make checksum ${MAKE_ARGS} || \ { echo "ERROR: Failed in checksum for ${PORTSDIR}/$position_msg." >&2 echo 'checksum' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } touch "${DBDIR}/requires/$origin/status/COMPLETE.FAILED_FETCH.REFETCH" fi fi touch "${DBDIR}/requires/$origin/status/COMPLETE_FETCH" fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE_BUILD" ] then if env ${MAKE_ENVS} make ${MAKE_ARGS} then : else echo 'build' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue fi touch "${DBDIR}/requires/$origin/status/COMPLETE_BUILD" fi rm -f "${DBDIR}/requires/$origin/status/in_build" if [ -e "${DBDIR}/requires/$origin/status/in_install" ] then echo "(Restarting the previously terminated installation process...)" else touch "${DBDIR}/requires/$origin/status/in_install" fi if [ -n "$currentpkg" -a ! -e "${DBDIR}/requires/$origin/status/COMPLETE_PKG_BACKUP" ] then echo "-- (Creating temporal backup package for $position_msg)" cd "${DBDIR}/backup_failure" pkg_create -b "$currentpkg" || \ { rm -f "${DBDIR}/backup_failure/$currentpkg.tbz" echo "WARNING: Failed to create the backup package, but ignored by hoping success." >&2 } cd "${PORTSDIR}/$origin" touch "${DBDIR}/requires/$origin/status/COMPLETE_PKG_BACKUP" fi if [ -n "$currentpkg" -a ! -e "${DBDIR}/requires/$origin/status/COMPLETE_BEFOREDEINSTALL" ] then if [ -e "${DBDIR}/requires/$origin/BEFOREDEINSTALL.conflist" ] then echo "-- BEFOREDEINSTALL operations (start)" sh -e "${DBDIR}/requires/$origin/BEFOREDEINSTALL.conflist" || \ { echo "ERROR: while BEFOREDEINSTALL operations for ${PORTSDIR}/$position_msg." >&2 echo 'BEFOREDEINSTALL operations' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin noclean rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } echo "-- BEFOREDEINSTALL operations (end)" fi touch "${DBDIR}/requires/$origin/status/COMPLETE_BEFOREDEINSTALL" fi if [ -n "$currentpkg" -a ! -e "${DBDIR}/requires/$origin/status/COMPLETE_DEINSTALL" ] then pkg_delete -f $currentpkg || \ { echo "WARNING: Failed to deinstall $currentpkg by pkg_delete." >&2 } echo "-- (Trying to deinstall by ports to make sure. This usually ends up with warnings.)" env ${MAKE_ENVS} make deinstall ${MAKE_ARGS} || \ { echo "WARNING: Failed to deinstall $currentpkg by make deinstall." >&2 } touch "${DBDIR}/requires/$origin/status/COMPLETE_DEINSTALL" fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE_INSTALL" ] then if [ ! -e "${DBDIR}/requires/$origin/status/FAILED_INSTALL" ] then if env ${MAKE_ENVS} make $insttarget ${MAKE_ARGS} then touch "${DBDIR}/requires/$origin/status/COMPLETE_INSTALL" else touch "${DBDIR}/requires/$origin/status/FAILED_INSTALL" fi fi if [ -e "${DBDIR}/requires/$origin/status/FAILED_INSTALL" ] then if [ ! -e "${DBDIR}/requires/$origin/status/COMPETE.FAILED_INSTALL.RECOVER" ] then echo "*** Trying to deinstall the failed/terminated installation... (Ignore failures)" if [ -n "$currentpkg" ] then pkg_delete -f $currentpkg || : fi echo "*** Trying to deinstall by ports to make sure. (This usually ends up with warnings)" env ${MAKE_ENVS} make deinstall ${MAKE_ARGS} || : if [ -n "$currentpkg" ] then echo "*** Restoring the backup..." if [ -e "${DBDIR}/backup_failure/$currentpkg.tbz" ] then echo "WARNING: No backup exists, gave up." >&2 elif pkg_add -fF "${DBDIR}/backup_failure/$currentpkg.tbz" then : else echo "WARNING: Failed to restore $currentpkg. Note that your system may experience troubles by this error." >&2 fi fi touch "${DBDIR}/requires/$origin/status/COMPETE.FAILED_INSTALL.RECOVER" fi if [ -n "$currentpkg" -a ! -e "${DBDIR}/requires/$origin/status/COMPETE.FAILED_INSTALL.AFTERINSTALL" -a -e "${DBDIR}/requires/$origin/AFTERINSTALL.conflist" ] then echo "-- AFTERINSTALL operations (start)" sh -e "${DBDIR}/requires/$origin/AFTERINSTALL.conflist" || { echo "-- (This error is ignored)"; } echo "-- AFTERINSTALL operations (end)" touch "${DBDIR}/requires/$origin/status/COMPETE.FAILED_INSTALL.AFTERINSTALL" fi echo 'install' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin noclean rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue fi fi if [ -e "${DBDIR}/requires/$origin/AFTERINSTALL.conflist" -a ! -e "${DBDIR}/requires/$origin/status/in_install.AFTERINSTALL" ] then echo "-- AFTERINSTALL operations (start)" sh -e "${DBDIR}/requires/$origin/AFTERINSTALL.conflist" || \ { echo "ERROR: while AFTERINSTALL operations for ${PORTSDIR}/$position_msg." >&2 echo 'AFTERINSTALL operations' > ${DBDIR}/requires/$origin/note_failtre record_failure $origin noclean rm_a_line "$origin" "${DBDIR}/reinst_todo.list" cmt_fail_reinst "$origin" continue } echo "-- AFTERINSTALL operations (end)" touch "${DBDIR}/requires/$origin/status/in_install.AFTERINSTALL" fi if [ ! -e "${DBDIR}/requires/$origin/status/COMPLETE_CLEAN_AFTER_INSTALL" ] then env ${MAKE_ENVS} make clean ${MAKE_ARGS} || \ { echo "WARNING: Failed to clean $position_msg." >&2 } touch "${DBDIR}/requires/$origin/status/COMPLETE_CLEAN_AFTER_INSTALL" fi record_success $origin rm_a_line "$origin" "${DBDIR}/reinst_todo.list" rm -f "${DBDIR}/backup_failure/$currentpkg.tbz" rm "${DBDIR}/requires/$origin/status/in_install" _MSG_CURRENT_STAGE=${_MSG_CURRENT_STAGE_general} echo done cd "$savedir" touch "${DBDIR}/COMPLETE_REINSTALLATION" _MSG_CURRENT_STAGE= echo fi # Clean up obsolete or unused distfiles if [ ! -e "${DBDIR}/COMPLETE_CLEANUP_OBSLETE_DISTFILES" ] then echo "Starting to clean up obsolete or unused distfiles at `timestamp`" find "${DISTDIR}" -type f | grep -v -E -f "${DBDIR}/distfiles.grep.pattern" | while read distfile do echo " $distfile" rm -f "$distfile" done touch "${DBDIR}/COMPLETE_CLEANUP_OBSLETE_DISTFILES" echo fi # Rebuild of package database if [ ! -e "${DBDIR}/COMPLETE_REBUILD_PKGDB" ] then if which -s pkgdb then echo "Starting to rebuild package database for portupgrade at `timestamp`" pkgdb -fu fi touch "${DBDIR}/COMPLETE_REBUILD_PKGDB" echo fi # Notice of failures touch "${DBDIR}/failed.list" if [ `cat "${DBDIR}/failed.list" | wc -l` -gt 0 ] then echo "*** (Re)installation of the following ports were unsuccessful." echo " Please recover them manually." echo " You are recommended to read ${PORTSDIR}/UPDATING to resolve the problems." echo " If you remember the last date to have upgraded the concerned ports," echo "pkg_updating(1) will be useful." echo " You should also consider whether the failed ports are really required, viz.," echo "not obsolete dependencies, by using pkg_info(1) with -R option." echo " After resolving the problems, execute" echo " ${APPNAME} ok add [resolved_port_globs]" echo "and restart by" echo " ${APPNAME} redo" echo "****************" show_list_failure echo "*** Warned by ${APPNAME}" echo fi # End terminate_process () { } echo "All done at `timestamp`"