Magellan Linux

Contents of /branches/mage-next/src/etc-update.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2637 - (show annotations) (download)
Thu Mar 27 08:15:57 2014 UTC (10 years, 1 month ago) by niro
File size: 10647 byte(s)
-be busybox friendly
1 #!/bin/bash
2 # $Id$
3 #
4 # Copyright 1999-2004 Gentoo Foundation
5 # Distributed under the terms of the GNU General Public License v2
6 # $Header: /home/cvsd/magellan-cvs/magellan-src/mage/usr/lib/mage/etc-update,v 1.7 2005-10-26 08:11:30 niro Exp $
7
8 # Author Brandon Low <lostlogic@gentoo.org>
9 #
10 # Previous version (from which I've borrowed a few bits) by:
11 # Jochem Kossen <j.kossen@home.nl>
12 # Leo Lipelis <aeoo@gentoo.org>
13 # Karl Trygve Kalleberg <karltk@gentoo.org>
14 #
15
16 # Modified by Niels Rogalla <niro@magellan-linux.de> to use this with Magellan-Linux
17 # version: 0.4.0-r8
18
19 function get_config() {
20 item=$1
21
22 # First strip off comment lines, then grab the configuration
23 # item. If there's more than one of the same configuration item,
24 # then allow the last setting to take precedence.
25 cut -d'#' -f1-1 /etc/etc-update.conf | \
26 sed -ne "s/^ *$item *= *\([\"']\{0,1\}\)\(.*\)\1/\2/p" |sed -e '$p;d'
27 }
28
29 function scan() {
30
31 echo "Scanning Configuration files..."
32 rm -rf ${TMP}/files > /dev/null 2>&1
33 mkdir ${TMP}/files || die "Failed mkdir command!" 1
34 count=0
35 input=0
36
37 for path in ${CONFIG_PROTECT}; do if [ -d ${path} ]; then
38 ofile=""
39 for file in `find ${path}/ -iname "._cfg????_*" |
40 sed -e "s:\(^.*/\)\(\._cfg[0-9]*_\)\(.*$\):\1\2\3\%\2\%\3:" |
41 sort -t'%' -k3 -k2 | LANG=POSIX LC_ALL=POSIX cut -f1 -d'%'`; do
42 rpath=`echo "${file/\/\///}" | sed -e "s:/[^/]*$::"`
43 rfile=`echo "${file/\/\///}" | sed -e "s:^.*/::"`
44 for mpath in ${CONFIG_PROTECT_MASK}; do
45 if [[ "${rpath}" == "${mpath}"* ]]; then
46 mv ${rpath}/${rfile} ${rpath}/${rfile:10}
47 break
48 fi
49 done
50 [ ! -f ${file} ] && continue
51
52
53 if [[ "${ofile:10}" != "${rfile:10}" ]] ||
54 [[ ${opath} != ${rpath} ]]; then
55 MATCHES=0
56 if [[ "${EU_AUTOMERGE}" == "yes" ]]; then
57 if [ ! -e "${rpath}/${rfile}" ] || [ ! -e "${rpath}/${rfile:10}" ]; then
58 MATCHES=0
59 else
60 diff -Bbua ${rpath}/${rfile} ${rpath}/${rfile:10} | egrep '^[+-]' | egrep -v '^[+-][\t ]*#|^--- |^\+\+\+ ' | egrep -qv '^[-+][\t ]*$'
61 MATCHES=$?
62 fi
63 elif [[ -z `diff -Nua ${rpath}/${rfile} ${rpath}/${rfile:10}|
64 grep "^[+-][^+-]"|grep -v '# .Header:.*'` ]]; then
65 MATCHES=1
66 fi
67 if [[ "${MATCHES}" == "1" ]]; then
68 echo "Automerging trivial changes in: ${rfile:10}"
69 mv ${rpath}/${rfile} ${rpath}/${rfile:10}
70 continue
71 else
72 count=${count}+1
73 echo "${rpath}/${rfile:10}" > ${TMP}/files/${count}
74 echo "${rpath}/${rfile}" >> ${TMP}/files/${count}
75 ofile="${rfile}"
76 opath="${rpath}"
77 continue
78 fi
79 fi
80
81 if [[ -z `diff -Nua ${rpath}/${rfile} ${rpath}/${ofile}|
82 grep "^[+-][^+-]"|grep -v '# .Header:.*'` ]]; then
83 mv ${rpath}/${rfile} ${rpath}/${ofile}
84 continue
85 else
86 echo "${rpath}/${rfile}" >> ${TMP}/files/${count}
87 ofile="${rfile}"
88 opath="${rpath}"
89 fi
90 done
91 fi; done
92
93 }
94
95 function sel_file() {
96 local -i isfirst=0
97 until [ -f ${TMP}/files/${input} ] || [ ${input} == -1 ] || [ ${input} == -3 ]; do
98 for file in `ls ${TMP}/files|sort -n`; do
99 if (( ${isfirst} == 0 )); then
100 isfirst=${file}
101 fi
102 echo -n "${file}${PAR} "
103 if (( ${mode} == 0 )); then
104 for word in `cat ${TMP}/files/${file}`; do
105 echo ${word}
106 done
107 else
108 head -n1 ${TMP}/files/${file}
109 fi
110 done > ${TMP}/menuitems
111
112 if [ "${OVERWRITE_ALL}" == "yes" ]; then
113 input=0
114 else
115 if (( ${mode} == 0 )); then
116 echo "The following is the list of files which need updating, each
117 configuration file is followed by a list of possible replacement files."
118 else
119 local my_title="Please select a file to update"
120 fi
121
122 if (( ${mode} == 0 )); then
123 cat ${TMP}/menuitems
124 echo "Please select a file to edit by entering the corresponding number."
125 echo " (don't use -3 or -5 if you're unsure what to do)"
126 echo " (-1 to exit) (-3 to auto merge all remaining files)"
127 echo -n " (-5 to auto-merge AND not use 'mv -i'): "
128 read input
129 else
130 dialog --title "${title}" --menu "${my_title}" \
131 0 0 0 `echo "-1 Exit";cat ${TMP}/menuitems` \
132 2> ${TMP}/input
133 input=`cat ${TMP}/input`
134 fi
135 if (( ${input} == -5 )); then
136 input=-3
137 export mv_opts=""
138 fi
139 if (( ${input} == -3 )); then
140 input=0
141 export OVERWRITE_ALL="yes"
142 fi
143 fi # -3 automerge
144 if (( ${input} == 0 )); then
145 input=${isfirst}
146 fi
147 done
148 }
149
150 function do_file() {
151 echo
152 local -i my_input
153 local -i fcount=0
154 until (( `cat ${TMP}/files/${input}|wc -l` < 2 )); do
155 my_input=0
156 if (( `cat ${TMP}/files/${input}|wc -l` == 2 )); then
157 my_input=1
158 fi
159 until (( ${my_input} > 0 )) && (( ${my_input} < `cat ${TMP}/files/${input}|wc -l` )); do
160 fcount=0
161
162 if [ "${OVERWRITE_ALL}" == "yes" ]; then
163 my_input=0
164 else
165 for line in `cat ${TMP}/files/${input}`; do
166 if (( ${fcount} > 0 )); then
167 echo -n "${fcount}${PAR} "
168 echo "${line}"
169 else
170 if (( ${mode} == 0 )); then
171 echo "Below are the new config files for ${line}:"
172 else
173 local my_title="Please select a file to process for ${line}"
174 fi
175 fi
176 fcount=${fcount}+1
177 done > ${TMP}/menuitems
178
179 if (( ${mode} == 0 )); then
180 cat ${TMP}/menuitems
181 echo -n "Please select a file to process (-1 to exit this file): "
182 read my_input
183 else
184 dialog --title "${title}" --menu "${my_title}" \
185 0 0 0 `cat ${TMP}/menuitems;echo "${fcount} Exit"` \
186 2> ${TMP}/input
187 my_input=`cat ${TMP}/input`
188 fi
189 fi # OVERWRITE_ALL
190
191 if (( ${my_input} == 0 )); then
192 my_input=1
193 elif (( ${my_input} == -1 )); then
194 input=0
195 return
196 elif (( ${my_input} == ${fcount} )); then
197 break
198 fi
199 done
200 if (( ${my_input} == ${fcount} )); then
201 break
202 fi
203
204 fcount=${my_input}+1
205
206 file=`cat ${TMP}/files/${input} | sed -e "${fcount}p;d"`
207 ofile=`head -n1 ${TMP}/files/${input}`
208
209 do_cfg "${file}" "${ofile}"
210
211 cat ${TMP}/files/${input}|sed -e "${fcount}!p;d" > ${TMP}/files/sed
212 mv ${TMP}/files/sed ${TMP}/files/${input}
213
214 if (( ${my_input} == -1 )); then
215 break
216 fi
217 done
218 echo
219 rm ${TMP}/files/${input}
220 count=${count}-1
221 }
222
223 function do_cfg() {
224
225 local file="${1}"
226 local ofile="${2}"
227 local -i my_input=0
228
229 until (( ${my_input} == -1 )) || [ ! -f ${file} ]; do
230 if [ "${OVERWRITE_ALL}" == "yes" ]; then
231 my_input=1
232 else
233 showdiffcmd=$(echo "${diff_command}" |
234 sed -e "s:%file1:${ofile}:" -e "s:%file2:${file}:")
235
236 if [ "${using_editor}" == 0 ]; then
237 (
238 echo "Showing differences between ${ofile} and ${file}"
239 ${showdiffcmd}
240 ) | ${pager}
241 else
242 echo "Beginning of differences between ${ofile} and ${file}"
243 ${showdiffcmd}
244 echo "End of differences between ${ofile} and ${file}"
245 fi
246 if [ -L "${file}" ]; then
247 echo
248 echo "-------------------------------------------------------------"
249 echo "NOTE: File is a symlink to another file. REPLACE recommended."
250 echo " The original file may simply have moved. Please review."
251 echo "-------------------------------------------------------------"
252 echo
253 fi
254 echo -n "1) Replace original with update
255 2) Delete update, keeping original as is
256 3) Interactively merge original with update
257 4) Show differences again
258 Please select from the menu above (-1 to ignore this update): "
259 read my_input
260 fi
261
262 case ${my_input} in
263 1) echo "Replacing ${ofile} with ${file}"
264 mv ${mv_opts} ${file} ${ofile}
265 my_input=-1
266 continue
267 ;;
268 2) echo "Deleting ${file}"
269 rm ${rm_opts} ${file}
270 continue
271 ;;
272 3) do_merge "${file}" "${ofile}"
273 my_input=${?}
274 # [ ${my_input} == 255 ] && my_input=-1
275 continue
276 ;;
277 4) continue
278 ;;
279 *) continue
280 ;;
281 esac
282 done
283 }
284
285 function do_merge() {
286
287 local file="${1}"
288 local ofile="${2}"
289 local mfile="${2}.merged"
290 local -i my_input=0
291 echo "${file} ${ofile} ${mfile}"
292
293 if [ -e ${mfile} ] ; then
294 echo "A previous version of the merged file exists, cleaning..."
295 rm ${rm_opts} ${mfile}
296 fi
297
298 until (( ${my_input} == -1 )); do
299 echo "Merging ${file} and ${ofile}"
300 `echo "${merge_command}" |
301 sed -e "s:%merged:${mfile}:g" \
302 -e "s:%orig:${ofile}:g" \
303 -e "s:%new:${file}:g"`
304 until (( ${my_input} == -1 )); do
305 echo -n "1) Replace ${ofile} with merged file
306 2) Show differences between merged file and original
307 3) Remerge original with update
308 4) Edit merged file
309 5) Return to the previous menu
310 Please select from the menu above (-1 to exit, losing this merge): "
311 read my_input
312 case ${my_input} in
313 1) echo "Replacing ${ofile} with ${mfile}"
314 # busybox does not support --reference
315 if ! chmod --reference=${ofile} ${mfile} > /dev/null 2&>1
316 then
317 chmod $(stat -c %a ${ofile}) ${mfile}
318 fi
319 mv ${mv_opts} ${mfile} ${ofile}
320 rm ${rm_opts} ${file}
321 return 255
322 ;;
323 2) ( echo "Showing differences between ${ofile} and ${mfile}"
324 `echo "${diff_command}" | \
325 sed -e "s:%file1:${ofile}:" \
326 -e "s:%file2:${mfile}:"` ) | ${pager}
327 continue
328 ;;
329 3) break
330 ;;
331 4) ${EDITOR:-nano -w} "${mfile}"
332 continue
333 ;;
334 5) rm ${rm_opts} ${mfile}
335 return 0
336 ;;
337 *) continue
338 ;;
339 esac
340 done
341 done
342 rm ${rm_opts} ${mfile}
343 return 255
344 }
345
346 function die() {
347 trap "" term
348 trap "" kill
349 echo "Exiting: ${1}"
350 rm -rf ${TMP}
351 exit ${2}
352 }
353
354 #
355 # Run the script
356 #
357 scriptname=`basename $0`
358
359 trap die term
360
361 TMP="/tmp/$$"
362 rm -rf ${TMP} 2> /dev/null
363 mkdir ${TMP} || die "failed mkdir command!" 1
364
365 # I need the CONFIG_PROTECT value
366 #CONFIG_PROTECT=$(/usr/lib/portage/bin/portageq config_protect)
367 #CONFIG_PROTECT_MASK=$(/usr/lib/portage/bin/portageq config_protect_mask)
368 source /etc/profile
369
370 # load etc-config's configuration
371 EU_AUTOMERGE=`get_config eu_automerge`
372 rm_opts=`get_config rm_opts`
373 mv_opts=`get_config mv_opts`
374 cp_opts=`get_config cp_opts`
375 pager=`get_config pager`
376 diff_command=`get_config diff_command`
377 using_editor=`get_config using_editor`
378 merge_command=`get_config merge_command`
379 declare -i mode=`get_config mode`
380 [ -z ${mode} ] && mode=0
381 [ -z "${pager}" ] && pager="cat"
382
383 #echo "rm_opts: $rm_opts, mv_opts: $mv_opts, cp_opts: $cp_opts"
384 #echo "pager: $pager, diff_command: $diff_command, merge_command: $merge_command"
385
386 if (( ${mode} == 0 )); then
387 PAR=")"
388 else
389 PAR=""
390 fi
391
392 declare -i count=0
393 declare -i input=0
394 declare title="Gentoolkit's etc-update tool!"
395
396 scan
397
398 until (( ${input} == -1 )); do
399 if (( ${count} == 0 )); then
400 die "Nothing left to do; exiting. :)" 0
401 fi
402 sel_file
403 if (( ${input} != -1 )); then
404 do_file
405 fi
406 done
407
408 die "User termination!" 0