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_20180821153931
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 "$@"
82 shift "${COMMAND_SHIFT}"
85 # ============= Define the common termination messages =============
86 main_define_common_termination_messages ()
88 temp_terminate_process_common ()
92 [ $opt_batch_mode = yes -o $errno -eq 0 ] && return
93 msg_where=`temp_get_msg_current_stage`
94 [ -n "$msg_where" ] && msg_where=" during $msg_where"
98 message_echo "INFO: Terminated at `message_timestamp`$msg_where."
100 message_echo " You can restart this process from the terminated point by"
102 message_echo "INFO: Aborted at `message_timestamp`$msg_where."
104 message_echo " You may restart this process from the aborted point by"
106 message_echo "executing without options or arguments as:"
107 if [ -n "$COMMAND_RESTART" ]
109 message_echo " ${APPNAME} $COMMAND_RESTART"
111 message_echo " ${APPNAME}"
116 # ============= Set termination messages for special commands =============
117 main_set_termination_messages_special ()
121 # ============= Option settings =============
122 main_option_settings ()
125 # Load, renew and save option values
127 if [ \( "x$opt_reload_conf" = xyes -o "x$opt_reset_targets" = xyes \) -a "x$COMMAND_MODE" != xredo ]
129 message_echo "ERROR: Options -L and -N are available only in the initial run of redo command." >&2
133 if [ "x$opt_batch_ports_only" = xyes -a "x$opt_interactive_ports_only" = xyes ]
135 message_echo "ERROR: Options -A and -I conflict with each other." >&2
139 if [ -e "${DBDIR}/saved_options.sh" ]
141 options_chk_invalid_optvals_renewal non_renewable || optcomb_err=$?
143 options_renewed_optvals M renewable_anytime || optcomb_err=$?
144 options_renewed_optvals N renewable_in_redo_on_target || optcomb_err=$?
145 options_renewed_optvals L renewable_in_redo_on_conf || optcomb_err=$?
146 } > ${TMPDIR}/renewed_optvals.sh
147 [ $optcomb_err -eq 0 ] || exit $optcomb_err
148 . "${DBDIR}/saved_options.sh"
149 . "${TMPDIR}/renewed_optvals.sh"
151 misc_is_superuser_privilege && misc_get_all_vardefs | options_filter saved > ${DBDIR}/saved_options.sh
155 # ============= Save the previous configuration if exists =============
156 main_save_prev_conf ()
158 local PROGRAM_DEPENDS
160 _program_exec_and_record_completion__operation ()
162 rm -rf "${DBDIR}/conf.prev"
163 [ -d "${DBDIR}/conf" ] && \
164 cp -Rp "${DBDIR}/conf" "${DBDIR}/conf.prev"
167 program_exec_and_record_completion SAVE_PREV_CONF
170 # ============= Load the saved configuration =============
173 . "${DBDIR}/conf/setenv.sh"
176 # ============= Get complete configuration variable definitions by importing pkgtools.conf(5) if available =============
177 main_get_complete_conf ()
179 local PROGRAM_DEPENDS
180 PROGRAM_DEPENDS='SAVE_PREV_CONF'
181 _program_exec_and_record_completion__operation ()
185 rm -rf "${DBDIR}/conf"
186 mkdir -p "${DBDIR}/conf"
187 [ "x`options_get_effective_opt_load_pkgtoolsconf 2> /dev/null`" != xno -a $opt_batch_mode = no ] \
189 [ $need_msg = yes ] && \
190 message_section_title "Parsing pkgtools.conf (by using installed portupgrade)"
191 conf_get_complete_var_defs > ${DBDIR}/conf/complete_setup.sh
192 [ $need_msg = yes ] && { message_echo "===> ok"; message_echo; }
195 program_exec_and_record_completion GET_COMPLETE_CONF_VAR_DEF
198 # ============= Parse the configuration =============
201 local PROGRAM_DEPENDS
202 PROGRAM_DEPENDS='GET_COMPLETE_CONF_VAR_DEF'
203 _program_exec_and_record_completion__operation ()
205 message_section_title "Parsing the configuration"
206 conf_manipulate_available_var_defs
207 . "${DBDIR}/conf/manipulated_defs.sh"
209 conf_build_effective_MOVED
210 # Environmental variables
211 conf_setup_effective_env > ${DBDIR}/conf/setenv.sh
212 . "${DBDIR}/conf/setenv.sh"
214 conf_parse_vars_for_each_port_glob HOLD
216 conf_parse_vars_for_each_port_glob TABOO
217 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" \
218 > ${DBDIR}/taboo.all.list
220 conf_parse_vars_for_each_port_glob FREEZE
221 fileedit_combine_lists "${DBDIR}/conf/FREEZE:PORTS.parsed" "${DBDIR}/freeze.list" \
222 > ${DBDIR}/freeze.all.list
224 conf_parse_vars_for_each_port_glob NOPKG
226 conf_build_replacement_patterns_from_REPLACE
228 conf_parse_vars_for_each_port_glob_with_bound_val CONFLICT TARGET DEF
230 conf_parse_vars_for_each_port_glob_with_bound_val BUILDCONFLICT TARGET DEF
232 conf_parse_vars_for_each_port_glob_with_bound_val INSTCONFLICT TARGET DEF
234 conf_parse_vars_for_each_port_glob_with_bound_val MARG TARGET DEF
236 conf_parse_vars_for_each_port_glob_with_bound_val MENV TARGET DEF
238 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREBUILD TARGET COMMAND
240 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREDEINSTALL TARGET COMMAND
242 conf_parse_vars_for_each_port_glob_with_bound_val AFTERINSTALL TARGET COMMAND
245 program_exec_and_record_completion PARSE_CONF
248 # ============= Set up parameters based on options, arguments, environment =============
249 main_setup_parameters ()
251 # ============= Termination messages during construction of the temporary database =============
252 main_define_common_termination_messages
253 temp_reset_termination_messages_common
254 main_set_termination_messages_special
256 # ============= Opening title =============
259 command_all_chk_need_opening_notice && message_opening_notice
262 # ============= Execute command operations which do not need package tools =============
264 command_all_exec_without_pkgtools "$@"
265 misc_is_superuser_privilege && database_maintain_mark_use
266 # ============= Definition of environment dependent functions =============
270 # ============= Option settings =============
272 # Execute command operations which are not affected by saved option settings
273 command_all_exec_irrespective_of_saved_options "$@"
275 # Load, renew and save option values
279 message_show_option_settings
281 # Execute command operations which should be carried out just after completing the option settings
282 command_all_exec_just_after_option_settings "$@"
284 # ============= Configurations =============
286 # Save the previous configuration if exists
289 # Get complete configuration variable definitions by importing pkgtools.conf(5) if available
290 main_get_complete_conf
292 # Parse the configuration
295 # Load the saved configuration
299 # ============= Operation without packages management tools =============
300 main_operation_without_pkg_management_tools ()
302 # Execute command operations which should be done without upgrade of tools
303 command_all_exec_before_tools_upgrade "$@"
305 # Check whether the temporary database is newer than the ports tree and refresh if so
306 database_maintain_refresh_if_obsolete
309 # ============= Collect all installed packages =============
310 main_collect_all_installed_packages ()
312 local PROGRAM_DEPENDS
314 _program_exec_and_record_completion__operation ()
317 message_section_title "Collecting all installed packages"
318 mkdir -p "${DBDIR}/fossil_pkgs"
319 heritage_path=${DBDIR}/fossil_pkgs/heritage_since_`pkgsys_get_timestamp_portstree`
320 if [ ! -e "$heritage_path" ]
322 pkg_info_all_flavored_origins > $heritage_path.tmp
323 mv "$heritage_path.tmp" "$heritage_path"
325 if [ ! -e "${DBDIR}/installed_ports" ]
327 cp "$heritage_path" "${DBDIR}/installed_ports.tmp"
328 mv "${DBDIR}/installed_ports.tmp" "${DBDIR}/installed_ports"
330 pkgsys_gen_init_pkg_origin_table
333 program_exec_and_record_completion COLLECT_ALL_INSTALLED_PACKAGES
336 # ============= Preliminary inspection of tools which have to be up-to-date =============
337 # (No need depend on PARSE_CONF because INSPECT_ALL_DEPENDENCIES will take the task.)
338 main_preliminary_inspection_of_tools ()
340 local PROGRAM_DEPENDS
342 _program_exec_restartable_loop_operation__routine ()
346 database_build_inspect_dependencies "$origin"
348 _program_exec_and_record_completion__operation ()
351 message_section_title "Preliminary inspection of tools which have to be up-to-date"
353 [ "$PKGSYS_USE_PKGNG" = yes ] && pkgsys_portsmgmt_pkg
354 pkgsys_is_dialog4ports_used && pkgsys_portsmgmt_dialog4ports
355 [ -n "$MYPORTORIGIN" ] && echo "$MYPORTORIGIN"
356 } 2> /dev/null > ${DBDIR}/stage.loop_list/tools_to_inspect
357 cp /dev/null "${DBDIR}/done_required_ports_to_inspect"
359 program_exec_restartable_loop_operation tools_to_inspect
360 database_build_post_inspect_dependencies
363 program_exec_and_record_completion PRELIMINARY_INSPECTION_OF_TOOLS
366 # ============= Upgrade of pkg(8) if new =============
367 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
368 main_upgrade_pkg8_if_new ()
370 local PROGRAM_DEPENDS
371 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
372 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no \
373 -a "$PKGSYS_USE_PKGNG" = yes ]
375 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
376 _program_exec_and_record_completion__operation ()
378 local _MSG_CURRENT_STAGE_general origin
379 _MSG_CURRENT_STAGE_general="pkg(8) upgrade"
380 origin=`pkgsys_portsmgmt_pkg`
381 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
382 message_section_title "Upgrade of $origin if new"
383 touch "${DBDIR}/target_all"
384 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
385 reinstall_exec "$origin"
386 reinstall_restore_conflicts
387 rm -f "${DBDIR}/target_all"
388 temp_set_msg_current_stage
391 program_exec_and_record_completion UPGRADE_PKGNG
395 # ============= Upgrade of dialog4ports(1) if new =============
396 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
397 main_upgrade_dialog4ports1_if_new ()
399 local PROGRAM_DEPENDS
400 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
401 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no ] \
402 && pkgsys_is_dialog4ports_used
404 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
405 _program_exec_and_record_completion__operation ()
407 local _MSG_CURRENT_STAGE_general origin
408 _MSG_CURRENT_STAGE_general="dialog4ports(1) upgrade"
409 origin=`pkgsys_portsmgmt_dialog4ports`
410 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
411 message_section_title "Upgrade of $origin if new"
412 touch "${DBDIR}/target_all"
413 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
414 reinstall_exec "$origin"
415 reinstall_restore_conflicts
416 rm -f "${DBDIR}/target_all"
417 temp_set_msg_current_stage
420 program_exec_and_record_completion UPGRADE_DIALOG4PORTS
424 # ============= Upgrade of this utility if new =============
425 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
428 local PROGRAM_DEPENDS
429 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
430 -a $opt_dry_run = no -a $opt_suppress_self_upadte = no \
431 -a -n "$MYPORTORIGIN" ]
433 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
434 _program_exec_and_record_completion__operation ()
436 local _MSG_CURRENT_STAGE_general
437 _MSG_CURRENT_STAGE_general="pkgng upgrade"
438 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
439 message_section_title "Upgrade of this utility if new"
440 touch "${DBDIR}/target_all"
441 cp "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.direct.src" "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.full"
442 reinstall_exec "$MYPORTORIGIN"
443 reinstall_restore_conflicts
444 rm -f "${DBDIR}/target_all"
445 temp_set_msg_current_stage
448 program_exec_and_record_completion UPGRADE_SELF
450 if [ "x`${APPNAME} -aV 2> /dev/null`" != "x$MYVERSION" ]
452 message_echo "INFO: ${APPNAME} is upgraded and the temporary database needs refresh."
453 database_maintain_clean_for_self_upgrade || :
454 message_echo "INFO: Restarting with the new version."
456 temp_trap_for_invoking_new_version
457 . "${TMPDIR}"/restart_command.sh
462 # ============= Overlay onto the temporary database by reflecting changes in configuration =============
463 main_reflect_conf_changes ()
465 local PROGRAM_DEPENDS
466 PROGRAM_DEPENDS='PARSE_CONF'
467 _program_exec_and_record_completion__operation ()
469 local tmpfile_diff tmpfile_old tmpfile_new key
470 [ -d "${DBDIR}/conf.prev" ] || return 0
471 message_section_title "Overlay onto the temporary database by reflecting changes in configuration"
472 tmpfile_old=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::old
473 tmpfile_new=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::new
474 tmpfile_updated_ports=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::updated_ports
475 if fileedit_manipulate_old_new_lines \
476 "${DBDIR}/conf.prev/setenv.sh" "${DBDIR}/conf/setenv.sh" "$tmpfile_old" "$tmpfile_new"
478 if grep -q -e ^LOCALBASE= -e ^LINUXBASE= -e ^PORTSDIR= "$tmpfile_old" "$tmpfile_new"
480 message_echo "ERROR: Migration of the temporary database is unavailable because LOCALBASE, LINUXBASE or PORTSDIR was changed." >&2
481 message_echo " ${APPNAME} clean" >&2
482 message_echo "must be executed in advance." >&2
486 cut -s -d '|' -f 1,2 "${DBDIR}/conf.prev/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.old
487 cut -s -d '|' -f 1,2 "${DBDIR}/conf/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.new
488 if fileedit_manipulate_old_new_lines \
489 "${TMPDIR}/MOVED_ALT.old" "${TMPDIR}/MOVED_ALT.new" "$tmpfile_old" "$tmpfile_new"
491 cat "$tmpfile_old" "$tmpfile_new" | while read from to
494 [ -n "$to" ] && echo "$to"
496 fi > $tmpfile_updated_ports
497 sort -u "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.new || :
498 sort -u "${DBDIR}/conf.prev/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.old || :
499 diff "${TMPDIR}/NOPKG:PORTS.parsed.old" "${TMPDIR}/NOPKG:PORTS.parsed.new" | sed -n 's/^[<>] //p' >> $tmpfile_updated_ports
500 if fileedit_manipulate_old_new_lines \
501 "${DBDIR}/conf.prev/REPLACE.csv" "${DBDIR}/conf/REPLACE.csv" "$tmpfile_old" "$tmpfile_new"
503 cat "$tmpfile_old" "$tmpfile_new" | while read from to
506 [ -n "$to" ] && echo "$to"
508 fi >> $tmpfile_updated_ports
509 [ `wc -l < $tmpfile_updated_ports` -gt 0 ] && rm -f "${DBDIR}/REPLACE.complete_sed_pattern"
510 [ -d "${DBDIR}/conf/each_port" ] && find "${DBDIR}/conf/each_port" -depth 2 \
513 origin=`str_dirpath_to_origin "$dbpath"`
514 dbpath_prev=${DBDIR}/conf.prev/each_port/$origin
515 diff -r "$dbpath_prev" "$dbpath" > /dev/null 2>&1 && continue
517 done >> $tmpfile_updated_ports
518 [ -d "${DBDIR}/conf.prev/each_port" ] && find "${DBDIR}/conf.prev/each_port" -depth 2 \
519 | while read dbpath_prev
521 origin=`str_dirpath_to_origin "$dbpath_prev"`
522 dbpath=${DBDIR}/conf/each_port/$origin
523 [ -d "$dbpath" ] && continue
525 done >> $tmpfile_updated_ports
526 if [ `wc -l < $tmpfile_updated_ports` -gt 0 ]
528 sort -u "$tmpfile_updated_ports" | while read origin
530 message_echo "Reset for $origin"
531 database_build_patch_reconf "$origin"
533 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
534 program_deregister_stage_complete ALL_COMPLETE
538 program_exec_and_record_completion PATCH_TO_TMPDB_REFLECT_CONF_CHANGES