OSDN Git Service

Fixed a bug that ports installed by prebuilt packages were not registered correctly.
[portsreinstall/current.git] / lib / libreinstall.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Reinstallation processes -
5 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Variables =============
10 # The following variables are available only within reinstall_exec and functions invoked by it.
11 REINSTALL_PKGTAG=       # Tag indicating version changes by reinstallation of the current port
12 REINSTALL_ORIGPKGTAG=   # Tag indicating the flavored port origin and version changes by reinstallation of the current port
13 REINSTALL_CURRENTPKG=   # Currently installed package name of the current port
14 REINSTALL_ORIGIN=       # Flavored port origin of the current port
15 REINSTALL_DBNODE_DIR=   # Path of the "requires" section of the temporary database for the current port
16 REINSTALL_IS_CURRENTPKG_LATEST= # Currently installed package name of the current port
17 REINSTALL_DBSUFFIX=     # Database suffix for the evaluation method of dependencies
18
19 # ============= Skip reinstallation by showing messages =============
20 reinstall_skip ()
21 {
22         local message
23         message=$1
24         message_echo "($message)"
25         message_target_relations "$REINSTALL_ORIGIN"
26         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/stage.loop_list/reinst_todo.remain"
27 }
28
29 # ============= Check whether a package is forbidden due to conflict =============
30 reinstall_quick_chk_forbidden_conflicts ()
31 {
32         local pkg pkg_regexp_esc
33         pkg=$1
34         pkg_regexp_esc=`str_escape_regexp "$pkg"`
35         grep -qE "^$pkg_regexp_esc:" "${DBDIR}/forbidden_conflicts" 2> /dev/null
36 }
37
38 # ============= Check whether a package is forbidden due to conflict =============
39 reinstall_chk_forbidden_conflicts ()
40 {
41         local pkg tmp_forbidden pkg_regexp_esc
42         pkg=$1
43         tmp_forbidden=${TMPDIR}/reinstall_chk_forbidden_conflicts:forbidden
44         pkg_regexp_esc=`str_escape_regexp "$pkg"`
45         grep -E "^$pkg_regexp_esc:" "${DBDIR}/forbidden_conflicts" > $tmp_forbidden 2> /dev/null || return
46         pkg_info_e `cut -d : -f 3 "$tmp_forbidden"`
47 }
48
49 # ============= Restore a package if it is temporarily deinstalled =============
50 reinstall_restore_if_temporarily_deinstalled ()
51 {
52         local tmp_delete
53         [ $opt_fetch_only = no -a $opt_dry_run = no ] || return 0
54         [ -n "$REINSTALL_CURRENTPKG" ] && return
55         tmp_list=${TMPDIR}/reinstall_restore_if_temporarily_deinstalled
56         rm -rf "$tmp_list".*
57         [ -e "$REINSTALL_FROMNODE_DIR/backedup_pkgfile" ] || return 0
58         while read backup_pkg
59         do
60                 [ -z "$backup_pkg" -o ! -e "$backup_pkg" ] && continue
61                 echo "$backup_pkg" >> $tmp_list.backedup
62                 pkg=`pkgsys_pkgarc_to_pkgname "$backup_pkg"`
63                 if reinstall_chk_forbidden_conflicts "$pkg"
64                 then
65                         echo "$backup_pkg" >> $tmp_list.avoid
66                 else
67                         echo "$backup_pkg" >> $tmp_list.restore
68                 fi
69         done < $REINSTALL_FROMNODE_DIR/backedup_pkgfile
70         [ -e "$tmp_list.backedup" ] || return 0
71         message_echo "INFO: This port is temporarily deinstalled, so restoration will be attempted."
72         if [ -e "$tmp_list.avoid" ]
73         then
74                 message_echo "INFO: The following backup(s) are avoided because of conflict with installed packages."
75                 message_cat < $tmp_list.avoid
76         fi
77         if [ -e "$tmp_list.restore" ]
78         then
79                 message_echo "INFO: The following backup(s) will be restored."
80                 message_cat < $tmp_list.restore
81                 while read backup_pkg
82                 do
83                         pkg_add_fF "$backup_pkg" || echo "$backup_pkg" >> $tmp_list.failed
84                 done < $tmp_list.restore
85                 if [ -e "$tmp_list.failed" ]
86                 then
87                         message_echo "WARNING: Failed to restore the following backup, but continuing anyway." >&2
88                         message_cat < $tmp_list.failed
89                 fi
90         fi
91         :
92 }
93
94 # ============= Skip reinstallation by showing messages if a flavored origin is in a list =============
95 reinstall_skip_if_in_a_list ()
96 {
97         local message list mode
98         message=$1
99         list=$2
100         mode=$3
101         grep -q -Fx "$REINSTALL_ORIGIN" "${DBDIR}/$list" 2> /dev/null || return
102         [ "x$mode" = xrestore ] && reinstall_restore_if_temporarily_deinstalled
103         reinstall_skip "$message" || :
104 }
105
106 # ============= Get the make arguments =============
107 reinstall_setup_make_args ()
108 {
109         local mode
110         mode=$1
111         {
112                 for key in LOCALBASE LINUXBASE PORT_DBDIR PORTSDIR DISTDIR PACKAGES PKGREPOSITORY
113                 do
114                         eval echo $key=\$$key
115                 done
116                 [ $opt_avoid_vulner = yes ] || echo 'DISABLE_VULNERABILITIES=yes'
117                 case $mode in
118                 anymode )
119                         ;;
120                 '' | distinct )
121                         [ $opt_batch_ports_only = yes ] && echo 'BATCH=yes'
122                         [ $opt_interactive_ports_only = yes ] && echo 'INTERACTIVE=yes'
123                         ;;
124                 esac
125                 if [ $opt_apply_default_config = yes ]
126                 then
127                         pkgsys_is_dialog4ports_used && echo 'NO_DIALOG=yes'
128                 fi
129                 dbdir=$REINSTALL_DBNODE_DIR
130                 [ -d "$dbdir" ] || dbdir=${DBDIR}/conf/each_port/$REINSTALL_ORIGIN
131                 cat "$dbdir/MARG.conf" 2> /dev/null || :
132                 flavor=`pkgsys_get_flavor_from_origin "$REINSTALL_ORIGIN"`
133                 [ -z "$flavor" ] || echo "FLAVOR=$flavor"
134         } | tr '\n' ' '
135 }
136
137 # ============= Get the make environment variables =============
138 reinstall_setup_make_envs ()
139 {
140         database_build_setup_make_envs "$REINSTALL_ORIGIN"
141 }
142
143 # ============= Common comand to execute make command =============
144 _reinstall_make_common ()
145 {
146         local mode port_path MAKE_ARGS MAKE_ENVS
147         mode=$1
148         shift
149         MAKE_ARGS=`reinstall_setup_make_args $mode`
150         MAKE_ENVS=`reinstall_setup_make_envs`
151         port_path=`pkgsys_get_portpath_from_origin "$REINSTALL_ORIGIN"`
152         fs_fix_unionfs_image_if_hidden "$port_path"
153         env $MAKE_ENVS make -C "$port_path" "$@" $MAKE_ARGS
154 }
155
156 # ============= Execute make command without restricting for BATCH or INTERACTIVE ports =============
157 reinstall_make_anymode ()
158 {
159         _reinstall_make_common anymode "$@"
160 }
161
162 # ============= Execute make command =============
163 reinstall_make ()
164 {
165         _reinstall_make_common '' "$@"
166 }
167
168 # ============= Error process during reinstallation =============
169 reinstall_errproc ()
170 {
171         local position msg port_path
172         position=$1
173         msg=$2
174         database_build_update_pkgname "$REINSTALL_ORIGIN" > /dev/null
175         message_echo "ERROR: In $position." >&2
176         message_echo "The port/package in concern is $REINSTALL_ORIGPKGTAG." >&2
177         [ -n "$msg" ] && message_echo "($msg)" >&2
178         message_echo >&2
179         port_path=`pkgsys_get_portpath_from_origin "$REINSTALL_ORIGIN"`
180         { fs_fix_unionfs_image_if_hidden "$port_path" \
181                 && pkgsys_chk_ports_tree_implementation; } || exit 1
182         mkdir -p "${DBDIR}/notes/$REINSTALL_ORIGIN"
183         echo "$position" > ${DBDIR}/notes/$REINSTALL_ORIGIN/note_failtre
184         database_record_failure "$REINSTALL_ORIGIN" noclean
185         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/stage.loop_list/reinst_todo.remain"
186         message_report_failure_for_a_port "$REINSTALL_ORIGIN"
187 }
188
189 # ============= Check the latest stage for a port =============
190 reinstall_chk_stage ()
191 {
192         local stagetag
193         stagetag=$1
194         [ -e "${DBDIR}/status.ports/$REINSTALL_ORIGIN/$stagetag" ]
195 }
196
197 # ============= Check completion of a stage for a port =============
198 reinstall_chk_stage_complete ()
199 {
200         local stagetag
201         stagetag=$1
202         [ -e "${DBDIR}/status.ports/$REINSTALL_ORIGIN/complete/$stagetag" ]
203 }
204
205 # ============= Register the latest stage for a port =============
206 reinstall_register_stage ()
207 {
208         local stagetag parentdir
209         stagetag=$1
210         parentdir=${DBDIR}/status.ports/$REINSTALL_ORIGIN
211         mkdir -p "$parentdir"
212         touch "$parentdir/$stagetag"
213 }
214
215 # ============= Register completion of a stage for a port =============
216 reinstall_register_stage_complete ()
217 {
218         local stagetag parentdir
219         stagetag=$1
220         parentdir=${DBDIR}/status.ports/$REINSTALL_ORIGIN/complete
221         mkdir -p "$parentdir"
222         touch "$parentdir/$stagetag"
223 }
224
225 # ============= Deregister the latest stage for a port =============
226 reinstall_deregister_stage ()
227 {
228         local stagetag
229         stagetag=$1
230         rm -f "${DBDIR}/status.ports/$REINSTALL_ORIGIN/$stagetag"
231 }
232
233 # ============= Deregister completion of a stage for a port =============
234 reinstall_deregister_stage_complete ()
235 {
236         local stagetag
237         stagetag=$1
238         rm -f "${DBDIR}/status.ports/$REINSTALL_ORIGIN/complete/$stagetag"
239 }
240
241 # ============= Back up and delete conflict =============
242 # Package names of conflict are given via stdin. 
243 reinstall_backup_and_delete_conflicts ()
244 {
245         local pkg origin origin_regexp_esc backup_pkgdir backup_pkg
246         message_echo "INFO: Deinstalling conflicting packages for $REINSTALL_ORIGPKGTAG."
247         while read pkg
248         do
249                 origin=`pkg_info_flavored_origin "$pkg"`
250                 message_echo "INFO: Backing up and deleting a conflict, $origin ($pkg)."
251                 origin_regexp_esc=`str_escape_regexp "$origin"`
252                 if [ -d "${DBDIR}/requires/$origin" ]
253                 then
254                         backup_pkgdir=${DBDIR}/backup_packages
255                 else
256                         backup_pkgdir=${PKGREPOSITORY}
257                 fi
258                 mkdir -p "$backup_pkgdir"
259                 if backup_pkg=`pkgsys_get_backup_pkg "$origin"`
260                 then
261                         message_echo "INFO: backup package already exists as $backup_pkg"
262                 elif ! backup_pkg=`pkgsys_create_backup_pkg "$pkg" "$backup_pkgdir"`
263                 then
264                         message_echo "WARNING: Failed to create the backup package, the conflict is kept installed." >&2
265                         continue
266                 fi
267                 grep -v -E "^${origin_regexp_esc}[[:space:]]" "${DBDIR}/deleted_conflicts" \
268                         > ${DBDIR}/deleted_conflicts.tmp 2> /dev/null || :
269                 printf '%s\t%s\n' "$origin" "$pkg" >> ${DBDIR}/deleted_conflicts.tmp
270                 mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
271                 pkg_delete_f "$pkg" || \
272                 {
273                         message_echo "WARNING: Failed to deinstall $pkg by $PKGSYS_CMD_PKG_DELETE." >&2
274                 }
275         done
276         cat "${DBDIR}/deleted_conflicts" 2> /dev/null | sort -u > ${DBDIR}/deleted_conflicts.tmp
277         mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
278 }
279
280 # ============= Back up and delete remaining actual install conflict (for installation by package) =============
281 reinstall_backup_and_delete_remaining_install_conflicts__by_pkg ()
282 {
283         local pkg tmp_conflicts
284         pkg=$1
285         tmp_conflicts=${TMPDIR}/reinstall_backup_and_delete_remaining_install_conflicts__by_pkg
286         message_echo "(Checking installation conflict...)"
287         pkgsys_get_conflicting_installed_pkgs install "$REINSTALL_ORIGIN" > $tmp_conflicts.pkgs || :
288         while read pkg_conflict
289         do
290                 fileedit_add_a_line_if_new "$pkg_conflict:$REINSTALL_ORIGIN:$pkg" \
291                         "${DBDIR}/forbidden_conflicts"
292         done < $tmp_conflicts.pkgs
293         reinstall_backup_and_delete_conflicts < $tmp_conflicts.pkgs
294 }
295
296 # ============= Back up and delete remaining actual install conflict (for installation by port) =============
297 reinstall_backup_and_delete_remaining_install_conflicts ()
298 {
299         local stagedir tmp_conflicts db_conflict
300         tmp_conflicts=${TMPDIR}/reinstall_backup_and_delete_remaining_install_conflicts
301         db_conflict=$REINSTALL_DBNODE_DIR/possible_additional_conflict.csv
302         message_echo "(Checking installation conflict...)"
303         rm -rf "$db_conflict.tmp" "$tmp_conflicts".*
304         stagedir=`database_query_get_makevar_val "$REINSTALL_ORIGIN" STAGEDIR`
305         pkgsys_get_conflicting_installed_pkgs install "$REINSTALL_ORIGIN" > $tmp_conflicts.pkgs || :
306         ( set -e
307                 cd "$stagedir"
308                 find . -not -type d
309         ) | sed 's|^\.||' | while read filepath
310         do
311                 [ ! -e "$filepath" ] && continue
312                 pkg=`pkg_which "$filepath" || :`
313                 [ -z "$pkg" ] && continue
314                 grep -qFx "$pkg" "$tmp_conflicts.pkgs" && continue
315                 origin=`pkg_info_flavored_origin "$pkg"`
316                 [ x"$origin" = x"$REINSTALL_ORIGIN" ] && continue
317                 printf '%s\t%s\n' "$pkg" "$filepath" >> $db_conflict.tmp
318         done
319         if [ -e "$db_conflict.tmp" ]
320         then
321                 while read pkg filepath
322                 do
323                         message_echo "INFO: Possible additional conflict with $pkg: $filepath"
324                 done < $db_conflict.tmp
325                 message_echo "INFO: The possible additional conflict packages will be escaped just in case."
326                 mv "$db_conflict.tmp" "$db_conflict"
327                 cut -f 1 "$db_conflict" >> $tmp_conflicts.pkgs
328         else
329                 rm -f "$db_conflict.tmp" "$db_conflict"
330         fi
331         while read pkg_conflict
332         do
333                 fileedit_add_a_line_if_new "$pkg_conflict:$REINSTALL_ORIGIN:$REINSTALL_NEWPKGNAME" \
334                         "${DBDIR}/forbidden_conflicts"
335         done < $tmp_conflicts.pkgs
336         reinstall_backup_and_delete_conflicts < $tmp_conflicts.pkgs
337 }
338
339 # ============= Remove needless possible additional conflict =============
340 # Use after installation of the target port and before restoration of its possible additional conflict.
341 reinstall_remove_needless_possible_conflict ()
342 {
343         local db_conflict db_forbidden suffix tmp_db
344         db_conflict=$REINSTALL_DBNODE_DIR/possible_additional_conflict.csv
345         db_forbidden=${DBDIR}/forbidden_conflicts
346         tmp_db=${TMPDIR}/reinstall_remove_needless_possible_conflict:db
347         [ -e "$db_conflict" ] || return 0
348         if [ ! -e "$db_forbidden" ]
349         then
350                 rm -fr "$db_conflict"
351                 return
352         fi
353         rm -rf "$db_conflict".*
354         touch $db_conflict.tmp
355         while read pkg filepath
356         do
357                 if which -s "$filepath"
358                 then
359                         echo printf '%s\t%s\n' "$pkg" "$filepath" >> $db_conflict.tmp
360                         message_echo "WARNING: Unregistered additional conflict with $pkg: $filepath" >&2
361                 else
362                         message_echo "INFO: The above notice of the possible additional conflict was needless: $pkg: $filepath"
363                 fi
364         done < $db_conflict
365         cut -f 1 "$db_conflict" | sort -u > $tmp_db.conflict_pkg.old
366         cut -f 1 "$db_conflict.tmp" | sort -u > $tmp_db.conflict_pkg.new
367         suffix=`echo ":$REINSTALL_ORIGIN:$REINSTALL_NEWPKGNAME" | str_escape_replaceval_filter`
368         grep -vFx -f "$tmp_db.conflict_pkg.new" "$tmp_db.conflict_pkg.old" | \
369                 sed -E "s/$/$suffix/" > $tmp_db.conflict_pkg.needless.filter
370         grep -vFx -f "$tmp_db.conflict_pkg.needless.filter" "$db_forbidden" > $db_forbidden.tmp || :
371         mv "$db_forbidden.tmp" "$db_forbidden"
372         mv "$db_conflict.tmp" "$db_conflict"
373         [ `wc -l < $db_conflict` -gt 0 ] || rm "$db_conflict"
374 }
375
376 # ============= Restoration of backed up conflict =============
377 reinstall_restore_conflicts ()
378 {
379         local origin_current tmpsrc
380         origin_current=$1
381         [ $opt_fetch_only = no -a $opt_dry_run = no ] || return 0
382         [ -e "${DBDIR}/deleted_conflicts" ] || return 0
383         tmpsrc=${TMPDIR}/reinstall_restore_conflicts::deleted_conflicts
384         cp "${DBDIR}/deleted_conflicts" "$tmpsrc"
385         while read origin pkg
386         do
387                 pkg_regexp_esc=`str_escape_regexp "$pkg"`
388                 origins_init=`database_query_initial_orgins "$origin" | grep -vFx "$origin" || :`
389                 origin_replace=`echo "$origin" \
390                         | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern"`
391                 [ "x$origin_replace" = "x$origin" ] && origin_replace=
392                 is_to_dereg_from_list=no
393                 if [ -n "$origin_current" -a "x$origin" = "x$origin_current" ] || \
394                         pkg_info_e "$pkg" || pkgsys_exists_from_orig "$origin"
395                 then
396                         is_to_dereg_from_list=yes
397                 else
398                         for origin_orig in $origins_init $origin_replace
399                         do
400                                 if [ -n "$origin_orig" ] && pkgsys_exists_from_orig "$origin_orig"
401                                 then
402                                         is_to_dereg_from_list=yes
403                                         break
404                                 fi
405                         done
406                 fi
407                 if pkgsys_chk_conflict_by_a_pkg install "$REINSTALL_ORIGIN" "$pkg"
408                 then
409                         fileedit_add_a_line_if_new "$pkg:$REINSTALL_ORIGIN:$REINSTALL_NEWPKGNAME" "${DBDIR}/forbidden_conflicts"
410                         is_skipped=yes
411                 elif reinstall_chk_forbidden_conflicts "$pkg"
412                 then
413                         is_skipped=yes
414                 else
415                         is_skipped=no
416                 fi
417                 if [ $is_skipped = yes ]
418                 then
419                         message_echo "INFO: Restoration of a conflict, $origin ($pkg), is avoided because it conflicts with installed packages."
420                 fi
421                 if [ $is_to_dereg_from_list = yes ]
422                 then
423                         pkg_current=
424                         origin_current=
425                         for origin_trial in $origin $origins_init $origin_replace
426                         do
427                                 pkg_trial=`pkgsys_get_installed_pkg_from_origin "$origin_trial" || :`
428                                 [ -z "$pkg_trial" ] && continue
429                                 pkg_current="$pkg_current, $pkg_trial"
430                                 origin_current="$origin_current, $origin_trial"
431                         done
432                         pkg_current=`expr "$pkg_current" : ', \(.*\)'` || pkg_current=none
433                         origin_current=`expr "$origin_current" : ', \(.*\)'` || origin_current=none
434                         pkgname_msg=$pkg
435                         origin_msg=$origin
436                         [ "x$pkg_current" = "x$pkg" ] || pkgname_msg="$pkg => $pkg_current"
437                         [ "x$origin_current" = "x$origin" ] || origin_msg="$origin => $origin_current"
438                         if [ $is_skipped = yes ]
439                         then
440                                 message_echo "WARNING: Conflicting package is installed: $origin_msg ($pkgname_msg)"
441                         else
442                                 message_echo "INFO: $origin_msg ($pkgname_msg) is already restored."
443                                 grep -v -E "[[:space:]]$pkg_regexp_esc$" "${DBDIR}/deleted_conflicts" \
444                                         > ${DBDIR}/deleted_conflicts.tmp || :
445                                 mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
446                         fi
447                         continue
448                 fi
449                 [ $is_skipped = yes ] && continue
450                 if grep -q -Fx -e "$origin" -e "$origin_replace" "${DBDIR}/taboo.all.list" 2> /dev/null
451                 then
452                         message_echo "INFO: Restoration of a conflict, $origin ($pkg), is avoided because it is taboo."
453                         continue
454                 fi
455                 message_echo "INFO: Restoring a former conflict, $origin ($pkg)."
456                 if ! backup_pkg=`pkgsys_get_backup_pkg "$origin"`
457                 then
458                         message_echo "WARNING: No backup exists, gave up." >&2
459                         continue
460                 fi
461                 if pkg_add_fF "$backup_pkg"
462                 then
463                         grep -v -E "[[:space:]]$pkg_regexp_esc$" "${DBDIR}/deleted_conflicts" \
464                                 > ${DBDIR}/deleted_conflicts.tmp || :
465                         mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
466                 else
467                         message_echo "WARNING: Failed to restore. Note that your system may experience troubles by this error." >&2
468                 fi
469         done < $tmpsrc
470 }
471
472 # ============= Check whether the all non-looped requirements are installed =============
473 reinstall_are_requirements_ready ()
474 {
475         [ -e "$REINSTALL_DBNODE_DIR/requirements.all.direct" ] || return 0
476         while read origin
477         do
478                 pkgsys_exists_from_orig "$origin" || return 1
479         done < $REINSTALL_DBNODE_DIR/requirements.all.direct
480 }
481
482 # ============= Get the all non-looped requirements ready for a port by restarting them if deinstalled =============
483 reinstall_chk_and_restore_requirements ()
484 {
485         local tmp_restore tmp_isfailed
486         tmp_restore=${TMPDIR}/reinstall_setup_requirements:restore
487         tmp_isfailed=${TMPDIR}/reinstall_setup_requirements:isfailed
488         cp /dev/null "$tmp_restore"
489         rm -f "$tmp_isfailed"
490         cat "$REINSTALL_DBNODE_DIR/requirements.all.direct" 2> /dev/null \
491                 | while read origin
492         do
493                 pkgsys_exists_from_orig "$origin" && continue
494                 if grep -q -Fx "$origin" "${DBDIR}/taboo.all.list" 2> /dev/null
495                 then
496                         message_echo "INFO: Restoration of a requirement [$origin] is avoided because it is set taboo."
497                         touch "$tmp_isfailed"
498                         break
499                 fi
500                 origins_init=`database_query_initial_orgins "$origin" | grep -vFx "$origin" || :`
501                 origin_replace=`echo "$origin" \
502                         | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern"`
503                 [ "x$origin_replace" = "x$origin" ] && origin_replace=
504                 is_installed=no
505                 for origin_orig in $origins_init $origin_replace
506                 do
507                         [ "x$origin_orig" = "x$origin" ] && continue
508                         if pkgsys_exists_from_orig "$origin_orig"
509                         then
510                                 is_installed=yes
511                                 break
512                         fi
513                         if grep -q -Fx "$origin_orig" "${DBDIR}/taboo.all.list" 2> /dev/null
514                         then
515                                 message_echo "INFO: Restoration of a requirement [$origin_orig] is avoided because it is set taboo."
516                                 touch "$tmp_isfailed"
517                                 is_installed=taboo
518                                 break
519                         fi
520                 done
521                 [ $is_installed = yes ] && continue
522                 [ $is_installed = taboo ] && break
523                 for origin_orig in $origin $origins_init $origin_replace
524                 do
525                         pkgarc=`pkgsys_get_backup_pkg "$origin_orig"` && break
526                 done
527                 if [ -z "$pkgarc" ]
528                 then
529                         if grep -q -Fx "$origin" "${DBDIR}/failed.list" 2> /dev/null
530                         then
531                                 touch "$tmp_isfailed"
532                                 break
533                         fi
534                         continue
535                 fi
536                 printf '%s\t%s\n' "$origin_orig" "$pkgarc" >> $tmp_restore
537         done
538         [ -e "$tmp_isfailed" ] && return 1
539         while read origin pkgarc
540         do
541                 pkg=`pkgsys_pkgarc_to_pkgname "$pkgarc"`
542                 pkg_regexp_esc=`str_escape_regexp "$pkg"`
543                 if reinstall_chk_forbidden_conflicts "$pkg"
544                 then
545                         message_echo "INFO: Restoration of a requirement [$origin ($pkg)] is avoided because it conflicts with installed packages."
546                         continue
547                 fi
548                 message_echo "INFO: Restoring a backed-up requirement [$origin ($pkg)]."
549                 if pkg_add_fF "$pkgarc"
550                 then
551                         grep -v -E "[[:space:]]$pkg_regexp_esc$" "${DBDIR}/deleted_conflicts" \
552                                 > ${DBDIR}/deleted_conflicts.tmp 2> /dev/null || :
553                         mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
554                 else
555                         message_echo "WARNING: Failed to restore by the backed-up package." >&2
556                 fi
557                 
558         done < $tmp_restore
559         :
560 }
561
562 # ============= Back-up of the currently installed package =============
563 reinstall_pkg_backup ()
564 {
565         local backup_pkg pkg
566         reinstall_chk_stage_complete PKG_BACKUP && return
567         pkg=`echo "$REINSTALL_CURRENTPKG" | tr ' ' '\n' | grep -v '^$' | tail -n 1`
568         if [ -n "$pkg" ]
569         then
570                 message_echo "-- (Creating temporary backup package for $REINSTALL_ORIGPKGTAG)"
571                 if backup_pkg=`pkgsys_create_backup_pkg "$pkg" "${DBDIR}/backup_packages"`
572                 then
573                         fileedit_add_a_line_if_new "$pkg" "$REINSTALL_FROMNODE_DIR/backedup_version"
574                         fileedit_add_a_line_if_new "$backup_pkg" "$REINSTALL_FROMNODE_DIR/backedup_pkgfile"
575                 else
576                         message_echo "WARNING: Failed to create the backup package, but ignored by hoping success." >&2
577                         return 1
578                 fi
579         fi
580         reinstall_register_stage_complete PKG_BACKUP
581 }
582
583 # ============= Deinstallation of the currently installed package =============
584 reinstall_deinstall ()
585 {
586         local tmp_installedpkg installed_pkgs dev_out dev_err
587         dev_out=/dev/stdout
588         dev_err=/dev/stderr
589         if [ $opt_batch_mode = yes ]
590         then
591                 dev_out=/dev/null
592                 dev_err=/dev/null
593         fi
594         tmp_installedpkg=${TMPDIR}/reinstall_deinstall:installedpkg
595         pkgsys_get_installed_pkg_from_origin "$REINSTALL_ORIGIN" > $tmp_installedpkg
596         [ `wc -l < $tmp_installedpkg` -gt 0 ] || return 0
597         installed_pkgs=`tr '\n' ' ' < $tmp_installedpkg | sed 's/ *$//'`
598         if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
599         then
600                 message_echo "INFO: Deinstalling $installed_pkgs by $PKGSYS_CMD_PKG_DELETE."
601                 pkg_delete_f $installed_pkgs || \
602                 {
603                         message_echo "WARNING: Failed to deinstall." >&2
604                 }
605         else
606                 while read pkg
607                 do
608                         message_echo "INFO: Deinstalling $pkg by $PKGSYS_CMD_PKG_DELETE." >&2
609                         pkg_delete_f "$pkg" || \
610                         {
611                                 message_echo "WARNING: Failed to deinstall." >&2
612                         }
613                 done < $tmp_installedpkg
614         fi
615         message_echo "-- (Trying to deinstall by ports to make sure. This may cause negligible warnings.)"
616         reinstall_make deinstall > $dev_out 2> $dev_err|| \
617         {
618                 message_echo "WARNING: Failed to deinstall $REINSTALL_CURRENTPKG by make deinstall." >&2
619         }
620 }
621
622 # ============= Deinstallation of installed packages for old ports of the current one =============
623 reinstall_deinstall_old_ports ()
624 {
625         [ -e "$REINSTALL_FROMNODE_DIR/old_origs" ] || return 0
626         while read origin_old
627         do
628                 pkgsys_get_installed_pkg_from_origin "$origin_old"
629         done < $REINSTALL_FROMNODE_DIR/old_origs | reinstall_backup_and_delete_conflicts
630 }
631
632 # ============= Recovery after failure of installation of the new package =============
633 reinstall_failed_install_recover ()
634 {
635         local backedup_version backup_pkg dev_out dev_err
636         dev_out=/dev/stdout
637         dev_err=/dev/stderr
638         if [ $opt_batch_mode = yes ]
639         then
640                 dev_out=/dev/null
641                 dev_err=/dev/null
642         fi
643         reinstall_chk_stage_complete FAILED_INSTALL.RECOVER && return
644         message_echo "INFO: Trying to deinstall the failed/terminated installation (Ignore failures)."
645         if [ -n "$REINSTALL_CURRENTPKG" ]
646         then
647                 pkg_delete_f "$REINSTALL_CURRENTPKG" || :
648         fi
649         message_echo "INFO: Trying to deinstall by ports to make sure (This may cause negligible warnings)."
650         reinstall_make deinstall > $dev_out 2> $dev_err|| :
651         backedup_version=`cat "$REINSTALL_FROMNODE_DIR/backedup_version" 2> /dev/null || :`
652         if grep -q -Fx "$REINSTALL_ORIGIN" "${DBDIR}/taboo.all.list" 2> /dev/null
653         then
654                 message_echo "INFO: Restoration of the backup of $backedup_version is avoided because it is taboo."
655         elif [ -n "$backedup_version" ]
656         then
657                 if reinstall_chk_forbidden_conflicts "$backedup_version"
658                 then
659                         message_echo "INFO: Restoration of the backup of $backedup_version, is avoided because it conflicts with installed packages."
660                 else
661                         message_echo "INFO: Restoring the backup of $backedup_version."
662                         if [ -e "$REINSTALL_FROMNODE_DIR/backedup_pkgfile" ]
663                         then
664                                 while read backup_pkg
665                                 do
666                                         if [ ! -e "$backup_pkg" ]
667                                         then
668                                                 message_echo "WARNING: The backup file $backup_pkg doesn't exist, gave up." >&2
669                                         elif ! pkg_add_fF "$backup_pkg"
670                                         then
671                                                 message_echo "WARNING: Failed to restore $backedup_version. Note that your system may experience troubles by this error." >&2
672                                         fi
673                                 done < $REINSTALL_FROMNODE_DIR/backedup_pkgfile
674                         else
675                                 message_echo "WARNING: No backup was saved, gave up." >&2
676                         fi
677                 fi
678         fi
679         reinstall_register_stage_complete FAILED_INSTALL.RECOVER
680 }
681
682 # ============= Report an installation success to the all dependents =============
683 reinstall_tell_update_to_depandents ()
684 {
685         local tag level dbsuffix
686         pkgsys_is_pkgtool "$REINSTALL_ORIGIN" && return
687         reinstall_chk_stage_complete TELL_UPDATE_TO_DEPANDENTSL && return
688         for tag in all run build none
689         do
690                 for level in full direct
691                 do
692                         dbsuffix=${tag}.${level}
693                         {
694                                 cat "$REINSTALL_DBNODE_DIR/dependents.$dbsuffix" "$REINSTALL_DBNODE_DIR/dependents.$dbsuffix.orig"
695                                 [ -e "$REINSTALL_DBNODE_DIR/succeeded_once" ] || cat "$REINSTALL_DBNODE_DIR/ignored_dependents.$tag" "$REINSTALL_DBNODE_DIR/ignored_dependents.$tag.orig"
696                         } 2> /dev/null \
697                                 | sort -u \
698                                 | while read origin_dependent
699                         do
700                                 [ -d "${DBDIR}/requires/$origin_dependent" ] || continue
701                                 touch "${DBDIR}/requires/$origin_dependent/need_reinstall_due_to_upgraded_requirements.$dbsuffix"
702                                 fileedit_rm_a_line "$origin_dependent" \
703                                         "${DBDIR}/success.$dbsuffix.list"
704                                 fileedit_rm_a_line "$origin_dependent" \
705                                         "${DBDIR}/todo_after_requirements_succeed.$dbsuffix.list"
706                         done
707                 done
708         done
709         reinstall_register_stage_complete TELL_UPDATE_TO_DEPANDENTS
710 }
711
712 # ============= Closing operations after an installation success =============
713 reinstall_closing_operations_after_successful_install ()
714 {
715         local tag level
716         reinstall_chk_stage_complete CLOSING_OPERATIONS_AFTER_SUCCESSFUL_INSTALL && return
717         database_build_update_pkgname "$REINSTALL_ORIGIN" > /dev/null
718         database_build_update_pkgtag "$REINSTALL_ORIGIN"
719         for tag in all run build none
720         do
721                 for level in full direct
722                 do
723                         rm -f "$REINSTALL_DBNODE_DIR/need_reinstall_due_to_upgraded_requirements.${tag}.${level}"
724                         [ -e "$REINSTALL_DBNODE_DIR/failed_requirements.${tag}.${level}" ] || continue
725                         cp "$REINSTALL_DBNODE_DIR/failed_requirements.${tag}.${level}" \
726                                 "$REINSTALL_DBNODE_DIR/failed_requirements.${tag}.${level}.previous"
727                 done
728         done
729         {
730                 echo "$REINSTALL_ORIGIN"
731                 database_query_initial_orgins "$REINSTALL_ORIGIN"
732         } | sort -u | while read initial_orig
733         do
734                 initial_orig_regexp=`str_escape_regexp "$initial_orig"`
735                 grep -E "^${initial_orig_regexp}[[:space:]]" "${DBDIR}/deleted_conflicts" 2> /dev/null \
736                         | cut -f 2 | while read initial_pkg
737                 do
738                         pkg_regexp=`str_escape_regexp "$initial_pkg"`
739                         grep -v -E "^${pkg_regexp}:" "${DBDIR}/forbidden_conflicts" \
740                                 > ${DBDIR}/forbidden_conflicts.tmp 2> /dev/null || :
741                         mv "${DBDIR}/forbidden_conflicts.tmp" "${DBDIR}/forbidden_conflicts"
742                 done
743                 grep -v -E "^${initial_orig_regexp}[[:space:]]" "${DBDIR}/deleted_conflicts" \
744                         > ${DBDIR}/deleted_conflicts.tmp 2> /dev/null || :
745                 mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
746                 pkgsys_delete_backup_pkg "$initial_orig"
747         done
748         rm -f "$REINSTALL_FROMNODE_DIR/backedup_pkgfile"
749         database_record_success "$REINSTALL_ORIGIN"
750         message_echo "===>  Done successfully"
751         reinstall_register_stage_complete CLOSING_OPERATIONS_AFTER_SUCCESSFUL_INSTALL
752 }
753
754 # ============= Fetch missing distfiles of a port without sanity check =============
755 reinstall_fetch_missing_distfiles ()
756 {
757         local port_path tmp_fetch
758         port_path=`pkgsys_get_portpath_from_origin "$REINSTALL_ORIGIN"` || return
759         tmp_fetch=${TMPDIR}/reinstall_fetch_missing_distfiles:fetch.sh
760         tmp_missing_fetch=${TMPDIR}/reinstall_fetch_missing_distfiles:missing_fetch.sh
761         rm -rf "$tmp_fetch.pre"
762         reinstall_make_anymode fetch-list 2> /dev/null > $tmp_fetch.src || return
763         grep '^SHA256[[:space:]]' "$port_path/distinfo" | \
764                 sed -E 's/^SHA256[[:space:]]+\(([^)]*)\).*/\1/' | \
765                 while read relative_distfile_path
766         do
767                 if ! { testhash=`( cd "${DISTDIR}" && sha256 "$relative_distfile_path" ) 2> /dev/null` && \
768                         grep -qxF "$testhash" "$port_path/distinfo"; }
769                 then
770                         relative_distfile_path_ptn=`str_escape_regexp "|| echo \"$relative_distfile_path\" not fetched; }"`
771                         if grep -E "$relative_distfile_path_ptn$" "$tmp_fetch.src"
772                         then
773                                 subdir_distfile=`dirname "$relative_distfile_path"`
774                                 [ "x$subdir_distfile" = x. ] || echo "mkdir -p \"${DISTDIR}/$subdir_distfile\"" >> $tmp_fetch.pre
775                         fi
776                 fi
777         done | grep -v '^[[:space:]]*$' > $tmp_fetch.main || :
778         [ -e "$tmp_fetch.pre" ] && sort -u "$tmp_fetch.pre"
779         cat "$tmp_fetch.main"
780 }
781
782 # ============= Execute a command by recording the standard output and error output into a file in case of error =============
783 reinstall_execcmd_tee_errlog ()
784 {
785         local func tmp_err
786         func=$1
787         tmp_err=${TMPDIR}/reinstall_execcmd_tee_errlog::error
788         rm -f "$tmp_err"
789         if [ $opt_batch_mode = yes ]
790         then
791                 { {
792                         $func
793                 } 2>&1 || touch "$tmp_err"; } > "$REINSTALL_DBNODE_DIR/error.log"
794         else
795                 { {
796                         $func
797                 } 2>&1 || touch "$tmp_err"; } | tee "$REINSTALL_DBNODE_DIR/error.log"
798         fi
799         [ -e "$tmp_err" ] && return 1
800         rm -f "$REINSTALL_DBNODE_DIR/error.log"
801         return
802 }
803
804 # ============= Execute a command to output to stdout by recording the error output into a file in case of error =============
805 reinstall_execcmd_getstdout_errlog ()
806 {
807         local func
808         func=$1
809         if $func > $REINSTALL_DBNODE_DIR/error.log 2>&1
810         then
811                 rm -f "$REINSTALL_DBNODE_DIR/error.log"
812                 return
813         fi
814         cat "$REINSTALL_DBNODE_DIR/error.log" >&2
815         return 1
816 }
817
818 # ============= Check whether any required package is missing or too old for build by ports =============
819 # Return status 0 for no problem about missing ports
820 reinstall_chk_missing_requirement ()
821 {
822         local tmp_filter tmp_miising
823         tmp_filter=${TMPDIR}/reinstall_chk_missing_requirement::requirements.all_but_test.unflavored
824         tmp_miising=${TMPDIR}/reinstall_chk_missing_requirement::missing_requirements
825         message_echo "Checking whether any required package is missing or too old..."
826         sed 's/@.*//' "$REINSTALL_DBNODE_DIR/requirements.all.full" > $tmp_filter || :
827         if reinstall_make missing 2> /dev/null | grep -Fx -f "$tmp_filter" > $tmp_miising
828         then
829                 message_echo "Found missing/too old requirements:"
830                 message_cat < $tmp_miising
831                 {
832                         echo "Found missing/too old requirements:"
833                         cat "$tmp_miising"
834                 } > "$REINSTALL_DBNODE_DIR/error.log"
835                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
836                 reinstall_restore_if_temporarily_deinstalled
837                 for tag in all run build none
838                 do
839                         for level in full direct
840                         do
841                                 fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" \
842                                         "${DBDIR}/todo_after_requirements_succeed.${tag}.${level}.list"
843                         done
844                 done
845                 fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/failed.list"
846                 reinstall_skip 'Skipped because of missing/too old packages'
847                 return 1
848         fi
849 }
850
851 # ============= Check whether the current port is marked to skip =============
852 # Return status 1 for port to skip
853 reinstall_exec_chk_skip ()
854 {
855         local tag level
856         local currentorigin_is_all currentorigin_is_target currentorigin_is_requires_requirements
857         local currentorigin_is_initial_requirements currentorigin_is_requires_dependents
858         local currentorigin_is_initial_dependents currentorigin_is_requires_requirements_complement
859         local currentorigin_is_relevant
860         database_query_get_target_attributes currentorigin "$REINSTALL_ORIGIN"
861         if [ -z "${currentorigin_is_all}" -a -z "${currentorigin_is_relevant}" ]
862         then
863                 reinstall_skip 'Skipped because being irrelevant'
864                 return 1
865         fi
866         reinstall_skip_if_in_a_list 'Skipped because being a leaf port' leaf_ports_to_delete && return 1
867         rm -f "$REINSTALL_DBNODE_DIR/this_is_skipped_build_requirement"
868         if expr "$REINSTALL_CURRENTPKG" : '.* .*' > /dev/null
869         then
870                 message_echo "WARNING: Multiple packages are registered for this port. Reinstallation is needed to fix it." >&2
871         elif grep -q -Fx "$REINSTALL_ORIGIN" "${DBDIR}/damaged_package" 2> /dev/null
872         then
873                 message_echo "WARNING: Installed files have invalid checksums for this port. Reinstallation is needed to fix it." >&2
874         else
875                 if [ -e "${DBDIR}/target_all" ]
876                 then
877                         if [ $REINSTALL_IS_CURRENTPKG_LATEST = yes ]
878                         then
879                                 reinstall_restore_if_temporarily_deinstalled
880                                 reinstall_skip 'Skipped because being already latest'
881                                 return 1
882                         fi
883                 elif [ ! -e "$REINSTALL_DBNODE_DIR/conf_updated" ]
884                 then
885                         if [ -e "$REINSTALL_DBNODE_DIR/installed_by_pkg" ] && database_query_is_default_conf "$REINSTALL_ORIGIN" quiet
886                         then
887                                 reinstall_restore_if_temporarily_deinstalled
888                                 reinstall_skip 'Skipped because already upgraded with a prebuilt package'
889                                 return 1
890                         fi
891                         reinstall_skip_if_in_a_list 'Skipped because the reinstallation has been already completed' \
892                                 "success.${REINSTALL_DBSUFFIX}.list" restore && return 1
893                         if [ $opt_skip_unchanged = yes ]
894                         then
895                                 if [ ! -e "$REINSTALL_DBNODE_DIR/necessary_upgrade.${REINSTALL_DBSUFFIX}" ]
896                                 then
897                                         reinstall_restore_if_temporarily_deinstalled
898                                         if [ -e "$REINSTALL_FROMNODE_DIR/installed_version" ]
899                                         then
900                                                 reinstall_skip 'Skipped because being already latest as well as the all requirements'
901                                         else
902                                                 touch "$REINSTALL_DBNODE_DIR/this_is_skipped_build_requirement"
903                                                 reinstall_skip 'Skipped because being an only-build-time dependency of already latest packages'
904                                         fi
905                                         return 1
906                                 fi
907                         fi
908                         if [ \( $opt_skip_unchanged = no -a -e "$REINSTALL_DBNODE_DIR/succeeded_once" \) \
909                                 -o \( $opt_skip_unchanged = yes -a $REINSTALL_IS_CURRENTPKG_LATEST = yes \) ]
910                         then
911                                 if [ ! -e "$REINSTALL_DBNODE_DIR/need_reinstall_due_to_upgraded_requirements.${REINSTALL_DBSUFFIX}" ]
912                                 then
913                                         if ! database_query_is_necessary_upgrade "$REINSTALL_ORIGIN"
914                                         then
915                                                 reinstall_restore_if_temporarily_deinstalled
916                                                 fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" \
917                                                         "${DBDIR}/todo_after_requirements_succeed.${REINSTALL_DBSUFFIX}.list"
918                                                 reinstall_skip 'Skipped because being already latest or failed as well as the all requirements'
919                                                 return 1
920                                         fi
921                                 fi
922                         fi
923                 fi
924                 reinstall_skip_if_in_a_list 'Marked to be manually-done' manually_done.list restore && return 1
925         fi
926         reinstall_skip_if_in_a_list 'Skipped because being a hold package' conf/HOLD:PORTS.parsed restore && return 1
927         if database_query_is_a_port_suppressed "$REINSTALL_ORIGIN"
928         then
929                 reinstall_restore_if_temporarily_deinstalled
930                 reinstall_skip 'Skipped because being suppressed'
931                 return 1
932         fi
933         reinstall_skip_if_in_a_list 'Ignored because being taboo' taboo.all.list && return 1
934         if [ $opt_fetch_only = no ] && \
935                 ! reinstall_are_requirements_ready && \
936                 ! reinstall_chk_and_restore_requirements
937         then
938                 reinstall_restore_if_temporarily_deinstalled
939                 for tag in all run build none
940                 do
941                         for level in full direct
942                         do
943                                 fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" \
944                                         "${DBDIR}/todo_after_requirements_succeed.${tag}.${level}.list"
945                         done
946                 done
947                 reinstall_skip 'Skipped because the requirements cannot be ready'
948                 return 1
949         fi
950 }
951
952 # ============= Reinstallation of the current origin: Check sanity =============
953 # Return status 0 for no sanity problem
954 reinstall_exec_reinstall_check_sanity ()
955 {
956         local check_sanity_msg func_pkg_inst_remote_verify_fetch func_pkg_inst_verify_pkg tmp_fetch_dir tmp_fetch_missing
957         if ! reinstall_chk_stage_complete CHECK_SANITY
958         then
959                 message_echo "Sanity Check..."
960                 _reinstall_exec__tmpcmd () { reinstall_make_anymode check-sanity; }
961                 if ! check_sanity_msg=`reinstall_execcmd_getstdout_errlog _reinstall_exec__tmpcmd`
962                 then
963                         echo "$check_sanity_msg"
964                         reinstall_restore_if_temporarily_deinstalled
965                         reinstall_errproc 'check sanity'
966                         if [ $opt_fetch_only = yes ]
967                         then
968                                 if [ $opt_inst_by_pkg_if_can = yes ]
969                                 then
970                                         if ! reinstall_chk_stage_complete FAILOVER_FETCH_PKG && \
971                                                 database_query_is_default_conf "$REINSTALL_ORIGIN"
972                                         then
973                                                 message_echo "INFO: The configuration of this port is default, so use of a prebuilt package is attempted."
974                                                 func_pkg_inst_remote_verify_fetch=pkg_inst_remote_verify_fetch
975                                                 func_pkg_inst_verify_pkg=pkg_inst_verify_pkg
976                                                 if [ $opt_use_legacy_pkg_for_missing_pkgng = yes ]
977                                                 then
978                                                         func_pkg_inst_remote_verify_fetch=pkg_inst_remote_wild_verify_fetch
979                                                         func_pkg_inst_verify_pkg=pkg_inst_wild_verify_pkg
980                                                 fi
981                                                 if ! $func_pkg_inst_verify_pkg "$REINSTALL_NEWPKGNAME"
982                                                 then
983                                                         message_echo "Trying to fetch the package because of the fetch only mode..."
984                                                         if $func_pkg_inst_remote_verify_fetch "$REINSTALL_NEWPKGNAME"
985                                                         then
986                                                                 reinstall_register_stage_complete FAILOVER_FETCH_PKG
987                                                         else
988                                                                 message_echo "WARNING: Failed to fetch package for $REINSTALL_NEWPKGNAME"
989                                                         fi
990                                                 fi
991                                         fi
992                                 fi
993                                 if ! reinstall_chk_stage_complete FAILOVER_FETCH
994                                 then
995                                         tmp_fetch_missing=${TMPDIR}/reinstall_exec:fetch.sh
996                                         reinstall_fetch_missing_distfiles > $tmp_fetch_missing
997                                         if [ `wc -l < $tmp_fetch_missing` -gt 0 ]
998                                         then
999                                                 message_echo "Trying to fetch the distfiles because of the fetch only mode..."
1000                                                 tmp_fetch_dir=${TMPDIR}/reinstall_exec:fetch_dir
1001                                                 rm -rf "$tmp_fetch_dir"
1002                                                 mkdir -p "$tmp_fetch_dir"
1003                                                 if ( cd "$tmp_fetch_dir" && sh "$tmp_fetch_missing" )
1004                                                 then
1005                                                         reinstall_register_stage_complete FAILOVER_FETCH
1006                                                 else
1007                                                         message_echo "WARNING: Failed to fetch distfiles"
1008                                                 fi
1009                                         fi
1010                                 fi
1011                                 message_fetch_only
1012                         fi
1013                         return 1
1014                 fi
1015                 message_echo
1016                 reinstall_register_stage_complete CHECK_SANITY
1017         fi
1018 }
1019
1020 # ============= Reinstallation of the current origin: Installation by package =============
1021 # Return status 0 for success
1022 reinstall_exec_reinstall_by_pkg ()
1023 {
1024         local pkg func_pkg_inst_remote_verify_fetch func_pkg_inst_remote
1025         if [ $REINSTALL_IS_FROZEN = yes ] || [ $opt_inst_by_pkg_if_can = yes ] && database_query_is_default_conf "$REINSTALL_ORIGIN"
1026         then
1027                 if [ $REINSTALL_IS_FROZEN = yes ]
1028                 then
1029                         pkg=`pkg_get_remote_repository_version "$REINSTALL_ORIGIN" || :`
1030                 else
1031                         pkg=$REINSTALL_NEWPKGNAME
1032                 fi
1033                 message_echo "INFO: The configuration of this port is default, so use of a prebuilt package is attempted."
1034                 if reinstall_chk_stage in_bypkg
1035                 then
1036                         message_echo "(Restarting the previously terminated (re)installation-by-package process...)"
1037                 else
1038                         reinstall_register_stage in_bypkg
1039                 fi
1040                 if ! reinstall_chk_stage_complete INSTALL_BY_PKG
1041                 then
1042                         if ! reinstall_chk_stage FAILED_INSTALL_BY_PKG
1043                         then
1044                                 if [ $opt_fetch_only = no -a "x$PKGSYS_USE_PKGNG" = xyes ] \
1045                                         && pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1046                                 then
1047                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1048                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1049                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/installation_complete_by_pkg.list"
1050                                         if reinstall_deinstall && pkg_is_tool_available && pkg_info_e "$pkg"
1051                                         then
1052                                                 reinstall_register_stage_complete INSTALL_BY_PKG
1053                                         else
1054                                                 reinstall_register_stage FAILED_INSTALL_BY_PKG
1055                                         fi
1056                                 else
1057                                         func_pkg_inst_remote_verify_fetch=pkg_inst_remote_verify_fetch
1058                                         func_pkg_inst_remote=pkg_inst_remote
1059                                         if [ $opt_use_legacy_pkg_for_missing_pkgng = yes ]
1060                                         then
1061                                                 func_pkg_inst_remote_verify_fetch=pkg_inst_remote_wild_verify_fetch
1062                                                 func_pkg_inst_remote=pkg_inst_remote_wild
1063                                         fi
1064                                         if $func_pkg_inst_remote_verify_fetch "$pkg"
1065                                         then
1066                                                 if [ $opt_fetch_only = yes ]
1067                                                 then
1068                                                         message_fetch_only
1069                                                 else
1070                                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1071                                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1072                                                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/installation_complete_by_pkg.list"
1073                                                         reinstall_backup_and_delete_remaining_install_conflicts__by_pkg "$pkg"
1074                                                         reinstall_pkg_backup || :
1075                                                         reinstall_register_stage in_add_pkg
1076                                                         reinstall_deinstall_old_ports
1077                                                         reinstall_deinstall
1078                                                         if $func_pkg_inst_remote "$pkg"
1079                                                         then
1080                                                                 if database_query_dependency_matching "$REINSTALL_ORIGIN"
1081                                                                 then
1082                                                                         reinstall_register_stage_complete INSTALL_BY_PKG
1083                                                                 else
1084                                                                         message_echo "INFO: The requirements of the package mismatch the configuration."
1085                                                                         message_echo "INFO: The installed package will be deleted and installation by port will be attempted instead."
1086                                                                         pkg_delete_f "$pkg" || :
1087                                                                         reinstall_register_stage FAILED_INSTALL_BY_PKG
1088                                                                 fi
1089                                                         else
1090                                                                 reinstall_register_stage FAILED_INSTALL_BY_PKG
1091                                                         fi
1092                                                         if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1093                                                         then
1094                                                                 pkg_is_tool_available || pkg_rescue_tools
1095                                                         fi
1096                                                 fi
1097                                         else
1098                                                 reinstall_register_stage FAILED_INSTALL_BY_PKG
1099                                         fi
1100                                 fi
1101                         fi
1102                         if [ $opt_fetch_only = no ]
1103                         then
1104                                 if reinstall_chk_stage FAILED_INSTALL_BY_PKG && \
1105                                         reinstall_chk_stage in_add_pkg
1106                                 then
1107                                         reinstall_failed_install_recover
1108                                 fi
1109                         fi
1110                 fi
1111                 if [ $opt_fetch_only = no ] && reinstall_chk_stage_complete INSTALL_BY_PKG
1112                 then
1113                         touch "$REINSTALL_DBNODE_DIR/installed_timestamp"
1114                         touch "$REINSTALL_DBNODE_DIR/installed_by_pkg"
1115                         fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" "${DBDIR}/installation_complete_by_pkg.list"
1116                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1117                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1118                         reinstall_deregister_stage in_bypkg
1119                         reinstall_tell_update_to_depandents
1120                         reinstall_closing_operations_after_successful_install
1121                         return
1122                 fi
1123                 reinstall_deregister_stage in_bypkg
1124                 if [ $opt_fetch_only = yes ]
1125                 then
1126                         message_echo "INFO: Continue to fetch distfiles in case of installation by port."
1127                 else
1128                         message_echo "WARNING: (Re)installation-by-package is unsuccessful, so retrying by using port." >&2
1129                 fi
1130         fi
1131         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/installation_complete_by_pkg.list"
1132         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1133         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1134         return 1
1135 }
1136
1137 # ============= Reinstallation of the current origin: Freeze the port =============
1138 # Return status 0 for no need of freezing
1139 reinstall_exec_reinstall_freeze_if_necessary ()
1140 {
1141         local pkg pkg_current
1142         message_echo "(Port to freeze)"
1143         _reinstall_exec__tmpcmd () { pkg_get_remote_repository_version "$REINSTALL_ORIGIN"; }
1144         if ! pkg=`reinstall_execcmd_getstdout_errlog _reinstall_exec__tmpcmd` || [ -z "$pkg" ]
1145         then
1146                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1147                 reinstall_restore_if_temporarily_deinstalled
1148                 reinstall_errproc 'freezing'
1149                 reinstall_skip "ERROR: Failed to get the repository version."
1150                 return 1
1151         fi
1152         pkg_current=`pkgsys_get_installed_pkg_from_origin "$REINSTALL_ORIGIN"`
1153         if [ "x$pkg" = "x$pkg_current" ]
1154         then
1155                 message_echo "INFO: The latest repository version $pkg installed, deemed success."
1156                 message_echo "WARNING: This action may cause problems due to the version/option mismatch." >&2
1157                 reinstall_tell_update_to_depandents
1158                 reinstall_closing_operations_after_successful_install
1159                 return 1
1160         fi
1161         message_echo "INFO: The latest repository version $pkg will be installed."
1162         reinstall_pkg_backup || :
1163         reinstall_deinstall_old_ports
1164         reinstall_deinstall
1165         reinstall_backup_and_delete_remaining_install_conflicts__by_pkg "$pkg"
1166         _reinstall_exec__tmpcmd () { pkg_inst_remote "$pkg"; }
1167         if reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1168         then
1169                 message_echo "INFO: Deemed success."
1170                 message_echo "WARNING: This action may cause problems due to the version/option mismatch." >&2
1171                 reinstall_tell_update_to_depandents
1172                 reinstall_closing_operations_after_successful_install
1173                 return
1174         fi
1175         message_echo "ERROR: Failed install the version in the repository for a port to freeze. Dependents are locked." >&2
1176         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1177         reinstall_restore_if_temporarily_deinstalled
1178         reinstall_errproc 'freezing'
1179         reinstall_skip 'Skipped because being a port to freeze.'
1180         return
1181 }
1182
1183 # ============= Reinstallation of the current origin: Avoid build if any requirement port to freeze is unfrozen =============
1184 # Return status 0 for no concern about freezing requirements
1185 reinstall_exec_reinstall_avoid_if_any_unfrozen_requirements_exists ()
1186 {
1187         if grep -qFx "$REINSTALL_DBNODE_DIR/requirements.all.full" "${DBDIR}/freeze.all.list" 2> /dev/null
1188         then
1189                 reinstall_restore_conflicts
1190                 {
1191                         pkgsys_get_conflicting_installed_pkgs build "$REINSTALL_ORIGIN" || :
1192                         pkgsys_get_conflicting_installed_pkgs install "$REINSTALL_ORIGIN" || :
1193                 } | reinstall_backup_and_delete_conflicts
1194                 if ! database_query_are_requirements_not_locked "$REINSTALL_ORIGIN"
1195                 then
1196                         reinstall_skip 'Skipped because of missing requirements to freeze.'
1197                         return 1
1198                 fi
1199         fi
1200 }
1201
1202 # ============= Reinstallation of the current origin: Prebuild process =============
1203 # Return status 1 for error end
1204 reinstall_exec_reinstall_prebuild ()
1205 {
1206         if [ $opt_fetch_only = no ]
1207         then
1208                 if reinstall_chk_stage in_prebuild
1209                 then
1210                         message_echo "(Restarting the previously terminated pre-build process...)"
1211                 else
1212                         reinstall_restore_conflicts
1213                         reinstall_register_stage in_prebuild
1214                 fi
1215         fi
1216         if [ $opt_fetch_only = no  -a -e "$REINSTALL_DBNODE_DIR/BEFOREBUILD.conf" ] && \
1217                 ! reinstall_chk_stage_complete BEFOREBUILD
1218         then
1219                 message_echo "-- BEFOREBUILD operations (start)"
1220                 _reinstall_exec__tmpcmd () { sh -e "$REINSTALL_DBNODE_DIR/BEFOREBUILD.conf"; }
1221                 if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1222                 then
1223                         reinstall_restore_if_temporarily_deinstalled
1224                         reinstall_errproc 'BEFOREBUILD operations'
1225                         return 1
1226                 fi
1227                 message_echo "-- BEFOREBUILD operations (end)"
1228                 reinstall_register_stage_complete BEFOREBUILD
1229         fi
1230         if [ $opt_fetch_only = no ] && ! reinstall_chk_stage_complete CLEAN_BEFORE_BUILD
1231         then
1232                 _reinstall_exec__tmpcmd () { reinstall_make_anymode clean NOCLEANDEPENDS=yes; }
1233                 if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1234                 then
1235                         reinstall_restore_if_temporarily_deinstalled
1236                         reinstall_errproc 'clean before build'
1237                         return 1
1238                 fi
1239                 message_echo
1240                 reinstall_register_stage_complete CLEAN_BEFORE_BUILD
1241         fi
1242         reinstall_deregister_stage in_prebuild
1243 }
1244
1245 # ============= Reinstallation of the current origin: Fetch process =============
1246 # Return status 1 for error end
1247 reinstall_exec_reinstall_fetch ()
1248 {
1249         local dev_out dev_err
1250         dev_out=/dev/stdout
1251         dev_err=/dev/stderr
1252         if [ $opt_batch_mode = yes ]
1253         then
1254                 dev_out=/dev/null
1255                 dev_err=/dev/null
1256         fi
1257         if ! reinstall_chk_stage_complete FETCH
1258         then
1259                 if ! reinstall_chk_stage FAILED_FETCH
1260                 then
1261                         reinstall_make_anymode checksum > $dev_out > $dev_err || \
1262                                 reinstall_register_stage FAILED_FETCH
1263                 fi
1264                 if reinstall_chk_stage FAILED_FETCH
1265                 then
1266                         if ! reinstall_chk_stage_complete FAILED_FETCH.RETRIAL_1
1267                         then
1268                                 message_echo "INFO: Refetching distfiles for $REINSTALL_ORIGPKGTAG."
1269                                 {
1270                                         reinstall_make_anymode fetch FETCH_ARGS=-Ap > $dev_out > $dev_err &&
1271                                                 reinstall_make_anymode checksum > $dev_out > $dev_err
1272                                 } || reinstall_register_stage FAILED_REFETCH_1
1273                                 reinstall_register_stage_complete FAILED_FETCH.RETRIAL_1
1274                         fi
1275                         if reinstall_chk_stage FAILED_REFETCH_1
1276                         then
1277                                 if ! reinstall_chk_stage_complete FAILED_FETCH.RETRIAL_2.DISTCLEAN
1278                                 then
1279                                         message_echo "INFO: Cleaning distfiles for the second refetch for $REINSTALL_ORIGPKGTAG."
1280                                         reinstall_make_anymode distclean > $dev_out > $dev_err || :
1281                                         reinstall_register_stage_complete FAILED_FETCH.RETRIAL_2.DISTCLEAN
1282                                 fi
1283                                 if ! reinstall_chk_stage_complete FAILED_FETCH.RETRIAL_2
1284                                 then
1285                                         message_echo "INFO: Refetching distfiles as the second retrial for $REINSTALL_ORIGPKGTAG."
1286                                         _reinstall_exec__tmpcmd () { reinstall_make_anymode fetch FETCH_ARGS=-Ap; }
1287                                         if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1288                                         then
1289                                                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1290                                                 reinstall_restore_if_temporarily_deinstalled
1291                                                 reinstall_errproc 'fetch'
1292                                                 return
1293                                         fi
1294                                         _reinstall_exec__tmpcmd () { reinstall_make_anymode checksum; }
1295                                         if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1296                                         then
1297                                                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1298                                                 reinstall_restore_if_temporarily_deinstalled
1299                                                 reinstall_errproc 'checksum'
1300                                                 return
1301                                         fi
1302                                         reinstall_register_stage_complete FAILED_FETCH.RETRIAL_2
1303                                 fi
1304                         fi
1305                 fi
1306                 reinstall_register_stage_complete FETCH
1307         fi
1308 }
1309
1310 # ============= Reinstallation of the current origin: Check matching of interactive or non-interactive mode=============
1311 # Return status 1 for error end
1312 reinstall_exec_reinstall_chk_interactive_mode ()
1313 {
1314         local to_skip msg_is_interactive
1315         if [ $opt_batch_ports_only = yes -o $opt_interactive_ports_only = yes ]
1316         then
1317                 to_skip=no
1318                 case `database_query_get_makevar_val "$REINSTALL_ORIGIN" IS_INTERACTIVE` in
1319                         yes )   msg_is_interactive='interactive'
1320                                 [ $opt_batch_ports_only = yes ] && to_skip=yes
1321                                 ;;
1322                         '' )    msg_is_interactive='not interactive'
1323                                 [ $opt_interactive_ports_only = yes ] && to_skip=yes
1324                                 ;;
1325                 esac
1326                 if [ $to_skip = yes ]
1327                 then
1328                         reinstall_restore_if_temporarily_deinstalled
1329                         database_build_update_pkgname "$REINSTALL_ORIGIN" > /dev/null
1330                         message_echo "INFO: Further processes for this port are skipped because it is $msg_is_interactive."
1331                         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/stage.loop_list/reinst_todo.remain"
1332                         return 1
1333                 fi
1334         fi
1335 }
1336
1337 # ============= Reinstallation of the current origin: Build process=============
1338 # Return status 1 for error end
1339 reinstall_exec_reinstall_build ()
1340 {
1341         local flag_restarted_build build_args is_build_env_modified conflicts_install dev_out dev_err
1342         dev_out=/dev/stdout
1343         dev_err=/dev/stderr
1344         if [ $opt_batch_mode = yes ]
1345         then
1346                 dev_out=/dev/null
1347                 dev_err=/dev/null
1348         fi
1349         if reinstall_chk_stage in_build
1350         then
1351                 message_echo "(Restarting the previously terminated build process...)"
1352                 flag_restarted_build=yes
1353         else
1354                 reinstall_register_stage in_build
1355                 flag_restarted_build=no
1356         fi
1357         if reinstall_chk_stage in_retrial_build
1358         then
1359                 message_echo "(Restarting the previously terminated retrial build process...)"
1360                 build_args='MAKE_JOBS_UNSAFE=yes'
1361         else
1362                 build_args=
1363         fi
1364         if ! reinstall_chk_stage_complete BUILD
1365         then
1366                 pkgsys_get_conflicting_installed_pkgs build "$REINSTALL_ORIGIN" \
1367                         | reinstall_backup_and_delete_conflicts
1368                 reinstall_chk_missing_requirement || return
1369                 if ! reinstall_make build $build_args > $dev_out 2> $dev_err
1370                 then
1371                         reinstall_register_stage in_retrial_build
1372                         [ $flag_restarted_build = yes ] && message_echo "INFO: This failure may be due to restarting from a terminated build."
1373                         is_build_env_modified=no
1374                         if conflicts_install=`pkgsys_get_conflicting_installed_pkgs install "$REINSTALL_ORIGIN"`
1375                         then
1376                                 message_echo "INFO: Install-only conflicts are deinstalled for retrial because they may have effects on build."
1377                                 echo "$conflicts_install" | reinstall_backup_and_delete_conflicts
1378                                 is_build_env_modified=yes
1379                         fi
1380                         if pkgsys_exists_from_orig "$REINSTALL_ORIGIN"
1381                         then
1382                                 message_echo "INFO: The currently installed package for this port is deinstalled for retrial because it may have effects on build."
1383                                 reinstall_pkg_backup || :
1384                                 reinstall_deinstall_old_ports
1385                                 reinstall_deinstall
1386                                 is_build_env_modified=yes
1387                         fi
1388                         reinstall_deregister_stage_complete CLEAN_BEFORE_BUILD
1389                         message_echo "INFO: Retrying the build process after cleaning for $REINSTALL_ORIGPKGTAG."
1390                         _reinstall_exec__tmpcmd () { reinstall_make clean; }
1391                         if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1392                         then
1393                                 if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1394                                 then
1395                                         pkg_is_tool_available || pkg_rescue_tools
1396                                 fi
1397                                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1398                                 reinstall_restore_if_temporarily_deinstalled
1399                                 reinstall_errproc 'clean after build failure'
1400                                 return 1
1401                         fi
1402                         reinstall_register_stage_complete CLEAN_BEFORE_BUILD
1403                         _reinstall_exec__tmpcmd () { reinstall_make build MAKE_JOBS_UNSAFE=yes; }
1404                         if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1405                         then
1406                                 if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1407                                 then
1408                                         pkg_is_tool_available || pkg_rescue_tools
1409                                 fi
1410                                 reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1411                                 reinstall_restore_if_temporarily_deinstalled
1412                                 if [ `cat "$REINSTALL_DBNODE_DIR/failed_requirements.build.full" 2> /dev/null | wc -l` -eq 0 ]
1413                                 then
1414                                         reinstall_errproc 'build'
1415                                 else
1416                                         message_echo "INFO: The build failure might be due to the build failure(s) of the following requirements:"
1417                                         message_cat "$REINSTALL_DBNODE_DIR/failed_requirements.build.full"
1418                                         reinstall_errproc 'requirements build'
1419                                 fi
1420                                 return 1
1421                         fi
1422                         reinstall_deregister_stage in_retrial_build
1423                 fi
1424                 if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1425                 then
1426                         pkg_is_tool_available || pkg_rescue_tools
1427                 fi
1428                 reinstall_register_stage_complete BUILD
1429         fi
1430         reinstall_deregister_stage in_retrial_build
1431         reinstall_deregister_stage in_build
1432 }
1433
1434 # ============= Reinstallation of the current origin: Stage process=============
1435 # Return status 1 for error end
1436 reinstall_exec_reinstall_stage ()
1437 {
1438         if reinstall_chk_stage in_stage
1439         then
1440                 message_echo "(Restarting the previously terminated staging process...)"
1441         else
1442                 reinstall_register_stage in_stage
1443         fi
1444         if ! reinstall_chk_stage_complete STAGE
1445         then
1446                 _reinstall_exec__tmpcmd () { reinstall_make stage; }
1447                 if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1448                 then
1449                         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1450                         reinstall_restore_if_temporarily_deinstalled
1451                         reinstall_errproc 'STAGE operations'
1452                         return 1
1453                 fi
1454                 reinstall_register_stage_complete STAGE
1455         fi
1456         reinstall_deregister_stage in_stage
1457 }
1458
1459 # ============= Reinstallation of the current origin: Install process=============
1460 # Return status 1 for error end
1461 reinstall_exec_reinstall_install ()
1462 {
1463         local insttarget dev_out dev_err
1464         dev_out=/dev/stdout
1465         dev_err=/dev/stderr
1466         if [ $opt_batch_mode = yes ]
1467         then
1468                 dev_out=/dev/null
1469                 dev_err=/dev/null
1470         fi
1471         if [ -e "$REINSTALL_FROMNODE_DIR/installed_version" ]
1472         then
1473                 insttarget=reinstall
1474         else
1475                 insttarget=install
1476         fi
1477         if reinstall_chk_stage in_install
1478         then
1479                 message_echo "(Restarting the previously terminated installation process...)"
1480         else
1481                 reinstall_register_stage in_install
1482         fi
1483         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1484         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1485         fileedit_rm_a_line "$REINSTALL_ORIGIN" "${DBDIR}/installation_complete_by_pkg.list"
1486         reinstall_pkg_backup || :
1487         if [ -e "$REINSTALL_DBNODE_DIR/BEFOREDEINSTALL.conf" ] && ! reinstall_chk_stage_complete BEFOREDEINSTALL
1488         then
1489                 message_echo "-- BEFOREDEINSTALL operations (start)"
1490                 _reinstall_exec__tmpcmd () { sh -e "$REINSTALL_DBNODE_DIR/BEFOREDEINSTALL.conf"; }
1491                 if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1492                 then
1493                         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1494                         reinstall_restore_if_temporarily_deinstalled
1495                         reinstall_errproc 'BEFOREDEINSTALL operations'
1496                         return 1
1497                 fi
1498                 message_echo "-- BEFOREDEINSTALL operations (end)"
1499                 reinstall_register_stage_complete BEFOREDEINSTALL
1500         fi
1501         if ! reinstall_chk_stage_complete INSTALL
1502         then
1503                 if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1504                 then
1505                         reinstall_backup_and_delete_remaining_install_conflicts
1506                         reinstall_deinstall_old_ports
1507                         reinstall_deinstall
1508                 else
1509                         reinstall_deinstall_old_ports
1510                         reinstall_deinstall
1511                         reinstall_backup_and_delete_remaining_install_conflicts
1512                 fi
1513                 if ! reinstall_chk_stage FAILED_INSTALL
1514                 then
1515                         if reinstall_make $insttarget > $dev_out 2> $dev_err || \
1516                                 {
1517                                         message_echo "INFO: Cleaning up for retrial."
1518                                         reinstall_make deinstall > $dev_out 2> $dev_err \
1519                                                 || message_echo "WARNING: Continuing by hoping a success." >&2
1520                                         message_echo "INFO: Retrying the installation."
1521                                         _reinstall_exec__tmpcmd () { reinstall_make $insttarget MAKE_JOBS_UNSAFE=yes; }
1522                                         reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1523                                 }
1524                         then
1525                                 touch "$REINSTALL_DBNODE_DIR/installed_timestamp"
1526                                 reinstall_register_stage_complete INSTALL
1527                         else
1528                                 reinstall_register_stage FAILED_INSTALL
1529                         fi
1530                 fi
1531                 if reinstall_chk_stage FAILED_INSTALL
1532                 then
1533                         if pkgsys_is_necessary_pkgtool "$REINSTALL_ORIGIN"
1534                         then
1535                                 pkg_is_tool_available || pkg_rescue_tools
1536                         else
1537                                 reinstall_failed_install_recover
1538                         fi
1539                         if [ -e "$REINSTALL_DBNODE_DIR/AFTERINSTALL.conf" ] && \
1540                                 ! reinstall_chk_stage_complete FAILED_INSTALL.AFTERINSTALL
1541                         then
1542                                 message_echo "-- AFTERINSTALL operations (start)"
1543                                 if ! sh -e "$REINSTALL_DBNODE_DIR/AFTERINSTALL.conf"
1544                                 then
1545                                         message_echo "WARNING: Failed in AFTERINSTALL operations." >&2
1546                                         message_echo "---- (The process is continued anyway)"
1547                                 fi
1548                                 message_echo "-- AFTERINSTALL operations (end)"
1549                                 reinstall_register_stage_complete FAILED_INSTALL.AFTERINSTALL
1550                         fi
1551                         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1552                         reinstall_restore_if_temporarily_deinstalled
1553                         reinstall_errproc 'install'
1554                         return 1
1555                 fi
1556         fi
1557         reinstall_remove_needless_possible_conflict
1558         reinstall_restore_if_temporarily_deinstalled
1559         if ! reinstall_chk_stage_complete UPDATE_CONFLICTS
1560         then
1561                 pkg_info_qL "$REINSTALL_NEWPKGNAME" > ${TMPDIR}/reinstall_exec:currently_installed_files
1562                 cat "${DBDIR}/backup_pkgarcs.lst" 2> /dev/null \
1563                         | while read origin_bak pkgpath_bak
1564                 do
1565                         pkg_bak=`pkgsys_pkgarc_to_pkgname "$pkgpath_bak"`
1566                         if [ "$origin_bak" = "$REINSTALL_ORIGIN" ]
1567                         then
1568                                 [ "$pkg_bak" = "$REINSTALL_NEWPKGNAME" ] && continue
1569                         elif reinstall_quick_chk_forbidden_conflicts "$pkg_bak"
1570                         then
1571                                 continue
1572                         elif ! pkgsys_chk_match_to_restored_files_by_backup_pkg \
1573                                 "$origin_bak" "${TMPDIR}/reinstall_exec:currently_installed_files"
1574                         then
1575                                 continue
1576                         fi
1577                         fileedit_add_a_line_if_new "$pkg_bak:$REINSTALL_ORIGIN:$REINSTALL_NEWPKGNAME" \
1578                                 "${DBDIR}/forbidden_conflicts"
1579                 done
1580                 reinstall_register_stage_complete UPDATE_CONFLICTS
1581         fi
1582         if database_query_is_default_conf "$REINSTALL_ORIGIN" quiet
1583         then
1584                 fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_default_conf.list"
1585         else
1586                 fileedit_add_a_line_if_new "$REINSTALL_ORIGIN" "${DBDIR}/inst_by_port_with_custom_conf.list"
1587         fi
1588         if [ -e "$REINSTALL_DBNODE_DIR/AFTERINSTALL.conf" ] && ! reinstall_chk_stage_complete AFTERINSTALL
1589         then
1590                 message_echo "-- AFTERINSTALL operations (start)"
1591                 _reinstall_exec__tmpcmd () { sh -e "$REINSTALL_DBNODE_DIR/AFTERINSTALL.conf"; }
1592                 if ! reinstall_execcmd_tee_errlog _reinstall_exec__tmpcmd
1593                 then
1594                         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1595                         reinstall_errproc 'AFTERINSTALL operations'
1596                         return 1
1597                 fi
1598                 message_echo "-- AFTERINSTALL operations (end)"
1599                 reinstall_register_stage_complete AFTERINSTALL
1600         fi
1601         reinstall_deregister_stage in_install
1602 }
1603
1604 # ============= Reinstallation of the current origin: Closing process after successful install =============
1605 reinstall_exec_reinstall_close_successful_install ()
1606 {
1607         local dev_out dev_err
1608         dev_out=/dev/stdout
1609         dev_err=/dev/stderr
1610         if [ $opt_batch_mode = yes ]
1611         then
1612                 dev_out=/dev/null
1613                 dev_err=/dev/null
1614         fi
1615         reinstall_restore_conflicts "$REINSTALL_ORIGIN"
1616         if ! reinstall_chk_stage_complete CLEAN_AFTER_INSTALL
1617         then
1618                 if ! reinstall_make clean > $dev_out 2> $dev_err
1619                 then
1620                         message_echo "WARNING: Failed to clean $REINSTALL_ORIGPKGTAG." >&2
1621                 fi
1622                 reinstall_register_stage_complete CLEAN_AFTER_INSTALL
1623         fi
1624         reinstall_tell_update_to_depandents
1625         reinstall_closing_operations_after_successful_install
1626 }
1627
1628 # ============= Reinstallation of the current origin =============
1629 # Return status 1 for error or incomplete end
1630 reinstall_exec_reinstall ()
1631 {
1632         local insttarget instdesc
1633         if [ -e "$REINSTALL_FROMNODE_DIR/installed_version" ]
1634         then
1635                 insttarget=reinstall
1636                 instdesc='a reinstallation'
1637         else
1638                 insttarget=install
1639                 instdesc='an installation'
1640         fi
1641         temp_set_msg_current_stage "$instdesc process for $REINSTALL_ORIGPKGTAG $PROGRAM_STEP_COUNTER"
1642         message_target_relations "$REINSTALL_ORIGIN"
1643         message_echo "------- Starting $instdesc process --------"
1644         reinstall_exec_reinstall_check_sanity || return
1645         if [ $opt_dry_run = yes ]
1646         then
1647                 message_dry_run
1648                 return
1649         fi
1650         reinstall_exec_reinstall_by_pkg && return
1651         if [ $REINSTALL_IS_FROZEN = yes ]
1652         then
1653                 reinstall_exec_reinstall_freeze_if_necessary || return
1654         fi
1655         reinstall_exec_reinstall_avoid_if_any_unfrozen_requirements_exists || return
1656         reinstall_exec_reinstall_prebuild || return
1657         reinstall_exec_reinstall_fetch || return
1658         if [ $opt_fetch_only = yes ]
1659         then
1660                 message_fetch_only
1661                 return
1662         fi
1663         reinstall_exec_reinstall_chk_interactive_mode || return
1664         reinstall_exec_reinstall_build || return
1665         reinstall_exec_reinstall_stage || return
1666         reinstall_exec_reinstall_install || return
1667         reinstall_exec_reinstall_close_successful_install
1668 }
1669
1670 # ============= Reinstallation for a flavored origin =============
1671 reinstall_exec ()
1672 {
1673         local REINSTALL_ORIGIN REINSTALL_DBNODE_DIR REINSTALL_FROMNODE_DIR
1674         local REINSTALL_CURRENTPKG REINSTALL_IS_CURRENTPKG_LATEST
1675         local REINSTALL_PKGTAG REINSTALL_ORIGPKGTAG REINSTALL_DBSUFFIX
1676         local REINSTALL_NEWPKGNAME REINSTALL_IS_FROZEN
1677         REINSTALL_ORIGIN=$1
1678         REINSTALL_DBNODE_DIR=${DBDIR}/requires/$REINSTALL_ORIGIN
1679         REINSTALL_FROMNODE_DIR=${DBDIR}/moved_from/$REINSTALL_ORIGIN
1680         REINSTALL_CURRENTPKG=`database_build_update_pkgname "$REINSTALL_ORIGIN" | tr '\n' ' ' | sed 's/ *$//'`
1681         REINSTALL_IS_CURRENTPKG_LATEST=no
1682         database_build_is_currentpkg_latest "$REINSTALL_ORIGIN" && REINSTALL_IS_CURRENTPKG_LATEST=yes
1683         database_build_update_pkgtag "$REINSTALL_ORIGIN"
1684         REINSTALL_PKGTAG=`cat "$REINSTALL_FROMNODE_DIR/pkgtag"`
1685         REINSTALL_ORIGPKGTAG="$REINSTALL_ORIGIN ($REINSTALL_PKGTAG)"
1686         REINSTALL_DBSUFFIX=`options_get_dependency_type`.`options_get_dependency_level`
1687         REINSTALL_NEWPKGNAME=`database_build_get_new_pkgname "$REINSTALL_ORIGIN"`
1688         REINSTALL_IS_FROZEN=no
1689         grep -qFx "$REINSTALL_ORIGIN" "${DBDIR}/freeze.all.list" 2> /dev/null && REINSTALL_IS_FROZEN=yes
1690         message_stage_title "$PROGRAM_STEP_COUNTER $REINSTALL_ORIGPKGTAG"
1691         reinstall_exec_chk_skip && reinstall_exec_reinstall || :
1692         message_echo
1693 }
1694
1695 # ============= Indivisual make of a port for user command operations =============
1696 reinstall_make_individual ()
1697 {
1698         local REINSTALL_ORIGIN REINSTALL_DBNODE_DIR
1699         REINSTALL_ORIGIN=$1
1700         REINSTALL_DBNODE_DIR=${DBDIR}/requires/$REINSTALL_ORIGIN
1701         shift || :
1702         reinstall_make_anymode "$@"
1703 }
1704