home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / bin / ucf < prev    next >
Encoding:
Text File  |  2009-01-25  |  34.8 KB  |  1,027 lines

  1. #!/bin/bash
  2. #                               -*- Mode: Sh -*-
  3. # updateConfFile.sh ---
  4. # Author           : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com )
  5. # Created On       : Fri Feb  1 03:41:47 2002
  6. # Created On Node  : glaurung.green-gryphon.com
  7. # Last Modified By : Manoj Srivastava
  8. # Last Modified On : Tue Jun  6 09:48:22 2006
  9. # Last Machine Used: glaurung.internal.golden-gryphon.com
  10. # Update Count     : 186
  11. # Status           : Unknown, Use with caution!
  12. # HISTORY          :
  13. # Description      :
  14. #
  15. # This script attempts to provide conffile like handling for files not
  16. # shipped in a Debian package, but handled by the postinst. Using this
  17. # script, one may ship a bunch of default cofiguration files somewhere
  18. # in /usr (/usr/share/<pkg> is a good location), and maintain files in
  19. # /etc.
  20. #
  21. # The motivation for this script was to provide conffile like handling
  22. # for start files for emacs lisp packages (for example,
  23. # /etc/emacs21/site-stard.d/50psgml-init.el) These start files are not
  24. # shipped with the package, instead, they are installed during the
  25. # post installation configuration phase by the script
  26. # /usr/lib/emacsen-common/emacs-package-install $package_name.
  27. #
  28. # This script is meant to be invoked by the packages install script at
  29. # /usr/lib/emacsen-common/packages/install/$package_name for each
  30. # flavour of installed emacsen by calling it with the proper values of
  31. # new file (/usr/share/emacs/site-lisp/<pkg>/<pkg>-init.el), and dest file
  32. # (/etc/emacs21/site-stard.d/50<pkg>-init.el)), and it should do the rest.
  33. #
  34.  
  35. # make sure we exit on error
  36. set -e
  37.  
  38. # set the version and revision
  39. progname="`basename \"$0\"`"
  40. pversion='$Revision: 1.26 $'
  41.  
  42. ######################################################################
  43. ########                                                     #########
  44. ########              Utility functions                      #########
  45. ########                                                     #########
  46. ######################################################################
  47. setq() {
  48.     # Variable Value Doc_string
  49.     if [ "x$2" = "x" ]; then
  50.     echo >&2 "$progname: Unable to determine $3"
  51.     exit 1;
  52.     else
  53.     if [ "x$VERBOSE" != "x" ]; then
  54.         echo >&2 "$progname: $3 is $2";
  55.     fi
  56.     eval "$1=\"\$2\"";
  57.     fi
  58. }
  59.  
  60. # Use debconf to show the differences
  61. show_diff() {
  62.     if [ -z "$1" ]; then
  63.     DIFF="There are no non-white space differences in the files."
  64.     else
  65.         if  [ 99999 -lt $(echo $1 | wc -c | awk '{print $1; }') ]; then
  66.             DIFF="The differences between the files are too large to display."
  67.         else
  68.             DIFF="$1"
  69.         fi
  70.     fi
  71.     if [ "$DEBCONF_OK" = "YES" ] && [ "$DEBIAN_HAS_FRONTEND" ]; then
  72.     templ=ucf/show_diff
  73.     db_capb escape
  74.     db_subst $templ DIFF "$(printf %s "$DIFF" | debconf-escape -e)"
  75.     db_input critical $templ || true
  76.     db_go || true
  77.     db_get $templ
  78.     # may contain sensitive information, so clear
  79.     # immediatly after use so it is never written
  80.     # to disk
  81.     db_reset $templ 
  82.     db_capb
  83.     else
  84.     echo "$DIFF" | sensible-pager
  85.     fi
  86. }
  87.  
  88. withecho () {
  89.         echo " $@" >&2
  90.         "$@"
  91. }
  92.  
  93. usageversion () {
  94.         cat >&2 <<END
  95. Debian GNU/Linux $progname $pversion.
  96.            Copyright (C) 2002-2005 Manoj Srivastava.
  97. This is free software; see the GNU General Public Licence for copying
  98. conditions.  There is NO warranty.
  99.  
  100. Usage: $progname  [options] new_file  destination
  101. Options:
  102.      -h,     --help          print this message
  103.      -s foo, --src-dir  foo  Set the src dir (historical md5sums live here)
  104.              --sum-file bar  Force the historical md5sums to be read from
  105.                              this file.  Overrides any setting of --src-dir.
  106.      -d [n], --debug    [n]  Set the Debug level to N
  107.      -n,     --no-action     Dry run. No action is actually taken.
  108.      -v,     --verbose       Make the script verbose
  109.              --three-way     Register this file in the cache, and turn on the
  110.                              diff3 option allowing the merging of maintainer
  111.                              changes into a (potentially modified) local 
  112.                              configuration file. )
  113.              --state-dir bar Set the state directory to bar instead of the
  114.                              default '/var/lib/ucf'. Used mostly for testing.
  115.              --debconf-ok    Indicate that it is ok for uct to use an already
  116.                              running debconf instance for prompting.
  117.              --debconf-template bar
  118.                              Specify an alternate, caller-provided debconf
  119.                              template to use for prompting.
  120. Usage: $progname  -p  destination
  121.      -p,     --purge         Remove any reference to destination from records
  122.  
  123. By default, the directory the new_file lives in is assumed to be the src-dir,
  124. which is where we look for any historical md5sums.
  125.  
  126. END
  127.     
  128. }
  129.  
  130. ######################################################################
  131. ########                                                     #########
  132. ########        file and hash save/restore functions         #########
  133. ########                                                     #########
  134. ######################################################################
  135. purge_md5sum () {
  136.     for i in $(/usr/bin/seq 6 -1 0); do
  137.     if [ -e "${statedir}/hashfile.${i}" ]; then
  138.         if [ "X$docmd" = "XYES" ]; then
  139.         cp -pf "${statedir}/hashfile.${i}" \
  140.             "${statedir}/hashfile.$(($i+1))"
  141.         else 
  142.         echo cp -pf "${statedir}/hashfile.${i}" \
  143.                           "${statedir}/hashfile.$(($i+1))"
  144.         fi 
  145.     fi 
  146.     done
  147.     if [ -e "$statedir/hashfile" ]; then
  148.     if [ "X$docmd" = "XYES" ]; then
  149.         cp -pf "$statedir/hashfile"  "$statedir/hashfile.0" 
  150.     else
  151.         echo cp -pf "$statedir/hashfile"  "$statedir/hashfile.0" 
  152.     fi
  153.     if [ "X$docmd" = "XYES" ]; then
  154.         set +e
  155.         if [ "X$VERBOSE" != "X" ]; then
  156.         echo "egrep -v [[:space:]]${safe_dest_file}$ $statedir/hashfile"
  157.         egrep -v "[[:space:]]${safe_dest_file}$"  "$statedir/hashfile" \
  158.             || true;
  159.         fi
  160.         #echo "egrep -v [[:space:]]${safe_dest_file}$ $statedir/hashfile"
  161.         egrep -v "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" > \
  162.         "$statedir/hashfile.tmp" || true; 
  163.         if [ "X$docmd" = "XYES" ]; then
  164.         mv -f "$statedir/hashfile.tmp"  "$statedir/hashfile" 
  165.         else
  166.         echo mv -f "$statedir/hashfile.tmp"  "$statedir/hashfile"
  167.         fi
  168.         set -e
  169.     fi
  170.     fi
  171.     test -n "$VERBOSE" && echo "The cache file is $cached_file"
  172.     if [ ! -z "$cached_file" -a -f "$statedir/cache/$cached_file" ]; then
  173.     $action rm -f "$statedir/cache/$cached_file"
  174.     fi
  175. }
  176.  
  177. replace_md5sum () {
  178.     for i in $(/usr/bin/seq 6 -1 0); do
  179.     if [ -e "${statedir}/hashfile.${i}" ]; then
  180.         if [ "X$docmd" = "XYES" ]; then
  181.         cp -pf "${statedir}/hashfile.${i}" \
  182.             "${statedir}/hashfile.$(($i+1))"
  183.         else
  184.         echo cp -pf "${statedir}/hashfile.${i}" \
  185.             "${statedir}/hashfile.$(($i+1))"
  186.         fi
  187.     fi
  188.     done
  189.     if [ -e "$statedir/hashfile" ]; then
  190.     if [ "X$docmd" = "XYES" ]; then
  191.         cp -pf "$statedir/hashfile"  "$statedir/hashfile.0" 
  192.     else
  193.         echo cp -pf "$statedir/hashfile"  "$statedir/hashfile.0" 
  194.     fi
  195.     if [ "X$docmd" = "XYES" ]; then
  196.         set +e
  197.         if [ "X$VERBOSE" != "X" ]; then
  198.         echo "(egrep -v \"[[:space:]]${safe_dest_file}$\" \"$statedir/hashfile\";"
  199.         egrep -v "[[:space:]]${safe_dest_file}$"  "$statedir/hashfile" || true;
  200.          md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|" ;
  201.         fi
  202.         egrep -v "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" > \
  203.         "$statedir/hashfile.tmp" || true; 
  204.         md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|" >> \
  205.         "$statedir/hashfile.tmp"; 
  206.         mv -f "$statedir/hashfile.tmp"  "$statedir/hashfile" 
  207.         set -e
  208.     else
  209.         echo "(egrep -v \"[[:space:]]${safe_dest_file}$\" \"$statedir/hashfile\""
  210.         echo " md5sum \"$orig_new_file\" | sed \"s|$orig_new_file|$dest_file|\"; " 
  211.         echo ") | sort > \"$statedir/hashfile\""
  212.     fi
  213.     else
  214.     if [ "X$docmd" = "XYES" ]; then
  215.         md5sum "$orig_new_file" | sed "s|$orig_new_file|$dest_file|"  > \
  216.         "$statedir/hashfile" 
  217.     else
  218.         echo " md5sum \"$orig_new_file\" | sed \"s|$orig_new_file|$dest_file|\" >" \
  219.         "\"$statedir/hashfile\""
  220.     fi
  221.     fi
  222.     if [ "X$THREEWAY" != "X" ]; then
  223.     $action cp -pf "$orig_new_file" "$statedir/cache/$cached_file"
  224.     fi
  225.     # cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  226. }
  227.  
  228. replace_conf_file () {
  229.     # do not mangle $dest_file since it's the one registered in the hashfile
  230.     # or we have been ask to register
  231.     real_file="$dest_file"
  232.     if [ -L "$dest_file" ]; then
  233.     real_file="$(readlink -nf $dest_file || :)"
  234.     if [ "x$real_file" = "x" ]; then
  235.         echo >&2 "$dest_file is a broken symlink!"
  236.         $action rm -f "$dest_file";
  237.         real_file="$dest_file"
  238.     fi
  239.     fi
  240.     if [ -e "$real_file" ]; then
  241.     if [ -z "$RETAIN_OLD" ]; then
  242.         #echo "Saving  ${real_file}.${OLD_SUFFIX},  in case."
  243.         if [ "x$VERBOSE" != "x" ]; then
  244.         echo >&2 "Not saving ${real_file}, since it was unmodified"
  245.         fi
  246.     else
  247.         $action cp -pf "${real_file}" "${real_file}.${OLD_SUFFIX}"
  248.     fi
  249.     fi
  250.     $action cp -pf "$new_file" "${real_file}"
  251.     replace_md5sum;
  252. }
  253.  
  254.  
  255.  
  256.  
  257. ######################################################################
  258. ########                                                     #########
  259. ########              Command line args                      #########
  260. ########                                                     #########
  261. ######################################################################
  262. #
  263. # Long term variables#
  264. #
  265. docmd='YES'
  266. action='withecho'
  267. action=
  268. DEBUG=0
  269. VERBOSE=''
  270. statedir='/var/lib/ucf';
  271. THREEWAY=
  272.  
  273. DIST_SUFFIX="ucf-dist"
  274. NEW_SUFFIX="ucf-new"
  275. OLD_SUFFIX="ucf-old"
  276.  
  277. # Note that we use `"$@"' to let each command-line parameter expand to a
  278. # separate word. The quotes around `$@' are essential!
  279. # We need TEMP as the `eval set --' would nuke the return value of getopt.
  280. TEMP=`getopt -a -o hs:d::D::nv -n "$progname" \
  281.       --long help,src-dir:,sum-file:,dest-dir:,debug::,DEBUG::,no-action,purge,verbose,three-way,debconf-ok,debconf-template:,state-dir: \
  282.              -- "$@"`
  283.  
  284. if [ $? != 0 ] ; then
  285.     echo "Error handling options.Terminating..." >&2 ;
  286.     exit 1 ;
  287. fi
  288.  
  289. # Note the quotes around `$TEMP': they are essential!
  290. eval set -- "$TEMP"
  291.  
  292. while true ; do
  293.     case "$1" in
  294.     -h|--help) usageversion;                        exit 0 ;;
  295.     -n|--no-action) action='echo'; docmd='NO';      shift  ;;
  296.     -v|--verbose) VERBOSE=1;                        shift  ;;
  297.     -s|--src-dir)
  298.         opt_source_dir="$2";                       shift 2 ;;
  299.     --sum-file)
  300.         opt_old_mdsum_file="$2";          shift 2 ;;
  301.     --state-dir)
  302.         opt_state_dir="$2";                        shift 2 ;;
  303.     --debconf-template)
  304.         override_template="$2";                    shift 2 ;;
  305.     -D|-d|--debug|--DEBUG)
  306.             # d has an optional argument. As we are in quoted mode,
  307.             # an empty parameter will be generated if its optional
  308.             # argument is not found.
  309.         case "$2" in
  310.         "") setq DEBUG 1    "The Debug value"; shift 2 ;;
  311.         *)  setq DEBUG "$2" "The Debug value"; shift 2 ;;
  312.         esac ;;
  313.         -p|--purge) PURGE=YES;                         shift   ;;
  314.        --three-way) THREEWAY=YES;                       shift   ;;
  315.        --debconf-ok) DEBCONF_OK=YES;                    shift   ;;
  316.     --)  shift ;                                   break   ;;
  317.     *) echo >&2 "Internal error!" ; exit 1 ;;
  318.     esac
  319. done
  320. ######################################################################
  321. ########                                                     #########
  322. ########              Sanity checking                        #########
  323. ########                                                     #########
  324. ######################################################################
  325. # Need to run as root, or else the 
  326. if test $(id -u) != 0; then
  327.     if [ "$docmd" = "YES" ]; then
  328.         echo "$progname: Need to be run as root." >&2
  329.         echo "$progname: Setting up no action mode." >&2
  330.         action='echo'; docmd='NO'; 
  331.     fi
  332. fi
  333.  
  334. if [ "X$PURGE" = "XYES" ]; then
  335.     if [ $# != 1 ]; then
  336.     echo >&2 "*** ERROR: Need exactly one argument when purging, got $#";
  337.     echo >&2 ""
  338.     usageversion;
  339.     exit 0 ;        
  340.     fi
  341.     temp_dest_file=$1;
  342.     setq dest_file "$(readlink -q -m $temp_dest_file)" "The Destination file";
  343. else
  344.     if [ $# != 2 ]; then
  345.     echo >&2 "*** ERROR: Need exactly two arguments, got $#";
  346.     echo >&2 ""
  347.     usageversion;
  348.     exit 0 ;
  349.     fi
  350.     temp_new_file=$1;
  351.     temp_dest_file=$2;
  352.  
  353.     if [ ! -e "$temp_new_file" ]; then
  354.     echo >&2 "Error: The new file ${temp_new_file} does not exist!";
  355.     exit 1;
  356.     fi
  357.     setq new_file  "$(readlink -q -m $temp_new_file)"  "The new file";
  358.     setq dest_file "$(readlink -q -m $temp_dest_file)" "The Destination file";
  359. fi
  360.  
  361.  
  362. safe_dest_file=$(echo $dest_file | perl -nle 'print "\Q$_\E\n"')
  363.  
  364.  
  365.  
  366. ######################################################################
  367. ########                                                     #########
  368. ########              Set Default Values                     #########
  369. ########                                                     #########
  370. ######################################################################
  371. # Load site defaults and over rides.
  372. if [ -f /etc/ucf.conf ]; then
  373.     . /etc/ucf.conf
  374. fi
  375.  
  376. # Command line, env variable, config file, or default
  377. if [ ! "x$opt_source_dir" = "x" ]; then
  378.     setq source_dir "$opt_source_dir" "The Source directory"
  379. elif [ ! "x$UCF_SOURCE_DIR" = "x" ]; then
  380.     setq source_dir "$UCF_SOURCE_DIR" "The Source directory"
  381. elif [ ! "x$conf_source_dir" = "x" ]; then
  382.     setq source_dir "$conf_source_dir" "The Source directory"
  383. else
  384.     if [ "X$new_file" != "X" ]; then
  385.     setq source_dir $(dirname "$new_file") "The Source directory"
  386.     else
  387.     setq source_dir /tmp "The Source directory"
  388.     fi
  389.     
  390. fi
  391.  
  392. if [ "X$PAGER" != "X" ] && type -a -p $PAGER >& /dev/null ; then
  393.     my_pager=$(type -a -p $PAGER);
  394. elif [ -s /usr/bin/pager ] && 
  395.      [ "X$(readlink -e /usr/bin/pager || :)" != "X" ]; then
  396.     my_pager=/usr/bin/pager
  397. elif [ -x /usr/bin/sensible-pager ]; then
  398.     my_pager=/usr/bin/sensible-pager
  399. elif [ -x /bin/more ]; then
  400.     my_pager=/bin/more
  401. else
  402.     my_pager=
  403. fi
  404.  
  405.  
  406.  
  407. if [ "X$my_pager" = "X" ]; then
  408.     STOP=YES
  409. elif [ "X$my_pager" = "X/bin/more" ]; then
  410.     STOP=YES
  411. fi
  412.  
  413. # Command line, env variable, config file, or default
  414. if [ ! "x$opt_state_dir" = "x" ]; then
  415.     setq statedir "$opt_state_dir" "The State directory"
  416. elif [ ! "x$UCF_STATE_DIR" = "x" ]; then
  417.     setq statedir "$UCF_STATE_DIR" "The State directory"
  418. elif [ ! "x$conf_state_dir" = "x" ]; then
  419.     setq statedir "$conf_state_dir" "The State directory"
  420. else
  421.     setq statedir '/var/lib/ucf'  "The State directory"    
  422. fi
  423.  
  424. # Command line, env variable, config file, or default
  425. if [ ! "x$opt_force_conffold" = "x" ]; then
  426.     setq force_conffold "$opt_force_conffold" "Keep the old file"
  427. elif [ ! "x$UCF_FORCE_CONFFOLD" = "x" ]; then
  428.     setq force_conffold "$UCF_FORCE_CONFFOLD" "Keep the old file"
  429. elif [ ! "x$conf_force_conffold" = "x" ]; then
  430.     setq force_conffold "$conf_force_conffold" "Keep the old file"
  431. else
  432.     force_conffold=''
  433. fi
  434.  
  435. # Command line, env variable, config file, or default
  436. if [ ! "x$opt_force_conffnew" = "x" ]; then
  437.     setq force_conffnew "$opt_force_conffnew" "Replace the old file"
  438. elif [ ! "x$UCF_FORCE_CONFFNEW" = "x" ]; then
  439.     setq force_conffnew "$UCF_FORCE_CONFFNEW" "Replace the old file"
  440. elif [ ! "x$conf_force_conffnew" = "x" ]; then
  441.     setq force_conffnew "$conf_force_conffnew" "Replace the old file"
  442. else
  443.     force_conffnew=''
  444. fi
  445.  
  446. # Command line, env variable, config file, or default
  447. if [ ! "x$opt_force_conffmiss" = "x" ]; then
  448.     setq force_conffmiss "$opt_force_conffmiss" "Replace any missing files"
  449. elif [ ! "x$UCF_FORCE_CONFFMISS" = "x" ]; then
  450.     setq force_conffmiss "$UCF_FORCE_CONFFMISS" "Replace any missing files"
  451. elif [ ! "x$conf_force_conffmiss" = "x" ]; then
  452.     setq force_conffmiss "$conf_force_conffmiss" "Replace any missing files"
  453. else
  454.     force_conffmiss=''
  455. fi
  456.  
  457. if [ -n "$opt_old_mdsum_file" ]; then
  458.     setq old_mdsum_file "$opt_old_mdsum_file" "The md5sum is found here"
  459. elif [ ! "x$UCF_OLD_MDSUM_FILE" = "x" ]; then
  460.     setq old_mdsum_file "$UCF_OLD_MDSUM_FILE" "The md5sum is found here"
  461. elif [ ! "x$conf_old_mdsum_file" = "x" ]; then
  462.     setq old_mdsum_file "$conf_old_mdsum_file" "Replace the old file"
  463. else
  464.     old_mdsum_file="$source_dir/"$(basename "${new_file}")".md5sum";
  465. fi
  466.  
  467.  
  468. ######################################################################
  469. ########                                                     #########
  470. ########               More Sanity checking                  #########
  471. ########                                                     #########
  472. ######################################################################
  473. if [ "X$force_conffold" != "X" -a "X$force_conffnew" != "X" ]; then
  474.     echo >&2 "Error: Only one of force_conffold and force_conffnew should";
  475.     echo >&2 "       be set";
  476.     exit 1;
  477. fi
  478.  
  479. # VERBOSE of 0 is supposed to be the same as not setting VERBOSE
  480. if [ "X$VERBOSE" = "X0" ]; then
  481.     VERBOSE=''
  482. fi
  483.  
  484.  
  485. #
  486. if [ -e "$statedir/hashfile" -a ! -w "$statedir/hashfile" ]; then
  487.     echo >&2 "ucf: do not have write privilege to the state data"
  488.     if [ "X$docmd" = "XYES" ]; then
  489.     exit 1;
  490.     fi
  491. fi
  492.  
  493. if [ ! -d $statedir/cache ]; then
  494.     $action mkdir -p $statedir/cache ;
  495. fi
  496.  
  497. # test and see if this file exists in the database
  498. if [ -e "$statedir/hashfile" ]; then
  499.     if [ "X$VERBOSE" != "X" ]; then
  500.     echo >&2 "The hash file exists"
  501.     echo egrep "[[:space:]]${safe_dest_file}$" "$statedir/hashfile"
  502.     egrep "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" || true
  503.     fi
  504.     lastsum=$(egrep "[[:space:]]${safe_dest_file}$" "$statedir/hashfile" | \
  505.                    awk '{print $1;}' )
  506. fi
  507.  
  508. old_mdsum_dir="$source_dir/"$(basename "${new_file}")".md5sum.d";
  509. cached_file=$(echo $dest_file | tr / :)
  510. ######################################################################
  511. ########                                                     #########
  512. ########                  Debugging dump                     #########
  513. ########                                                     #########
  514. ######################################################################
  515.  
  516. if [ $DEBUG -gt 0 ]; then
  517.     cat <<EOF
  518. The new start file is      \`$new_file\'
  519. The destination is         \`$dest_file\' (\`$safe_dest_file\')
  520. The history is kept under  \'$source_dir\'
  521. The file may be cached at \'$statedir/cache/$cached_file\'
  522. EOF
  523.     if [ -s "$dest_file" ]; then
  524.     echo "The destination file exists, and has md5sum:"
  525.     md5sum "$dest_file"
  526.     else
  527.     echo "The destination file does not exist."
  528.     fi
  529.     if [ "X$lastsum" != "X" ]; then
  530.     echo "The old md5sum exists, and is:"
  531.     echo $lastsum
  532.     else 
  533.     echo "The old md5sum does not exist."
  534.         if [ -d "$old_mdsum_dir" -o -f "$old_mdsum_file" ]; then
  535.             echo "However, there are historical md5sums around."
  536.         fi
  537.     fi
  538.     if [ -e "$new_file" ]; then
  539.     echo "The new file exists, and has md5sum:"
  540.     md5sum "$new_file"
  541.     else 
  542.     echo "The new file does not exist."
  543.     fi
  544.     if [ -d "$old_mdsum_dir" ]; then
  545.     echo "The historical md5sum dir $old_mdsum_dir exists"
  546.     elif [ -f "$old_mdsum_file" ]; then
  547.     echo "The historical md5sum file $old_mdsum_file exists"
  548.     else
  549.     echo "Historical md5sums are not available"
  550.     fi
  551. fi
  552.  
  553. ######################################################################
  554. ########                                                     #########
  555. ########        Short circuit if we are purging              #########
  556. ########                                                     #########
  557. ######################################################################
  558.  
  559. if [ "X$PURGE" = "XYES" ]; then
  560.     if [ "X$VERBOSE" != "X" ]; then
  561.     echo >&2 "Preparing to purge ${dest_file}"
  562.     fi
  563.     purge_md5sum;
  564.     exit 0;
  565. fi
  566.  
  567.  
  568.  
  569. ######################################################################
  570. ########                                                     #########
  571. ########                  DebConf stuff                      #########
  572. ########                                                     #########
  573. ######################################################################
  574.  
  575. # Is debconf already running? Kinda tricky, because it will be after the
  576. # confmodule is sourced, so only test before that.
  577. if [ -z "$DEBCONF_ALREADY_RUNNING" ]; then
  578.     if [ "$DEBIAN_HAS_FRONTEND" ]; then
  579.     DEBCONF_ALREADY_RUNNING='YES'
  580.     else
  581.     DEBCONF_ALREADY_RUNNING='NO'
  582.     fi
  583. fi
  584.  
  585. export DEBCONF_ALREADY_RUNNING
  586.  
  587. if [ -z "$DEBCONF_OK" ]; then
  588.     if [ "$DEBCONF_ALREADY_RUNNING" = 'YES' ]; then
  589.     DEBCONF_OK='NO'
  590.     else
  591.     DEBCONF_OK='YES'
  592.     fi
  593. fi
  594.  
  595. # Time to start nagging the users who call ucf without debconf-ok
  596. if [ "$DEBCONF_ALREADY_RUNNING"  = 'YES' ] && [ "$DEBCONF_OK" = NO ]; then
  597.     # Commented out for now, uncomment after a while to begin nagging
  598.     # maintainers to fix their scripts.
  599.     cat \
  600. <<END
  601. *** WARNING: ucf was run from a maintainer script that uses debconf, but
  602.              the script did not pass --debconf-ok to ucf. The maintainer
  603.              script should be fixed to not stop debconf before calling ucf,
  604.              and pass it this parameter. For now, ucf will revert to using
  605.              old-style, non-debconf prompting. Ugh!
  606.  
  607.              Please inform the package maintainer about this problem.
  608. END
  609. fi
  610.  
  611. # Start up debconf or at least get the db_* commands available
  612. if [ -e /usr/share/debconf/confmodule ]; then
  613.     if test $(id -u) = 0; then
  614.     . /usr/share/debconf/confmodule
  615.  
  616.     # Load our templates, just in case our template has
  617.     # not been loaded or the Debconf DB lost or corrupted
  618.     # since then, but only if it is OK to use debconf.
  619.         if [ "$DEBCONF_OK" = 'YES' ]; then
  620.             db_x_loadtemplatefile /var/lib/dpkg/info/ucf.templates ucf
  621.         fi
  622.     else
  623.         echo >&2 "$progname: Not loading confmodule, since we are not running as root."
  624.     fi
  625.     # Only set the title if debconf was not already running.
  626.     # If it was running, then we do not want to clobber the
  627.     # title used for configuring the whole package with debconf.
  628.     if [ "$DEBCONF_ALREADY_RUNNING" = 'NO' ]; then
  629.     if ! db_settitle ucf/title 2>/dev/null; then
  630.               # Older debconf that does not support that command.
  631.             if test $(id -u) = 0; then
  632.         db_title "Modified configuration file"
  633.             else
  634.                 echo >&2 "$progname: Not changing title, since we are not running as root."
  635.             fi
  636.     fi
  637.     fi
  638. fi
  639.     
  640.  
  641.  
  642. ######################################################################
  643. ########                                                     #########
  644. ########                Start Processing                     #########
  645. ########                                                     #########
  646. ######################################################################
  647.  
  648. orig_new_file="$new_file"    # Since sometimes we replace the newfile below
  649. newsum=$(md5sum "$new_file" | awk '{print $1}')
  650.  
  651. # Determine the action for the current file. The default is to ask,
  652. # with non-replacement being the norm.
  653. # If the config dir exists
  654. #   if file in always overwrite, state +=1;
  655. #   fi
  656. #   if file in never overwrite, state +=2;
  657. #   fi
  658. #   if file in ask; state +=4
  659. #   fi
  660. #   if state == 0; then state = default
  661. #   if state >= 4; ask
  662. #   if state == 3;  ask
  663. #   if state == 2; exit
  664. #   if state == 1; then replace_conffile; exit
  665.  
  666. ######################################################################
  667. ########                                                     #########
  668. ########               Do the replacement                    #########
  669. ########                                                     #########
  670. ######################################################################
  671. # Step 1: If we have no record of this file, and dest file
  672. #         does, We need to determine how to initialize the
  673. #         ${old_mdsum_prefix}.old file..               
  674. if [ -e "$dest_file" ]; then
  675.     destsum=$(md5sum "$dest_file"  | awk '{print $1}');
  676.     if [ "X$lastsum" = "X" ]; then
  677. #      a: If we have a directory containing historical md5sums of this
  678. #         file in question, we should look and see if the currently
  679. #         installed file matches any of the old md5sums; in which case
  680. #         it can be silently replaced.
  681.     if [ -d "$old_mdsum_dir" -o -f "$old_mdsum_file" ]; then
  682.         if [ -d "$old_mdsum_dir"  ]; then
  683.         for file in ${old_mdsum_dir}/*; do
  684.             oldsum=$(cat "$file"  | awk '{print $1}');
  685.             if [ "$oldsum" = "$destsum"  ]; then
  686.             if [ "X$force_conffold" = "X" ]; then
  687. #                           Bingo! replace, set the md5sum, and we are done 
  688.                 if [ "X$VERBOSE" != "X" ]; then
  689.                 echo >&2 \
  690.                     "Replacing config file $dest_file with new version"
  691.                 fi
  692.                 replace_conf_file;
  693.                 exit 0;
  694.             else
  695.                 replace_md5sum;
  696.                 cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  697.                 exit 0;
  698.             fi
  699.             fi
  700.         done
  701.         elif [ -f "$old_mdsum_file" ]; then
  702.         oldsum=$(egrep "^${destsum}" "$old_mdsum_file" || true)
  703.         if [ "X$oldsum" != "X" ]; then
  704. #                    Bingo
  705.             if [ "X$force_conffold" = "X" ]; then
  706.             if [ "X$VERBOSE" != "X" ]; then
  707.                 echo >&2 \
  708.                 "Replacing config file $dest_file with new version"
  709.             fi
  710.             replace_conf_file;
  711.             exit 0;
  712.             else
  713.             replace_md5sum;
  714.             cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  715.             exit 0;
  716.             fi
  717.         fi
  718.         fi
  719. #       Well, nothing matched. We now check to see if the
  720. #       maintainer has an opinion on how to set the ``md5sum of the
  721. #       previously installed version'', since we have no way of
  722. #       determining that automatically. Please note that unless
  723. #       there are limited number of previously released packages
  724. #       (like just one), the maintainer is also making a guess at
  725. #       this point by supplying a historical md5sum default file. 
  726.         if [ "X$VERBOSE" != "X" ]; then
  727.         echo >&2 "Histotical md5sums did not match."
  728.         fi
  729.         if [ -d "$old_mdsum_dir"  ]; then
  730.         if [ -e "${old_mdsum_dir}/default" ]; then
  731.             if [ "X$VERBOSE" != "X" ]; then
  732.             echo >&2 "However, a default entry exists, using it."
  733.             fi
  734.             lastsum=$(cat "${old_mdsum_dir}/default" | \
  735.             awk '{print $1;}')
  736.             do_replace_md5sum=1;
  737.         fi
  738.         elif [ -f "$old_mdsum_file" ]; then
  739.         oldsum=$(egrep "[[:space:]]default$" "$old_mdsum_file" | \
  740.             awk '{print $1;}')
  741.         if [ "X$oldsum" != "X" ]; then
  742. #                    Bingo
  743.             lastsum=$oldsum;
  744.             do_replace_md5sum=1;
  745.         fi
  746.         fi
  747.     fi
  748.  
  749. #       At this point, we are almost certain that either the
  750. #       historical record of md5sums is not complete, or the user has
  751. #       changed the configuration file. Rather than guessing and
  752. #       chosing one of the historical md5sums, we fall through to the
  753. #       solution used if there had been no historical md5sums
  754. #       directory/file.
  755.     if [ "X$lastsum" = "X" ]; then
  756. #      b: We do not have a historical list of md5sums, or none
  757. #         matched, and we still need to initialize the
  758. #         ${old_mdsum_prefix}.old file. We can't determine whther or
  759. #         not they made any changes, so we err on the side of caution
  760. #         and ask'
  761.         if [ "X$VERBOSE" != "X" ]; then
  762.         echo >&2 "No match found, we shall ask."
  763.         fi
  764.         lastsum='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
  765.     fi # the old md5sum file does not exist, and the historical
  766.        # record failed
  767.     fi # the old md5sum file does not exist (bug))
  768. else  # "$dest_file" does not exist
  769. # Step 2: If destfile does not exist, create it, set the file
  770. #         "${old_mdsum_prefix}.old" to the md5sum of the new file, and we
  771. #         are done
  772.     if [ "X$lastsum" = "X" ]; then
  773.         # Ok, so there is no indication that the package was ever
  774.         # installed on this machine.
  775.     echo >&2 ""
  776.     echo >&2 "Creating config file $dest_file with new version"
  777.     replace_conf_file;
  778.     exit 0;
  779.     elif [ "$lastsum" = "$newsum" ]; then
  780.         # OK, new version of the file is the same as the last version
  781.         # we saw. Since the user apparently has deleted the file,
  782.         # nothing needs be done, unless we have been told differently
  783.         if [ "X$force_conffmiss" != "X" ]; then
  784.             echo >&2 ""
  785.         echo >&2 "Recreating deleted config file $dest_file with new version, as asked"
  786.         replace_conf_file;
  787.         exit 0;
  788.         else
  789.             echo >&2 "Not replacing deleted config file $dest_file";
  790.         fi
  791.         
  792.     else
  793.         # OK. New upstream version. 
  794.         if [ "X$force_conffmiss" != "X" ]; then
  795.             # User has said to replace missing files, so we do so, no
  796.             # questions asked.
  797.             echo >&2 ""
  798.         echo >&2 "Recreating deleted config file $dest_file with new version, as asked"
  799.         replace_conf_file;
  800.         exit 0;
  801.         else
  802.             # Even though the user has deleted this file, they should
  803.             # be asked now, unless specified otherwise.
  804.             if [ "X$force_conffold" = "X" ]; then
  805.                 destsum='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
  806.             else
  807.                 exit 0;
  808.         fi    
  809.         fi            
  810.     fi
  811. fi
  812.  
  813. # Here, the destfile exists.
  814.  
  815. # step 3: If the old md5sum and the md5sum of the new file
  816. #         do not match, we need to take action.
  817. if [ "$lastsum" = "$newsum" ]; then
  818.     if [ "X$VERBOSE" != "X" ]; then
  819.     echo >&2 "md5sums match, nothing needs be done."
  820.     fi
  821.     if [ "X$do_replace_md5sum" != "X" ]; then
  822.     replace_md5sum;
  823.     fi
  824.     exit 0;            # Hah. Match. We are done.
  825. fi
  826. #      a: If the md5sum of the dest file is the same as lastsum, replace the 
  827. #         destfile, saying we are replacing old config files
  828. if [ "$destsum" = "$lastsum" ]; then
  829.     if [ "X$force_conffold" = "X" ]; then
  830.     echo >&2 "Replacing config file $dest_file with new version"
  831.     replace_conf_file;
  832.     exit 0;
  833.     else
  834.     replace_md5sum;
  835.     cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  836.     exit 0;
  837.     fi
  838. else
  839. #      b: If the md5sum of the dest file differs from lastsum, we need to ask
  840. #         the user what action to take.
  841.     if [ "X$force_conffnew" != "X" ]; then
  842.     echo >&2 "Replacing config file $dest_file with new version"
  843.     echo >&2 "even though the files differ, since you asked for it"
  844.     replace_conf_file;
  845.     exit 0;
  846.     fi
  847.     if [ "X$force_conffold" != "X" ]; then
  848.     replace_md5sum;
  849.     cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  850.     exit 0;
  851.     fi
  852. #      c: If the destination file is the same as the new maintianer provided one,
  853. #         we need do nothing.
  854.     if [ "$newsum" = "$destsum" ]; then
  855.     if [ "X$VERBOSE" != "X" ]; then
  856.         echo >&2 "md5sums of the file in place matches, nothing needs be done."
  857.     fi
  858.     replace_md5sum;
  859.     exit 0;            # Hah. Match. We are done.
  860.     fi
  861.  
  862.  
  863.     done='NO';
  864.     while [ "X$done" = "XNO" ]; do
  865.     if [ "$DEBCONF_OK" = "YES" ] && [ "$DEBIAN_HAS_FRONTEND" ]; then
  866.         # Use debconf to prompt.
  867.         if [ "X$THREEWAY" != "X" -a -e "$statedir/cache/$cached_file" ]; then
  868.             templ=ucf/changeprompt_threeway
  869.         else
  870.             templ=ucf/changeprompt
  871.         fi
  872.         if [ "X$override_template" != "X" ]; then
  873.             choices="$(db_metaget $templ Choices-C)"
  874.             choices2="$(db_metaget $override_template Choices-C)"
  875.             if [ "$choices" = "$choices2" ]; then
  876.                 templ=$override_template
  877.             fi
  878.         fi
  879.         db_fset $templ seen false
  880.         db_reset $templ
  881.         db_subst $templ FILE "$dest_file"
  882.         db_subst $templ BASENAME $(basename "$dest_file")
  883.         db_input critical $templ || true
  884.         if ! db_go; then
  885.             # The current ucf interface does not provide a way for it
  886.             # to tell its caller that the user chose to back up.
  887.             # However, we could get here, if the caller turned on
  888.             # debconf's backup capb. The best thing to do seems to be
  889.             # to ignore requests to back up.
  890.             continue
  891.         fi
  892.         db_get $templ
  893.         ANSWER="$RET"
  894.     else
  895.         # Prompt without using debconf.
  896.         cat >&2 <<EOPRMT
  897. Configuration file \`$dest_file'
  898.  ==> File on system created by you or by a script.
  899.  ==> File also in package provided by package maintainer.
  900.    What would you like to do about it ?  Your options are:
  901.     Y or I  : install the package maintainer's version
  902.     N or O  : keep your currently-installed version
  903.       D     : show the differences between the versions
  904.       S     : show the side-by-side differences between the versions
  905. EOPRMT
  906.         if [ "X$THREEWAY" != "X" -a -e "$statedir/cache/$cached_file" ]; then
  907.             cat >&2 <<EOTD
  908.     3 or T  : show a three way difference between current, older,
  909.               and new versions of the file
  910.       M     : Do a 3 way merge between current, older,
  911.               and new versions of the file [Very Experimental]
  912. EOTD
  913.         fi
  914.         cat >&2 <<EOPEND
  915.       Z     : start a new shell to examine the situation
  916.  The default action is to keep your current version.
  917. EOPEND
  918.         if [ "X$THREEWAY" != "X" -a -e "$statedir/cache/$cached_file" ]; then
  919.             echo -n >&2 "*** " $(basename "$dest_file") \
  920.                 " (Y/I/N/O/D/3/T/M/Z) [default=N] ?"
  921.         else
  922.             echo -n >&2 "*** " $(basename "$dest_file") \
  923.                 " (Y/I/N/O/D/Z) [default=N] ?"
  924.         fi
  925.           read -e ANSWER </dev/tty
  926.     fi
  927.  
  928.     case "$ANSWER" in
  929.         install_new|y|Y|I|i)
  930.         echo >&2 "Replacing config file $dest_file with new version"
  931.         RETAIN_OLD=YES
  932.         replace_conf_file;
  933.         exit 0;
  934.         ;;
  935.         diff|D|d)
  936.         if [ -e "$dest_file" ]; then
  937.             DIFF="$(diff -uBbw "$dest_file" "$new_file")" || true
  938.         else
  939.             DIFF="$(diff -uBbw /dev/null "$new_file")" || true
  940.         fi
  941.         show_diff "$DIFF"
  942.         ;;
  943.         sdiff|S|s)
  944.         if [ -e "$dest_file" ]; then
  945.             DIFF="$( sdiff -BbW "$dest_file" "$new_file")"  || true
  946.         else
  947.             DIFF="$(sdiff -BbW /dev/null "$new_file")"  || true
  948.         fi
  949.         show_diff "$DIFF"
  950.         ;;
  951.         diff_threeway|3|t|T)
  952.         if [ -e "$statedir/cache/$cached_file" \
  953.             -a "X$THREEWAY" != "X" ]; then
  954.                     if [ -e "$dest_file" ]; then
  955.                 DIFF="$(diff3 -L Current -L Older -L New -A \
  956.                 "$dest_file" "$statedir/cache/$cached_file" \
  957.                 "$new_file")"  || true
  958.                     else
  959.                         DIFF="$(diff3 -L Current -L Older -L New -A \
  960.                 /dev/null "$statedir/cache/$cached_file" \
  961.                 "$new_file")"  || true
  962.                     fi
  963.             show_diff "$DIFF"
  964.         else 
  965.             if [ -e "$dest_file" ]; then
  966.             DIFF="$(diff -uBbw "$dest_file" "$new_file")"  || true
  967.             else
  968.             DIFF="$(diff -uBbw /dev/null "$new_file")"  || true
  969.             fi
  970.             show_diff "$DIFF"
  971.         fi
  972.         ;;
  973.         merge_threeway|M|m)
  974.         echo >&2 "Merging changes into the new version"
  975.         if [ -e "$statedir/cache/$cached_file" \
  976.             -a "X$THREEWAY" != "X" ]; then
  977.             ret=0
  978.             diff3 -L Current -L Older -L New -m \
  979.             "$dest_file" "$statedir/cache/$cached_file" \
  980.             "$new_file" > $dest_file.${NEW_SUFFIX} || ret=$?
  981.                     case "$ret" in
  982.                         0)
  983.                     new_file="$dest_file.${NEW_SUFFIX}"
  984.                     RETAIN_OLD=YES
  985.                     replace_conf_file;
  986.                             ;;
  987.                         *)
  988.                 echo >&2
  989.                     echo >&2 " Conflicts found! Please edit" \
  990.                     "\`$dest_file' and sort them out manually."
  991.                 echo >&2 " The file \`$dest_file.${NEW_SUFFIX}' has a" \
  992.                     "record of the failed merge of the configuration file."
  993.                 echo >&2
  994.                             exit 3                            
  995.                     esac
  996.         else 
  997.             replace_conf_file;
  998.         fi
  999.                 rm -f "$dest_file.${NEW_SUFFIX}" # don't need this around no mo'
  1000.                 exit 0
  1001.         ;;
  1002.         shell|Z|z)
  1003.         bash >/dev/tty </dev/tty || true
  1004.         ;;
  1005.         keep_current|n|N|o|O|'')
  1006.         replace_md5sum;
  1007.  
  1008.         cp -pf "$orig_new_file" "$dest_file.${DIST_SUFFIX}"
  1009.         exit 0;
  1010.         ;;
  1011.         *)
  1012.         if [ "$DEBCONF_OK" = "YES" ]; then
  1013.             echo "Error: unknown response from debconf:'$RET'" >&2
  1014.             exit 1
  1015.         else
  1016.             echo
  1017.             echo "Please answer with one of the single letters listed." >&2
  1018.             echo
  1019.         fi
  1020.     esac
  1021.     done
  1022. fi
  1023.  
  1024. db_stop
  1025.  
  1026. exit 0;
  1027.