OSDN Git Service

Version 3.0.5+toward_3.1.0_20140709012553
[portsreinstall/current.git] / bin / portsreinstall
1 #!/bin/sh -e
2 # ==================================================================================
3 # portsreinstall main script
4 # Copyright (C) 2010-2014 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
5 # This software is distributed under the 2-Clause BSD License.
6 # ==================================================================================
7
8 # ==================================================
9 # ================== ENVIRONMENT ===================
10 # ==================================================
11
12 # ============ Set up of environment =============
13 APPNAME=`basename "$0"`
14
15 # MYVERSION=3.1.0
16 # COMPATIBLE_VERSIONS='^(3\.1\.[0-9]+)$'
17 # Template for development versions
18 MYVERSION=3.0.5+toward_3.1.0_20140709012553
19 COMPATIBLE_VERSIONS='^(3\.0\.[0-9]+\+toward_3\.1\.[0-9]+_[0-9]+|3\.0\.[0-9]+\+toward_3\.0\.[0-9]+_[0-9]+|3\.1\.[0-9]+)$'
20 MYPREFIX=`dirname "\`dirname \"$0\"\`" | sed 's|/bin$||'`
21 MYPREFIX=${MYPREFIX:-/usr/local}
22 LIBDIR=${MYPREFIX}/lib/${APPNAME}
23
24 . ${LIBDIR}/libtemp.sh
25 . ${LIBDIR}/libstr.sh
26 . ${LIBDIR}/liboptions.sh
27 . ${LIBDIR}/libusage.sh
28 . ${LIBDIR}/libmessage.sh
29 . ${LIBDIR}/libpkgsys.sh
30 . ${LIBDIR}/libmisc.sh
31 . ${LIBDIR}/libfileedit.sh
32 . ${LIBDIR}/libconf.sh
33 . ${LIBDIR}/libdatabase_build.sh
34 . ${LIBDIR}/libdatabase_query.sh
35 . ${LIBDIR}/libdatabase_record.sh
36 . ${LIBDIR}/libcommand.sh
37 . ${LIBDIR}/libprogram.sh
38 . ${LIBDIR}/libreinstall.sh
39 . ${LIBDIR}/libdeinstall.sh
40
41 misc_init_vardefs
42 temp_trap_init
43 DBDIR=/var/tmp/${APPNAME}.db
44 CONFFILE=${MYPREFIX}/etc/${APPNAME}.conf
45 PKGTOOLSCONF=${MYPREFIX}/etc/pkgtools.conf
46
47 # ==================================================
48 # ========= PARSING OPTIONS AND ARGUMENTS ==========
49 # ==================================================
50
51 # ============= Save arguments for upgraded restart =============
52 options_dump_args "$@" > ${TMPDIR}/restart_command.sh
53
54 # ============= Option check =============
55 options_set_default
56
57 options_getopts "$@" || :
58 if [ $OPTIONS_ERRNO -eq 2 ]
59 then
60         message_echo "INTERNAL ERROR: In parsing options" >&2
61         exit 1
62 fi
63 shift "${OPTIONS_SHIFT}"
64
65 # ============= Argument check for no-command options =============
66 if [ $opt_help_mode -ne 0 -o $opt_show_version = yes ]
67 then
68         if [ $# -gt 0 ]
69         then
70                 OPTIONS_ERRNO=1
71         fi
72 fi
73
74 # ============= Output usage if the case of a help mode or option/argument errors =============
75 if [ $OPTIONS_ERRNO -ne 0 ]
76 then
77         exit $OPTIONS_ERRNO
78 elif [ $opt_help_mode -eq 1 ]
79 then
80         usage_short
81         exit
82 elif [ $opt_help_mode -eq 2 ]
83 then
84         usage_long | less -r
85         exit
86 fi
87
88 # ============= Output version number =============
89 if [ $opt_show_version = yes ]
90 then
91         message_version
92         exit
93 fi
94
95 # ============= Set up variables for environment of ports and packages =============
96 conf_setup_ports_envs
97 conf_setup_packages_envs
98
99 # ============= Execute command operations before getting the temporary database ready =============
100 command_exec_before_db_creation "$@"
101
102 # ============= Creation of temporary database directory =============
103 database_build_create
104
105 # ============= Argument check for conventional runs =============
106 command_parse_args "$@"
107 shift "${COMMAND_SHIFT}"
108
109
110 # ==================================================
111 # ================== TOOLS SET UP ==================
112 # ==================================================
113
114 # ============= Termination messages during construction of the temporary database =============
115
116 # Set termination messages
117 temp_terminate_process_common ()
118 {
119         local msg_where
120         [ $opt_batch_mode = yes ] && return
121         msg_where=`temp_get_msg_current_stage`
122         [ -n "$msg_where" ] && msg_where=" during $msg_where"
123         echo
124         if [ $errno -eq 130 ]
125         then
126                 echo "INFO: Terminated at `message_timestamp`$msg_where."
127                 echo
128                 echo " You can restart this process from the terminated point by"
129         else
130                 echo "INFO: Aborted at `message_timestamp`$msg_where."
131                 echo
132                 echo " You may restart this process from the aborted point by"
133         fi
134         echo "executing without options or arguments as:"
135         if [ -n "$COMMAND_RESTART" ]
136         then
137                 echo "  ${APPNAME} $COMMAND_RESTART"
138         else
139                 echo "  ${APPNAME}"
140         fi
141 }
142
143 temp_terminate_process ()
144 {
145         local tmp_msg
146         tmp_msg=${TMPDIR}/temp_terminate_process:msg
147         [ $errno -eq 0 -o $opt_batch_mode = yes ] && return
148         temp_terminate_process_common
149         [ -n "$COMMAND_RESTART" ] && return
150         cat > $tmp_msg << eof
151  Instead, if you only want to construct the temporary database so as to stop before the actual reinstallation, execute as:
152   ${APPNAME} prepare
153 eof
154         message_cat "$tmp_msg"
155 }
156
157 # ============= Opening title =============
158
159 message_credit
160 [ $COMMAND_MODE = do -o $COMMAND_MODE = redo -o $COMMAND_MODE = forget ] && \
161         message_opening_notice
162 message_echo
163
164 # ============= Execute command operations which do not need package tools =============
165
166 command_exec_without_pkgtools "$@"
167 misc_is_superuser_privilege && touch "${DBDIR}/in_use"
168
169 # ============= Definition of environment dependent functions =============
170
171 pkgsys_def_pkgtools
172
173 # ============= Option settings =============
174
175 # Execute command operations which are not affected by saved option settings
176 command_exec_irrespective_of_saved_options "$@"
177
178 # Load, renew and save option values
179 optcomb_err=0
180 options_chk_invalid_optvals_renewal non_renewable || optcomb_err=$?
181 if [ \( $opt_reload_conf = yes -o $opt_reset_targets = yes \) -a "x$COMMAND_MODE" != xredo ]
182 then
183         message_echo "ERROR: Options -L and -N are available only in the initial run of redo command." >&2
184         message_echo >&2
185         optcomb_err=1
186 fi
187 if [ $opt_batch_ports_only = yes -a $opt_interactive_ports_only = yes ]
188 then
189         message_echo "ERROR: Options -A and -I conflict with each other." >&2
190         message_echo >&2
191         optcomb_err=1
192 fi
193 if [ -e "${DBDIR}/saved_options.sh" ]
194 then
195         {
196                 options_renewed_optvals M renewable_anytime || optcomb_err=$?
197                 options_renewed_optvals N renewable_in_redo_on_target || optcomb_err=$?
198                 options_renewed_optvals L renewable_in_redo_on_conf || optcomb_err=$?
199         } > ${TMPDIR}/renewed_optvals.sh
200         [ $optcomb_err -eq 0 ] || exit $optcomb_err
201         . "${DBDIR}/saved_options.sh"
202         . "${TMPDIR}/renewed_optvals.sh"
203 fi
204 misc_is_superuser_privilege && misc_get_all_vardefs | options_filter saved > ${DBDIR}/saved_options.sh
205
206 # Show option values
207 if [ -e "${DBDIR}/saved_options.sh" -a $opt_batch_mode = no \
208         -a \( $COMMAND_MODE = do -o $COMMAND_MODE = redo \) ]
209 then
210         message_echo "INFO: List of option values:"
211         message_echo "-----------------------------------------"
212         message_cat "${DBDIR}/saved_options.sh"
213         message_echo "-----------------------------------------"
214         message_echo
215 fi
216
217 # ============= Configurations =============
218
219 # Save the previous configuration if exists
220 PROGRAM_DEPENDS=''
221 _program_exec_and_record_completion__operation ()
222 {
223         rm -rf "${DBDIR}/conf.prev"
224         [ -d "${DBDIR}/conf" ] && \
225                 cp -Rp "${DBDIR}/conf" "${DBDIR}/conf.prev"
226         :
227 }
228 program_exec_and_record_completion SAVE_PREV_CONF
229
230 # Get complete configuration variable definitions by importing pkgtools.conf(5) if available
231 PROGRAM_DEPENDS='SAVE_PREV_CONF'
232 _program_exec_and_record_completion__operation ()
233 {
234         local need_msg
235         need_msg=no
236         rm -rf "${DBDIR}/conf"
237         mkdir -p "${DBDIR}/conf"
238         [ "x`options_get_effective_opt_load_pkgtoolsconf 2> /dev/null`" != xno -a $opt_batch_mode = no ] \
239                 && need_msg=yes
240         [ $need_msg = yes ] && \
241                 message_section_title "Parsing pkgtools.conf (by using installed portupgrade)"
242         conf_get_complete_var_defs > ${DBDIR}/conf/complete_setup.sh
243         [ $need_msg = yes ] &&  { message_echo "===> ok"; message_echo; }
244         :
245 }
246 program_exec_and_record_completion GET_COMPLETE_CONF_VAR_DEF
247
248 # Parse the configuration
249 PROGRAM_DEPENDS='GET_COMPLETE_CONF_VAR_DEF'
250 _program_exec_and_record_completion__operation ()
251 {
252         message_section_title "Parsing the configuration"
253         conf_manipulate_available_var_defs
254         . "${DBDIR}/conf/manipulated_defs.sh"
255         # ALT_MOVED_*
256         conf_build_effective_MOVED
257         # Environmental variables
258         conf_setup_effective_env > ${DBDIR}/conf/setenv.sh
259         . "${DBDIR}/conf/setenv.sh"
260         # HOLD_*
261         conf_parse_vars_for_each_port_glob HOLD
262         str_escape_regexp_filter < ${DBDIR}/conf/HOLD:PORTS.parsed \
263                 | sed 's/^/^/;s/$/$/' > ${DBDIR}/conf/HOLD_PORTS.grep_pattern
264         # TABOO_*
265         conf_parse_vars_for_each_port_glob TABOO
266         fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" \
267                 > ${DBDIR}/taboo.all.list
268         # NOPKG_*
269         conf_parse_vars_for_each_port_glob NOPKG
270         # REPLACE_*
271         conf_build_replacement_patterns_from_REPLACE
272         # MARG_*
273         conf_parse_vars_for_each_port_glob_with_bound_val MARG TARGET DEF
274         # MENV_*
275         conf_parse_vars_for_each_port_glob_with_bound_val MENV TARGET DEF
276         # BEFOREBUILD_*
277         conf_parse_vars_for_each_port_glob_with_bound_val BEFOREBUILD TARGET COMMAND
278         # BEFOREDEINSTALL_*
279         conf_parse_vars_for_each_port_glob_with_bound_val BEFOREDEINSTALL TARGET COMMAND
280         # AFTERINSTALL_*
281         conf_parse_vars_for_each_port_glob_with_bound_val AFTERINSTALL TARGET COMMAND
282         message_echo
283 }
284 program_exec_and_record_completion PARSE_CONF
285
286 . "${DBDIR}/conf/setenv.sh"
287
288 # ============= Upgrade of tools =============
289
290 # Execute command operations which should be done without upgrade of tools
291 command_exec_before_tools_upgrade "$@"
292
293 # Check whether the temporary database is newer than the ports tree and refresh if so
294 database_build_refresh_if_obsolete
295
296 # Get the port origin for this utility if installed by port
297 MYPORTORIGIN=`pkgsys_get_my_origin 2> /dev/null` || :
298
299 # Collect all installed packages
300 PROGRAM_DEPENDS=''
301 _program_exec_and_record_completion__operation ()
302 {
303         local tmp_installed_ports tmp_installed_pkgs
304         message_section_title "Collecting all installed packages"
305         if [ -e "${DBDIR}/installed_ports.inspected" ]
306         then
307                 if ! [ "${DBDIR}/installed_ports" -ot "${DBDIR}/initial" -a "${DBDIR}/installed_ports:pkg_vs_origin.tbl" -ot "${DBDIR}/initial" ]
308                 then
309                         tmp_installed_ports=${TMPDIR}/COLLECT_ALL_INSTALLED_PACKAGES:installed_ports.tmp
310                         tmp_installed_pkgs=${TMPDIR}/COLLECT_ALL_INSTALLED_PACKAGES:installed_pkgs
311                         cp /dev/null "$tmp_installed_ports"
312                         cp /dev/null "$tmp_installed_pkgs"
313                         find "${DBDIR}/initial" -depth 2 -type d | while read dbpath
314                         do
315                                 echo "$dbpath" >> $tmp_installed_ports
316                                 cat "$dbpath/installed_version" >> $tmp_installed_pkgs >&2 || :
317                         done
318                         sed -E 's|.*/([^/]+/[^/]+)$|\1|' "$tmp_installed_ports" > ${DBDIR}/installed_ports
319                         paste "$tmp_installed_pkgs" "${DBDIR}/installed_ports" > ${DBDIR}/installed_ports:pkg_vs_origin.tbl
320                 fi
321         else
322                 pkg_info_qoa > ${DBDIR}/installed_ports
323                 pkg_info_gen_pkg_origin_table
324         fi
325         str_escape_regexp_filter < "${DBDIR}/installed_ports" \
326                 | sed 's/^/^/; s/$/$/' > ${DBDIR}/installed_ports.grep_pattern
327         message_echo
328 }
329 program_exec_and_record_completion COLLECT_ALL_INSTALLED_PACKAGES
330
331 # Preliminary inspection of tools which have to be up-to-date
332 # (No need depend on PARSE_CONF because INSPECT_ALL_DEPENDENCIES will take the task.)
333 PROGRAM_DEPENDS=
334 _program_exec_restartable_loop_operation__routine ()
335 {
336         local origin
337         origin=$1
338         database_build_inspect_dependencies "$origin"
339 }
340 _program_exec_and_record_completion__operation ()
341 {
342         local DEPTH_INDEX
343         message_section_title "Preliminary inspection of tools which have to be up-to-date"
344         {
345                 [ "$PKGSYS_USE_PKGNG" = yes ] && echo 'ports-mgmt/pkg'
346                 pkgsys_is_dialog4ports_used && echo 'ports-mgmt/dialog4ports'
347                 [ -n "$MYPORTORIGIN" ] && echo "$MYPORTORIGIN"
348         } 2> /dev/null > ${DBDIR}/stage.loop_list/tools_to_inspect
349         DEPTH_INDEX='--'
350         program_exec_restartable_loop_operation tools_to_inspect
351         database_build_post_inspect_dependencies
352         message_echo
353 }
354 program_exec_and_record_completion PRELIMINARY_INSPECTION_OF_TOOLS
355
356 # Upgrade of ports-mgmt/pkg if new
357 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
358 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
359         -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no \
360         -a "$PKGSYS_USE_PKGNG" = yes ]
361 then
362         PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
363         _program_exec_and_record_completion__operation ()
364         {
365                 local _MSG_CURRENT_STAGE_general
366                 _MSG_CURRENT_STAGE_general="pkgng upgrade"
367                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
368                 message_section_title "Upgrade of ports-mgmt/pkg if new"
369                 touch "${DBDIR}/target_all"
370                 reinstall_exec ports-mgmt/pkg
371                 reinstall_restore_conflicts
372                 rm -f "${DBDIR}/target_all"
373                 temp_set_msg_current_stage
374                 message_echo
375         }
376         program_exec_and_record_completion UPGRADE_PKGNG
377 fi
378
379 # Upgrade of ports-mgmt/dialog4ports if new
380 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
381 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
382         -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no ] \
383         && pkgsys_is_dialog4ports_used
384 then
385         PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
386         _program_exec_and_record_completion__operation ()
387         {
388                 local _MSG_CURRENT_STAGE_general
389                 _MSG_CURRENT_STAGE_general="pkgng dialog4ports"
390                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
391                 message_section_title "Upgrade of dialog4ports if new"
392                 touch "${DBDIR}/target_all"
393                 reinstall_exec ports-mgmt/dialog4ports
394                 reinstall_restore_conflicts
395                 rm -f "${DBDIR}/target_all"
396                 temp_set_msg_current_stage
397                 message_echo
398         }
399         program_exec_and_record_completion UPGRADE_DIALOG4PORTS
400 fi
401
402 # Upgrade of this utility if new
403 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
404 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
405         -a $opt_dry_run = no -a $opt_suppress_self_upadte = no \
406         -a -n "$MYPORTORIGIN" ]
407 then
408         PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
409         _program_exec_and_record_completion__operation ()
410         {
411                 local _MSG_CURRENT_STAGE_general
412                 _MSG_CURRENT_STAGE_general="pkgng upgrade"
413                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
414                 message_section_title "Upgrade of this utility if new"
415                 touch "${DBDIR}/target_all"
416                 reinstall_exec "$MYPORTORIGIN"
417                 reinstall_restore_conflicts
418                 rm -f "${DBDIR}/target_all"
419                 temp_set_msg_current_stage
420                 message_echo
421         }
422         program_exec_and_record_completion UPGRADE_SELF
423 fi
424
425 if [ "x`${APPNAME} -aV 2> /dev/null`" != "x$MYVERSION" ]
426 then
427         message_echo "INFO: ${APPNAME} is upgraded and the temporary database needs refresh."
428         database_build_clean_for_self_upgrade || :
429         message_echo "INFO: Restarting with the new version."
430         message_echo
431         temp_trap_for_invoking_new_version
432         . "${TMPDIR}"/restart_command.sh
433         exit
434 fi
435
436
437 # ==================================================
438 # ================== PREPARATION ===================
439 # ==================================================
440
441 # ============= Correspondence to configuration changes =============
442
443 # Patch to the temporary database by reflecting changes in configuration
444 PROGRAM_DEPENDS='PARSE_CONF'
445 _program_exec_and_record_completion__operation ()
446 {
447         local tmpfile_diff tmpfile_old tmpfile_new key
448         [ -d "${DBDIR}/conf.prev" ] || return 0
449         message_section_title "Patch to the temporary database by reflecting changes in configuration"
450         tmpfile_old=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::old
451         tmpfile_new=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::new
452         tmpfile_updated_ports=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::updated_ports
453         if fileedit_manipulate_old_new_lines \
454                 "${DBDIR}/conf.prev/setenv.sh" "${DBDIR}/conf/setenv.sh" "$tmpfile_old" "$tmpfile_new"
455         then
456                 if grep -q -e ^LOCALBASE= -e ^LINUXBASE= -e ^PORTSDIR= "$tmpfile_old" "$tmpfile_new"
457                 then
458                         message_echo "ERROR: Migration of the temporary database is unavailable because LOCALBASE, LINUXBASE or PORTSDIR was changed." >&2
459                         message_echo "        ${APPNAME} clean" >&2
460                         message_echo "must be executed in advance." >&2
461                         exit 1
462                 fi
463         fi
464         cut -s -d '|' -f 1,2 "${DBDIR}/conf.prev/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.old
465         cut -s -d '|' -f 1,2 "${DBDIR}/conf/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.new
466         if fileedit_manipulate_old_new_lines \
467                 "${TMPDIR}/MOVED_ALT.old" "${TMPDIR}/MOVED_ALT.new" "$tmpfile_old" "$tmpfile_new"
468         then
469                 cat "$tmpfile_old" "$tmpfile_new" | while read from to
470                 do
471                         echo "$from"
472                         [ -n "$to" ] && echo "$to"
473                 done
474         fi > $tmpfile_updated_ports
475         if fileedit_manipulate_old_new_lines \
476                 "${DBDIR}/conf.prev/REPLACE.csv" "${DBDIR}/conf/REPLACE.csv" "$tmpfile_old" "$tmpfile_new"
477         then
478                 cat "$tmpfile_old" "$tmpfile_new" | while read from to
479                 do
480                         echo "$from"
481                         [ -n "$to" ] && echo "$to"
482                 done
483         fi >> $tmpfile_updated_ports
484         [ `wc -l < $tmpfile_updated_ports` -gt 0 ] && rm -f "${DBDIR}/REPLACE.complete_sed_pattern"
485         [ -d "${DBDIR}/conf/each_port" ] && find "${DBDIR}/conf/each_port" -depth 2 \
486                 | while read dbpath
487         do
488                 origin=`str_dirpath_to_origin "$dbpath"`
489                 dbpath_prev=${DBDIR}/conf.prev/each_port/$origin
490                 diff -r "$dbpath_prev" "$dbpath" > /dev/null 2>&1 && continue
491                 echo "$origin"
492         done >> $tmpfile_updated_ports
493         [ -d "${DBDIR}/conf.prev/each_port" ] && find "${DBDIR}/conf.prev/each_port" -depth 2 \
494                 | while read dbpath_prev
495         do
496                 origin=`str_dirpath_to_origin "$dbpath_prev"`
497                 dbpath=${DBDIR}/conf/each_port/$origin
498                 [ -d "$dbpath" ] && continue
499                 echo "$origin"
500         done >> $tmpfile_updated_ports
501         if [ `wc -l < $tmpfile_updated_ports` -gt 0 ]
502         then
503                 sort -u "$tmpfile_updated_ports" | while read origin
504                 do
505                         database_build_patch_reconf "$origin"
506                 done
507                 program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
508         fi
509         message_echo
510 }
511 program_exec_and_record_completion PATCH_TO_TMPDB_REFLECT_CONF_CHANGES
512
513 # ============= Database construction =============
514
515 # Execute command operations which must be done before building the temporary database
516 command_exec_before_building_tempdb "$@"
517
518 # Meta process for redo
519 PROGRAM_DEPENDS=''
520 _program_exec_and_record_completion__operation ()
521 {
522         rm -f "${DBDIR}/new_success_in_current_run"
523         [ "x$COMMAND_MODE" = xredo ] || return 0
524         message_echo "[REDO mode]"
525         message_echo
526 }
527 program_exec_and_record_completion REDO_INIT
528
529 # Determine specified targets
530 PROGRAM_DEPENDS=''
531 _program_exec_and_record_completion__operation ()
532 {
533         local tag level dbsuffix
534         message_section_title "Determining specified targets"
535         cat "${DBDIR}/stage.loop_list/target_itself.specified" \
536                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
537                 "${DBDIR}/stage.loop_list/target_requirements.specified" \
538                 "${DBDIR}/need.list" \
539                 "${DBDIR}/targets_specified_so_far" 2> /dev/null \
540                 | sort -u > ${DBDIR}/targets_specified_so_far.tmp
541         mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
542         rm -f "${DBDIR}/stage.loop_list/target_itself.specified" \
543                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
544                 "${DBDIR}/stage.loop_list/target_requirements.specified"
545         if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
546         then
547                 options_select_new_ports_if_duplicated O \
548                         "${DBDIR}/stage.loop_list/target_itself.specified" "$opt_target_itself"
549                 options_select_new_ports_if_duplicated t \
550                         "${DBDIR}/stage.loop_list/target_dependents.specified" "$opt_target_dependents"
551                 options_select_new_ports_if_duplicated T \
552                         "${DBDIR}/stage.loop_list/target_requirements.specified" "$opt_target_requirements"
553                 if [ `cat "${DBDIR}/stage.loop_list/target_itself.specified" \
554                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
555                         "${DBDIR}/stage.loop_list/target_requirements.specified" | wc -l` -eq 0 ]
556                 then
557                         message_echo "ERROR: No matching port for target globs." >&2
558                         message_echo >&2
559                         exit 1
560                 fi
561                 cat "${DBDIR}/stage.loop_list/target_itself.specified" \
562                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
563                         "${DBDIR}/stage.loop_list/target_requirements.specified" \
564                         | sort -u > ${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset
565                 cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset" "${DBDIR}/need.list" 2> /dev/null \
566                         | sort -u > ${DBDIR}/need.list.tmp
567                 mv "${DBDIR}/need.list.tmp" "${DBDIR}/need.list"
568                 sort -u "${DBDIR}/need.list" "${DBDIR}/targets_specified_so_far" \
569                         > ${DBDIR}/targets_specified_so_far.tmp
570                 mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
571                 for tag in all run build none
572                 do
573                         for level in direct full
574                         do
575                                 dbsuffix=$tag.$level
576                                 {
577                                         cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset"
578                                         cat "${DBDIR}/stage.loop_list/target_dependents.specified" | while read origin
579                                         do
580                                                 nodedir=${DBDIR}/requires/$origin
581                                                 cat "$nodedir/dependents.$dbsuffix" 2> /dev/null
582                                         done
583                                         cat "${DBDIR}/stage.loop_list/target_requirements.specified" | while read origin
584                                         do
585                                                 nodedir=${DBDIR}/requires/$origin
586                                                 cat "$nodedir/requirements.$dbsuffix" 2> /dev/null
587                                         done
588                                 } | sort -u | while read origin
589                                 do
590                                         fileedit_rm_a_line "$origin" "${DBDIR}/success.$dbsuffix.list"
591                                         fileedit_rm_a_line "$origin" "${DBDIR}/todo_after_requirements_succeed.$dbsuffix.list"
592                                         rm -f "${DBDIR}/requires/$origin/succeeded_once"
593                                 done
594                         done
595                 done
596         fi
597         message_echo
598 }
599 program_exec_and_record_completion DETERMINE_SPECIFIED_TARGETS
600
601 # Show specified targets
602 if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" -a $opt_batch_mode = no ]
603 then
604         message_echo "INFO: (Re/de-)installation will be carried out only for the targets:"
605         echo
606         if [ `wc -l < ${DBDIR}/stage.loop_list/target_itself.specified` -gt 0 ]
607         then
608                 message_echo "[Targets only]"
609                 echo "----------------------------------------"
610                 cat "${DBDIR}/stage.loop_list/target_itself.specified"
611                 echo "----------------------------------------"
612                 echo
613         fi
614         if [ `wc -l < ${DBDIR}/stage.loop_list/target_dependents.specified` -gt 0 ]
615         then
616                 message_echo "[Targets with their `options_get_dependency_msgterm` dependents]"
617                 echo "----------------------------------------"
618                 cat "${DBDIR}/stage.loop_list/target_dependents.specified"
619                 echo "----------------------------------------"
620                 echo
621         fi
622         if [ `wc -l < ${DBDIR}/stage.loop_list/target_requirements.specified` -gt 0 ]
623         then
624                 message_echo "[Targets with their `options_get_dependency_msgterm` requirements]"
625                 echo "----------------------------------------"
626                 cat "${DBDIR}/stage.loop_list/target_requirements.specified"
627                 echo "----------------------------------------"
628                 echo
629         fi
630 fi
631
632 # Determine all target ports
633 PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS COLLECT_ALL_INSTALLED_PACKAGES'
634 _program_exec_and_record_completion__operation ()
635 {
636         message_section_title "Determining all target ports"
637         {
638                 if [ $opt_only_target_scope = no ]
639                 then
640                         cat "${DBDIR}/installed_ports" 2> /dev/null || :
641                 fi
642                 cat "${DBDIR}/stage.loop_list/target_itself.specified" || :
643                 cat "${DBDIR}/stage.loop_list/target_dependents.specified" || :
644                 cat "${DBDIR}/stage.loop_list/target_requirements.specified" || :
645                 cat "${DBDIR}/targets_specified_so_far" || :
646         }  2> /dev/null | sort -u > "${DBDIR}/stage.loop_list/ports_to_inspect"
647         message_echo
648 }
649 program_exec_and_record_completion DETERMINE_ALL_TARGET_PORTS
650
651 # Inspection of all dependencies
652 PROGRAM_DEPENDS='PARSE_CONF DETERMINE_ALL_TARGET_PORTS'
653 _program_exec_restartable_loop_operation__routine ()
654 {
655         local origin
656         origin=$1
657         database_build_inspect_dependencies "$origin"
658 }
659 _program_exec_and_record_completion__operation ()
660 {
661         local DEPTH_INDEX 
662         message_section_title "Inspecting dependencies of the all installed packages"
663         [ $opt_only_target_scope = no -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] && \
664                 message_echo "INFO: Ports which seem irrelevant to the targets are also inspected in order to get complete information."
665         DEPTH_INDEX='--'
666         program_exec_restartable_loop_operation ports_to_inspect
667         database_build_post_inspect_dependencies
668         message_echo
669 }
670 program_exec_and_record_completion INSPECT_ALL_DEPENDENCIES
671
672 # Convert dependency-lists to actual ones
673 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES'
674 _program_exec_restartable_loop_operation__routine ()
675 {
676         local origin table dbtag level tag target
677         origin=$1
678         for table in dependents requirements
679         do
680                 for dbtag in requires obsolete
681                 do
682                         for level in direct full
683                         do
684                                 for tag in all run build
685                                 do
686                                         target=${DBDIR}/$dbtag/$origin/${table}.${tag}.${level}
687                                         if [ -e "$target.src" ]
688                                         then
689                                                 sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" "$target.src" \
690                                                         | grep -v '^$' | sort -u > $target.tmp
691                                                 [ -e "$target" ] && ! diff "$target.tmp" "$target" > /dev/null \
692                                                         && echo "$origin" >> ${DBDIR}/update_dependencies
693                                                 mv "$target.tmp" "$target"
694                                         else
695                                                 [ -e "$target" ] && echo "$origin" >> ${DBDIR}/update_dependencies
696                                                 rm -f "$target"
697                                         fi
698                                 done
699                         done
700                 done
701         done
702 }
703 _program_exec_and_record_completion__operation ()
704 {
705         message_section_title "Conversion of dependency-lists to actual ones"
706         program_exec_restartable_loop_operation convert_dependency_lists
707         sort -u "${DBDIR}/update_dependencies" > ${DBDIR}/update_dependencies.tmp
708         mv "${DBDIR}/update_dependencies.tmp" "${DBDIR}/update_dependencies"
709         str_escape_regexp_filter < ${DBDIR}/update_dependencies \
710                 | sed 's/^/^/; s/$/$/' > ${DBDIR}/update_dependencies.grep_pattern
711         for tag in all run build
712         do
713                 ( cd "${DBDIR}/requires" && \
714                         find . -depth 3 -type f -name requirements.${tag}.full -or -name requirements.${tag}.full.orig ) \
715                         | sort -u \
716                         | sed 's|^./||;s|/[^/]*$||' \
717                         | grep -v -E -f "${DBDIR}/update_dependencies.grep_pattern" \
718                         | str_escape_regexp_filter | sed 's/^/^/; s/$/$/' \
719                         > ${TMPDIR}/convert_requirements_list:full_complete.grep_pattern || :
720                 ( cd "${DBDIR}/requires" && \
721                         find . -depth 3 -type f -name requirements.${tag}.direct -or -name requirements.${tag}.direct.orig ) \
722                         | sort -u \
723                         | sed 's|^./||;s|/[^/]*$||' \
724                         | grep -v -E -f "${TMPDIR}/convert_requirements_list:full_complete.grep_pattern" \
725                         > ${DBDIR}/stage.loop_list/complete_recursive_${tag}time_reqlists || :
726         done
727         for inspected_level_tmp in direct node
728         do
729                 cat "${DBDIR}/ports.inspected.${inspected_level_tmp}.list" || :
730         done 2> /dev/null | sort -u > ${DBDIR}/stage.loop_list/trim_dependency_lists_rm_uninspected_ports
731         find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/stage.loop_list/inspect_dependent
732         [ -e "${DBDIR}/dependents_files" ] && \
733                 mv "${DBDIR}/dependents_files" "${DBDIR}/dependents_files.prev"
734         rm -f "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" "${DBDIR}/dependents_files.tmp"
735         message_echo
736 }
737 program_exec_and_record_completion CONVERT_REQUIREMENTS_LIST
738
739 # Completion of recursive requirement lists
740 for _REQUIREMENT_LISTS_tag in all run build
741 do
742         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
743         _program_exec_restartable_loop_operation__routine ()
744         {
745                 local tag dbpath origin suffix
746                 tag=${_REQUIREMENT_LISTS_tag}
747                 dbpath=$1
748                 origin=`str_dirpath_to_origin "$dbpath"`
749                 for suffix in '' .orig
750                 do
751                         database_build_get_complete_recursive_dependency requirements.${tag} "$origin" "$suffix" > /dev/null
752                 done
753         }
754         _program_exec_and_record_completion__operation ()
755         {
756                 local tag
757                 tag=${_REQUIREMENT_LISTS_tag}
758                 message_section_title "Completion of ${tag}-time requirement lists"
759                 program_exec_restartable_loop_operation complete_recursive_${tag}time_reqlists
760                 message_echo
761         }
762         program_exec_and_record_completion RECURSIVE_REQUIREMENT_LISTS:${_REQUIREMENT_LISTS_tag}
763 done
764
765 # Trim dependency lists by removing uninspected ports
766 if [ $opt_only_target_scope = yes ]
767 then
768         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST'
769         _program_exec_restartable_loop_operation__routine ()
770         {
771                 local dbpath tag level srcdb
772                 dbpath=$1
773                 for tag in all run build
774                 do
775                         for level in direct full
776                         do
777                                 srcdb=requirements.${tag}.${level}
778                                 [ -e "$dbpath/$srcdb" ] || continue
779                                 grep -E -f "${DBDIR}/inspected_ports.grep_pattern" "$dbpath/$srcdb" \
780                                         > $dbpath/$srcdb.tmp || :
781                                 mv "$dbpath/$srcdb.tmp" "$dbpath/$srcdb"
782                         done
783                 done
784         }
785         _program_exec_and_record_completion__operation ()
786         {
787                 message_section_title "Trimming dependency lists by removing uninspected ports"
788                 program_exec_restartable_loop_operation trim_dependency_lists_rm_uninspected_ports
789                 message_echo
790         }
791         program_exec_and_record_completion TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS
792 fi
793
794 # Inspection of dependents
795 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS'
796 _program_exec_restartable_loop_operation__routine ()
797 {
798         local dbpath origin tag level suffix srcdb dstdb
799         dbpath=$1
800         origin=`str_dirpath_to_origin "$dbpath"`
801         for tag in all run build
802         do
803                 for level in direct full
804                 do
805                         for suffix in '' .orig
806                         do
807                                 srcdb=requirements.${tag}.${level}${suffix}
808                                 dstdb=dependents.${tag}.${level}${suffix}
809                                 [ -e "$dbpath/$srcdb" ] || continue
810                                 while read origin_requirement
811                                 do
812                                         dstpath=${DBDIR}/requires/$origin_requirement
813                                         echo "$dstpath/$dstdb" >> ${DBDIR}/dependents_files.tmp
814                                         [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue
815                                         [ -d "$dstpath" ] || mkdir -p "$dstpath"
816                                         echo "$origin" >> $dstpath/$dstdb.raw
817                                         echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp
818                                 done < $dbpath/$srcdb
819                         done
820                 done
821         done
822 }
823 _program_exec_and_record_completion__operation ()
824 {
825         local dbrequires_valesc
826         message_section_title "Inspection of dependents"
827         dbrequires_valesc=`str_escape_replaceval "${DBDIR}/requires/"`
828         program_exec_restartable_loop_operation inspect_dependent
829         sort -u "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" 2> /dev/null \
830                 > ${DBDIR}/stage.loop_list/make_dependents_lists_unique || :
831         sort -u "${DBDIR}/dependents_files.tmp" 2> /dev/null > ${DBDIR}/dependents_files || :
832         [ -e "${DBDIR}/make_dependents_lists_unique.prev" ] && \
833                 fileedit_manipulate_old_lines "${DBDIR}/dependents_files.prev" "${DBDIR}/dependents_files" \
834                 | xargs rm -f
835         message_echo
836 }
837 program_exec_and_record_completion INSPECT_DEPENDENTS
838
839 # Remove duplicated lines in dependents lists
840 PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS'
841 _program_exec_restartable_loop_operation__routine ()
842 {
843         local dbpath tag level dstdb
844         dstdb=$1
845         cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp
846         mv "$dstdb.tmp" "$dstdb"
847         rm -f "$dstdb.raw"
848 }
849 _program_exec_and_record_completion__operation ()
850 {
851         local dbrequires_valesc
852         message_section_title "Removing duplicated items in dependents lists"
853         program_exec_restartable_loop_operation make_dependents_lists_unique
854         message_echo
855 }
856 program_exec_and_record_completion MAKE_DEPENDENTS_LISTS_UNIQUE
857
858 # Preparation of target attribute information
859 for _TARGET_ATTR_INFO_table in requirements dependents itself
860 do
861         [ `cat "${DBDIR}/stage.loop_list/target_${_TARGET_ATTR_INFO_table}.replaced.specified" 2> /dev/null \
862                 | wc -l` -gt 0 ] || continue
863         PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS CONVERT_REQUIREMENTS_LIST'
864         _program_exec_restartable_loop_operation__routine ()
865         {
866                 local origin dbtargets_valesc table
867                 origin=$1
868                 dbtargets_valesc=`str_escape_replaceval "${DBDIR}/targets/"`
869                 table=${_TARGET_ATTR_INFO_table}
870                 for database in requires initial
871                 do
872                         dbpath=${DBDIR}/$database/$origin
873                         dstpath=${DBDIR}/targets/$origin
874                         [ -d "$dstpath" ] || mkdir -p "$dstpath"
875                         touch "$dstpath/target_itself"
876                         echo "$origin" >> ${DBDIR}/all_targets.lst
877                         [ $table = itself ] && continue
878                         for tag in all run build
879                         do
880                                 for level in direct full
881                                 do
882                                         srcdb=${table}.${tag}.${level}
883                                         dstdb=target_${database}_${table}.${tag}.${level}
884                                         [ -e "$dbpath/$srcdb" ] || continue
885                                         cat "$dbpath/$srcdb" >> ${DBDIR}/all_targets.lst
886                                         sed -E "s/^/$dbtargets_valesc/; s|$|/$dstdb|" "$dbpath/$srcdb" \
887                                                 | fileedit_add_a_line_to_files_if_new "$origin"
888                                 done
889                         done
890                 done
891         }
892         _program_exec_and_record_completion__operation ()
893         {
894                 local table
895                 table=${_TARGET_ATTR_INFO_table}
896                 message_section_title "Preparation of target attribute information for dependency [$table]"
897                 program_exec_restartable_loop_operation target_$table.replaced.specified
898                 message_echo
899         }
900         program_exec_and_record_completion TARGET_ATTR_INFO:${_TARGET_ATTR_INFO_table}
901 done
902
903 # Post-process after the preparation of target attribute information
904 PROGRAM_DEPENDS='MAKE_DEPENDENTS_LISTS_UNIQUE TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents'
905 _program_exec_and_record_completion__operation ()
906 {
907         message_section_title "Post-process after the preparation of target attribute information"
908         sort -u "${DBDIR}/all_targets.lst" 2> /dev/null \
909                 | grep -E -f "${DBDIR}/inspected_ports.grep_pattern" \
910                 | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" \
911                 > ${DBDIR}/all_targets.lst.tmp || :
912         mv "${DBDIR}/all_targets.lst.tmp" "${DBDIR}/all_targets.lst"
913         find "${DBDIR}/targets" -depth 2 -type d > ${DBDIR}/stage.loop_list/build_complement_to_new_dependents_for_targets 2> /dev/null || :
914         {
915                 cat "${DBDIR}/all_targets.lst" "${DBDIR}/need.with_replaced.list" 2> /dev/null || :
916                 find "${DBDIR}/requires" -depth 3 -type f -name installed_version \
917                         | sed -E 's|.*/([^/]+/[^/]+)/[^/]*$|\1|'
918         } | sort -u > ${DBDIR}/stage.loop_list/inspect_necessity
919         cp /dev/null "${DBDIR}/stage.loop_list/parse_target_attr_info"
920         find -E "${DBDIR}/requires" -depth 3 -type f -regex '.*/necessary_port\.(direct|full)$' -delete
921         message_echo
922 }
923 program_exec_and_record_completion TARGET_ATTR_INFO_POSTPROCESS
924
925 # Build of data on complement to new dependents for target attribute information
926 PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents CONVERT_REQUIREMENTS_LIST'
927 _program_exec_restartable_loop_operation__routine ()
928 {
929         local dbpath origin
930         dbpath=$1
931         origin=`str_dirpath_to_origin "$dbpath"`
932         database_build_complement_to_new_dependents_for_targets "$origin"
933 }
934 _program_exec_and_record_completion__operation ()
935 {
936         message_section_title "Build of data on complement to new dependents for target attribute information"
937         program_exec_restartable_loop_operation build_complement_to_new_dependents_for_targets
938         sort -u "${DBDIR}/stage.loop_list/parse_target_attr_info" > ${DBDIR}/stage.loop_list/parse_target_attr_info.tmp
939         mv "${DBDIR}/stage.loop_list/parse_target_attr_info.tmp" "${DBDIR}/stage.loop_list/parse_target_attr_info"
940         message_echo
941 }
942 program_exec_and_record_completion COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO
943
944 # Parse target attribute information
945 PROGRAM_DEPENDS='COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO'
946 _program_exec_restartable_loop_operation__routine ()
947 {
948         local dbpath origin
949         dbpath=$1
950         origin=`str_dirpath_to_origin "$dbpath"`
951         database_build_target_attributes "$origin"
952 }
953 _program_exec_and_record_completion__operation ()
954 {
955         message_section_title "Parsing target attribute information"
956         program_exec_restartable_loop_operation parse_target_attr_info
957         message_echo
958 }
959 program_exec_and_record_completion PARSE_TARGET_ATTR_INFO
960
961 # Inspection of necessity
962 PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS RECURSIVE_REQUIREMENT_LISTS:run RECURSIVE_REQUIREMENT_LISTS:build INSPECT_ALL_DEPENDENCIES'
963 _program_exec_restartable_loop_operation__routine ()
964 {
965         local origin
966         origin=$1
967         for level in direct full
968         do
969                 database_build_inspect_necessity_for_only_new_upgrade "$origin" "$level"
970         done
971 }
972 _program_exec_and_record_completion__operation ()
973 {
974         message_section_title "Inspection of necessity"
975         program_exec_restartable_loop_operation inspect_necessity
976         for level in direct full
977         do
978                 find "${DBDIR}/requires" -depth 3 -type f -name "necessary_port.${level}" \
979                         > ${DBDIR}/stage.loop_list/necessary_ports.${level}
980         done
981         message_echo
982 }
983 program_exec_and_record_completion INSPECT_NECESSITY
984
985 # Inspection of necessary upgrades
986 for _NECESSARY_UPDATES_level in direct full
987 do
988         PROGRAM_DEPENDS='INSPECT_NECESSITY INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE'
989         _program_exec_restartable_loop_operation__routine ()
990         {
991                 local markerpath level dbpath origin tag
992                 markerpath=$1
993                 level=${_NECESSARY_UPDATES_level}
994                 dbpath=`dirname "$markerpath"`
995                 origin=`str_dirpath_to_origin "$dbpath"`
996                 database_query_does_a_port_need_update "$origin" || return 0
997                 for tag in all run build none
998                 do
999                         touch "$dbpath/necessary_upgrade.$tag.${level}"
1000                         [ -e "$dbpath/dependents.$tag.${level}" ] || continue
1001                         while read origin_dependent
1002                         do
1003                                 touch "${DBDIR}/requires/$origin_dependent/necessary_upgrade.$tag.${level}"
1004                         done < $dbpath/dependents.$tag.${level}
1005                 done
1006         }
1007         _program_exec_and_record_completion__operation ()
1008         {
1009                 local level
1010                 level=${_NECESSARY_UPDATES_level}
1011                 message_section_title "Inspection of necessary upgrades at the $level level"
1012                 program_exec_restartable_loop_operation necessary_ports.${level}
1013                 message_echo
1014         }
1015         program_exec_and_record_completion NECESSARY_UPDATES:${_NECESSARY_UPDATES_level}
1016 done
1017
1018 # Preparation for inspection of new leaf ports
1019 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1020 then
1021         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE PARSE_CONF'
1022         _program_exec_and_record_completion__operation ()
1023         {
1024                 message_section_title "Preparation for inspection of new leaf ports"
1025                 find "${DBDIR}/requires" -depth 3 -type f -name dependents.all.full \
1026                         | sed -E 's|.*/([^/]+/[^/]+)/[^/]+$|\1|' \
1027                         | sort -u > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports
1028                 sort -u "${DBDIR}/inspected_ports" > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports
1029                 fileedit_manipulate_new_lines \
1030                         "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports" \
1031                         "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports" \
1032                         | grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" \
1033                         > ${DBDIR}/stage.loop_list/leaf_ports_primary_candidates || :
1034                 cp /dev/null "${DBDIR}/grep.leaf_ports.pattern"
1035                 cp /dev/null "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
1036                 message_echo
1037         }
1038         program_exec_and_record_completion PREPARE_INSPECT_LEAF_PORTS
1039 fi
1040
1041 # Inspection of new primary leaf ports
1042 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1043 then
1044         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE PREPARE_INSPECT_LEAF_PORTS PARSE_CONF'
1045         _program_exec_restartable_loop_operation__routine ()
1046         {
1047                 local origin origin_ini origin_esc dbpath origin_req
1048                 origin=$1
1049                 pkgsys_is_pkgtool "$origin" && return
1050                 dbpath=${DBDIR}/requires/$origin
1051                 origin_esc=`str_escape_regexp "$origin"`
1052                 grep -q -E "^$origin_esc$" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
1053                 if ! grep -q -E "^$origin_esc$" "${DBDIR}/noneed.list" 2> /dev/null
1054                 then
1055                         if [ -e "$dbpath/initial_orig" ]
1056                         then
1057                                 origin_ini=`cat "$dbpath/initial_orig"`
1058                                 [ -e "${DBDIR}/initial/$origin_ini/installed_version" \
1059                                         -a `cat "${DBDIR}/initial/$origin_ini/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
1060                                         && return
1061                         fi
1062                         [ -e "${DBDIR}/initial/$origin/installed_version" \
1063                                 -a `cat "${DBDIR}/initial/$origin/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
1064                                 && return
1065                 fi
1066                 if [ -e "$dbpath/requirements.all.full" ]
1067                 then
1068                         grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" "$dbpath/requirements.all.full" | \
1069                                 fileedit_add_lines_if_new "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
1070                 fi
1071                 fileedit_add_a_line_if_new "^$origin_esc$" "${DBDIR}/grep.leaf_ports.pattern"
1072         }
1073         _program_exec_and_record_completion__operation ()
1074         {
1075                 local num_leaves num_leaves_prev
1076                 message_section_title "Inspection of new primary leaf ports"
1077                 program_exec_restartable_loop_operation leaf_ports_primary_candidates
1078                 wc -l < ${DBDIR}/grep.leaf_ports.pattern | tr -d ' ' > ${DBDIR}/num_leaves
1079                 cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
1080                 message_echo "  `cat "${DBDIR}/num_leaves"` primary leaf port(s) is/are found."
1081                 message_echo
1082         }
1083         program_exec_and_record_completion INSPECT_PRIMARY_LEAF_PORTS
1084 fi
1085
1086 # Inspection of requirements of new leaf ports
1087 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1088 then
1089         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE INSPECT_PRIMARY_LEAF_PORTS PARSE_CONF'
1090         _program_exec_and_record_completion__operation ()
1091         {
1092                 local num_leaves num_leaves_prev num_inspect num_leaves_new
1093                 message_section_title "Inspection of requirements of new leaf ports"
1094                 message_echo "INFO: The inspection proceeds by iterative method."
1095                 while :
1096                 do
1097                         _program_exec_restartable_loop_operation__routine ()
1098                         {
1099                                 local origin origin_esc dbpath
1100                                 origin=$1
1101                                 pkgsys_is_pkgtool "$origin" && return
1102                                 dbpath=${DBDIR}/requires/$origin
1103                                 origin_esc=`str_escape_regexp "$origin"`
1104                                 grep -q -E "^$origin_esc$" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
1105                                 grep -E -v -f "${DBDIR}/grep.leaf_ports.pattern" \
1106                                         "$dbpath/dependents.all.full" > /dev/null 2>&1 && return
1107                                 cat "$dbpath/requirements.all.full" 2> /dev/null \
1108                                         >> ${DBDIR}/leaf_ports_secondary_candidates.new_requirements || :
1109                                 fileedit_add_a_line_if_new "^$origin_esc$" "${DBDIR}/grep.leaf_ports.pattern"
1110                         }
1111                         program_exec_restartable_loop_operation leaf_ports_secondary_candidates
1112                         num_leaves_prev=`cat "${DBDIR}/num_leaves"`
1113                         num_leaves=`wc -l < ${DBDIR}/grep.leaf_ports.pattern | tr -d ' '`
1114                         num_leaves_new=`echo $(($num_leaves-$num_leaves_prev)) | tr -d ' '`
1115                         if [ $num_leaves_new -eq 0 ]
1116                         then
1117                                 message_echo "  No more leaf port is found."
1118                                 message_echo "  $num_leaves leaf port(s) is/are found in total."
1119                                 break
1120                         fi
1121                         {
1122                                 grep -E -v -f "${DBDIR}/grep.leaf_ports.pattern" \
1123                                         "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
1124                                 cat "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" || :
1125                         } | grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" | sort -u \
1126                                 > ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp || :
1127                         program_reset_loop_for_stage INSPECT_REQUIREMENTS_OF_LEAF_PORTS
1128                         mv "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp" \
1129                                 "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
1130                         cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
1131                         echo "$num_leaves" > ${DBDIR}/num_leaves
1132                         num_inspect=`wc -l < ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates | tr -d ' '`
1133                         message_echo "  $num_leaves_new leaf port(s) is/are newly found; continue for $num_inspect candidate(s)."
1134                 done
1135                 grep -E -f "${DBDIR}/grep.leaf_ports.pattern" "${DBDIR}/inspected_ports" | sort -u > ${DBDIR}/leaf_ports || :
1136                 message_echo
1137         }
1138         program_exec_and_record_completion INSPECT_REQUIREMENTS_OF_LEAF_PORTS
1139 fi
1140
1141 # Order the ports considering dependencies
1142 PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
1143 _program_exec_and_record_completion__operation ()
1144 {
1145         message_section_title "Ordering dependencies"
1146         if ! database_build_order_ports_considering_dependencies
1147         then
1148                 message_echo "ERROR: Unsatisfied dependencies are remained:" >&2
1149                 message_cat "${DBDIR}/unsatisfied.list"
1150                 message_echo "*** Aborted by ${APPNAME}"
1151                 message_echo "The ports tree seems broken. You might have caught an incomplete version."
1152                 message_echo "You are encouraged to update the ports tree by portsnap(8)."
1153                 message_echo "Then execute"
1154                 message_echo " ${APPNAME} clean"
1155                 message_echo "before restart."
1156                 temp_terminate_process () { :; }
1157                 exit 1
1158         fi
1159         message_echo
1160 }
1161 program_exec_and_record_completion ORDER_ALL_DEPENDENCIES
1162
1163 # Selection of removing leaf ports
1164 PROGRAM_DEPENDS='INSPECT_REQUIREMENTS_OF_LEAF_PORTS'
1165 _program_exec_and_record_completion__operation ()
1166 {
1167         message_section_title "Selection of removing leaf ports"
1168         deinstall_select_leaf_ports_to_delete
1169         message_echo
1170 }
1171 program_exec_and_record_completion SELECT_LEAF_PORTS
1172
1173 # Selection of removing obsolete ports
1174 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES PARSE_CONF'
1175 _program_exec_and_record_completion__operation ()
1176 {
1177         message_section_title "Selection of removing obsolete ports"
1178         deinstall_select_obsolete_ports_to_delete
1179         message_echo
1180 }
1181 program_exec_and_record_completion SELECT_OBSOLETE_PORTS
1182
1183 # Collection of leaf ports to delete
1184 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1185 then
1186         PROGRAM_DEPENDS='SELECT_LEAF_PORTS'
1187         _program_exec_and_record_completion__operation ()
1188         {
1189                 local src src_unselected reqptn_file src_with_initial_origins
1190                 message_section_title "Collecting leaf ports to delete"
1191                 src=${DBDIR}/leaf_ports
1192                 src_unselected=${DBDIR}/leaf_ports_to_delete.unselected
1193                 src_with_initial_origins=${DBDIR}/leaf_ports.with_ini
1194                 reqptn_file=${DBDIR}/leaf_ports.requirements_of_unselected.grep_pattern
1195                 cat "$src_unselected" 2> /dev/null | while read origin
1196                 do
1197                         cat "${DBDIR}/requires/$origin/requirements.all.full" || :
1198                 done | sort -u | str_escape_regexp_filter \
1199                         | sed 's/^/^/;s/$/$/' > $reqptn_file
1200                 database_query_add_initial_origins < $src > $src_with_initial_origins
1201                 message_echo
1202         }
1203         program_exec_and_record_completion COLLECT_LEAF_PORTS_TO_DELETE
1204 fi
1205
1206 # Collection of obsolete ports to delete
1207 PROGRAM_DEPENDS='SELECT_OBSOLETE_PORTS'
1208 _program_exec_and_record_completion__operation ()
1209 {
1210         local src src_selected src_unselected dst_selected reqptn_file
1211         message_section_title "Collecting obsolete ports to delete"
1212         src=${DBDIR}/obsolete_ports.can_be_deleted
1213         src_selected=${DBDIR}/obsolete_ports_to_delete.selected
1214         src_unselected=${DBDIR}/obsolete_ports_to_delete.unselected
1215         dst_selected=${DBDIR}/obsolete_ports_to_delete
1216         reqptn_file=${DBDIR}/obsolete_ports.requirements_of_unselected.grep_pattern
1217         cat "$src_unselected" 2> /dev/null | while read origin
1218         do
1219                 cat "${DBDIR}/initial/$origin/requirements.run.full" || :
1220                 cat "${DBDIR}/obsolete/$origin/requirements.run.full" || :
1221         done | sort -u | str_escape_regexp_filter \
1222                 | sed 's/^/^/;s/$/$/' > $reqptn_file
1223         grep -v -E -f "$reqptn_file" "$src_selected" > $dst_selected 2> /dev/null || :
1224         message_echo
1225 }
1226 program_exec_and_record_completion COLLECT_OBSOLETE_PORTS_TO_DELETE
1227
1228 # Set up the list of ports to reinstall
1229 PROGRAM_DEPENDS='ORDER_ALL_DEPENDENCIES'
1230 _program_exec_and_record_completion__operation ()
1231 {
1232         message_section_title "Setting up the list of ports to reinstall"
1233         cp -p "${DBDIR}/reinst_order.list" "${DBDIR}/stage.loop_list/reinst_todo"
1234         message_echo
1235 }
1236 program_exec_and_record_completion SETUP_REINST_TODO
1237
1238 # Composition of a list for deinstallation of obsolete and leaf packages
1239 PROGRAM_DEPENDS='COLLECT_LEAF_PORTS_TO_DELETE COLLECT_OBSOLETE_PORTS_TO_DELETE'
1240 _program_exec_and_record_completion__operation ()
1241 {
1242         local reqptn_leaf reqptn_obs leaf_selected leaf_selected_src obs_selected obs_selected_src grepptn preserved
1243         message_section_title "Composing a list for deinstallation of obsolete and leaf packages"
1244         reqptn_leaf=${DBDIR}/leaf_ports.requirements_of_unselected.grep_pattern
1245         reqptn_obs=${DBDIR}/obsolete_ports.requirements_of_unselected.grep_pattern
1246         leaf_selected_src=${DBDIR}/leaf_ports_to_delete.selected
1247         leaf_selected=${DBDIR}/leaf_ports_to_delete
1248         obs_selected_src=${DBDIR}/obsolete_ports_to_delete.selected
1249         obs_selected=${DBDIR}/obsolete_ports_to_delete
1250         grepptn=${DBDIR}/ports_to_delete.grep_pattern
1251         grepptn_col1=${DBDIR}/ports_to_delete.grep_pattern_col1
1252         preserved=${TMPDIR}/LIST_DEINST_PKGS::preserved
1253         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1254         then
1255                 cat "$reqptn_leaf" "$reqptn_obs" 2> /dev/null | sort -u > $grepptn
1256                 grep -v -E -f "$grepptn" "$leaf_selected_src" 2> /dev/null \
1257                         | database_query_add_initial_origins > $leaf_selected || :
1258                 cat "$obs_selected" "$leaf_selected" 2> /dev/null || :
1259         else
1260                 rm -f "$leaf_selected"
1261                 cat "$obs_selected" 2> /dev/null
1262         fi | sort -u > ${DBDIR}/stage.loop_list/ports_to_delete
1263         str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \
1264                 | sed 's/^/^/;s/$/$/' > $grepptn
1265         str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \
1266                 | sed 's/^/^/;s/$/[[:space:]]/' > $grepptn_col1
1267         cat "${DBDIR}/leaf_ports.with_ini" "${DBDIR}/obsolete_ports" 2> /dev/null \
1268                 | grep -E -v -f "$grepptn" > ${DBDIR}/stage.loop_list/ports_to_restore || :
1269         if [ $opt_batch_mode = no ]
1270         then
1271                 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] && \
1272                         grep -v -E -f "$grepptn" "$leaf_selected_src" > $preserved 2> /dev/null
1273                 then
1274                         message_echo "INFO: Following leaf ports are preserved because required by other preserved leaf/obsolete ports."
1275                         message_echo "----------------"
1276                         while read origin
1277                         do
1278                                 pkgtag=`cat "${DBDIR}/required/$origin/pkgtag" 2> /dev/null` || :
1279                                 if [ -n "$pkgtag" ]
1280                                 then
1281                                         echo "$origin" "($pkgtag)"
1282                                 else
1283                                         echo "$origin"
1284                                 fi
1285                         done < $preserved
1286                         message_echo "----------------"
1287                 fi
1288                 if grep -v -E -f "$grepptn" "$obs_selected_src" > $preserved 2> /dev/null
1289                 then
1290                         message_echo "INFO: Following obsolete ports are preserved because required by other obsolete ports."
1291                         message_echo "----------------"
1292                         while read origin
1293                         do
1294                                 pkgtag=`cat "${DBDIR}/initial/$origin/installed_version" 2> /dev/null` || :
1295                                 if [ -n "$pkgtag" ]
1296                                 then
1297                                         echo "$origin" "($pkgtag)"
1298                                 else
1299                                         echo "$origin"
1300                                 fi
1301                         done < $preserved
1302                         message_echo "----------------"
1303                 fi
1304         fi
1305         message_echo
1306 }
1307 program_exec_and_record_completion LIST_DEINST_PKGS
1308
1309 # Collect entire distfiles list
1310 if [ $opt_inspect_entire_distinfo = yes ]
1311 then
1312         PROGRAM_DEPENDS=''
1313         _program_exec_and_record_completion__operation ()
1314         {
1315                 message_section_title "Collecting entire distfiles list"
1316                 find "${PORTSDIR}" -depth 3 -name distinfo -exec cat {} \; \
1317                         | grep '^SHA256 ' | sed -E 's/^SHA256 \(([^)]*)\).*/\1/' \
1318                         | sort -u > ${DBDIR}/distfiles.entire.tmp
1319                 mv "${DBDIR}/distfiles.entire.tmp" "${DBDIR}/distfiles.entire"
1320                 message_echo
1321         }
1322         program_exec_and_record_completion COLLECT_ALL_DISTFILES_LIST
1323 fi
1324
1325 # Inspection of all required distfiles
1326 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES COLLECT_ALL_DISTFILES_LIST'
1327 _program_exec_and_record_completion__operation ()
1328 {
1329         message_section_title "Summarizing distfiles list"
1330         cat "${DBDIR}/distfiles.entire" "${DBDIR}/distfiles.inspected" 2> /dev/null \
1331                 | sort -u | str_escape_regexp_filter \
1332                 | sed 's|^|^\\.\\/|; s|$|$|' > ${DBDIR}/distfiles.grep.pattern || :
1333         message_echo
1334 }
1335 program_exec_and_record_completion DISTFILES_LIST
1336
1337 # Clean up of reinstallation status for preparation
1338 PROGRAM_DEPENDS='REDO_INIT INSPECT_ALL_DEPENDENCIES'
1339 _program_exec_and_record_completion__operation ()
1340 {
1341         message_section_title "Cleaning up of reinstallation status for preparation"
1342         rm -rf "${DBDIR}/status.ports"
1343         message_echo
1344 }
1345 program_exec_and_record_completion CLEANUP_REINST_STATUS
1346
1347 # Completion of building the temporary database
1348 PROGRAM_DEPENDS='REDO_INIT SETUP_REINST_TODO CLEANUP_REINST_STATUS PARSE_CONF INSPECT_ALL_DEPENDENCIES NECESSARY_UPDATES:direct NECESSARY_UPDATES:full PARSE_TARGET_ATTR_INFO MAKE_DEPENDENTS_LISTS_UNIQUE COLLECT_LEAF_PORTS_TO_DELETE'
1349 _program_exec_and_record_completion__operation ()
1350 {
1351         message_section_title "The temporary database is completely built up"
1352         message_echo
1353 }
1354 program_exec_and_record_completion PREPARATION
1355
1356
1357 # ==================================================
1358 # ====================== MAIN ======================
1359 # ==================================================
1360
1361 # Execute command operations which must be done before actual (re/de)installation processes
1362 command_exec_before_actual_re_de_installation "$@"
1363
1364 # Set termination messages
1365 temp_terminate_process ()
1366 {
1367         temp_terminate_process_common
1368 }
1369
1370 # Reinstallation of remained ports
1371 PROGRAM_DEPENDS='PREPARATION'
1372 _program_exec_restartable_loop_operation__routine ()
1373 {
1374         reinstall_exec "$@"
1375 }
1376 _program_exec_and_record_completion__operation ()
1377 {
1378         local _MSG_CURRENT_STAGE_general
1379         _MSG_CURRENT_STAGE_general="reinstallation"
1380         temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1381         message_section_title "Reinstallation"
1382         program_exec_restartable_loop_operation reinst_todo
1383         reinstall_restore_conflicts
1384         temp_set_msg_current_stage
1385         message_echo
1386 }
1387 program_exec_and_record_completion REINSTALLATION
1388
1389 # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again 
1390 PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1391 _program_exec_restartable_loop_operation__routine ()
1392 {
1393         deinstall_restore "$@"
1394 }
1395 _program_exec_and_record_completion__operation ()
1396 {
1397         local _MSG_CURRENT_STAGE_general
1398         _MSG_CURRENT_STAGE_general="restoration of unselected obsolete/leaf packages"
1399         temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1400         message_section_title "Restoration of unselected obsolete/leaf packages"
1401         program_exec_restartable_loop_operation ports_to_restore
1402         temp_set_msg_current_stage
1403         message_echo
1404 }
1405 program_exec_and_record_completion RESTORE_ONCE_DEINST_PKGS
1406
1407 # Deinstallation of unused obsolete and leaf packages
1408 PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1409 _program_exec_restartable_loop_operation__routine ()
1410 {
1411         deinstall_exec "$@"
1412 }
1413 _program_exec_and_record_completion__operation ()
1414 {
1415         local _MSG_CURRENT_STAGE_general
1416         _MSG_CURRENT_STAGE_general="deinstallation of obsolete/leaf packages"
1417         temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1418         message_section_title "Deinstallation of unused obsolete/leaf packages"
1419         program_exec_restartable_loop_operation ports_to_delete
1420         temp_set_msg_current_stage
1421         message_echo
1422 }
1423 program_exec_and_record_completion DEINST_UNUSED_PKGS
1424
1425 # Clean up obsolete or unused distfiles
1426 if [ $opt_only_target_scope = no -a $opt_keep_distfiles = no ]
1427 then
1428         PROGRAM_DEPENDS='REINSTALLATION DISTFILES_LIST'
1429         _program_exec_and_record_completion__operation ()
1430         {
1431                 local tmp_distfiles_exists
1432                 message_section_title "Cleaning up obsolete or unused distfiles"
1433                 tmp_distfiles_exists=${TMPDIR}/CLEANUP_OBSLETE_DISTFILES::distfiles_exists
1434                 [ $opt_dry_run = yes ] && message_echo "INFO: The operations are not actually carried out."
1435                 ( set -e; cd "${DISTDIR}" && find . -type f ) \
1436                         | sed 's|^\./||' | sort -u > $tmp_distfiles_exists
1437                 fileedit_manipulate_old_lines "$tmp_distfiles_exists" "${DBDIR}/distfiles.entire" \
1438                         | while read distfile
1439                 do
1440                         if [ $opt_batch_mode = no ]
1441                         then
1442                                 echo "  $distfile"
1443                         fi
1444                         [ $opt_dry_run = yes ] && continue
1445                         rm -f "${DISTDIR}/$distfile"
1446                 done
1447                 message_echo
1448         }
1449         program_exec_and_record_completion CLEANUP_OBSLETE_DISTFILES
1450 fi
1451
1452 # Rebuild of package database
1453 PROGRAM_DEPENDS='REINSTALLATION RESTORE_ONCE_DEINST_PKGS DEINST_UNUSED_PKGS'
1454 _program_exec_and_record_completion__operation ()
1455 {
1456         which -s pkgdb || return 0
1457         message_section_title "Rebuilding package database for portupgrade"
1458         pkgdb -fu
1459         message_echo
1460 }
1461 program_exec_and_record_completion REBUILD_PKGDB
1462
1463
1464 # ==================================================
1465 # ================ ENDING MESSAGES =================
1466 # ==================================================
1467
1468 # Notice of failures
1469 exists_unresolved_ports=
1470 message_summary_dependents_of_failed_reinstallation failure || exists_unresolved_ports=y
1471 message_summary_dependents_of_failed_reinstallation redo || exists_unresolved_ports=y
1472 message_summary_dependents_of_failed_reinstallation conflict || exists_unresolved_ports=y
1473 [ -n "$exists_unresolved_ports" ] && message_summary_advice_on_manual_solution
1474
1475 # End
1476 temp_terminate_process () { :; }
1477
1478 if [ -z "$exists_unresolved_ports" ]
1479 then
1480         message_section_title "COMPLETELY DONE"
1481         message_echo "- E N D -"
1482 else
1483         message_warn_no_achieved_progress || :
1484         message_section_title "Done with some unresolved problems"
1485         message_echo "- To be continued -"
1486 fi