OSDN Git Service

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