/usr/sbin/confmeld

     1	#!/bin/bash
     2	#---------------------------------------------------------------------
     3	## @Synopsis merge the config files located in the config stage directory to the system.
     4	## @Copyright Other additions/corrections Copyright 2002 by the Source Mage Team
     5	## Script to install staged config files.
     6	#---------------------------------------------------------------------
     7	
     8	#-----
     9	## Help... hmm... I wonder what it does...
    10	#-----
    11	function help">help">help()
    12	{
    13	  cat << EOF
    14	Melds the staged config files from $CONFIG_STAGE_DIRECTORY
    15	
    16	Examples:
    17	confmeld
    18	confmeld -l
    19	confmeld nano
    20	confmeld /etc/sysconfig/facilities
    21	
    22	Optional Parameters:
    23	-h, --help             will just print this help">help">help
    24	-l, --list             will just list all the spells and their staged configs
    25	-c, --list-configs     will just list all the staged configs
    26	-s, --list-spells      will just list all the spells with staged configs
    27	-q, --no-column        don't column the output
    28	-f, --force <action>   always use do <action> when merging
    29	
    30	where <action> can be one of:
    31	discard-new            do nothing
    32	discard-old            trash the old config and install over it
    33	use-old                leave the old config in its place and backup the new one
    34	use-new                backup the old config and install the new one in its place
    35	
    36	Optional arguments:
    37	You can invoke confmeld with a spell name or a staged config as an argument.
    38	Confmeld will then work only on that argument.
    39	
    40	EOF
    41	  exit 1
    42	}
    43	
    44	#--------------------------------------------------------------------
    45	## List all the configs in the config stage root
    46	##
    47	## @stdout a list of all configs in the config stage root
    48	#--------------------------------------------------------------------
    49	function all_config_files()
    50	{
    51	  find $CONFIG_STAGE_DIRECTORY -type f
    52	}
    53	
    54	#--------------------------------------------------------------------
    55	## List all uniq config *filenames* in the config stage directory
    56	##
    57	## @stdout a list of all uniq configs in the stage directory
    58	#--------------------------------------------------------------------
    59	function all_uniq_config_files()
    60	{
    61	  all_config_files |
    62	  sed "s#^$CONFIG_STAGE_DIRECTORY/[^/]*/[^/]*##" |
    63	  sort -u
    64	}
    65	
    66	#--------------------------------------------------------------------
    67	## list all spells that have staged configs
    68	##
    69	## @stdout list of spells that have staged configs
    70	#--------------------------------------------------------------------
    71	function all_spells_with_staged_configs()
    72	{
    73	  all_config_files |
    74	  sed "s#$CONFIG_STAGE_DIRECTORY/*##g" |
    75	  cut -s -d/ -f1 | uniq
    76	}
    77	
    78	#-----
    79	## override column so that we can pass -q to not columnate. Adapted from gaze
    80	#-----
    81	function maybe_column">maybe_column()  {
    82	  if [[ $USE_COLUMN == no ]]; then
    83	    cat
    84	  else
    85	    column "$@"
    86	  fi
    87	}
    88	
    89	#--------------------------------------------------------------------
    90	## nicely list all spells that have staged configs and exit
    91	##
    92	## @stdout list of spells that have staged configs
    93	#--------------------------------------------------------------------
    94	function list_spells_with_staged_configs()
    95	{
    96	  local spells=$(all_spells_with_staged_configs)
    97	
    98	  if [[ -n $spells ]]; then
    99	    message "${MESSAGE_COLOR}Spells with staged configuration files:$SPELL_COLOR"
   100	    echo "$spells" | maybe_column">maybe_column
   101	    message "$DEFAULT_COLOR"
   102	  fi
   103	  exit 0
   104	}
   105	
   106	#--------------------------------------------------------------------
   107	## nicely list all staged configs and exit
   108	##
   109	## @stdout list of staged configs
   110	#--------------------------------------------------------------------
   111	function list_staged_configs()
   112	{
   113	  local configs=$(all_uniq_config_files)
   114	
   115	  if [[ -n $configs ]]; then
   116	    message "${MESSAGE_COLOR}Staged configuration files:$FILE_COLOR"
   117	    echo "$configs" | maybe_column">maybe_column
   118	    message "$DEFAULT_COLOR"
   119	  fi
   120	  exit 0
   121	}
   122	
   123	#--------------------------------------------------------------------
   124	## nicely list all spells and their staged configs
   125	##
   126	## @stdout list of spells and their staged configs
   127	#--------------------------------------------------------------------
   128	function list_all()
   129	{
   130	  local spell config
   131	  for spell in $(all_spells_with_staged_configs); do
   132	    message "${SPELL_COLOR}$spell:$FILE_COLOR"
   133	    all_config_files |
   134	    sed -n "s,^$CONFIG_STAGE_DIRECTORY/$spell/[^/]*,,p" |
   135	    maybe_column">maybe_column
   136	    message "$DEFAULT_COLOR"
   137	  done
   138	  exit 0
   139	}
   140	
   141	#--------------------------------------------------------------------
   142	## parses the path to get specific information about the config file
   143	##
   144	## @param config file path
   145	## @param upvar for spell name
   146	## @param upvar for spell success time
   147	## @param upvar for actual path to file
   148	#--------------------------------------------------------------------
   149	function parse_stage_config_path()
   150	{
   151	  local file=$1
   152	  local __tmp __spell __sdate __path
   153	  __tmp=$(echo $file | sed "s#^$CONFIG_STAGE_DIRECTORY/##")
   154	  __spell=$(echo $__tmp | cut -d/ -f1)
   155	  __sdate=$(echo $__tmp | cut -d/ -f2)
   156	  __path=$(echo $__tmp | cut -d/ -f3-)
   157	  eval "$2=\"$__spell\""
   158	  eval "$3=\"$__sdate\""
   159	  eval "$4=\"$__path\""
   160	}
   161	
   162	#--------------------------------------------------------------------
   163	## Override the merging menu and always use a preset action
   164	##
   165	## @param action
   166	#--------------------------------------------------------------------
   167	function override_changed_config_menu()
   168	{
   169	
   170	  case $1 in
   171	    discard-new) DEFAULT_CHANGED_CONFIG_ACTION=3 ;;
   172	    discard-old) DEFAULT_CHANGED_CONFIG_ACTION=0 ;;
   173	        use-old) DEFAULT_CHANGED_CONFIG_ACTION=2 ;;
   174	        use-new) DEFAULT_CHANGED_CONFIG_ACTION=1 ;;
   175	              *) error_message "${PROBLEM_COLOR}Bad default merge action!$DEFAULT_COLOR"
   176	                 help">help">help ;;
   177	  esac
   178	  PROMPT_DELAY=0
   179	
   180	}
   181	
   182	#--------------------------------------------------------------------
   183	## Final check for removing empty spell directories, so the stage dir
   184	## is left clean
   185	#--------------------------------------------------------------------
   186	function final_cleanup()
   187	{
   188	  find $CONFIG_STAGE_DIRECTORY -mindepth 1 -maxdepth 2 -type d -empty -delete
   189	}
   190	
   191	#--------------------------------------------------------------------
   192	## merge only the passed file
   193	##
   194	## @param config
   195	#--------------------------------------------------------------------
   196	function merge_single_file()
   197	{
   198	  local file=$1 spell sdate target nice_date
   199	
   200	  parse_stage_config_path $file spell sdate target &&
   201	  if [[ -f $file && $target ]]
   202	  then
   203	    # make the $sdate human readable
   204	    # date -d can't use the whole original, so we have to do it in steps
   205	    nice_date=$(date -d ${sdate:0:8} "+%a %d %b %Y")
   206	    nice_date="$nice_date $(date -d ${sdate:8:4} "+%X %Z")"
   207	    message "${SPELL_COLOR}$spell$DEFAULT_COLOR cast on $nice_date has config"
   208	    message "${FILE_COLOR}$file$DEFAULT_COLOR"
   209	    message "to be merged with $FILE_COLOR/$target${DEFAULT_COLOR}\n"
   210	    tablet_set_spell $spell &&
   211	    install_config_file $file $INSTALL_ROOT/$target
   212	    recursive_config_stage_cleanup $file $spell
   213	    echo -e "\n"
   214	  fi
   215	}
   216	
   217	#--------------------------------------------------------------------
   218	## merge only the passed files or spells
   219	##
   220	## @param spell/config
   221	## @param ...
   222	#--------------------------------------------------------------------
   223	function confmeld_partial()
   224	{
   225	  local thing config configs rc=0
   226	
   227	  for thing in "$@"; do
   228	    if codex_does_spell_exist $thing &> /dev/null; then
   229	      # we got a spell
   230	      configs=$(find $CONFIG_STAGE_DIRECTORY/$thing -type f)
   231	    else
   232	      # we got a config or three
   233	      configs=$(find $CONFIG_STAGE_DIRECTORY -type f -wholename "*$thing")
   234	      if [[ -z $configs ]]; then
   235	        error_message "${PROBLEM_COLOR}No such spell or config:$DEFAULT_COLOR $thing"
   236	        rc=1
   237	        break
   238	      fi
   239	    fi
   240	    for config in $configs; do
   241	      merge_single_file "$config"
   242	    done
   243	  done
   244	  final_cleanup
   245	
   246	  exit $rc
   247	}
   248	
   249	#--------------------------------------------------------------------
   250	## merge all the staged configs
   251	#--------------------------------------------------------------------
   252	function confmeld_all()
   253	{
   254	  local spell
   255	
   256	  for file in $(all_config_files)
   257	  do
   258	    merge_single_file "$file"
   259	  done
   260	
   261	  final_cleanup
   262	}
   263	
   264	function process_parameters">process_parameters">process_parameters()
   265	{
   266	  local subroutine arguments
   267	  local mode=$1
   268	  shift
   269	
   270	  while [[ -n $1 ]]; do
   271	    if [[ ${1:0:1} == "-" ]]; then
   272	      case "$1" in
   273	                --help|-h) help">help">help ;;
   274	           --no-column|-q) USE_COLUMN=no ;;
   275	        --list-configs|-c) subroutine=list_staged_configs ;;
   276	         --list-spells|-s) subroutine=list_spells_with_staged_configs ;;
   277	                --list|-l) subroutine=list_all ;;
   278	               --force|-f) subroutine="override_changed_config_menu $2"
   279	                           shift ;;
   280	                        *) help">help">help ;;
   281	      esac
   282	    else
   283	      arguments="$1 $arguments"
   284	    fi
   285	    shift
   286	  done
   287	  [[ $mode == check-only ]] && return 0
   288	  $subroutine
   289	
   290	  [[ $arguments ]] && confmeld_partial $arguments
   291	}
   292	
   293	#--------------------------------------------------------------------
   294	## Main
   295	##
   296	## If there's no arguments get all the config files and start installing
   297	## them to the system using install_config_file
   298	#--------------------------------------------------------------------
   299	function main">main">main">main">main()
   300	{
   301	  local target spell sdate
   302	  local last_spell=""
   303	  local last_sdate=""
   304	
   305	  [[ -d $CONFIG_STAGE_DIRECTORY ]] || mkdir -p $CONFIG_STAGE_DIRECTORY
   306	
   307	  process_parameters">process_parameters">process_parameters normal "$@"
   308	
   309	  confmeld_all
   310	}
   311	
   312	
   313	. /etc/sorcery/config
   314	if  [  "$UID"  -gt  0  ];  then
   315	  # validate the parameters before su-ing, since we may still drop out
   316	  process_parameters">process_parameters">process_parameters check-only "$@"
   317	
   318	  echo  "Enter the root password, please."
   319	  exec su -c "confmeld $@" root
   320	else
   321	  STAGED_INSTALL="off"
   322	  main">main">main">main">main "$@"
   323	fi
   324	
   325	#---------------------------------------------------------------------
   326	##=back
   327	##
   328	##=head1 LICENSE
   329	##
   330	## This software is free software; you can redistribute it and/or modify
   331	## it under the terms of the GNU General Public License as published by
   332	## the Free Software Foundation; either version 2 of the License, or
   333	## (at your option) any later version.
   334	##
   335	## This software is distributed in the hope that it will be useful,
   336	## but WITHOUT ANY WARRANTY; without even the implied warranty of
   337	## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   338	## GNU General Public License for more details.
   339	##
   340	## You should have received a copy of the GNU General Public License
   341	## along with this software; if not, write to the Free Software
   342	## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   343	##
   344	#---------------------------------------------------------------------