#!/bin/sh
# $Header: /cvsroot/sadm/cfm-1/sbin/cdist,v 1.2 2000/04/03 10:18:02 dmetz Exp $
# $crtd:  by  Derald Metzger  on  31jan94 $
# $cmnt: 
##   Cmd to rdist copies of controled files from a cm working dir to user dirs.
# A Distfile for the current cm dir should be present.
#   This wrapper is intended to afford a measure of protections for
# users of the rdist cmd.
#               Copyright (c) 1998 - 2000 Derald Metzger
# This file is part of the cfm pkg (GPL).
# $

CDIST="/usr/bin/rdist "
# Don't push these. They are part of the database structure.
# The passwd file is usually a group level controled file.
exclude_list=':RCS:.cvsignore:.exeignore:passwd:'

usage="
  DESCR:
    cdist is a maintenance tool for distribution of files from control dirs.
    It rdist's files to dirs on multiple hosts specified in ./Distfile.
    The -v option can be used to report validity of all files it handles.
    cdist is essentially a wrapper for the unix rdist cmd.
    See the rdist man page. Some features of rdist are restricted:
      cdist requires an arg to move any files (\`all' to push all files),
      cdist accepts filenames as args and treats them as rdist pkgs,
      ie you can issue special cmds associated with the push.
      Args are filtered to remove dirs; ie NO dirs trees.
      cdist appends to a logfile a record of its actions.
      Two copies of the logfile are referenced to overcome an rdist 
      \`feature' that would otherwise preclude a dir as a destination.
  USAGE:
    cdist [ rdist_options ] { all | file [...] }"

#   Sanity check. The Distfile must be for the current dir.
# cur_dir is the full path of the current dir
cur_dir=`(exec pwd)`
# dir_tail is stripped of any /mnt* or /export*. 
dir_tail=`echo $cur_dir | sed -e "s,/mnt[^/]*,," -e "s,/export[^/]*,,"`
if [ $dir_tail != $cur_dir ]; then \
  dir=$dir_tail   # \\\ this needs some fixing
else
  dir=`pwd | sed -e "s/^\/tmp_mnt//"`
fi

grep "CMDIR    = ( $dir )" Distfile >/dev/null
if [ $? -ne 0 ]; then \
  echo "### cdist: Distfile internal id failed to match cwd
    `grep CMDIR Distfile`
      PWD    =   $dir $usage"
  exit
fi

#   Set aside the opts so we can find our args.
while getopts bhinqRvwyd:f:m:c: c
do
  case $c in
    d|f|m|c) CDIST=${CDIST}" -$c $OPTARG" ;;
    b|h|i|n|q|R|w|y) CDIST=${CDIST}" -$c" ;;
    v) CDIST=${CDIST}" -$c"; verify_fllg=YES
  esac
done
shift `expr $OPTIND - 1`

#   Get the input file list.
if [ "$1" = "" ]; then \
  echo "### $cmd: insufficient args! $usage"
  exit
elif [ "$1" = all ]; then \
  shift 1
  ilist=`/bin/ls -a`
else
  ilist="$@"
fi

#   Get the special handling files list.
special_list=`echo :\`grep '^[-A-Za-z0-9_\.][-A-Za-z0-9_\.]*:$' Distfile | sort -u\``
special_list=`echo $special_list | sed -e 's/ //g'`

#   Clean up the input files list.
generics=""
specials=""
for i in $ilist
do
  # no dirs
  if [ -d $i ]; then continue; fi
  # reject exclude_list matches, tell him about them
  if [ `expr "$exclude_list" : ".*:${i}:.*"` != 0 ]; then \
    echo "- skipping $i"
    continue
  fi
  # we'll do the ones left, but as separate rdist pkgs if in Distfile
  if [ `expr "$special_list,x" : ".*:${i}:.*"` != 0 ]; then \
    specials="$specials $i"
  else
    generics="$generics $i"
  fi
done

#   Make log entry to reflect all files checked.
echo "`date +%y%m%d:%H%M` cdist $LOGNAME $generics $specials" >>.cdist_log

#   Push the files. .cdist_log is listed twice because of an rdist quirk.
$CDIST -f Distfile -d FILES="( $generics .cdist_log .cdist_log )" generics $specials

exit
---------------------------------------------------------------

Note that there will always be at least 2 log files idd (.cdist_log 
.cdist_log) so a dir can be used as the generics_list destination.
Sample Distfile:
----------------
CMDIR    = ( /cm/sactl/SunOS-4/site/swaf/SUNos/etc )
USERDIR  = ( /etc )

HOSTS = ( wpcadm )

generics:
${FILES} -> ${HOSTS}
  install ${USERDIR}/;

syslog.conf:
syslog.conf -> ${HOSTS}
  install ${USERDIR}/syslog.conf;
  special "kill -1 `cat /etc/syslog.pid`;";
  special "logger -p auth.notice rdist update of /etc/syslog.conf;";
