Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 283 - (hide annotations) (download)
Wed Oct 26 08:11:30 2005 UTC (18 years, 6 months ago) by niro
File size: 10651 byte(s)
synced with upstream:
- fixed several segfaults
- allow single quotes in config-file
- now really using less as pager

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

Properties

Name Value
svn:executable *