backupninja and ninjahelper: have find following symlinks for config files also work...
[matthijs/upstream/backupninja.git] / src / ninjahelper.in
1 #!@BASH@
2 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
3
4 ####################################################
5 ## Functions
6
7 function check_perms() {
8    local file=$1
9    local perms=`ls -ld $file`
10    group_w_perm=${perms:5:1}
11    world_w_perm=${perms:8:1}
12    if [ "$group_w_perm" == "w" -o "$world_w_perm" == "w" ]; then
13       echo $perms
14       echo "helper scripts must not be group or world writable! Dying on file $file"
15       exit
16    fi
17    if [ `ls -ld $file | awk '{print $3}'` != "root" ]; then
18       echo "helper scripts must be owned by root! Dying on file $file"
19       exit
20    fi
21 }
22
23
24 ##
25 ## returns the next available file name given a file
26 ## in the form @CFGDIR@/backup.d/10.sys
27 ## sets variable $next_filename
28 ##
29 get_next_filename() {
30    next_filename=$1
31    dir=`dirname $next_filename`
32    file=`basename $next_filename`
33    number=${file:0:2}
34    suffix=${file:3}
35    while [ -f $next_filename ]; do
36      let "number += 1"
37      next_filename="$dir/$number.$suffix"
38    done
39 }
40
41 ##
42 ## installs packages (passed in as $@) if not present
43 ##
44 require_packages() {
45    for pkg in "$@"; do
46       installed=`dpkg -s $pkg | grep 'ok installed'`
47       if [ -z "$installed" ]; then 
48          booleanBox "install $pkg?" "This backup action requires package $pkg. Do you want to install it now?"
49          if [ $? = 0 ]; then
50             apt-get install $pkg
51             echo "hit return to continue...."
52             read
53          fi
54       fi
55    done
56 }
57
58 ##
59 ## menu for the wizards
60 ##
61 donew() {
62    # (re-)initialize vservers support
63    init_vservers
64    # menu
65    listBegin "new action menu" "select an action to create"
66    listItem return "return to main menu"
67    for data in $HELPERS; do
68       data=${data//_/ }
69       helper_function=${data%%:*}
70       helper_info=${data##*:}
71       listItem $helper_function "$helper_info"
72    done
73    listDisplay menu
74     
75    [ $? = 1 ] && return
76    result="$REPLY"
77    [ "$result" = "return" -o "$result" = "" ] && return
78    run_wizard=${result}_wizard
79    $run_wizard
80    result=$?
81    # 0 is ok, 1 is cancel, anything else is bad.
82    if [ $result != 1 -a $result != 0 ]; then    
83       echo "An error occurred ($result), bailing out. Hit return to continue."
84       read
85    fi 
86 }
87
88 do_rm_action() {
89    booleanBox "remove action" "Are you sure you want to remove action file $1?"
90    if [ $? = 0 ]; then
91      rm $1;
92    fi
93 }
94
95 do_run() {
96    backupninja --run $1
97    echo "Hit return to continue..."
98    read
99 }
100
101 do_xedit() {
102    if [ -z "$EDITOR" -o ! -x "`which $EDITOR`" ]; then
103       if [ -h /etc/alternatives/editor -a -x "`readlink /etc/alternatives/editor`" ]; then
104          EDITOR="`readlink /etc/alternatives/editor`"
105       elif [ -x "`which nano`" ]; then
106          EDITOR="`which nano`"
107       elif [ -x "`which vim`" ]; then
108          EDITOR="`which vim`"
109       elif [ -x "`which vi`" ]; then
110          EDITOR="`which vi`"
111       else
112          echo "No suitable editor found."
113          echo "Please define $EDITOR or configure /etc/alternatives/editor."
114          exit
115       fi
116    fi
117    $EDITOR $1
118 }
119
120 do_run_test() {
121    backupninja --test --run $1
122    echo "Hit return to continue..."
123    read
124 }
125
126 do_disable() {
127    mv $1 $1.disabled
128 }
129
130 do_enable() {
131    mv $1 ${1%.*}
132 }
133
134 do_rename() {
135    dir=`dirname $1`
136    filename=`basename $1`
137    inputBox "rename action" "enter a new filename" $filename
138    mv $dir/$filename $dir/$REPLY
139 }
140
141 doaction() {
142    action=$1
143    base=`basename $action`
144    if [ "${base##*.}" == "disabled" ]; then
145       enable="enable";
146    else
147       enable="disable";
148    fi
149    while true; do
150       menuBox "action menu" "$action $first" \
151          main "return to main menu" \
152          view "view configuration" \
153          xedit "launch external editor" \
154          $enable "$enable action" \
155          name "change the filename" \
156          run "run this action now" \
157          test "do a test run" \
158          kill "remove this action" 
159       [ $? = 1 ] && return;
160       result="$REPLY"
161       case "$result" in
162          "view") dialog --textbox $action 0 0;; 
163          "xedit") do_xedit $action;;
164          "disable") do_disable $action; return;;
165          "enable") do_enable $action; return;;
166          "name") do_rename $action; return;;
167          "run") do_run $action;;
168          "test") do_run_test $action;; 
169          "kill") do_rm_action $action; return;;
170          "main") return;;
171       esac
172    done
173 }
174
175 #####################################################
176 ## begin program
177
178 if [ ! -x "`which dialog`" ]; then
179    echo "ninjahelper is a menu based wizard for backupninja."
180    echo "It requires 'dialog' in order to run. Do you want to install dialog now?"
181    while true; do
182       echo -n "(yes/no): "
183       read install
184       if [ "$install" == "yes" ]; then
185          apt-get install dialog
186             break
187          elif [ "$install" == "no" ]; then
188             exit
189          else
190             echo "You must answer 'yes' or 'no'"
191       fi
192    done
193 fi
194
195 # bootstrap
196 conffile="@CFGDIR@/backupninja.conf"
197 if [ ! -r "$conffile" ]; then
198    echo "Configuration file $conffile not found." 
199    exit 1
200 fi
201
202 # find $libdirectory
203 libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
204 if [ -z "$libdirectory" ]; then
205    if [ -d "@libdir@" ]; then
206       libdirectory="@libdir@"
207    else
208       echo "Could not find entry 'libdirectory' in $conffile." 
209       exit 1
210    fi
211 else
212    if [ ! -d "$libdirectory" ]; then
213       echo "Lib directory $libdirectory not found." 
214       exit 1
215    fi
216 fi
217
218 # include shared functions
219 . $libdirectory/easydialog
220 . $libdirectory/tools
221 . $libdirectory/vserver
222
223 # am I running as root?
224 if [ "$UID" != "0" ]; then
225    msgBox "warning" "`basename $0` must be run by root!"
226    exit 1
227 fi
228
229 # get global config options (second param is the default)
230 setfile $conffile
231 getconf configdirectory @CFGDIR@/backup.d
232 if [ ! -d $configdirectory ]; then
233    msgBox "warning" "The backupninja configuration directory $configdirectory does not exist. Ninjahelper cannot run without it!"
234    exit 1
235 fi
236 getconf scriptdirectory @datadir@
237
238 # load all the helpers
239 HELPERS=""
240 for file in `find $scriptdirectory -follow -name '*.helper'`; do
241    check_perms $file
242    . $file
243    if [ $? != 0 ]; then
244       echo "An error occurred while loading $file. Hit return to continue."
245       read
246    fi
247 done
248
249 setApplicationTitle "ninjahelper"
250 setDimension 75 19
251
252 #####################################################
253 ## main event loop
254
255 while true; do
256
257 menulist=
258 action=
259 let "i = 1"
260 for file in `find ${configdirectory} -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n`; do
261    menulist="$menulist $i $file"
262    actions[$i]=$file
263    let "i += 1"
264 done
265
266 menuBox "main menu" "Select a backup action for more options, or create a new action:" $menulist \
267   new "create a new backup action" \
268   quit "leave ninjahelper" 
269
270 [ $? = 1 -o $? = 255 ] && exit 0;
271
272 choice="$REPLY"
273 if [ "$choice" == "new" ]; then
274    donew;
275 elif [ "$choice" == "quit" ]; then
276    exit 0;
277 else
278    action=${actions[$choice]};
279    if [ -f "$action" ]; then
280       doaction $action
281    else
282       msgBox "error" "error: cannot find the file '$action'"
283    fi
284 fi
285
286 done