Magellan Linux

Contents of /trunk/mage/usr/lib/mage/etc-update

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *