Annotation of /branches/mage-next/src/etc-update.in
Parent Directory | Revision Log
Revision 2525 -
(hide annotations)
(download)
Wed Jan 29 10:42:21 2014 UTC (10 years, 7 months ago) by niro
Original Path: branches/mage-next/usr/lib/mage/etc-update
File size: 10545 byte(s)
Wed Jan 29 10:42:21 2014 UTC (10 years, 7 months ago) by niro
Original Path: branches/mage-next/usr/lib/mage/etc-update
File size: 10545 byte(s)
-open mage-next branch
1 | niro | 24 | #!/bin/bash |
2 | niro | 1544 | # $Id$ |
3 | # | ||
4 | niro | 283 | # 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 | niro | 24 | # 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 | niro | 1544 | # Modified by Niels Rogalla <niro@magellan-linux.de> to use this with Magellan-Linux |
17 | niro | 283 | # version: 0.4.0-r8 |
18 | niro | 24 | |
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 | niro | 283 | sed -ne "s/^ *$item *= *\([\"']\{0,1\}\)\(.*\)\1/\2/p" |sed -e '$p;d' |
29 | niro | 24 | } |
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 | niro | 283 | 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 | niro | 24 | 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 | niro | 283 | echo " (don't use -3 or -5 if you're unsure what to do)" |
128 | niro | 24 | 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 | niro | 283 | input=0 |
197 | niro | 24 | 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 | niro | 283 | my_input=-1 |
268 | niro | 24 | 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 | chmod --reference=${ofile} ${mfile} | ||
317 | mv ${mv_opts} ${mfile} ${ofile} | ||
318 | rm ${rm_opts} ${file} | ||
319 | return 255 | ||
320 | ;; | ||
321 | 2) ( echo "Showing differences between ${ofile} and ${mfile}" | ||
322 | `echo "${diff_command}" | \ | ||
323 | sed -e "s:%file1:${ofile}:" \ | ||
324 | -e "s:%file2:${mfile}:"` ) | ${pager} | ||
325 | continue | ||
326 | ;; | ||
327 | 3) break | ||
328 | ;; | ||
329 | 4) ${EDITOR:-nano -w} "${mfile}" | ||
330 | continue | ||
331 | ;; | ||
332 | 5) rm ${rm_opts} ${mfile} | ||
333 | return 0 | ||
334 | ;; | ||
335 | *) continue | ||
336 | ;; | ||
337 | esac | ||
338 | done | ||
339 | done | ||
340 | rm ${rm_opts} ${mfile} | ||
341 | return 255 | ||
342 | } | ||
343 | |||
344 | function die() { | ||
345 | trap "" term | ||
346 | trap "" kill | ||
347 | echo "Exiting: ${1}" | ||
348 | rm -rf ${TMP} | ||
349 | exit ${2} | ||
350 | } | ||
351 | |||
352 | # | ||
353 | # Run the script | ||
354 | # | ||
355 | scriptname=`basename $0` | ||
356 | |||
357 | trap die term | ||
358 | |||
359 | niro | 283 | TMP="/tmp/$$" |
360 | niro | 24 | rm -rf ${TMP} 2> /dev/null |
361 | mkdir ${TMP} || die "failed mkdir command!" 1 | ||
362 | |||
363 | # I need the CONFIG_PROTECT value | ||
364 | #CONFIG_PROTECT=$(/usr/lib/portage/bin/portageq config_protect) | ||
365 | #CONFIG_PROTECT_MASK=$(/usr/lib/portage/bin/portageq config_protect_mask) | ||
366 | source /etc/profile | ||
367 | |||
368 | # load etc-config's configuration | ||
369 | EU_AUTOMERGE=`get_config eu_automerge` | ||
370 | rm_opts=`get_config rm_opts` | ||
371 | mv_opts=`get_config mv_opts` | ||
372 | cp_opts=`get_config cp_opts` | ||
373 | pager=`get_config pager` | ||
374 | diff_command=`get_config diff_command` | ||
375 | using_editor=`get_config using_editor` | ||
376 | merge_command=`get_config merge_command` | ||
377 | declare -i mode=`get_config mode` | ||
378 | [ -z ${mode} ] && mode=0 | ||
379 | [ -z "${pager}" ] && pager="cat" | ||
380 | |||
381 | #echo "rm_opts: $rm_opts, mv_opts: $mv_opts, cp_opts: $cp_opts" | ||
382 | #echo "pager: $pager, diff_command: $diff_command, merge_command: $merge_command" | ||
383 | |||
384 | if (( ${mode} == 0 )); then | ||
385 | PAR=")" | ||
386 | else | ||
387 | PAR="" | ||
388 | fi | ||
389 | |||
390 | declare -i count=0 | ||
391 | declare -i input=0 | ||
392 | declare title="Gentoolkit's etc-update tool!" | ||
393 | |||
394 | scan | ||
395 | |||
396 | until (( ${input} == -1 )); do | ||
397 | if (( ${count} == 0 )); then | ||
398 | die "Nothing left to do; exiting. :)" 0 | ||
399 | fi | ||
400 | sel_file | ||
401 | if (( ${input} != -1 )); then | ||
402 | do_file | ||
403 | fi | ||
404 | done | ||
405 | |||
406 | die "User termination!" 0 |
Properties
Name | Value |
---|---|
svn:executable | * |