CRUX-ARM : Home

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