3f9ebf93f60f504ca13308a44997eb4eddf97d28
[infrastructure.git] / scripts / crontabs.sh
1 #!/bin/bash
2
3 # utility for gathering your crontab file on miscell hosts
4
5 # relies on a config file named
6 # ~/.crontabsrc
7
8 # SYNTAX
9 #
10 # COMMENTS: line containing a sharp (#)
11
12 # any other line should be a HOST declaration like this
13 # [method:][username@]hostname
14 #
15 # defaults :
16 # (*) method defaults to ssh:
17 # (*) username defaults to $DEF_USER
18
19 # examples
20 #
21 # foo
22 #       =>      ssh:yourlogin@foo
23 # rsh:bar
24 #       =>      rsh:yourlogin@bar
25 # joe@tutu
26 #       =>      ssh:joe@tutu
27 # localhost
28 #       =>      local:nologin@$(hostname)
29
30 # the config file can optionnally get passed as an argument
31
32 COMMAND=$(basename $0)
33
34 DEF_CONFIG="$HOME/.$(basename ${COMMAND} .sh)rc"
35
36 OPT_VERBOSE="true" 
37 OPT_VERSION="" 
38
39 ### try different ways to get username
40 # linux
41 DEF_USER="$(id --user --name 2>/dev/null)"
42 # macintosh : id does not accept this syntax
43 [[ -z "$DEF_USER" ]] && DEF_USER="$LOGNAME"
44 # some other systems I met 
45 [[ -z "$DEF_USER" ]] && DEF_USER="$USER"
46 # still not found ? let's bail out
47 if [[ -z "$DEF_USER" ]] ; then
48   echo "$COMMAND : could not get DEF_USER - emergency exit"
49   exit 1
50 fi
51
52 usage () {
53
54   echo "Usage: $0 [config-file]"
55   echo "  default config file is $DEF_CONFIG"
56   echo "Config file syntax :"
57   echo "  line containing a # is taken as a comment"
58   echo "  other lines should match the following syntax"
59   echo "  [method:][username@]hostname"
60   echo "Defaults:"
61   echo "  method defaults to ssh (as opposed to rsh or local)"
62   echo "  username defaults to $DEF_USER"
63 }
64
65 ####################
66 info () {
67   if [ -n "$OPT_VERBOSE" ] ; then
68     echo "INFO : $@"
69   fi
70 }
71
72 error () {
73   echo "ERROR : $@"
74 }
75
76 ####################
77 parse_config () {
78   config=$1; shift
79
80   if [ ! -f $config ] ; then
81     error "$config not found"
82     exit 1
83   fi
84
85   descriptions=$(grep -v '#' $config)
86
87   for desc in $descriptions ; do
88
89     ###defaults
90     method=ssh
91     user="$DEF_USER"
92     case $desc in
93       *:*@*)
94         method=$(echo $desc | sed -e 's,:.*$,,')
95         user=$(echo $desc | sed -e 's,^.*:,,' -e 's,@.*$,,')
96         host=$(echo $desc | sed -e 's,^.*@,,')
97         ;;
98       *:*)
99         method=$(echo $desc | sed -e 's,:.*$,,')
100         host=$(echo $desc | sed -e 's,^.*:,,')
101         ;;
102       *@*)
103         user=$(echo $desc | sed -e 's,@.*$,,')
104         host=$(echo $desc | sed -e 's,^.*@,,')
105         ;;
106       *)
107         host=$desc
108         ;;
109     esac
110
111     if [ "$host" == localhost ] ; then
112       host="$(hostname)"
113       method="local"
114     fi
115
116     case $method in
117       rsh|ssh|local)
118         get_crontab $method "$user" $host
119         ;;
120       *)
121         error "ERROR: $desc - method must be rsh, ssh or local"
122         break
123         ;;
124     esac
125
126   done
127 }
128
129 ####################
130 get_crontab () {
131   method=$1; shift
132   user=$1; shift
133   host=$1; shift
134
135   ## where to backup
136   if [ "$user" = "$DEF_USER" ] ; then
137     backup=~/.crontab-$host
138   else
139     backup=~/.crontab-$host-"$user"
140   fi
141
142   info "getting crontab for $user on $host with method $method into $backup"
143
144   ## temporary - overwites backup only if needed
145   tmp=/tmp/$COMMAND-$$.txt
146
147   case $method in
148     local)
149       crontab -l
150       ;;
151     ssh)
152       ssh "$user"@$host crontab -l
153       ;;
154     rsh)
155       rsh -l "$user" $host crontab -l
156       ;;
157   esac > $tmp 2> /dev/null
158
159   if [ "$?" != 0 ] ; then
160     ### info and not error : allow for too extensive crontabsrc
161     info " could not get crontab on $host"
162     rm -f $tmp
163     return 1
164   fi
165
166   diff $tmp $backup > /dev/null 2>&1
167
168   if [ "$?" != 0 ] ; then
169     ## files differ
170     cp $tmp $backup
171     if [ "$?" = 0 ] ; then
172       info "crontab on host $host saved in $backup"
173     else
174       error "could not overwrite $backup"
175     fi
176   else
177     info "no changes in crontab on $host - kept $backup"
178     rm -f $tmp
179   fi
180 }
181 ####################
182 main () {
183
184   while [[ -n "$@" ]] ; do
185     case "$1" in
186       -s*|--silent*)
187         OPT_VERBOSE="" ; shift ;;
188       -v*|--version*)
189         OPT_VERSION="true" ; shift ;;
190       -*)
191         usage ; exit 1 ;;
192       *)
193         break ;;
194     esac
195   done
196
197   if [ -n "$OPT_VERSION" ] ; then
198     echo "This is $COMMAND"
199     exit 0
200   fi
201
202   if [[ -n "$@" ]] ; then
203     CONFIG=$1; shift
204   else
205     CONFIG=$DEF_CONFIG
206     [ -f $CONFIG ] || echo localhost > $CONFIG
207   fi
208
209   parse_config $CONFIG
210 }
211
212 ####################
213 main "$@"