2 # ==============================================================================
3 # portsreinstall library script
4 # - Common functions of main programs -
5 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Define the software version =============
13 COMPATIBLE_VERSIONS='^(4\.[1]\.[0-9])$'
14 # Template for development versions
15 MYVERSION=4.0.0+toward_4.1.0_20180910103620
16 COMPATIBLE_VERSIONS='^(4\.[0-1]\.[0-9]]|4\.[0]\.[0]+(|\+toward_4\.[0-1]\.[0-9]+_[0-9]+))$'
19 # ============= Parse options, arguments and control parameters =============
20 # All arguments/options of the main program must be passed.
21 main_parse_options_arguments ()
23 # ============= Save arguments for upgraded restart =============
24 options_dump_args "$@" > ${TMPDIR}/restart_command.sh
26 # ============= Option check =============
29 options_getopts "$@" || :
30 if [ $OPTIONS_ERRNO -eq 2 ]
32 message_echo "INTERNAL ERROR: In parsing options" >&2
35 shift "${OPTIONS_SHIFT}"
39 # ============= Argument check for no-command options =============
40 if [ $opt_help_mode -ne 0 -o $opt_show_version = yes ]
44 message_echo "SYNTAX ERROR: No command is allowed for showing Help or Version" >&2
49 # ============= Output usage if the case of a help mode or option/argument errors =============
50 if [ $OPTIONS_ERRNO -ne 0 ]
53 elif [ $opt_help_mode -eq 1 ]
57 elif [ $opt_help_mode -eq 2 ]
63 # ============= Output version number =============
64 if [ $opt_show_version = yes ]
70 # ============= Set up variables for environment of ports and packages =============
72 conf_setup_packages_envs
74 # ============= Execute command operations before getting the temporary database ready =============
75 command_all_exec_before_db_creation "$@"
77 # ============= Creation of temporary database directory =============
78 database_maintain_create
80 # ============= Argument check for conventional runs =============
81 command_all_parse_args "$@"
84 # ============= Define the common termination messages =============
85 main_define_common_termination_messages ()
87 temp_terminate_process_common ()
91 [ $opt_batch_mode = yes -o $errno -eq 0 ] && return
92 msg_where=`temp_get_msg_current_stage`
93 [ -n "$msg_where" ] && msg_where=" during $msg_where"
97 message_echo "INFO: Terminated at `message_timestamp`$msg_where."
99 [ $opt_no_opening_message = yes ] && return
100 message_echo " You can restart this process from the terminated point by"
102 message_echo "INFO: Aborted at `message_timestamp`$msg_where."
104 [ $opt_no_opening_message = yes ] && return
105 message_echo " You may restart this process from the aborted point by"
107 message_echo "executing without options or arguments as:"
108 if [ -n "$COMMAND_RESTART" ]
110 message_echo " ${APPNAME} $COMMAND_RESTART"
112 message_echo " ${APPNAME}"
117 # ============= Set termination messages for special commands =============
118 main_set_termination_messages_special ()
122 # ============= Option settings =============
123 main_option_settings ()
126 # Load, renew and save option values
128 if [ \( "x$opt_reload_conf" = xyes -o "x$opt_reset_targets" = xyes \) -a "x$COMMAND_MODE" != xredo ]
130 message_echo "ERROR: Options -L and -N are available only in the initial run of redo command." >&2
134 if [ "x$opt_batch_ports_only" = xyes -a "x$opt_interactive_ports_only" = xyes ]
136 message_echo "ERROR: Options -A and -I conflict with each other." >&2
140 if [ -e "${DBDIR}/saved_options.sh" ]
142 options_chk_invalid_optvals_renewal non_renewable || optcomb_err=$?
144 options_renewed_optvals M renewable_anytime || optcomb_err=$?
145 options_renewed_optvals N renewable_in_redo_on_target || optcomb_err=$?
146 options_renewed_optvals L renewable_in_redo_on_conf || optcomb_err=$?
147 } > ${TMPDIR}/renewed_optvals.sh
148 [ $optcomb_err -eq 0 ] || exit $optcomb_err
149 . "${DBDIR}/saved_options.sh"
150 . "${TMPDIR}/renewed_optvals.sh"
152 misc_is_superuser_privilege && misc_get_all_vardefs | options_filter saved > ${DBDIR}/saved_options.sh
156 # ============= Save the previous configuration if exists =============
157 main_save_prev_conf ()
159 local PROGRAM_DEPENDS
161 _program_exec_and_record_completion__operation ()
163 rm -rf "${DBDIR}/conf.prev"
164 [ -d "${DBDIR}/conf" ] && \
165 cp -Rp "${DBDIR}/conf" "${DBDIR}/conf.prev"
168 program_exec_and_record_completion SAVE_PREV_CONF
171 # ============= Load the saved configuration =============
174 . "${DBDIR}/conf/setenv.sh"
177 # ============= Get complete configuration variable definitions by importing pkgtools.conf(5) if available =============
178 main_get_complete_conf ()
180 local PROGRAM_DEPENDS
181 PROGRAM_DEPENDS='SAVE_PREV_CONF'
182 _program_exec_and_record_completion__operation ()
186 rm -rf "${DBDIR}/conf"
187 mkdir -p "${DBDIR}/conf"
188 [ "x`options_get_effective_opt_load_pkgtoolsconf 2> /dev/null`" != xno -a $opt_batch_mode = no ] \
190 [ $need_msg = yes ] && \
191 message_section_title "Parsing pkgtools.conf (by using installed portupgrade)"
192 conf_get_complete_var_defs > ${DBDIR}/conf/complete_setup.sh
193 [ $need_msg = yes ] && { message_echo "===> ok"; message_echo; }
196 program_exec_and_record_completion GET_COMPLETE_CONF_VAR_DEF
199 # ============= Parse the configuration =============
202 local PROGRAM_DEPENDS
203 PROGRAM_DEPENDS='GET_COMPLETE_CONF_VAR_DEF'
204 _program_exec_and_record_completion__operation ()
206 message_section_title "Parsing the configuration"
207 conf_manipulate_available_var_defs
208 . "${DBDIR}/conf/manipulated_defs.sh"
210 conf_build_effective_MOVED
211 # Environmental variables
212 conf_setup_effective_env > ${DBDIR}/conf/setenv.sh
213 . "${DBDIR}/conf/setenv.sh"
215 conf_parse_vars_for_each_port_glob HOLD
217 conf_parse_vars_for_each_port_glob TABOO
218 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" \
219 > ${DBDIR}/taboo.all.list
221 conf_parse_vars_for_each_port_glob FREEZE
222 fileedit_combine_lists "${DBDIR}/conf/FREEZE:PORTS.parsed" "${DBDIR}/freeze.list" \
223 > ${DBDIR}/freeze.all.list
225 conf_parse_vars_for_each_port_glob NOPKG
227 conf_build_replacement_patterns_from_REPLACE
229 conf_parse_vars_for_each_port_glob_with_bound_val CONFLICT TARGET DEF
231 conf_parse_vars_for_each_port_glob_with_bound_val BUILDCONFLICT TARGET DEF
233 conf_parse_vars_for_each_port_glob_with_bound_val INSTCONFLICT TARGET DEF
235 conf_parse_vars_for_each_port_glob_with_bound_val MARG TARGET DEF
237 conf_parse_vars_for_each_port_glob_with_bound_val MENV TARGET DEF
239 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREBUILD TARGET COMMAND
241 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREDEINSTALL TARGET COMMAND
243 conf_parse_vars_for_each_port_glob_with_bound_val AFTERINSTALL TARGET COMMAND
246 program_exec_and_record_completion PARSE_CONF
249 # ============= Set up parameters based on options, arguments, environment =============
250 main_setup_parameters ()
252 # ============= Termination messages during construction of the temporary database =============
253 main_define_common_termination_messages
254 temp_reset_termination_messages_common
255 main_set_termination_messages_special
257 # ============= Opening title =============
260 command_all_chk_need_opening_notice && message_opening_notice
263 # ============= Execute command operations which do not need package tools =============
265 command_all_exec_without_pkgtools "$@"
266 misc_is_superuser_privilege && database_maintain_mark_use
267 # ============= Definition of environment dependent functions =============
271 # ============= Option settings =============
273 # Execute command operations which are not affected by saved option settings
274 command_all_exec_irrespective_of_saved_options "$@"
276 # Load, renew and save option values
280 message_show_option_settings
282 # Execute command operations which should be carried out just after completing the option settings
283 command_all_exec_just_after_option_settings "$@"
285 # ============= Command-specific pre-configuration =============
287 # Execute command operations which must be done before the database construction
288 command_all_exec_command_specific_preconfiguration "$@"
290 # ============= Configurations =============
292 # Save the previous configuration if exists
295 # Get complete configuration variable definitions by importing pkgtools.conf(5) if available
296 main_get_complete_conf
298 # Parse the configuration
301 # Load the saved configuration
303 if [ $opt_just_save_options = yes ]
305 message_echo "(Save-options-only mode)"
310 # ============= Operation without packages management tools =============
311 main_operation_without_pkg_management_tools ()
313 # Execute command operations which should be done without upgrade of tools
314 command_all_exec_before_tools_upgrade "$@"
316 # Check whether the temporary database is newer than the ports tree and refresh if so
317 database_maintain_refresh_if_obsolete
320 # ============= Collect all installed packages =============
321 main_collect_all_installed_packages ()
323 local PROGRAM_DEPENDS
325 _program_exec_and_record_completion__operation ()
328 message_section_title "Collecting all installed packages"
329 mkdir -p "${DBDIR}/fossil_pkgs"
330 fossil_path=${DBDIR}/fossil_pkgs/fossil_since_`pkgsys_get_timestamp_portstree`
331 if [ ! -e "$fossil_path" ]
333 pkg_info_all_flavored_origins > $fossil_path.tmp
334 mv "$fossil_path.tmp" "$fossil_path"
336 if [ ! -e "${DBDIR}/installed_ports" ]
338 cp "$fossil_path" "${DBDIR}/installed_ports.tmp"
339 mv "${DBDIR}/installed_ports.tmp" "${DBDIR}/installed_ports"
341 pkgsys_gen_init_pkg_origin_table
344 program_exec_and_record_completion COLLECT_ALL_INSTALLED_PACKAGES
347 # ============= Preliminary inspection of tools which have to be up-to-date =============
348 # (No need depend on PARSE_CONF because INSPECT_ALL_DEPENDENCIES will take the task.)
349 main_preliminary_inspection_of_tools ()
351 local PROGRAM_DEPENDS
353 _program_exec_restartable_loop_operation__routine ()
357 database_build_inspect_dependencies "$origin"
359 _program_exec_and_record_completion__operation ()
362 message_section_title "Preliminary inspection of tools which have to be up-to-date"
364 [ "$PKGSYS_USE_PKGNG" = yes ] && pkgsys_portsmgmt_pkg
365 pkgsys_is_dialog4ports_used && pkgsys_portsmgmt_dialog4ports
366 [ -n "$MYPORTORIGIN" ] && echo "$MYPORTORIGIN"
367 } 2> /dev/null > ${DBDIR}/stage.loop_list/tools_to_inspect
368 cp /dev/null "${DBDIR}/done_required_ports_to_inspect"
370 program_exec_restartable_loop_operation tools_to_inspect
371 database_build_post_inspect_dependencies
374 program_exec_and_record_completion PRELIMINARY_INSPECTION_OF_TOOLS
377 # ============= Upgrade of pkg(8) if new =============
378 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
379 main_upgrade_pkg8_if_new ()
381 local PROGRAM_DEPENDS
382 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
383 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no \
384 -a "$PKGSYS_USE_PKGNG" = yes ]
386 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
387 _program_exec_and_record_completion__operation ()
389 local _MSG_CURRENT_STAGE_general origin
390 _MSG_CURRENT_STAGE_general="pkg(8) upgrade"
391 origin=`pkgsys_portsmgmt_pkg`
392 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
393 message_section_title "Upgrade of $origin if new"
394 touch "${DBDIR}/target_all"
395 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
396 reinstall_exec "$origin"
397 reinstall_restore_conflicts
398 rm -f "${DBDIR}/target_all"
399 temp_set_msg_current_stage
402 program_exec_and_record_completion UPGRADE_PKGNG
406 # ============= Upgrade of dialog4ports(1) if new =============
407 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
408 main_upgrade_dialog4ports1_if_new ()
410 local PROGRAM_DEPENDS
411 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
412 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no ] \
413 && pkgsys_is_dialog4ports_used
415 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
416 _program_exec_and_record_completion__operation ()
418 local _MSG_CURRENT_STAGE_general origin
419 _MSG_CURRENT_STAGE_general="dialog4ports(1) upgrade"
420 origin=`pkgsys_portsmgmt_dialog4ports`
421 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
422 message_section_title "Upgrade of $origin if new"
423 touch "${DBDIR}/target_all"
424 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
425 reinstall_exec "$origin"
426 reinstall_restore_conflicts
427 rm -f "${DBDIR}/target_all"
428 temp_set_msg_current_stage
431 program_exec_and_record_completion UPGRADE_DIALOG4PORTS
435 # ============= Upgrade of this utility if new =============
436 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
439 local PROGRAM_DEPENDS
440 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
441 -a $opt_dry_run = no -a $opt_suppress_self_upadte = no \
442 -a -n "$MYPORTORIGIN" ]
444 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
445 _program_exec_and_record_completion__operation ()
447 local _MSG_CURRENT_STAGE_general
448 _MSG_CURRENT_STAGE_general="pkgng upgrade"
449 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
450 message_section_title "Upgrade of this utility if new"
451 touch "${DBDIR}/target_all"
452 cp "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.direct.src" "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.full"
453 reinstall_exec "$MYPORTORIGIN"
454 reinstall_restore_conflicts
455 rm -f "${DBDIR}/target_all"
456 temp_set_msg_current_stage
459 program_exec_and_record_completion UPGRADE_SELF
461 if [ "x`${APPNAME} -aV 2> /dev/null`" != "x$MYVERSION" ]
463 message_echo "INFO: ${APPNAME} is upgraded and the temporary database needs refresh."
464 database_maintain_clean_for_self_upgrade || :
465 message_echo "INFO: Restarting with the new version."
467 temp_trap_for_invoking_new_version
468 . "${TMPDIR}"/restart_command.sh
473 # ============= Overlay onto the temporary database by reflecting changes in configuration =============
474 main_reflect_conf_changes ()
476 local PROGRAM_DEPENDS
477 PROGRAM_DEPENDS='PARSE_CONF'
478 _program_exec_and_record_completion__operation ()
480 local tmpfile_diff tmpfile_old tmpfile_new key
481 [ -d "${DBDIR}/conf.prev" ] || return 0
482 message_section_title "Overlay onto the temporary database by reflecting changes in configuration"
483 tmpfile_old=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::old
484 tmpfile_new=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::new
485 tmpfile_updated_ports=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::updated_ports
486 if fileedit_manipulate_old_new_lines \
487 "${DBDIR}/conf.prev/setenv.sh" "${DBDIR}/conf/setenv.sh" "$tmpfile_old" "$tmpfile_new"
489 if grep -q -e ^LOCALBASE= -e ^LINUXBASE= -e ^PORTSDIR= "$tmpfile_old" "$tmpfile_new"
491 message_echo "ERROR: Migration of the temporary database is unavailable because LOCALBASE, LINUXBASE or PORTSDIR was changed." >&2
492 message_echo " ${APPNAME} clean" >&2
493 message_echo "must be executed in advance." >&2
497 cut -s -d '|' -f 1,2 "${DBDIR}/conf.prev/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.old
498 cut -s -d '|' -f 1,2 "${DBDIR}/conf/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.new
499 if fileedit_manipulate_old_new_lines \
500 "${TMPDIR}/MOVED_ALT.old" "${TMPDIR}/MOVED_ALT.new" "$tmpfile_old" "$tmpfile_new"
502 cat "$tmpfile_old" "$tmpfile_new" | while read from to
505 [ -n "$to" ] && echo "$to"
507 fi > $tmpfile_updated_ports
508 sort -u "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.new || :
509 sort -u "${DBDIR}/conf.prev/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.old || :
510 diff "${TMPDIR}/NOPKG:PORTS.parsed.old" "${TMPDIR}/NOPKG:PORTS.parsed.new" | sed -n 's/^[<>] //p' >> $tmpfile_updated_ports
511 if fileedit_manipulate_old_new_lines \
512 "${DBDIR}/conf.prev/REPLACE.csv" "${DBDIR}/conf/REPLACE.csv" "$tmpfile_old" "$tmpfile_new"
514 cat "$tmpfile_old" "$tmpfile_new" | while read from to
517 [ -n "$to" ] && echo "$to"
519 fi >> $tmpfile_updated_ports
520 [ `wc -l < $tmpfile_updated_ports` -gt 0 ] && rm -f "${DBDIR}/REPLACE.complete_sed_pattern"
521 [ -d "${DBDIR}/conf/each_port" ] && find "${DBDIR}/conf/each_port" -depth 2 \
524 origin=`str_dirpath_to_origin "$dbpath"`
525 dbpath_prev=${DBDIR}/conf.prev/each_port/$origin
526 diff -r "$dbpath_prev" "$dbpath" > /dev/null 2>&1 && continue
528 done >> $tmpfile_updated_ports
529 [ -d "${DBDIR}/conf.prev/each_port" ] && find "${DBDIR}/conf.prev/each_port" -depth 2 \
530 | while read dbpath_prev
532 origin=`str_dirpath_to_origin "$dbpath_prev"`
533 dbpath=${DBDIR}/conf/each_port/$origin
534 [ -d "$dbpath" ] && continue
536 done >> $tmpfile_updated_ports
537 if [ `wc -l < $tmpfile_updated_ports` -gt 0 ]
539 sort -u "$tmpfile_updated_ports" | while read origin
541 message_echo "Reset for $origin"
542 database_build_patch_reconf "$origin"
544 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
545 program_deregister_stage_complete ALL_COMPLETE
549 program_exec_and_record_completion PATCH_TO_TMPDB_REFLECT_CONF_CHANGES