OSDN Git Service

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