OSDN Git Service

Fixed a bug related to the previous modification.
[portsreinstall/current.git] / lib / libdeinstall.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Deinstallation 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 # ============= Dialog for selection of removing new leaf ports =============
10 deinstall_select_leaf_ports_to_delete_dialog ()
11 {
12         local src dst_selected dst_unselected itemlist title desc
13         src=$1
14         dst_selected=$2
15         dst_unselected=$3
16         itemlist=${TMPDIR}/deinstall_select_leaf_ports_to_delete_dialog::itemlist
17         title='New leaf ports and their exclusive requirements to be deleted'
18         desc='Unchecked ones are preserved with their requirements.\nCancellation means to preserve all.'
19         while read origin
20         do
21                 pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null` || :
22                 val=on
23                 grep -Fxq "$origin" "$dst_unselected" 2> /dev/null && val=off
24                 printf '%s\t"(%s)"\t%s\n' "$origin" "$pkgtag" "$val"
25         done < $src > $itemlist
26         misc_dialog_checklist "$title" "$desc" "$dst_selected" "$itemlist"
27         grep -Fx -v -f "$dst_selected" "$src" > $dst_unselected || :
28 }
29
30 # ============= Automatic selection of removing ports =============
31 deinstall_select_auto ()
32 {
33         local src dst_add dst_rem tmp_srcprev tmp_srcnew diff_removed diff_added
34         src=$1
35         dst_add=$2
36         dst_rem=$3
37         tmp_srcprev=${TMPDIR}/deinstall_select_auto:src.prev
38         tmp_srcnew=${TMPDIR}/deinstall_select_auto:src.new
39         diff_removed=${TMPDIR}/deinstall_select_auto:diff_removed
40         diff_added=${TMPDIR}/deinstall_select_auto:diff_added
41         cat "$dst_add" "$dst_rem" 2> /dev/null | sort -u > $tmp_srcprev
42         cat "$src" 2> /dev/null | sort -u > $tmp_srcnew
43         fileedit_manipulate_old_new_lines "$tmp_srcprev" "$tmp_srcnew" "$diff_removed" "$diff_added" || return 0
44         grep -v -Fx -f "$diff_removed" "$dst_rem" 2> /dev/null | \
45                 grep -Fx -f "$src" > $dst_rem.tmp || :
46         mv "$dst_rem.tmp" "$dst_rem"
47         cat "$dst_add" "$diff_added" 2> /dev/null | sort -u | \
48                 grep -Fx -f "$src" > $dst_add.tmp || :
49         mv "$dst_add.tmp" "$dst_add"
50 }
51
52 # ============= Selection of removing new leaf ports =============
53 deinstall_select_leaf_ports_to_delete ()
54 {
55         local mode src dst_selected dst_unselected tmp_srcprev
56         mode=$1
57         src=${DBDIR}/leaf_ports
58         dst_selected=${DBDIR}/leaf_ports_to_delete.selected
59         dst_unselected=${DBDIR}/leaf_ports_to_delete.unselected
60         tmp_srcprev=${TMPDIR}/deinstall_select_leaf_ports_to_delete:src.prev
61         if [ "x$mode" = xforce ]
62         then
63                 if [ -e "${DBDIR}/inspected_ports_only_partially" ]
64                 then
65                         return 3
66                 elif [ `cat "$src" 2> /dev/null | wc -l` -eq 0 ]
67                 then
68                         cp /dev/null "$dst_selected"
69                         cp /dev/null "$dst_unselected"
70                         return 2
71                 fi
72                 deinstall_select_leaf_ports_to_delete_dialog "$src" "$dst_selected" "$dst_unselected"
73         elif [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
74         then
75                 case $opt_dialog_auto in
76                 no )
77                         touch "$dst_selected" "$dst_unselected" "$src"
78                         if [ `cat "$src" 2> /dev/null | wc -l` -gt 0 ]
79                         then
80                                 cat "$dst_selected" "$dst_unselected" 2> /dev/null | sort -u > $tmp_srcprev
81                                 diff -q "$tmp_srcprev" "$src" > /dev/null 2>&1 || \
82                                         deinstall_select_leaf_ports_to_delete_dialog "$src" "$dst_selected" "$dst_unselected"
83                         else
84                                 cp /dev/null "$dst_selected"
85                                 cp /dev/null "$dst_unselected"
86                         fi
87                         ;;
88                 all )
89                         deinstall_select_auto "$src" "$dst_selected" "$dst_unselected"
90                         ;;
91                 none )
92                         deinstall_select_auto "$src" "$dst_unselected" "$dst_selected"
93                         ;;
94                 esac
95         fi
96 }
97
98 # ============= Dialog for selection of removing obsolete ports =============
99 deinstall_select_obsolete_ports_to_delete_dialog ()
100 {
101         local src dst_selected dst_unselected itemlist title desc
102         src=$1
103         dst_selected=$2
104         dst_unselected=$3
105         itemlist=${TMPDIR}/deinstall_select_obsolete_ports_to_delete_dialog::itemlist
106         title='Obsolete packages to be deleted'
107         desc='Unchecked ones are preserved.\nCancellation means to preserve all.'
108         while read origin
109         do
110                 pkgtag=`cat "${DBDIR}/initial/$origin/installed_version"`
111                 val=on
112                 grep -Fxq "$origin" "$dst_unselected" 2> /dev/null && val=off
113                 printf '%s\t"(%s)"\t%s\n' "$origin" "$pkgtag" "$val"
114         done < $src > $itemlist
115         misc_dialog_checklist "$title" "$desc" "$dst_selected" "$itemlist"
116         grep -Fx -v -f "$dst_selected" "$src" > $dst_unselected || :
117 }
118
119 # ============= Selection of removing obsolete ports =============
120 deinstall_select_obsolete_ports_to_delete ()
121 {
122         local mode src dst_selected dst_unselected tmp_srcprev
123         mode=$1
124         src=${DBDIR}/obsolete_ports.can_be_deleted
125         dst_selected=${DBDIR}/obsolete_ports_to_delete.selected
126         dst_unselected=${DBDIR}/obsolete_ports_to_delete.unselected
127         tmp_srcprev=${TMPDIR}/deinstall_select_obsolete_ports_to_delete:src.prev
128         if [ "x$mode" = xforce ]
129         then
130                 if [ `cat "$src" 2> /dev/null | wc -l` -eq 0 ]
131                 then
132                         cp /dev/null "$dst_selected"
133                         cp /dev/null "$dst_unselected"
134                         return 2
135                 fi
136                 deinstall_select_obsolete_ports_to_delete_dialog "$src" "$dst_selected" "$dst_unselected"
137         else
138                 case $opt_dialog_auto in
139                 no )
140                         touch "$dst_selected" "$dst_unselected" "$src"
141                         if [ `cat "$src" 2> /dev/null | wc -l` -gt 0 ]
142                         then
143                                 cat "$dst_selected" "$dst_unselected" 2> /dev/null | sort -u > $tmp_srcprev
144                                 diff -q "$tmp_srcprev" "$src" > /dev/null 2>&1 || \
145                                         deinstall_select_obsolete_ports_to_delete_dialog "$src" "$dst_selected" "$dst_unselected"
146                         else
147                                 cp /dev/null "$dst_selected"
148                                 cp /dev/null "$dst_unselected"
149                         fi
150                         ;;
151                 all )
152                         deinstall_select_auto "$src" "$dst_selected" "$dst_unselected"
153                         ;;
154                 none )
155                         deinstall_select_auto "$src" "$dst_unselected" "$dst_selected"
156                         ;;
157                 esac
158         fi
159 }
160
161 # ============= Restoration of a package for a flavored origin =============
162 deinstall_restore ()
163 {
164         local origin tmp_forbidden currentpkg backup_pkg pkg
165         origin=$1
166         tmp_forbidden=${TMPDIR}/deinstall_restore:forbidden
167         pkgsys_exists_from_orig "$origin" && return
168         backup_pkg=`pkgsys_get_backup_pkg "$origin"` || return 0
169         currentpkg=`pkgsys_pkgarc_to_pkgname "$backup_pkg"`
170         message_stage_title "$PROGRAM_STEP_COUNTER $origin ($currentpkg)"
171         message_target_relations "$origin"
172         temp_set_msg_current_stage "a ${_MSG_CURRENT_STAGE_general} process for $origin ($currentpkg) $PROGRAM_STEP_COUNTER"
173         database_query_get_target_attributes currentorigin "$origin"
174         if [ -z "${currentorigin_is_relevant}" ]
175         then
176                 message_echo "-- (Skipping an irrelevant package for obsolete port $origin as $currentpkg)"
177                 message_echo
178                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
179                 return
180         fi
181         if database_query_is_a_port_suppressed "$origin"
182         then
183                 message_echo "-- (Skipped because being suppressed)"
184                 message_echo
185                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
186                 return
187         fi
188         pkg=`pkgsys_pkgarc_to_pkgname "$backup_pkg"`
189         if reinstall_chk_forbidden_conflicts "$pkg"
190         then
191                 message_echo "-- (Skipped because conflicting with installed packages)"
192                 return
193         fi
194         if [ $opt_dry_run = yes ]
195         then
196                 message_dry_run
197                 message_echo
198                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
199                 return
200         elif ! pkg_add_fF "$backup_pkg"
201         then
202                 message_echo "*** Going on to the next process anyway..."
203         fi
204         temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
205         message_echo
206 }
207
208 # ============= Deinstallation of a package for a flavored origin =============
209 deinstall_exec ()
210 {
211         local origin_master origin origin_regexp currentpkg backup_pkgdir backup_pkg pkg
212         origin_master=$1
213         currentpkg=`pkgsys_get_installed_pkg_from_origin "$origin_master" | tr '\n' ' ' | sed 's/ *$//'`
214         [ -n "$currentpkg" ] || currentpkg='deinstalled'
215         message_stage_title "$PROGRAM_STEP_COUNTER $origin_master ($currentpkg)"
216         message_target_relations "$origin_master"
217         for origin in `{ echo "$origin_master"; database_query_initial_orgins "$origin_master"; } | sort -u`
218         do
219                 origin_regexp=`str_escape_regexp "$origin"`
220                 grep -v -E "^${origin_regexp}[[:space:]]" "${DBDIR}/deleted_conflicts" > ${DBDIR}/deleted_conflicts.tmp 2> /dev/null || :
221                 mv "${DBDIR}/deleted_conflicts.tmp" "${DBDIR}/deleted_conflicts"
222                 currentpkg=`pkgsys_get_installed_pkg_from_origin "$origin" | tr '\n' ' ' | sed 's/ *$//'`
223                 [ -n "$currentpkg" ] || continue
224                 temp_set_msg_current_stage "a ${_MSG_CURRENT_STAGE_general} process for $origin ($currentpkg) $PROGRAM_STEP_COUNTER"
225                 database_query_get_target_attributes currentorigin "$origin"
226                 if [ -z "${currentorigin_is_relevant}" ]
227                 then
228                         message_echo "-- (Skipping an non-target package for obsolete port $origin as $currentpkg)"
229                         continue
230                 fi
231                 if database_query_is_a_port_suppressed "$origin"
232                 then
233                         message_echo "-- (Skipped for $origin as $currentpkg because being suppressed)"
234                         continue
235                 fi
236                 if [ $opt_dry_run = yes ]
237                 then
238                         message_echo "-- (Create backup package for $origin as $currentpkg)"
239                         continue
240                 fi
241                 message_echo "-- (Creating backup package for $origin as $currentpkg)"
242                 if ! pkgsys_get_backup_pkg "$origin" > /dev/null
243                 then
244                         if [ -d "${DBDIR}/requires/$origin" ]
245                         then
246                                 backup_pkgdir=${DBDIR}/backup_packages
247                         else
248                                 backup_pkgdir=${PKGREPOSITORY}
249                         fi
250                         mkdir -p "$backup_pkgdir"
251                         pkg=`echo "$currentpkg" | tr ' ' '\n' | grep -v '^$' | tail -n 1`
252                         backup_pkg=`pkgsys_create_backup_pkg "$pkg" "$backup_pkgdir"` || :
253                         if [ -n "$backup_pkg" ]
254                         then
255                                 message_echo "INFO: The backup is saved at $backup_pkg."
256                                 message_echo
257                         else
258                                 message_echo "*** Continuating forcibly by keeping the installed package"
259                                 continue
260                         fi
261                 fi
262                 message_echo "-- (Deleting package for $origin as $currentpkg)"
263                 echo "$currentpkg" | tr ' ' '\n' | grep -v '^$' | while read pkg
264                 do
265                         if ! pkg_delete_f "$currentpkg"
266                         then
267                                 message_echo "*** Continuating forcibly by hoping success..."
268                         fi
269                 done
270         done
271         [ $opt_dry_run = yes ] && message_dry_run
272         temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
273         message_echo
274 }