OSDN Git Service

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