OSDN Git Service

Version 3.0.0+toward_3.1.0_20130606182950
[portsreinstall/current.git] / lib / libcommand.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Operations of commands as well as check of command line arguments -
5 # Copyright (C) 2013 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Variables =============
10 COMMAND_MODE=do
11 COMMAND_SHIFT=0
12 COMMAND_OPERATION=
13 COMMAND_SAVE_DIR=
14 COMMAND_LOAD_FILE=
15 COMMAND_SHOW_SUBJECT=
16 COMMAND_DO_MODE=all
17 COMMAND_RESTART=
18 COMMAND_SHOW_OPTIONS=
19 COMMAND_SHOW_DEPTAG=
20 COMMAND_SHOW_LEVEL=
21
22 # ============= Check the number of following command line arguments (in case glob arguments are needed) =============
23 _command_parse_args__chk_glob_args ()
24 {
25         local nargs
26         nargs=1
27         [ $nargs -gt 0 ] && return
28         message_echo "ERROR: No port glob is specified." >&2
29         exit 1
30 }
31
32 # ============= Check the number of following command line arguments (in case without arguments) =============
33 _command_parse_args__chk_no_arg ()
34 {
35         local nargs term_redundant_argument
36         nargs=$1
37         [ $nargs -eq 0 ] && return
38         term_redundant_argument='A redundant argument is'
39         [ $nargs -gt 1 ] && term_redundant_argument='Redundant arguments are'
40         message_echo "ERROR: $term_redundant_argument specified." >&2
41         exit 1
42 }
43
44 # ============= Execute command operations before getting the temporary database ready =============
45 command_exec_before_db_creation ()
46 {
47         local COMMAND_RESTART COMMAND_MODE COMMAND_OPERATION
48         COMMAND_RESTART="$@"
49         COMMAND_MODE=${1:-do}
50         shift || :
51         case $COMMAND_MODE in
52         clean)
53                 COMMAND_OPERATION=${1:-normal}
54                 shift || :
55                 case $COMMAND_OPERATION in
56                 force)
57                         message_echo "INFO: The temporary database is tried to be cleaned up without checking the privilege."
58                         rm -rf "${DBDIR}"
59                         message_echo "Done"
60                         exit
61                         ;;
62                 esac
63                 _command_parse_args__chk_no_arg $#
64                 ;;
65         esac
66 }
67
68 # ============= Check and parse command line arguments =============
69 command_parse_args ()
70 {
71         local num_args_init
72         num_args_init=$#
73         COMMAND_RESTART="$@"
74         COMMAND_MODE=${1:-do}
75         shift || :
76         case $COMMAND_MODE in
77         clean)
78                 COMMAND_OPERATION=${1:-normal}
79                 shift || :
80                 case $COMMAND_OPERATION in
81                 normal)
82                         misc_chk_privilege
83                         ;;
84                 esac
85                 _command_parse_args__chk_no_arg $#
86                 ;;
87         reset)
88                 misc_chk_privilege
89                 COMMAND_OPERATION=${1:-all}
90                 shift || :
91                 case $COMMAND_OPERATION in
92                 all|keepopts)
93                         ;;
94                 *)
95                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be empty, \"all\" or \"keepopts\"." >&2
96                         exit 1
97                         ;;
98                 esac
99                 _command_parse_args__chk_no_arg $#
100                 ;;
101         ok|taboo|need|noneed)
102                 misc_chk_privilege
103                 [ $COMMAND_MODE = ok ] && database_query_chk_preparation_completion
104                 temp_warn_obsolete_temp_db
105                 COMMAND_OPERATION=$1
106                 shift || :
107                 case $COMMAND_OPERATION in
108                 add|del)
109                         ;;
110                 '')
111                         message_echo "ERROR: Missing operation which must be \"add\" or \"del\"." >&2
112                         exit 1
113                         ;;
114                 *)
115                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be \"add\" or \"del\"." >&2
116                         exit 1
117                         ;;
118                 esac
119                 _command_parse_args__chk_glob_args $#
120                 ;;
121         reselect)
122                 misc_chk_privilege
123                 database_query_chk_preparation_completion
124                 temp_warn_obsolete_temp_db
125                 COMMAND_OPERATION=$1
126                 shift || :
127                 case $COMMAND_OPERATION in
128                 leaves)
129                         if [ -e "${DBDIR}/inspected_ports_only_partially" ]
130                         then
131                                 message_echo "ERROR: Leaf ports cannot be analyzed because the dependency inspection is partial." >&2
132                                 message_echo "Executing redo command with -N option by disabling -o option fixes this situation." >&2
133                                 exit 1
134                         fi
135                         ;;
136                 obsolete)
137                         ;;
138                 '')
139                         message_echo "ERROR: Missing operation which must be \"add\" or \"del\"." >&2
140                         exit 1
141                         ;;
142                 *)
143                         message_echo "ERROR: Invalid operation [$COMMAND_OPERATION]; it must be \"add\" or \"del\"." >&2
144                         exit 1
145                         ;;
146                 esac
147                 _command_parse_args__chk_glob_args $#
148                 ;;
149         save)
150                 misc_chk_privilege
151                 if [ ! -d "${DBDIR}" ]
152                 then
153                         message_echo "ERROR: The temporary database has not been created yet." >&2
154                         exit 1
155                 fi
156                 COMMAND_SAVE_DIR=$1
157                 shift || :
158                 _command_parse_args__chk_no_arg $#
159                 if [ -z "$COMMAND_SAVE_DIR" ]
160                 then
161                         message_echo "ERROR: Directory to save the temporary database archive is not specified." >&2
162                         exit 1
163                 fi
164                 if [ ! -d "$COMMAND_SAVE_DIR" ]
165                 then
166                         message_echo "ERROR: Directory [$COMMAND_SAVE_DIR] is not found." >&2
167                         exit 1
168                 fi
169                 ;;
170         load)
171                 misc_chk_privilege
172                 if [ -e "${DBDIR}/in_use" ]
173                 then
174                         message_echo "ERROR: A temporary database exists." >&2
175                         message_echo "You must execute" >&2
176                         message_echo "        ${APPNAME} clean" >&2
177                         message_echo "before executing \"load\" command." >&2
178                         exit 1
179                 fi
180                 COMMAND_LOAD_FILE=$1
181                 shift || :
182                 _command_parse_args__chk_no_arg $#
183                 if [ -z "$COMMAND_LOAD_FILE" ]
184                 then
185                         message_echo "ERROR: No temporary database archive is specified." >&2
186                         exit 1
187                 fi
188                 if [ ! -f "$COMMAND_LOAD_FILE" ]
189                 then
190                         message_echo "ERROR: The temporary database archive is not found." >&2
191                         exit 1
192                 fi
193                 COMMAND_LOAD_FILE=`realpath "$COMMAND_LOAD_FILE"`
194                 ;;
195         glob)
196                 _command_parse_args__chk_glob_args $#
197                 ;;
198         options)
199                 _command_parse_args__chk_no_arg $#
200                 ;;
201         reconf|forget|escape|restore)
202                 misc_chk_privilege
203                 temp_warn_obsolete_temp_db
204                 _command_parse_args__chk_glob_args $#
205                 ;;
206         show)
207                 database_query_chk_preparation_completion
208                 temp_warn_obsolete_temp_db
209                 if ! expr "$1" : '@.*' > /dev/null
210                 then
211                         COMMAND_SHOW_SUBJECT=${1:-todo}
212                         shift || :
213                 else
214                         COMMAND_SHOW_SUBJECT=todo
215                 fi
216                 COMMAND_SHOW_OPTIONS=$1
217                 if expr "$COMMAND_SHOW_OPTIONS" : '@.*' > /dev/null
218                 then
219                         COMMAND_SHOW_DEPTAG=`expr "$COMMAND_SHOW_OPTIONS," : '@\(.*\)' | cut -d , -f 1` || :
220                         COMMAND_SHOW_LEVEL=`expr "$COMMAND_SHOW_OPTIONS," : '@\(.*\)' | cut -d , -f 2` || :
221                         case $COMMAND_SHOW_DEPTAG in
222                         all|run|build|'')       ;;
223                         *)
224                                 message_echo "ERROR: Invalid show option [$COMMAND_SHOW_OPTIONS]." >&2
225                                 exit 1
226                                 ;;
227                         esac
228                         case $COMMAND_SHOW_LEVEL in
229                         full|direct|'') ;;
230                         *)
231                                 message_echo "ERROR: Invalid show option [$COMMAND_SHOW_OPTIONS]." >&2
232                                 exit 1
233                                 ;;
234                         esac
235                         shift || :
236                 fi
237                 case $COMMAND_SHOW_SUBJECT in
238                 todo|done|redo|resolved|failure|taboo|need|noneed|restored|deleted|conflict)
239                         _command_parse_args__chk_no_arg $#
240                         ;;
241                 initrequirements|requirements|initdependents|dependents)
242                         _command_parse_args__chk_glob_args $#
243                         ;;
244                 *)
245                         message_echo "ERROR: Invalid subject [$COMMAND_SHOW_SUBJECT]." >&2
246                         exit 1
247                         ;;
248                 esac
249                 ;;
250         all|prepare)
251                 COMMAND_DO_MODE=$COMMAND_MODE
252                 COMMAND_MODE=do
253                 misc_chk_privilege
254                 temp_warn_obsolete_temp_db
255                 _command_parse_args__chk_no_arg $#
256                 ;;
257         redo|do)
258                 COMMAND_DO_MODE=${1:-all}
259                 shift || :
260                 case $COMMAND_DO_MODE in
261                 all|prepare);;
262                 *)
263                         message_echo "ERROR: Invalid operation mode [$COMMAND_DO_MODE]." >&2
264                         exit 1
265                         ;;
266                 esac
267                 misc_chk_privilege
268                 temp_warn_obsolete_temp_db
269                 _command_parse_args__chk_no_arg $#
270                 if [ "$COMMAND_DO_MODE" = prepare ]
271                 then
272                         COMMAND_RESTART=prepare
273                 else
274                         COMMAND_RESTART=
275                 fi
276                 ;;
277         *)
278                 message_echo "ERROR: Invalid command [$COMMAND_MODE]." >&2
279                 exit 1
280                 ;;
281         esac
282         COMMAND_SHIFT=$(($num_args_init - $#))
283 }
284
285 # ============= Notify that option settings are reset =============
286 command_exec_without_pkgtools__notify_reset_options ()
287 {
288         message_echo "NOTE: Option settings are ignored (because of no effect) and reset."
289 }
290
291 # ============= Execute command operations which do not need package tools =============
292 command_exec_without_pkgtools ()
293 {
294         local dbdir_parent 
295         case $COMMAND_MODE in
296         clean)
297                 message_echo "Starting to clean up the temporary database..."
298                 command_exec_without_pkgtools__notify_reset_options
299                 rm -rf "${DBDIR}"
300                 message_echo "Done"
301                 exit
302                 ;;
303         load)
304                 message_echo "Starting to load the temporary database from the archive..."
305                 command_exec_without_pkgtools__notify_reset_options
306                 dbdir_parent=`dirname "${DBDIR}"`
307                 [ -d "$dbdir_parent" ] || mkdir -p "$dbdir_parent"
308                 tar xzf "$COMMAND_LOAD_FILE" -C "$dbdir_parent" --exclude "*/.lock"
309                 message_echo "Done"
310                 exit
311                 ;;
312         esac
313 }
314
315 # ============= Notify that option settings are ignored because of no effect =============
316 _command_exec_irrespective_of_saved_options__notify_ignored_options ()
317 {
318         message_echo "NOTE: Option settings are ignored because they have no effect on this command."
319 }
320
321 # ============= Operations of forget command =============
322 command_forget ()
323 {
324         message_echo "The temporary database is trying to forget about the specified ports as much as possible."
325         message_echo "Concretely, the data on each of the specified ports and their requirements/dependents is removed unless initially installed or required by other preserved ports."
326         message_echo
327         
328         # Preparation for inspection of the specified ports
329         PROGRAM_DEPENDS=''
330         _program_exec_and_record_completion__operation ()
331         {
332                 message_section_title "Preparation for inspection of the specified ports"
333                 rm -rf "${DBDIR}/forget"
334                 mkdir "${DBDIR}/forget"
335                 for list in masters remove_scope
336                 do
337                         rm -f "${DBDIR}/stage.loop_list/forget_$list"*
338                 done
339                 message_echo
340         }
341         program_exec_and_record_completion FORGET::PREPARATION_INSPECT_MASTER
342         
343         # (Re)initialization of the specified ports to inspect
344         pkgsys_eval_ports_glob "$@" > ${DBDIR}/stage.loop_list/forget_masters
345         
346         # Inspection of the specified ports
347         PROGRAM_DEPENDS='FORGET::PREPARATION_INSPECT_MASTER'
348         _program_exec_restartable_loop_operation__routine ()
349         {
350                 local origin origin_orig
351                 origin=$1
352                 if [ -e "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern" ]
353                 then
354                         origin_orig=`echo "$origin" \
355                                 | sed -E -f "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern"`
356                 else
357                         origin_orig=$origin
358                 fi
359                 if [ ! -e "${DBDIR}/initial/$origin/installed_version" \
360                         -a ! -e "${DBDIR}/initial/$origin_orig/installed_version" \
361                         -a `cat "${DBDIR}/requires/$origin/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ]
362                 then
363                         message_echo "$origin"
364                         echo "$origin" >> ${DBDIR}/forget/remove.master
365                         cat "${DBDIR}/requires/$origin/requirements.all.full" \
366                                 2> /dev/null >> ${DBDIR}/forget/remove.scope || :
367                         database_build_forget "$origin"
368                 fi
369         }
370         _program_exec_and_record_completion__operation ()
371         {
372                 message_section_title "Inspection of the specified ports"
373                 message_echo "----------------"
374                 program_exec_restartable_loop_operation forget_masters
375                 message_echo "----------------"
376                 cat "${DBDIR}/forget/remove.scope" 2> /dev/null \
377                         | sort -u > ${DBDIR}/forget/remove.scope.tmp
378                 mv "${DBDIR}/forget/remove.scope.tmp" "${DBDIR}/forget/remove.scope"
379                 cat "${DBDIR}/forget/remove.master" "${DBDIR}/forget/remove.scope" 2> /dev/null \
380                         | str_escape_regexp_filter \
381                         | sed 's/^/^/;s/$/$/' > ${DBDIR}/forget/remove.scope.grep_pattern
382                 ln -f "${DBDIR}/forget/remove.scope" "${DBDIR}/stage.loop_list/forget_remove_scope"
383                 message_echo
384         }
385         program_exec_and_record_completion FORGET::INSPECT_MASTER
386         
387         # Inspection of the requirements of the specified ports to remove
388         PROGRAM_DEPENDS='FORGET::INSPECT_MASTER'
389         _program_exec_restartable_loop_operation__routine ()
390         {
391                 local origin origin_orig
392                 origin=$1
393                 if [ -e "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern" ]
394                 then
395                         origin_orig=`echo "$origin" \
396                                 | sed -E -f "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern"`
397                 else
398                         origin_orig=$origin
399                 fi
400                 if [ ! -e "${DBDIR}/initial/$origin/installed_version" \
401                         -a ! -e "${DBDIR}/initial/$origin_orig/installed_version" ] \
402                         && ! grep -v -E -f "${DBDIR}/forget/remove.scope.grep_pattern" \
403                                 "${DBDIR}/requires/$origin/dependents.all.full" \
404                                 > /dev/null 2>&1
405                 then
406                         message_echo "$origin"
407                         database_build_forget "$origin"
408                         echo "$origin" >> ${DBDIR}/forget/remove
409                 fi
410         }
411         _program_exec_and_record_completion__operation ()
412         {
413                 message_section_title "Inspection of the requirements of the specified ports to remove"
414                 message_echo "----------------"
415                 program_exec_restartable_loop_operation forget_remove_scope
416                 message_echo "----------------"
417                 cat "${DBDIR}/forget/remove.master" "${DBDIR}/forget/remove" 2> /dev/null \
418                         | str_escape_regexp_filter \
419                         | sed 's/^/^/;s/$/$/' > ${DBDIR}/forget/remove.grep_pattern
420                 cat "${DBDIR}/inspected_ports.update" 2> /dev/null | sort -u \
421                         | grep -v -E -f "${DBDIR}/forget/remove.grep_pattern" \
422                                 > ${DBDIR}/inspected_ports.update.tmp || :
423                 mv "${DBDIR}/inspected_ports.update.tmp" "${DBDIR}/inspected_ports.update"
424                 message_echo
425         }
426         program_exec_and_record_completion FORGET::INSPECT_REQUIREMENTS_OF_REMOVED_PORTS
427         
428         # Set up so that ports are inspected again in the building process of the temporary database
429         program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
430         
431         # Clean up the database for this command because it is no more effective
432         program_deregister_stage_complete FORGET::PREPARATION_INSPECT_MASTER
433         message_echo "Done"
434 }
435
436 # ============= Execute command operations which are irrespective of option settings =============
437 command_exec_irrespective_of_saved_options ()
438 {
439         local dbfile tmp_manually_done_diff evalated_globs dbdir_parent dbdir_node arcfile grandtitle title isfirst origin origin_regexp backup_pkg origin_orig origin_replace pkg_orig tmp_done_orig origin_regexp
440         case $COMMAND_MODE in
441         ok)
442                 dbfile=${DBDIR}/manually_done.list
443                 [ -e "$dbfile" ] || touch "$dbfile"
444                 cp "$dbfile" "$dbfile.tmp"
445                 case $COMMAND_OPERATION in
446                 add)
447                         pkgsys_register_evaluated_globs add "$dbfile.tmp" "$@"
448                         message_echo "`str_linearize_list_and \"$*\"` is/are registered to the list of manually resolved ports"
449                         ;;
450                 del)
451                         pkgsys_register_evaluated_globs remove "$dbfile.tmp" "$@"
452                         message_echo "`str_linearize_list_and \"$*\"` is/are deregistered from the list of manually resolved ports"
453                         ;;
454                 esac
455                 tmp_manually_done_diff_old=${TMPDIR}/command_exec_irrespective_of_saved_options:manually_done.list.diff_old
456                 tmp_manually_done_diff_new=${TMPDIR}/command_exec_irrespective_of_saved_options:manually_done.list.diff_new
457                 if fileedit_manipulate_old_new_lines "$dbfile" "$dbfile.tmp" \
458                         "$tmp_manually_done_diff_old" "$tmp_manually_done_diff_new"
459                 then
460                         while read origin
461                         do
462                                 database_record_failure "$origin"
463                         done < $tmp_manually_done_diff_old
464                         while read origin
465                         do
466                                 database_record_success "$origin"
467                         done < $tmp_manually_done_diff_new
468                 fi
469                 mv "$dbfile.tmp" "$dbfile"
470                 _command_exec_irrespective_of_saved_options__notify_ignored_options
471                 message_echo "Now the following ports have been manually resolved:"
472                 message_cat "$dbfile"
473                 exit
474                 ;;
475         taboo)
476                 evalated_globs=`str_linearize_list_and "$@"`
477                 case $COMMAND_OPERATION in
478                 add)
479                         pkgsys_register_evaluated_globs add "${DBDIR}/taboo.list" "$@"
480                         message_echo "$evalated_globs is/are registered to the list of ports to be ignored."
481                         ;;
482                 del)
483                         pkgsys_register_evaluated_globs remove "${DBDIR}/taboo.list" "$@"
484                         message_echo "$evalated_globs is/are deregistered from the list of ports to be ignored."
485                         ;;
486                 esac
487                 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" > ${DBDIR}/taboo.all.list
488                 _command_exec_irrespective_of_saved_options__notify_ignored_options
489                 message_echo "Now the following ports are registered to be ignored:"
490                 message_cat "${DBDIR}/taboo.all.list"
491                 exit
492                 ;;
493         need)
494                 evalated_globs=`str_linearize_list_and "$@"`
495                 case $COMMAND_OPERATION in
496                 add)
497                         pkgsys_register_evaluated_globs add "${DBDIR}/need.list" "$@"
498                         message_echo "$evalated_globs is/are registered to the list of necessary ports."
499                         ;;
500                 del)
501                         pkgsys_register_evaluated_globs remove "${DBDIR}/need.list" "$@"
502                         message_echo "$evalated_globs is/are deregistered from the list of necessary ports."
503                         ;;
504                 esac
505                 str_escape_regexp_filter < ${DBDIR}/need.list \
506                         | sed 's/^/^/; s/$/$/' > ${DBDIR}/need.grep_pattern
507                 {
508                         sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" "${DBDIR}/need.list" || :
509                         cat "${DBDIR}/need.list" || :
510                 } 2> /dev/null | sort -u > ${DBDIR}/need.with_replaced.list
511                 program_deregister_stage_complete DETERMINE_SPECIFIED_TARGETS
512                 _command_exec_irrespective_of_saved_options__notify_ignored_options
513                 message_echo "Now the following ports are registered to be necessary:"
514                 message_cat "${DBDIR}/need.list"
515                 exit
516                 ;;
517         noneed)
518                 evalated_globs=`str_linearize_list_and "$@"`
519                 case $COMMAND_OPERATION in
520                 add)
521                         pkgsys_register_evaluated_globs add "${DBDIR}/noneed.list" "$@"
522                         message_echo "$evalated_globs is/are registered to the list of unnecessary ports."
523                         ;;
524                 del)
525                         pkgsys_register_evaluated_globs remove "${DBDIR}/noneed.list" "$@"
526                         message_echo "$evalated_globs is/are deregistered from the list of unnecessary ports."
527                         ;;
528                 esac
529                 program_deregister_stage_complete INSPECT_PRIMARY_LEAF_PORTS
530                 _command_exec_irrespective_of_saved_options__notify_ignored_options
531                 message_echo "Now the following ports are registered to be unnecessary:"
532                 message_cat "${DBDIR}/noneed.list"
533                 exit
534                 ;;
535         reselect)
536                 case $COMMAND_OPERATION in
537                 leaves)
538                         if ! deinstall_select_leaf_ports_to_delete force
539                         then
540                                 case $? in
541                                 2)
542                                         message_echo "INFO: No leaf port is found."
543                                         ;;
544                                 3)
545                                         message_echo "INFO: Leaf ports are undefined because requirements of some ports are not fully inspected."
546                                         ;;
547                                 esac
548                         else
549                                 program_deregister_stage_complete COLLECT_LEAF_PORTS_TO_DELETE
550                         fi
551                         ;;
552                 obsolete)
553                         if ! deinstall_select_obsolete_ports_to_delete force
554                         then
555                                 case $? in
556                                 2)
557                                         message_echo "INFO: No obsolete package is found."
558                                         ;;
559                                 esac
560                         else
561                                 program_deregister_stage_complete COLLECT_OBSOLETE_PORTS_TO_DELETE
562                         fi
563                         ;;
564                 esac
565                 exit
566                 ;;
567         save)
568                 dbdir_parent=`dirname "${DBDIR}"`
569                 dbdir_node=`basename "${DBDIR}"`
570                 arcfile=`realpath "$COMMAND_SAVE_DIR"`/${APPNAME}_`date +%Y%m%d_%H%M%S`.tar.gz
571                 _command_exec_irrespective_of_saved_options__notify_ignored_options
572                 message_echo "Starting to save the temporary database as [$arcfile]..."
573                 tar czf "$arcfile" -C "$dbdir_parent" "$dbdir_node"
574                 message_echo "Done"
575                 exit
576                 ;;
577         glob)
578                 _command_exec_irrespective_of_saved_options__notify_ignored_options
579                 message_echo "Evaluated port origins are as follows:"
580                 pkgsys_eval_ports_glob "$@"
581                 exit
582                 ;;
583         reconf)
584                 _command_exec_irrespective_of_saved_options__notify_ignored_options
585                 message_echo "Temporary database sections for the following ports are reset for later rebuild:"
586                 for origin in `pkgsys_eval_ports_glob "$@"`
587                 do
588                         origin_regexp=`str_escape_regexp "$origin"`
589                         if grep -q -E "^$origin_regexp$" "${DBDIR}/inspected_ports" 2> /dev/null
590                         then
591                                 database_build_make "$origin" config
592                                 database_build_patch_reconf "$origin"
593                         else
594                                 message_echo "$origin (not inspected)"
595                                 continue
596                         fi
597                 done
598                 program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
599                 message_echo "Done"
600                 exit
601                 ;;
602         forget)
603                 _command_exec_irrespective_of_saved_options__notify_ignored_options
604                 command_forget "$@"
605                 exit
606                 ;;
607         escape)
608                 _command_exec_irrespective_of_saved_options__notify_ignored_options
609                 message_echo "Backing up and deleting the following packages for a temporary escape:"
610                 message_echo
611                 for origin in `pkgsys_eval_ports_glob "$@"`
612                 do
613                         pkgsys_register_evaluated_globs add "${DBDIR}/taboo.list" "$origin"
614                         message_echo "  Registered $origin as taboo."
615                         pkg=`pkg_info_qO "$origin"` || continue
616                         [ -n "$pkg" ] || continue
617                         if backup_pkg=`pkgsys_get_backup_pkg "$origin"`
618                         then
619                                 message_echo "INFO: A backup package for $pkg ($origin) already exists as $backup_pkg."
620                         elif backup_pkg=`pkgsys_create_backup_pkg "$pkg" "${DBDIR}/backup_packages"`
621                         then
622                                 message_echo "  Backed up $pkg ($origin) into $backup_pkg"
623                         else
624                                 message_echo "ERROR: Failed to back up $pkg ($origin)." >&2
625                                 message_echo >&2
626                                 continue
627                         fi
628                         pkg_delete_f "$pkg" || \
629                         {
630                                 message_echo "ERROR: Failed to deinstall $pkg ($origin)." >&2
631                                 message_echo >&2
632                         }
633                         message_echo "  Deinstalled $pkg ($origin)."
634                         message_echo
635                 done
636                 program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
637                 message_echo "Done"
638                 exit
639                 ;;
640         restore)
641                 _command_exec_irrespective_of_saved_options__notify_ignored_options
642                 message_echo "Restoring the following temporary escaped packages:"
643                 message_echo
644                 tmp_done_orig=${TMPDIR}/command_exec_irrespective_of_saved_options::restore::done_orig
645                 cp /dev/null "$tmp_done_orig"
646                 for origin in `pkgsys_eval_ports_glob "$@"`
647                 do
648                         pkgsys_register_evaluated_globs remove "${DBDIR}/taboo.list" "$origin"
649                         message_echo "  Deregistered $origin from taboo."
650                         origin_regexp=`str_escape_regexp "$origin"`
651                         grep -E -q "^$origin_regexp$" "$tmp_done_orig" || :
652                         if pkg_info_eO "$origin"
653                         then
654                                 pkg=`pkg_info_qO "$origin"` || :
655                                 message_echo "WARNING: $pkg ($origin) is already installed." >&2
656                                 message_echo >&2
657                                 continue
658                         fi
659                         origin_orig=`echo "$origin" \
660                                 | sed -E -f "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern"`
661                         if [ "x$origin_orig" = "x$origin" ] && pkg_info_eO "$origin_orig"
662                         then
663                                 pkg_orig=`pkg_info_qO "$origin_orig"` || :
664                                 message_echo "WARNING: An original version of $origin ($pkg_orig, $origin_orig) is already installed." >&2
665                                 message_echo >&2
666                                 continue
667                         fi
668                         origin_replace=`echo "$origin" \
669                                 | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern"`
670                         if [ "x$origin_replace" != "x$origin" ]
671                         then
672                                 if pkg_info_eO "$origin_replace"
673                                 then
674                                         pkg_replace=`pkg_info_qO "$origin_replace"` || :
675                                         message_echo "WARNING: A replacement of $origin ($pkg_replace, $origin_replace) is already installed." >&2
676                                         message_echo >&2
677                                         continue
678                                 fi
679                                 if backup_pkg=`pkgsys_get_backup_pkg "$origin_replace" 2> /dev/null`
680                                 then
681                                         message_echo "INFO: $origin is replaced with $origin_replace ($pkg_replace)."
682                                         echo "$origin_replace" >> $tmp_done_orig
683                                         origin=$origin_replace
684                                 fi
685                         else
686                                 backup_pkg=
687                         fi
688                         if [ -z "$backup_pkg" ] && ! backup_pkg=`pkgsys_get_backup_pkg "$origin" 2> /dev/null`
689                         then
690                                 message_echo "ERROR: Backup for $origin is not found." >&2
691                                 message_echo >&2
692                                 continue
693                         fi
694                         pkg=`pkgsys_pkgarc_to_pkgname "$backup_pkg"`
695                         if ! pkg_add_fF "$backup_pkg"
696                         then
697                                 message_echo "ERROR: Failed to restore $pkg ($origin)." >&2
698                                 message_echo >&2
699                         fi
700                         message_echo "  Restored $pkg ($origin)."
701                         message_echo
702                 done
703                 program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
704                 message_echo "Done"
705                 exit
706                 ;;
707         redo)
708                 if [ $opt_reload_conf = yes ]
709                 then
710                         program_deregister_stage_complete SAVE_PREV_CONF
711                 fi
712                 ;;
713         esac
714 }
715
716 # ============= Output of "options" command =============
717 _command_exec_before_tools_upgrade__options ()
718 {
719         local opt_control group_reset group_remain reset_opts result_opts str_opt_control str_rstoption notice_reset notice_result
720         opt_control=$1
721         group_reset=$2
722         group_remain=$3
723         reset_opts=`options_inverse_parse $group_reset`
724         result_opts=`options_inverse_parse $group_remain`
725         if [ $is_batch_mode = yes ]
726         then
727                 printf '%s\t%s\t%s\n' "$opt_control" "$reset_opts" "$result_opts"
728         else
729                 str_opt_control=`echo "$opt_control" | sed -E 's/(.)/-\1 /g;s/ *$//'`
730                 str_rstoption=Option`[ \`echo -n "$opt_control" | wc -c\` -ge 2 ] && echo s` || :
731                 notice_reset=`[ -z "$reset_opts" ] && echo ' (nothing)'` || :
732                 notice_result=`[ -z "$result_opts" ] && echo ' (default)'` || :
733                 echo "$str_rstoption [$str_opt_control] will reset [$reset_opts]$notice_reset so that the settings become [$result_opts]$notice_result."
734         fi
735 }
736
737 # ============= Execute command operations which should be done without upgrade of tools =============
738 command_exec_before_tools_upgrade ()
739 {
740         local flag_filter_skip_unchanged flag_filter_only_target pkgnamedb dbsuffix list origin_target
741         case $COMMAND_MODE in
742         reset)
743                 message_echo "Starting to reset the temporary database by preserving the initial snapshot of installed packages..."
744                 find "${DBDIR}" -depth 1 \
745                         -not \( -name saved_options.sh \
746                                 -or -name initial -or -name MYVERSION \
747                                 -or -name backup_failure -or -name installed_ports\* \) \
748                         -exec rm -rf {} \; 2> /dev/null || :
749                 case $COMMAND_OPERATION in
750                 all)
751                         command_exec_without_pkgtools__notify_reset_options
752                         rm -f "${DBDIR}/saved_options.sh"
753                         ;;
754                 keepopts)
755                         message_echo "INFO: option settings are preserved."
756                         ;;
757                 esac
758                 find "${DBDIR}/initial" -depth 2 -type d \
759                         | sed -E 's|.*/([^/]+/[^/]+)$|\1|' > ${DBDIR}/inspected_ports.update
760                 mkdir -p "${DBDIR}/stage.loop_list"
761                 message_echo "Done"
762                 exit
763                 ;;
764         options)
765                 ( set -e
766                         is_batch_mode=$opt_batch_mode
767                         options_set_default
768                         [ -e "${DBDIR}/saved_options.sh" ] && . "${DBDIR}/saved_options.sh"
769                         savedopts=`options_inverse_parse`
770                         if [ $is_batch_mode = yes ]
771                         then
772                                 printf '\t%s\n' "$savedopts"
773                         else
774                                 echo "The saved setting is [$savedopts]."
775                         fi
776                         _command_exec_before_tools_upgrade__options M \
777                                 'renewable_anytime' 'non_renewable renewable_in_redo_on_target renewable_in_redo_on_conf'
778                         _command_exec_before_tools_upgrade__options N \
779                                 'renewable_in_redo_on_target' 'non_renewable renewable_anytime renewable_in_redo_on_conf'
780                         _command_exec_before_tools_upgrade__options L \
781                                 'renewable_in_redo_on_conf' 'non_renewable renewable_anytime renewable_in_redo_on_target'
782                         _command_exec_before_tools_upgrade__options MN \
783                                 'renewable_anytime renewable_in_redo_on_target' 'non_renewable renewable_in_redo_on_conf'
784                         _command_exec_before_tools_upgrade__options ML \
785                                 'renewable_anytime renewable_in_redo_on_conf' 'non_renewable renewable_in_redo_on_target'
786                         _command_exec_before_tools_upgrade__options NL \
787                                 'renewable_in_redo_on_target renewable_in_redo_on_conf' 'non_renewable renewable_anytime'
788                         _command_exec_before_tools_upgrade__options MNL \
789                                 'renewable_anytime renewable_in_redo_on_target renewable_in_redo_on_conf' 'non_renewable'
790                 )
791                 exit
792                 ;;
793         show)
794                 flag_filter_skip_unchanged=
795                 flag_filter_only_target=
796                 pkgnamedb='requires obsolete initial'
797                 [ -n "$COMMAND_SHOW_DEPTAG" ] || COMMAND_SHOW_DEPTAG=`options_get_dependency_type`
798                 [ -n "$COMMAND_SHOW_LEVEL" ] || COMMAND_SHOW_LEVEL=`options_get_dependency_level`
799                 dbsuffix=$COMMAND_SHOW_DEPTAG.$COMMAND_SHOW_LEVEL
800                 case $COMMAND_SHOW_SUBJECT in
801                 todo|done|redo|resolved|failure|taboo|need|noneed|deleted|restored|conflict)
802                         database_query_show_single_list_exec "$COMMAND_SHOW_SUBJECT" \
803                                 "$COMMAND_SHOW_DEPTAG" "$COMMAND_SHOW_LEVEL" || :
804                         ;;
805                 initrequirements)
806                         grandtitle="Dependencies based on the initially installed packages"
807                         title="The following port(s) was/were required by %s:"
808                         list=requirements.$dbsuffix
809                         pkgnamedb='initial'
810                         [ $COMMAND_SHOW_DEPTAG = none ] && \
811                                 message_echo "WARNING: This command has no meaning with the current options setting." >&2
812                         database_query_for_each_matching_port "$grandtitle" "$title" "$list" "$pkgnamedb" \
813                                 "$COMMAND_SHOW_DEPTAG" "$COMMAND_SHOW_LEVEL" "$@"
814                         ;;
815                 requirements)
816                         grandtitle="Dependencies based on the latest ports tree"
817                         title="The following port(s) is/are required by %s:"
818                         list=requirements.$dbsuffix
819                         pkgnamedb='requires obsolete'
820                         [ $COMMAND_SHOW_DEPTAG = none ] && \
821                                 message_echo "WARNING: This command has no meaning with the current options setting." >&2
822                         database_query_for_each_matching_port "$grandtitle" "$title" "$list" "$pkgnamedb" \
823                                 "$COMMAND_SHOW_DEPTAG" "$COMMAND_SHOW_LEVEL" "$@"
824                         ;;
825                 initdependents)
826                         grandtitle="Dependencies based on the initially installed packages"
827                         title="The following port(s) depended on %s:"
828                         list=dependents.$dbsuffix
829                         pkgnamedb='initial'
830                         [ $COMMAND_SHOW_DEPTAG = none ] && \
831                                 message_echo "WARNING: This command has no meaning with the current options setting." >&2
832                         database_query_for_each_matching_port "$grandtitle" "$title" "$list" "$pkgnamedb" \
833                                 "$COMMAND_SHOW_DEPTAG" "$COMMAND_SHOW_LEVEL" "$@"
834                         ;;
835                 dependents)
836                         grandtitle="Dependencies based on the latest ports tree"
837                         title="The following port(s) depend(s) on %s:"
838                         list=dependents.$dbsuffix
839                         pkgnamedb='requires obsolete'
840                         [ $COMMAND_SHOW_DEPTAG = none ] && \
841                                 message_echo "WARNING: This command has no meaning with the current options setting." >&2
842                         database_query_for_each_matching_port "$grandtitle" "$title" "$list" "$pkgnamedb" \
843                                 "$COMMAND_SHOW_DEPTAG" "$COMMAND_SHOW_LEVEL" "$@"
844                         ;;
845                 esac
846                 exit
847                 ;;
848         esac
849 }
850
851 # ============= Execute command operations which must be done before building the temporary database =============
852 command_exec_before_building_tempdb ()
853 {
854         case $COMMAND_MODE in
855         redo)
856                 program_deregister_stage_complete REDO_INIT
857                 if [ $opt_reset_targets = yes ]
858                 then
859                         program_deregister_stage_complete DETERMINE_SPECIFIED_TARGETS
860                         program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES
861                         rm -rf "${DBDIR}/targets"
862                 fi
863                 ;;
864         esac
865         program_deregister_stage_complete FORGET::PREPARATION_INSPECT_MASTER
866 }
867
868 # ============= Execute command operations which must be done before actual (re/de)installation processes =============
869 command_exec_before_actual_re_de_installation ()
870 {
871         case $COMMAND_MODE in
872         do|redo)
873                 case $COMMAND_DO_MODE in
874                 prepare)
875                         message_cat 3<< eof
876 Done (skipped reinstallation) at `message_timestamp`
877
878  You can restart this process from the aborted/terminated point by executing without options or arguments as:
879   ${APPNAME}
880 eof
881                         temp_terminate_process ()
882                         {
883                         }
884                         exit
885                         ;;
886                 esac
887                 ;;
888         esac
889 }