3 ################################################
4 ### Managed by someone's ansible provisioner ###
5 ################################################
6 # Part of: https://git.somenet.org/root/pub/somesible.git
7 # 2017-2024 by someone <someone@somenet.org>
11 # updateConfFile.sh ---
12 # Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com )
13 # Created On : Fri Feb 1 03:41:47 2002
14 # Created On Node : glaurung.green-gryphon.com
15 # Last Modified By : Manoj Srivastava
16 # Last Modified On : Tue Jun 6 09:48:22 2006
17 # Last Machine Used: glaurung.internal.golden-gryphon.com
19 # Status : Unknown, Use with caution!
23 # This script attempts to provide conffile like handling for files not
24 # shipped in a Debian package, but handled by the postinst. Using this
25 # script, one may ship a bunch of default cofiguration files somewhere
26 # in /usr (/usr/share/<pkg> is a good location), and maintain files in
29 # The motivation for this script was to provide conffile like handling
30 # for start files for emacs lisp packages (for example,
31 # /etc/emacs21/site-stard.d/50psgml-init.el) These start files are not
32 # shipped with the package, instead, they are installed during the
33 # post installation configuration phase by the script
34 # /usr/lib/emacsen-common/emacs-package-install $package_name.
36 # This script is meant to be invoked by the packages install script at
37 # /usr/lib/emacsen-common/packages/install/$package_name for each
38 # flavour of installed emacsen by calling it with the proper values of
39 # new file (/usr/share/emacs/site-lisp/<pkg>/<pkg>-init.el), and dest file
40 # (/etc/emacs21/site-stard.d/50<pkg>-init.el)), and it should do the rest.
43 # make sure we exit on error
46 # set the version and revision
47 progname="$(basename $0)"
48 pversion='Revision: 3.00 '
52 ######################################################################
54 ######## Utility functions #########
56 ######################################################################
58 # Variable Value Doc_string
59 if [ "x$2" = "x" ]; then
60 echo >&2 "$progname: Unable to determine $3"
63 if [ "x$VERBOSE" != "x" ]; then
64 echo >&2 "$progname: $3 is $2";
70 # Usage: get_file_metadate file_name
74 # get file modification date without the nanoseconds and timezone info
75 local moddate="$(date +"%F %T" --date $(stat --format '@%Y' "$1"))"
76 # print file_name user.group permissions above_date
77 stat --format "%n %U.%G 0%a $moddate" "$1"
83 # Runs the diff command with approrpiate arguments
84 # Usage run_diff diff|sdiff diff_opts old_file new_file
92 # Note: get_file_metadata not in quotes to ignore "\n" characters
93 local old_file_label="$(get_file_metadata "$old_file")"
94 local new_file_label="$(get_file_metadata "$new_file")"
96 [ -e "$old_file" ] || old_file=/dev/null
97 [ -e "$new_file" ] || new_file=/dev/null
99 if [ "$diff_cmd" = "diff" ] ; then
100 diff "$diff_opt" --label "$old_file_label" "$old_file" \
101 --label "$new_file_label" "$new_file" || true
102 elif [ "$diff_cmd" = "sdiff" ] ; then
103 # unfortunatelly the sdiff command does not support --label option
104 local out="$(sdiff "$diff_opt" "$old_file" "$new_file")" || true
105 [ -z "$out" ] || printf "Old file: %s\nNew file: %s\n\n%s" \
106 "$old_file_label" "$new_file_label" "$out"
108 echo "Unknown diff command: $diff_cmd" >&2
114 # Use debconf to show the differences
115 # Usage: show_diff actual_file_differences file_stat_differences
118 DIFF="There are no non-white space differences in the files."
120 if [ 99999 -lt "$(echo $1 | wc -c | awk '{print $1; }')" ]; then
121 DIFF="The differences between the files are too large to display."
126 if [ "$DEBCONF_OK" = "YES" ] && [ "$DEBIAN_HAS_FRONTEND" ]; then
129 db_subst $templ DIFF "$(printf %s "$DIFF" | debconf-escape -e)"
130 db_fset $templ seen false
131 db_input critical $templ || true
134 # may contain sensitive information, so clear
135 # immediatly after use so it is never written
137 db_subst $templ DIFF ""
141 if [ -z "$my_pager" ]; then
142 echo "$DIFF" | sensible-pager
144 echo "$DIFF" | $my_pager
156 Debian GNU/Linux $progname $pversion.
157 Copyright (C) 2002-2005 Manoj Srivastava.
158 This is free software; see the GNU General Public Licence for copying
159 conditions. There is NO warranty.
161 Usage: $progname [options] new_file destination
163 -h, --help print this message
164 -s foo, --src-dir foo Set the src dir (historical md5sums live here)
165 --sum-file bar Force the historical md5sums to be read from
166 this file. Overrides any setting of --src-dir.
167 -d[n], --debug=[n] Set the Debug level to N. Please note there must
168 be no spaces before the debug level
169 -n, --no-action Dry run. No action is actually taken.
170 -P foo, --package foo Don't follow dpkg-divert diversions by package foo.
171 -v, --verbose Make the script verbose
172 --three-way Register this file in the cache, and turn on the
173 diff3 option allowing the merging of maintainer
174 changes into a (potentially modified) local
175 configuration file. )
176 --state-dir bar Set the state directory to bar instead of the
177 default '/var/lib/ucf'. Used mostly for testing.
178 --debconf-ok Indicate that it is ok for ucf to use an already
179 running debconf instance for prompting.
180 --debconf-template bar
181 Specify an alternate, caller-provided debconf
182 template to use for prompting.
183 Usage: $progname -p destination
184 -p, --purge Remove any reference to destination from records
186 By default, the directory the new_file lives in is assumed to be the src-dir,
187 which is where we look for any historical md5sums.
193 ######################################################################
195 ######## file and hash save/restore functions #########
197 ######################################################################
199 for i in $(/usr/bin/seq 6 -1 0); do
200 if [ -e "${statedir}/hashfile.${i}" ]; then
201 if [ "X$docmd" = "XYES" ]; then
202 cp -pf "${statedir}/hashfile.${i}" \
203 "${statedir}/hashfile.$(($i+1))"
205 echo cp -pf "${statedir}/hashfile.${i}" \
206 "${statedir}/hashfile.$(($i+1))"
210 if [ -e "$statedir/hashfile" ]; then
211 if [ "X$docmd" = "XYES" ]; then
212 cp -pf "$statedir/hashfile" "$statedir/hashfile.0"
214 echo cp -pf "$statedir/hashfile" "$statedir/hashfile.0"
216 if [ "X$docmd" = "XYES" ]; then
218 if [ "X$VERBOSE" != "X" ]; then
219 echo >&2 "grep -Ev [[:space:]]${safe_dest_file}$ $statedir/hashfile"
220 grep -Ev "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" >&2 \
223 #echo "grep -Ev [[:space:]]${safe_dest_file}$ $statedir/hashfile"
224 grep -Ev "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" > \
225 "$statedir/hashfile.tmp" || true;
226 if [ "X$docmd" = "XYES" ]; then
227 mv -f "$statedir/hashfile.tmp" "$statedir/hashfile"
229 echo mv -f "$statedir/hashfile.tmp" "$statedir/hashfile"
234 test -n "$VERBOSE" && echo >&2 "The cache file is $cached_file"
235 if [ ! -z "$cached_file" -a -f "$statedir/cache/$cached_file" ]; then
236 $action rm -f "$statedir/cache/$cached_file"
241 for i in $(/usr/bin/seq 6 -1 0); do
242 if [ -e "${statedir}/hashfile.${i}" ]; then
243 if [ "X$docmd" = "XYES" ]; then
244 cp -pf "${statedir}/hashfile.${i}" \
245 "${statedir}/hashfile.$(($i+1))"
247 echo cp -pf "${statedir}/hashfile.${i}" \
248 "${statedir}/hashfile.$(($i+1))"
252 if [ -e "$statedir/hashfile" ]; then
253 if [ "X$docmd" = "XYES" ]; then
254 cp -pf "$statedir/hashfile" "$statedir/hashfile.0"
256 echo cp -pf "$statedir/hashfile" "$statedir/hashfile.0"
258 if [ "X$docmd" = "XYES" ]; then
260 if [ "X$VERBOSE" != "X" ]; then
261 echo >&2 "(grep -Ev \"[[:space:]]${safe_dest_file}$\" \"$statedir/hashfile\";"
262 grep -Ev "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" >&2 || true;
263 md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|" >&2;
265 grep -Ev "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" > \
266 "$statedir/hashfile.tmp" || true;
267 md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|" >> \
268 "$statedir/hashfile.tmp";
269 mv -f "$statedir/hashfile.tmp" "$statedir/hashfile"
272 echo "(grep -Ev \"[[:space:]]${safe_dest_file}$\" \"$statedir/hashfile\""
273 echo " md5sum \"$orig_new_file\" | sed \"s|$orig_new_file|$dest_file|\"; "
274 echo ") | sort > \"$statedir/hashfile\""
277 if [ "X$docmd" = "XYES" ]; then
278 md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|" > \
281 echo " md5sum \"$orig_new_file\" | sed \"s|$orig_new_file|$dest_file|\" >" \
282 "\"$statedir/hashfile\""
285 file_size=$(stat -c '%s' "$orig_new_file")
286 if [ "X$THREEWAY" != "X" ] || [ "$file_size" -lt 25600 ]; then
287 $action cp -pf "$orig_new_file" "$statedir/cache/$cached_file"
289 # cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
292 replace_conf_file () {
293 # do not mangle $dest_file since it's the one registered in the hashfile
294 # or we have been ask to register
295 real_file="$dest_file"
296 if [ -L "$dest_file" ]; then
297 real_file="$(readlink -nf $dest_file || :)"
298 if [ "x$real_file" = "x" ]; then
299 echo >&2 "$dest_file is a broken symlink!"
300 $action rm -f "$dest_file";
301 real_file="$dest_file"
304 if [ -e "$real_file" ]; then
305 if [ -z "$RETAIN_OLD" ]; then
306 #echo "Saving ${real_file}.${OLD_SUFFIX}, in case."
307 if [ "x$VERBOSE" != "x" ]; then
308 echo >&2 "Not saving ${real_file}, since it was unmodified"
311 $action cp -pf $selinux "${real_file}" "${real_file}.${OLD_SUFFIX}"
314 if [ -e "${real_file}" ]; then
315 # Do not change the permissions and attributes of the destination
316 $action cp -f $selinux "$new_file" "${real_file}"
318 # No destination file exists
319 $action cp -pf $selinux "$new_file" "${real_file}"
324 # Escape single quotes in the arguments passed in
326 printf "%s\n" "$1" | sed -e "s,','\\\\'',g"
331 ######################################################################
333 ######## Command line args #########
335 ######################################################################
337 # Long term variables#
345 statedir='/var/lib/ucf';
348 DIST_SUFFIX="ucf-dist"
351 ERR_SUFFIX="merge-error"
352 # save up the cmdline with proper quoting/escaping
354 saved="${saved:+$saved }'$(quote_single "$arg")'"
357 # Note that we use `"$@"' to let each command-line parameter expand to a
358 # separate word. The quotes around `$@' are essential!
359 # We need TEMP as the `eval set --' would nuke the return value of getopt.
360 TEMP=$(getopt -a -o hs:d::D::npP:Zv -n "$progname" \
361 --long help,src-dir:,sum-file:,dest-dir:,debug::,DEBUG::,no-action,package:,purge,verbose,three-way,debconf-ok,debconf-template:,state-dir: \
364 # Note the quotes around `$TEMP': they are essential!
369 -h|--help) usageversion; exit 0 ;;
370 -n|--no-action) action='echo'; docmd='NO'; shift ;;
371 -v|--verbose) VERBOSE=1; shift ;;
373 opt_package="$2"; shift 2 ;;
375 opt_source_dir="$2"; shift 2 ;;
377 opt_old_mdsum_file="$2"; shift 2 ;;
379 opt_state_dir="$2"; shift 2 ;;
381 override_template="$2"; shift 2 ;;
382 -D|-d|--debug|--DEBUG)
383 # d has an optional argument. As we are in quoted mode,
384 # an empty parameter will be generated if its optional
385 # argument is not found.
387 "") setq DEBUG 1 "The Debug value"; shift 2 ;;
388 *) setq DEBUG "$2" "The Debug value"; shift 2 ;;
390 -p|--purge) PURGE=YES; shift ;;
391 --three-way) THREEWAY=YES; shift ;;
392 --debconf-ok) DEBCONF_OK=YES; shift ;;
393 -Z) selinux='-Z'; shift ;;
395 *) echo >&2 "Internal error!" ; exit 1 ;;
400 ######################################################################
402 ######## Sanity checking #########
404 ######################################################################
405 # Need to run as root, or else the
406 if test "$(id -u)" != 0; then
407 if [ "$docmd" = "YES" ]; then
408 echo "$progname: Need to be run as root." >&2
409 echo "$progname: Setting up no action mode." >&2
410 action='echo'; docmd='NO';
414 if [ "X$PURGE" = "XYES" ]; then
416 echo >&2 "*** ERROR: Need exactly one argument when purging, got $#";
422 if [ -e "$temp_dest_file" ]; then
423 setq dest_file "$(readlink -q -m $temp_dest_file)" "The Destination file";
425 setq dest_file "$temp_dest_file" "The Destination file";
429 echo >&2 "*** ERROR: Need exactly two arguments, got $#";
437 if [ ! -e "${temp_new_file}" ]; then
438 echo >&2 "Error: The new file ${temp_new_file} does not exist!";
441 setq new_file "$(readlink -q -m $temp_new_file)" "The new file";
442 if [ -e "$temp_dest_file" ]; then
443 setq dest_file "$(readlink -q -m $temp_dest_file)" "The Destination file";
445 setq dest_file "$temp_dest_file" "The Destination file";
449 # Follow dpkg-divert as though we are installed as part of $opt_package
450 divert_line=$(dpkg-divert --listpackage "$dest_file")
451 if [ -n "$divert_line" ]; then
452 # name of the package or 'LOCAL' for a local diversion
453 divert_package="$divert_line"
455 if [ "$divert_package" != "$opt_package" ]; then
456 dest_file=$(dpkg-divert --truename "$dest_file")
459 safe_dest_file=$(echo "$dest_file" | perl -nle 'print "\Q$_\E\n"')
462 ######################################################################
464 ######## Set Default Values #########
466 ######################################################################
467 # Load site defaults and over rides.
468 if [ -f /etc/ucf.conf ]; then
472 # Command line, env variable, config file, or default
473 if [ ! "x$opt_source_dir" = "x" ]; then
474 setq source_dir "$opt_source_dir" "The Source directory"
475 elif [ ! "x$UCF_SOURCE_DIR" = "x" ]; then
476 setq source_dir "$UCF_SOURCE_DIR" "The Source directory"
477 elif [ ! "x$conf_source_dir" = "x" ]; then
478 setq source_dir "$conf_source_dir" "The Source directory"
480 if [ "X$new_file" != "X" ]; then
481 setq source_dir "$(dirname $new_file)" "The Source directory"
483 setq source_dir "/tmp" "The Source directory"
488 if [ "X$PAGER" != "X" ] && which "$PAGER" >/dev/null 2>&1 ; then
489 my_pager="$(which $PAGER)";
490 elif [ -s /usr/bin/pager ] &&
491 [ "X$(readlink -e /usr/bin/pager || :)" != "X" ]; then
492 my_pager=/usr/bin/pager
493 elif [ -x /usr/bin/sensible-pager ]; then
494 my_pager=/usr/bin/sensible-pager
495 elif [ -x /bin/more ]; then
502 # Command line, env variable, config file, or default
503 if [ ! "x$opt_state_dir" = "x" ]; then
504 setq statedir "$opt_state_dir" "The State directory"
505 elif [ ! "x$UCF_STATE_DIR" = "x" ]; then
506 setq statedir "$UCF_STATE_DIR" "The State directory"
507 elif [ ! "x$conf_state_dir" = "x" ]; then
508 setq statedir "$conf_state_dir" "The State directory"
510 setq statedir '/var/lib/ucf' "The State directory"
513 # Command line, env variable, config file, or default
514 if [ ! "x$opt_force_conffold" = "x" ]; then
515 setq force_conffold "$opt_force_conffold" "Keep the old file"
516 elif [ ! "x$UCF_FORCE_CONFFOLD" = "x" ]; then
517 setq force_conffold "$UCF_FORCE_CONFFOLD" "Keep the old file"
518 elif [ ! "x$conf_force_conffold" = "x" ]; then
519 setq force_conffold "$conf_force_conffold" "Keep the old file"
524 # Command line, env variable, config file, or default
525 if [ ! "x$opt_force_conffnew" = "x" ]; then
526 setq force_conffnew "$opt_force_conffnew" "Replace the old file"
527 elif [ ! "x$UCF_FORCE_CONFFNEW" = "x" ]; then
528 setq force_conffnew "$UCF_FORCE_CONFFNEW" "Replace the old file"
529 elif [ ! "x$conf_force_conffnew" = "x" ]; then
530 setq force_conffnew "$conf_force_conffnew" "Replace the old file"
535 # Command line, env variable, config file, or default
536 if [ ! "x$opt_force_conffmiss" = "x" ]; then
537 setq force_conffmiss "$opt_force_conffmiss" "Replace any missing files"
538 elif [ ! "x$UCF_FORCE_CONFFMISS" = "x" ]; then
539 setq force_conffmiss "$UCF_FORCE_CONFFMISS" "Replace any missing files"
540 elif [ ! "x$conf_force_conffmiss" = "x" ]; then
541 setq force_conffmiss "$conf_force_conffmiss" "Replace any missing files"
546 if [ -n "$opt_old_mdsum_file" ]; then
547 setq old_mdsum_file "$opt_old_mdsum_file" "The md5sum is found here"
548 elif [ ! "x$UCF_OLD_MDSUM_FILE" = "x" ]; then
549 setq old_mdsum_file "$UCF_OLD_MDSUM_FILE" "The md5sum is found here"
550 elif [ ! "x$conf_old_mdsum_file" = "x" ]; then
551 setq old_mdsum_file "$conf_old_mdsum_file" "Replace the old file"
552 elif [ ! "x${new_file}" = "x" ]; then
553 old_mdsum_file="$source_dir/$(basename ${new_file}).md5sum";
559 ######################################################################
561 ######## More Sanity checking #########
563 ######################################################################
565 # someone's hack: always use new file!
568 if [ "X$force_conffold" != "X" -a "X$force_conffnew" != "X" ]; then
569 echo >&2 "Error: Only one of force_conffold and force_conffnew should";
574 # VERBOSE of 0 is supposed to be the same as not setting VERBOSE
575 if [ "X$VERBOSE" = "X0" ]; then
581 if [ -e "$statedir/hashfile" -a ! -w "$statedir/hashfile" ]; then
582 echo >&2 "ucf: do not have write privilege to the state data"
583 if [ "X$docmd" = "XYES" ]; then
588 if [ ! -d $statedir/cache ]; then
589 $action mkdir -p $statedir/cache ;
592 # test and see if this file exists in the database
593 if [ -e "$statedir/hashfile" ]; then
594 if [ "X$VERBOSE" != "X" ]; then
595 echo >&2 "The hash file exists"
596 echo >&2 "grep -E" "[[:space:]]${safe_dest_file}$" "$statedir/hashfile"
597 grep -E "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" >&2 || true
599 lastsum=$(grep -E "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" | \
603 if [ ! "x${new_file}" = "x" ]; then
604 old_mdsum_dir="$source_dir/"$(basename "${new_file}")".md5sum.d";
609 cached_file="$(echo $dest_file | tr / :)"
610 ######################################################################
612 ######## Debugging dump #########
614 ######################################################################
616 if [ $DEBUG -gt 0 ]; then
618 The new start file is \`$new_file\'
619 The destination is \`$dest_file\' (\`$safe_dest_file\')
620 The history is kept under \'$source_dir\'
621 The file may be cached at \'$statedir/cache/$cached_file\'
623 if [ -s "$dest_file" ]; then
624 echo "The destination file exists, and has md5sum:"
627 echo "The destination file does not exist."
629 if [ "X$lastsum" != "X" ]; then
630 echo "The old md5sum exists, and is:"
633 echo "The old md5sum does not exist."
634 if [ -d "$old_mdsum_dir" -o -f "$old_mdsum_file" ]; then
635 echo "However, there are historical md5sums around."
638 if [ -e "$new_file" ]; then
639 echo "The new file exists, and has md5sum:"
642 echo "The new file does not exist."
644 if [ -d "$old_mdsum_dir" ]; then
645 echo "The historical md5sum dir $old_mdsum_dir exists"
646 elif [ -f "$old_mdsum_file" ]; then
647 echo "The historical md5sum file $old_mdsum_file exists"
649 echo "Historical md5sums are not available"
653 ######################################################################
655 ######## Short circuit if we are purging #########
657 ######################################################################
659 if [ "X$PURGE" = "XYES" ]; then
660 if [ "X$VERBOSE" != "X" ]; then
661 echo >&2 "Preparing to purge ${dest_file}"
668 # now we can restore $@
671 ######################################################################
673 ######## DebConf stuff #########
675 ######################################################################
677 # Is debconf already running? Kinda tricky, because it will be after the
678 # confmodule is sourced, so only test before that.
679 if [ -z "$DEBCONF_ALREADY_RUNNING" ]; then
680 if [ "$DEBIAN_HAS_FRONTEND" ]; then
681 DEBCONF_ALREADY_RUNNING='YES'
683 DEBCONF_ALREADY_RUNNING='NO'
687 export DEBCONF_ALREADY_RUNNING
689 if [ -z "$DEBCONF_OK" ]; then
690 if [ "$DEBCONF_ALREADY_RUNNING" = 'YES' ]; then
697 # Time to start nagging the users who call ucf without debconf-ok
698 if [ "$DEBCONF_ALREADY_RUNNING" = 'YES' ] && [ "$DEBCONF_OK" = NO ]; then
699 # Commented out for now, uncomment after a while to begin nagging
700 # maintainers to fix their scripts.
703 *** WARNING: ucf was run from a maintainer script that uses debconf, but
704 the script did not pass --debconf-ok to ucf. The maintainer
705 script should be fixed to not stop debconf before calling ucf,
706 and pass it this parameter. For now, ucf will revert to using
707 old-style, non-debconf prompting. Ugh!
709 Please inform the package maintainer about this problem.
713 # Start up debconf or at least get the db_* commands available
714 if [ -e /usr/share/debconf/confmodule ]; then
715 if test "$(id -u)" = 0; then
716 . /usr/share/debconf/confmodule
718 # Load our templates, just in case our template has
719 # not been loaded or the Debconf DB lost or corrupted
720 # since then, but only if it is OK to use debconf.
721 if [ "$DEBCONF_OK" = 'YES' ]; then
722 db_x_loadtemplatefile "$(dpkg-query --control-path ucf templates)" ucf
725 echo >&2 "$progname: Not loading confmodule, since we are not running as root."
727 # Only set the title if debconf was not already running.
728 # If it was running, then we do not want to clobber the
729 # title used for configuring the whole package with debconf.
730 if [ "$DEBCONF_ALREADY_RUNNING" = 'NO' ]; then
731 if ! db_settitle ucf/title 2>/dev/null; then
732 # Older debconf that does not support that command.
733 if test "$(id -u)" = 0; then
734 db_title "Modified configuration file"
736 echo >&2 "$progname: Not changing title, since we are not running as root."
744 ######################################################################
746 ######## Start Processing #########
748 ######################################################################
750 orig_new_file="$new_file" # Since sometimes we replace the newfile below
751 newsum=$(md5sum "$new_file" | awk '{print $1}')
753 # Determine the action for the current file. The default is to ask,
754 # with non-replacement being the norm.
755 # If the config dir exists
756 # if file in always overwrite, state +=1;
758 # if file in never overwrite, state +=2;
760 # if file in ask; state +=4
762 # if state == 0; then state = default
765 # if state == 2; exit
766 # if state == 1; then replace_conffile; exit
768 ######################################################################
770 ######## Do the replacement #########
772 ######################################################################
773 # Step 1: If we have no record of this file, and dest file
774 # does, We need to determine how to initialize the
775 # ${old_mdsum_prefix}.old file..
776 if [ -e "$dest_file" ]; then
777 destsum=$(md5sum "$dest_file" | awk '{print $1}');
778 if [ "X$lastsum" = "X" ]; then
779 # a: If we have a directory containing historical md5sums of this
780 # file in question, we should look and see if the currently
781 # installed file matches any of the old md5sums; in which case
782 # it can be silently replaced.
783 if [ -d "$old_mdsum_dir" -o -f "$old_mdsum_file" ]; then
784 if [ -d "$old_mdsum_dir" ]; then
785 for file in ${old_mdsum_dir}/*; do
786 oldsum="$(awk '{print $1}' $file)";
787 if [ "$oldsum" = "$destsum" ]; then
788 if [ "X$force_conffold" = "X" ]; then
789 # Bingo! replace, set the md5sum, and we are done
790 if [ "X$VERBOSE" != "X" ]; then
792 "Replacing config file $dest_file with new version"
798 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
803 elif [ -f "$old_mdsum_file" ]; then
804 oldsum=$(grep -E "^${destsum}" "$old_mdsum_file" || true)
805 if [ "X$oldsum" != "X" ]; then
807 if [ "X$force_conffold" = "X" ]; then
808 if [ "X$VERBOSE" != "X" ]; then
810 "Replacing config file $dest_file with new version"
816 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
821 # Well, nothing matched. We now check to see if the
822 # maintainer has an opinion on how to set the ``md5sum of the
823 # previously installed version'', since we have no way of
824 # determining that automatically. Please note that unless
825 # there are limited number of previously released packages
826 # (like just one), the maintainer is also making a guess at
827 # this point by supplying a historical md5sum default file.
828 if [ "X$VERBOSE" != "X" ]; then
829 echo >&2 "Historical md5sums did not match."
831 if [ -d "$old_mdsum_dir" ]; then
832 if [ -e "${old_mdsum_dir}/default" ]; then
833 if [ "X$VERBOSE" != "X" ]; then
834 echo >&2 "However, a default entry exists, using it."
836 lastsum="$(awk '{print $1;}' ${old_mdsum_dir}/default)"
839 elif [ -f "$old_mdsum_file" ]; then
840 oldsum=$(grep -E "[[:space:]]default$" "$old_mdsum_file" | \
842 if [ "X$oldsum" != "X" ]; then
850 # At this point, we are almost certain that either the
851 # historical record of md5sums is not complete, or the user has
852 # changed the configuration file. Rather than guessing and
853 # chosing one of the historical md5sums, we fall through to the
854 # solution used if there had been no historical md5sums
856 if [ "X$lastsum" = "X" ]; then
857 # b: We do not have a historical list of md5sums, or none
858 # matched, and we still need to initialize the
859 # ${old_mdsum_prefix}.old file. We can't determine whther or
860 # not they made any changes, so we err on the side of caution
862 if [ "X$VERBOSE" != "X" ]; then
863 echo >&2 "No match found, we shall ask."
865 lastsum='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
866 fi # the old md5sum file does not exist, and the historical
868 fi # the old md5sum file does not exist (bug))
869 else # "$dest_file" does not exist
870 # Step 2: If destfile does not exist, create it, set the file
871 # "${old_mdsum_prefix}.old" to the md5sum of the new file, and we
873 if [ "X$lastsum" = "X" ]; then
874 # Ok, so there is no indication that the package was ever
875 # installed on this machine.
877 echo >&2 "Creating config file $dest_file with new version"
880 elif [ "$lastsum" = "$newsum" ]; then
881 # OK, new version of the file is the same as the last version
882 # we saw. Since the user apparently has deleted the file,
883 # nothing needs be done, unless we have been told differently
884 if [ "X$force_conffmiss" != "X" ]; then
886 echo >&2 "Recreating deleted config file $dest_file with new version, as asked"
890 echo >&2 "Not replacing deleted config file $dest_file";
894 # OK. New upstream version.
895 if [ "X$force_conffmiss" != "X" ]; then
896 # User has said to replace missing files, so we do so, no
899 echo >&2 "Recreating deleted config file $dest_file with new version, as asked"
903 # Even though the user has deleted this file, they should
904 # be asked now, unless specified otherwise.
905 if [ "X$force_conffold" = "X" ]; then
906 destsum='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
914 # Here, the destfile exists.
916 # step 3: If the old md5sum and the md5sum of the new file
917 # do not match, we need to take action.
918 if [ "$lastsum" = "$newsum" ]; then
919 if [ "X$VERBOSE" != "X" ]; then
920 echo >&2 "md5sums match, nothing needs be done."
922 if [ "X$do_replace_md5sum" != "X" ]; then
925 exit 0; # Hah. Match. We are done.
927 # a: If the md5sum of the dest file is the same as lastsum, replace the
928 # destfile, saying we are replacing old config files
929 if [ "$destsum" = "$lastsum" ]; then
930 if [ "X$force_conffold" = "X" ]; then
931 echo >&2 "Replacing config file $dest_file with new version"
936 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
940 # b: If the md5sum of the dest file differs from lastsum, we need to ask
941 # the user what action to take.
942 if [ "X$force_conffnew" != "X" ]; then
943 echo >&2 "Replacing config file $dest_file with new version"
944 echo >&2 "since you asked for it."
945 if [ "$destsum" = "$newsum" ]; then
946 echo >&2 "The new and the old files are identical, AFAICS"
948 echo >&2 "The new and the old files are different"
953 if [ "X$force_conffold" != "X" ]; then
955 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
958 # c: If the destination file is the same as the new maintianer provided one,
959 # we need do nothing.
960 if [ "$newsum" = "$destsum" ]; then
961 if [ "X$VERBOSE" != "X" ]; then
962 echo >&2 "md5sums of the file in place matches, nothing needs be done."
965 exit 0; # Hah. Match. We are done.
970 while [ "X$done" = "XNO" ]; do
971 if [ "$DEBCONF_OK" = "YES" ] && [ "$DEBIAN_HAS_FRONTEND" ]; then
972 # Use debconf to prompt.
973 if [ -e "$statedir/cache/$cached_file" ] && [ "X$THREEWAY" != "X" ]; then
974 templ=ucf/changeprompt_threeway
976 templ=ucf/changeprompt
978 if [ "X$override_template" != "X" ]; then
979 choices="$(db_metaget $templ Choices-C)"
980 choices2="$(db_metaget $override_template Choices-C)"
981 if [ "$choices" = "$choices2" ]; then
982 templ=$override_template
985 db_fset "$templ" seen false
987 db_subst "$templ" FILE "$dest_file"
988 db_subst "$templ" NEW "$new_file"
989 db_subst "$templ" BASENAME "$(basename $dest_file)"
990 db_input critical "$templ" || true
992 # The current ucf interface does not provide a way for it
993 # to tell its caller that the user chose to back up.
994 # However, we could get here, if the caller turned on
995 # debconf's backup capb. The best thing to do seems to be
996 # to ignore requests to back up.
1002 echo >&2 "Need debconf to interact"
1004 ########################################################################################
1005 # # Prompt without using debconf. #
1006 # cat >&2 <<EOPRMT #
1007 # Configuration file \`$dest_file' #
1008 # ==> File on system created by you or by a script. #
1009 # ==> File also in package provided by package maintainer. #
1010 # What would you like to do about it ? Your options are: #
1011 # Y or I : install the package maintainer's version #
1012 # N or O : keep your currently-installed version #
1013 # D : show the differences between the versions #
1014 # S : show the side-by-side differences between the versions #
1016 # if [ "X$THREEWAY" != "X" -a -e "$statedir/cache/$cached_file" ]; then #
1018 # 3 or T : show a three way difference between current, older, #
1019 # and new versions of the file #
1020 # M : Do a 3 way merge between current, older, #
1021 # and new versions of the file [Very Experimental] #
1024 # cat >&2 <<EOPEND #
1025 # Z : start a new shell to examine the situation #
1026 # The default action is to keep your current version. #
1028 # if [ "X$THREEWAY" != "X" -a -e "$statedir/cache/$cached_file" ]; then #
1029 # echo -n >&2 "*** " $(basename "$dest_file") \ #
1030 # " (Y/I/N/O/D/3/T/M/Z) [default=N] ?" #
1032 # echo -n >&2 "*** " $(basename "$dest_file") \ #
1033 # " (Y/I/N/O/D/Z) [default=N] ?" #
1035 # read -e ANSWER </dev/tty #
1036 ########################################################################################
1040 install_new|y|Y|I|i)
1041 echo >&2 "Replacing config file $dest_file with new version"
1047 DIFF="$(run_diff diff -uBbwt "$dest_file" "$new_file")"
1051 DIFF="$(run_diff sdiff -BbW "$dest_file" "$new_file")"
1054 diff_threeway|3|t|T)
1055 if [ -e "$statedir/cache/$cached_file" \
1056 -a "X$THREEWAY" != "X" ]; then
1057 if [ -e "$dest_file" ]; then
1058 DIFF="$(diff3 -L Current -L Older -L New -A \
1059 "$dest_file" "$statedir/cache/$cached_file" \
1060 "$new_file")" || true
1062 DIFF="$(diff3 -L Current -L Older -L New -A \
1063 /dev/null "$statedir/cache/$cached_file" \
1064 "$new_file")" || true
1068 DIFF="$(run_diff diff -uBbwt "$dest_file" "$new_file")"
1073 echo >&2 "Merging changes into the new version"
1074 if [ -e "$statedir/cache/$cached_file" \
1075 -a "X$THREEWAY" != "X" ]; then
1077 diff3 -L Current -L Older -L New -m \
1078 "$dest_file" "$statedir/cache/$cached_file" \
1079 "$new_file" > "$dest_file.${NEW_SUFFIX}" || ret=$?
1082 new_file="$dest_file.${NEW_SUFFIX}"
1085 rm -f "$dest_file.${NEW_SUFFIX}" # don't need this around no mo'
1089 mv "$dest_file.${NEW_SUFFIX}" "$dest_file.${ERR_SUFFIX}"
1090 db_subst ucf/conflicts_found dest_file "$dest_file"
1091 db_subst ucf/conflicts_found ERR_SUFFIX "${ERR_SUFFIX}"
1092 db_input critical ucf/conflicts_found || true
1098 rm -f "$dest_file.${NEW_SUFFIX}" # don't need this around no mo'
1103 # We explicitly connect STDIN and STDOUT to the
1104 # script's controlling terminal, so even if STDIN is
1105 # fed by a pipe, as is the case when run from
1106 # /usr/bin/debconf, the shell should be fully
1107 # functional. However, the test for a controlling
1108 # terminal uses /usr/bin/tty, which consults only
1109 # STDIN. As far as I can tell, when run from debconf,
1110 # ucf will _never_ use the current terminal. If the
1111 # goal is to check for access to a terminal, the test
1112 # should be for foreground process group membership,
1113 # not a terminal connected to STDIN (tty -s), and not
1114 # a terminal it doesn't necessarily own (tty -s
1115 # </dev/tty). The easiest way do this from a shell is
1116 # probably with /bin/ps.
1117 if ps -o stat= --ppid $$ | grep -q '+'; then
1118 export UCF_CONFFILE_OLD="$dest_file"
1119 export UCF_CONFFILE_NEW="$new_file"
1120 bash >/dev/tty </dev/tty || true
1121 elif [ -n "$DISPLAY" ]; then
1122 x-terminal-emulator || true
1124 # Don't know what to do
1125 echo >&2 "No terminal, and no DISPLAY set, can't fork shell."
1129 keep_current|n|N|o|O|'')
1132 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
1136 if [ "$DEBCONF_OK" = "YES" ]; then
1137 echo "Error: unknown response from debconf:'$RET'" >&2
1141 echo "Please answer with one of the single letters listed." >&2