--- /dev/null
+#!/bin/bash
+
+# utility for gathering your crontab file on miscell hosts
+#
+# relies on a config file named
+# ~/.crontabsrc
+#
+# SYNTAX
+#
+# COMMENTS: line containing a sharp (#)
+#
+# any other line should be a HOST declaration like this
+# [method:][username@]hostname
+#
+# defaults :
+# (*) method defaults to ssh:
+# (*) username defaults to $DEF_USER
+
+# examples
+#
+# foo
+# => ssh:yourlogin@foo
+# rsh:bar
+# => rsh:yourlogin@bar
+# joe@tutu
+# => ssh:joe@tutu
+# localhost
+# => local:nologin@$(hostname)
+
+# the config file can optionnally get passed as an argument
+
+COMMAND=$(basename $0)
+REV=$(echo '$Revision: 437 $' | sed -e 's,\$,,g')
+
+DEF_CONFIG="$HOME/.$(basename ${COMMAND} .sh)rc"
+
+OPT_VERBOSE="true"
+OPT_VERSION=""
+
+### try different ways to get username
+# linux
+DEF_USER="$(id --user --name 2>/dev/null)"
+# macintosh : id does not accept this syntax
+[[ -z "$DEF_USER" ]] && DEF_USER="$LOGNAME"
+# some other systems I met
+[[ -z "$DEF_USER" ]] && DEF_USER="$USER"
+# still not found ? let's bail out
+if [[ -z "$DEF_USER" ]] ; then
+ echo "$COMMAND : could not get DEF_USER - emergency exit"
+ exit 1
+fi
+
+usage () {
+
+ echo "Usage: $0 [config-file]"
+ echo " default config file is $DEF_CONFIG"
+ echo "Config file syntax :"
+ echo " line containing a # is taken as a comment"
+ echo " other lines should match the following syntax"
+ echo " [method:][username@]hostname"
+ echo "Defaults:"
+ echo " method defaults to ssh (as opposed to rsh or local)"
+ echo " username defaults to $DEF_USER"
+}
+
+####################
+info () {
+ if [ -n "$OPT_VERBOSE" ] ; then
+ echo "INFO : $@"
+ fi
+}
+
+error () {
+ echo "ERROR : $@"
+}
+
+####################
+parse_config () {
+ config=$1; shift
+
+ if [ ! -f $config ] ; then
+ error "$config not found"
+ exit 1
+ fi
+
+ descriptions=$(grep -v '#' $config)
+
+ for desc in $descriptions ; do
+
+ ###defaults
+ method=ssh
+ user="$DEF_USER"
+ case $desc in
+ *:*@*)
+ method=$(echo $desc | sed -e 's,:.*$,,')
+ user=$(echo $desc | sed -e 's,^.*:,,' -e 's,@.*$,,')
+ host=$(echo $desc | sed -e 's,^.*@,,')
+ ;;
+ *:*)
+ method=$(echo $desc | sed -e 's,:.*$,,')
+ host=$(echo $desc | sed -e 's,^.*:,,')
+ ;;
+ *@*)
+ user=$(echo $desc | sed -e 's,@.*$,,')
+ host=$(echo $desc | sed -e 's,^.*@,,')
+ ;;
+ *)
+ host=$desc
+ ;;
+ esac
+
+ if [ "$host" == localhost ] ; then
+ host="$(hostname)"
+ method="local"
+ fi
+
+ case $method in
+ rsh|ssh|local)
+ get_crontab $method "$user" $host
+ ;;
+ *)
+ error "ERROR: $desc - method must be rsh, ssh or local"
+ break
+ ;;
+ esac
+
+ done
+}
+
+####################
+get_crontab () {
+ method=$1; shift
+ user=$1; shift
+ host=$1; shift
+
+ ## where to backup
+ if [ "$user" = "$DEF_USER" ] ; then
+ backup=~/.crontab-$host
+ else
+ backup=~/.crontab-$host-"$user"
+ fi
+
+ info "getting crontab for $user on $host with method $method into $backup"
+
+ ## temporary - overwites backup only if needed
+ tmp=/tmp/$COMMAND-$$.txt
+
+ case $method in
+ local)
+ crontab -l
+ ;;
+ ssh)
+ ssh "$user"@$host crontab -l
+ ;;
+ rsh)
+ rsh -l "$user" $host crontab -l
+ ;;
+ esac > $tmp 2> /dev/null
+
+ if [ "$?" != 0 ] ; then
+ ### info and not error : allow for too extensive crontabsrc
+ info " could not get crontab on $host"
+ rm -f $tmp
+ return 1
+ fi
+
+ diff $tmp $backup > /dev/null 2>&1
+
+ if [ "$?" != 0 ] ; then
+ ## files differ
+ cp $tmp $backup
+ if [ "$?" = 0 ] ; then
+ info "crontab on host $host saved in $backup"
+ else
+ error "could not overwrite $backup"
+ fi
+ else
+ info "no changes in crontab on $host - kept $backup"
+ rm -f $tmp
+ fi
+}
+####################
+main () {
+
+ while [[ -n "$@" ]] ; do
+ case "$1" in
+ -s*|--silent*)
+ OPT_VERBOSE="" ; shift ;;
+ -v*|--version*)
+ OPT_VERSION="true" ; shift ;;
+ -*)
+ usage ; exit 1 ;;
+ *)
+ break ;;
+ esac
+ done
+
+ if [ -n "$OPT_VERSION" ] ; then
+ echo "This is $COMMAND, $REV"
+ exit 0
+ fi
+
+ if [[ -n "$@" ]] ; then
+ CONFIG=$1; shift
+ else
+ CONFIG=$DEF_CONFIG
+ fi
+
+ parse_config $CONFIG
+}
+
+####################
+main "$@"