OSDN Git Service

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