OSDN Git Service

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