CRUX-ARM : Home

Home :: Documentation :: Download :: Development :: Community :: Ports :: Packages :: Bugs :: Links :: About :: Donors
Initial import
[pkgutils-cross.git] / rejmerge.in
CommitLineData
9ac667e6
SR
1#!/bin/bash
2#
3# rejmerge (pkgutils)
4#
5# Copyright (c) 2000-2005 Per Liden
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20# USA.
21#
22
23info_n() {
24 echo -n "=======> $1"
25}
26
27info() {
28 info_n "$1"
29 echo
30}
31
32interrupted() {
33 echo ""
34 info "Aborted."
35 exit 1
36}
37
38atexit() {
39 if [ -e "$TMPFILE" ]; then
40 rm -f "$TMPFILE"
41 fi
42}
43
44rejmerge_diff() {
45 diff -u "$1" "$2" > "$3"
46}
47
48rejmerge_merge() {
49 diff --old-group-format="%<" \
50 --new-group-format="%>" \
51 --changed-group-format="<<<<< MERGE CONFLICT $1 >>>>>
52%<<<<<< MERGE CONFLICT $2 >>>>>
53%><<<<< END MERGE CONFLICT >>>>>
54" \
55 "$1" "$2" > "$3"
56
57 REJMERGE_MERGE_INFO="$(grep -c '^<<<<< END MERGE CONFLICT >>>>>$' "$3") merge conflict(s)."
58}
59
60permissions_menu() {
61 while true; do
62 info "Access permissions $1"
63 stat -c '%A %U %G %n' "$1"
64 stat -c '%A %U %G %n' "$2"
65 while true; do
66 info_n "[K]eep [U]pgrade [D]iff [S]kip? "
67 read -n1 CMD
68 echo
69
70 case "$CMD" in
71 k|K) chown --reference="$1" "$2"
72 chmod --reference="$1" "$2"
73 break 2
74 ;;
75 u|U) chown --reference="$2" "$1"
76 chmod --reference="$2" "$1"
77 break 2
78 ;;
79 d|D) break 1
80 ;;
81 s|S) break 2
82 ;;
83 esac
84 done
85 done
86}
87
88merge_menu() {
89 rejmerge_merge "$1" "$2" "$TMPFILE"
90
91 while true; do
92 info "Merged $1"
93 cat "$TMPFILE" | more
94
95 if [ "$REJMERGE_MERGE_INFO" ]; then
96 info "$REJMERGE_MERGE_INFO"
97 unset REJMERGE_MERGE_INFO
98 fi
99
100 while true; do
101 info_n "[I]nstall [E]dit [V]iew [S]kip? "
102 read -n1 CMD
103 echo
104
105 case "$CMD" in
106 i|I) chmod --reference="$1" "$TMPFILE"
107 mv -f "$TMPFILE" "$1"
108 rm -f "$2"
109 break 2
110 ;;
111 e|E) $EDITOR "$TMPFILE"
112 break 1
113 ;;
114 v|V) break 1
115 ;;
116 s|S) break 2
117 ;;
118 esac
119 done
120 done
121
122 : > "$TMPFILE"
123}
124
125diff_menu() {
126 rejmerge_diff "$1" "$2" "$TMPFILE"
127
128 while true; do
129 info "$1"
130 cat "$TMPFILE" | more
131 while true; do
132 info_n "[K]eep [U]pgrade [M]erge [D]iff [S]kip? "
133 read -n1 CMD
134 echo
135
136 case "$CMD" in
137 k|K) rm -f "$2"
138 break 2
139 ;;
140 u|U) mv -f "$2" "$1"
141 break 2
142 ;;
143 m|M) merge_menu "$1" "$2"
144 break 2
145 ;;
146 d|D) break 1
147 ;;
148 s|S) break 2
149 ;;
150 esac
151 done
152 done
153
154 : > "$TMPFILE"
155}
156
157file_menu() {
158 while true; do
159 info "$1"
160 file "$1" "$2"
161 while true; do
162 info_n "[K]eep [U]pgrade [D]iff [S]kip? "
163 read -n1 CMD
164 echo
165
166 case "$CMD" in
167 k|K) rm -f "$2"
168 break 2
169 ;;
170 u|U) mv -f "$2" "$1"
171 break 2
172 ;;
173 d|D) break 1
174 ;;
175 s|S) break 2
176 ;;
177 esac
178 done
179 done
180}
181
182print_help() {
183 echo "usage: $REJMERGE_COMMAND [options]"
184 echo "options:"
185 echo " -r, --root <path> specify alternative root"
186 echo " -v, --version print version and exit "
187 echo " -h, --help print help and exit"
188}
189
190parse_options() {
191 while [ "$1" ]; do
192 case $1 in
193 -r|--root)
194 if [ ! "$2" ]; then
195 echo "$REJMERGE_COMMAND: option $1 requires an argument"
196 exit 1
197 fi
198 REJMERGE_ROOT="$2"
199 REJMERGE_CONF="$2$REJMERGE_CONF"
200 REJECTED_DIR="$2$REJECTED_DIR"
201 shift ;;
202 -v|--version)
203 echo "$REJMERGE_COMMAND (pkgutils) $REJMERGE_VERSION"
204 exit 0 ;;
205 -h|--help)
206 print_help
207 exit 0 ;;
208 *)
209 echo "$REJMERGE_COMMAND: invalid option $1"
210 exit 1 ;;
211 esac
212 shift
213 done
214
215 if [ ! -d "$REJECTED_DIR" ]; then
216 echo "$REJMERGE_COMMAND: $REJECTED_DIR not found"
217 exit 1
218 fi
219}
220
221files_regular() {
222 local STAT_FILE1=$(stat -c '%F' "$1")
223 local STAT_FILE2=$(stat -c '%F' "$2")
224
225 if [ "$STAT_FILE1" != "regular file" ]; then
226 return 1
227 fi
228
229 if [ "$STAT_FILE2" != "regular file" ]; then
230 return 1
231 fi
232
233 return 0
234}
235
236main() {
237 parse_options "$@"
238
239 if [ "$UID" != "0" ]; then
240 echo "$REJMERGE_COMMAND: only root can merge rejected files"
241 exit 1
242 fi
243
244 # Read configuration
245 if [ -f "$REJMERGE_CONF" ]; then
246 . "$REJMERGE_CONF"
247 fi
248
249 REJECTED_FILES_FOUND="no"
250
251 # Check files
252 for REJECTED_FILE in $(find $REJECTED_DIR ! -type d); do
253 INSTALLED_FILE="$REJMERGE_ROOT${REJECTED_FILE##$REJECTED_DIR}"
254
255 # Remove rejected file if there is no installed version
256 if [ ! -e "$INSTALLED_FILE" ]; then
257 rm -f "$REJECTED_FILE"
258 continue
259 fi
260
261 # Check permissions
262 local STAT_FILE1=$(stat -c '%A %U %G' "$INSTALLED_FILE")
263 local STAT_FILE2=$(stat -c '%A %U %G' "$REJECTED_FILE")
264
265 if [ "$STAT_FILE1" != "$STAT_FILE2" ]; then
266 REJECTED_FILES_FOUND="yes"
267 permissions_menu "$INSTALLED_FILE" "$REJECTED_FILE"
268 fi
269
270 # Check file types
271 if files_regular "$INSTALLED_FILE" "$REJECTED_FILE"; then
272 # Both files are regular
273 if cmp -s "$INSTALLED_FILE" "$REJECTED_FILE"; then
274 rm -f "$REJECTED_FILE"
275 else
276 REJECTED_FILES_FOUND="yes"
277 diff_menu "$INSTALLED_FILE" "$REJECTED_FILE"
278 fi
279 else
280 # At least one file is non-regular
281 REJECTED_FILES_FOUND="yes"
282 file_menu "$INSTALLED_FILE" "$REJECTED_FILE"
283 fi
284 done
285
286 # Remove empty directories
287 for DIR in $(find $REJECTED_DIR -depth -type d); do
288 if [ "$DIR" != "$REJECTED_DIR" ]; then
289 rmdir "$DIR" &> /dev/null
290 fi
291 done
292
293 if [ "$REJECTED_FILES_FOUND" = "no" ]; then
294 echo "Nothing to merge"
295 fi
296
297 exit 0
298}
299
300trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
301trap "atexit" EXIT
302
303export LC_ALL=POSIX
304
305readonly REJMERGE_VERSION="#VERSION#"
306readonly REJMERGE_COMMAND="${0##*/}"
307REJMERGE_ROOT=""
308REJMERGE_CONF="/etc/rejmerge.conf"
309REJECTED_DIR="/var/lib/pkg/rejected"
310EDITOR=${EDITOR:-vi}
311TMPFILE=$(mktemp) || exit 1
312
313main "$@"
314
315# End of file