1#########################################################################
2#
3# Subroutines for installing
4#
5#########################################################################
6#
7# Copyright Rainer Wichmann (2005)
8#
9# License Information:
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24
25getconfopts () {
26    fconf="$1"
27
28    if test -f "$fconf"
29    then
30	#
31	# check if readable
32	#
33	cat "$fconf" >/dev/null 2>&1 || return 1
34	#
35	# empty string if no --enable-nocl=..., else password
36	#
37	is_nocl=`cat "$fconf" | tr -d '\n' | egrep "^ *'?--enable-nocl=" | sed -e "s%^ *%%" | sed -e "s%^'%%" | sed -e "s%^--enable-nocl=%%" | sed -e "s% *$%%" | sed -e "s%'$%%"`
38	if test x"${is_nocl}" = x
39	then
40	    is_nocl="start"
41	else
42	    printINFO "Option --enable-nocl=${is_nocl} used."
43        fi
44	#
45	#
46	#
47	is_xor=`cat "$fconf" | tr -d '\n' | egrep "^ *'?--enable-stealth=" | sed -e "s%^ *%%" | sed -e "s%^'%%" | sed -e "s%^--enable-nocl=%%" | sed -e "s% *$%%" | sed -e "s%'$%%"`
48	if test x"${is_xor}" = x
49	then
50	    is_xor="no"
51	else
52	    printINFO "Option --enable-stealth=${is_xor} used."
53        fi
54	return 0
55    else
56	return 1
57    fi
58}
59
60writerecord () {
61    IDATE=`date +"%Y-%m-%d %H:%M:%S"`
62    echo "  <client>"
63    echo "    <client_host>${host}</client_host>"
64    echo "    <client_group>${hostgroup}</client_group>"
65    echo "    <client_os_machine>${arch}</client_os_machine>"
66    echo "    <client_install_status>${install_entry}</client_install_status>"
67    echo "    <client_install_date>${IDATE}</client_install_date>"
68    echo "    <client_install_name>${SH_NAME}</client_install_name>"
69    echo "    <client_install_prefix>${SH_PREFIX}</client_install_prefix>"
70    echo "    <client_install_version>${src_version}.${realformat}</client_install_version>"
71    echo "  </client>"
72}
73
74FTEST=0
75
76set_flag () {
77    case "$line" in
78    *\</client\>*)
79    FTEST=0;
80    return 0;
81    ;;
82
83    *\<client_host\>${host}\</client_host\>*)
84    FTEST=1;
85    return 1;
86    ;;
87
88    *)
89    return ${FTEST};
90    ;;
91    esac
92}
93
94
95#------------------------------------------------------------------------
96# Update client db
97#------------------------------------------------------------------------
98updateDB() {
99
100    if test "x$1" = x
101    then
102        install_entry="D2_installed"
103    else
104        install_entry="$1"
105    fi
106    export install_entry
107
108    if test x"$DATABASE" = x
109    then
110        DATABASE="${basedir}/${defdatabase}"
111    fi
112
113    updlock="${DATABASE}.lockdir"
114    trap "rm -rf ${updlock}" 1 2 13 15
115
116    #
117    # A lockfile will not work, because 'root' can write anyway.
118    # However, 'mkdir' an existing directory will fail even for root
119    #
120    until (umask 222; mkdir "${updlock}") 2>/dev/null   # test & set
121    do
122       printINFO "Waiting for lock"
123       sleep 1
124    done
125
126
127    IDATE=`date +"%Y-%m-%d %H:%M:%S"`
128    rm -f "$tmpF"; touch "$tmpF"
129
130    if test -f "$DATABASE"; then
131        rcfile_perm=`ls -l "${DATABASE}" | \
132        awk '{ u= substr($1,2,3); g=substr($1,5,3); o=substr($1,8,3); \
133           gsub("-","",u); gsub("-","",g); gsub("-","",o); \
134           print "u=" u ",g=" g ",o=" o; }'`
135        rcfile_perm=`echo ${rcfile_perm} | sed s%g=,%g-rwx,% | sed s%,o=$%,o-rwx%`
136        rcfile_owner=`ls -l "${DATABASE}" | \
137           awk '{print $3 }'`
138        rcfile_group=`ls -l "${DATABASE}" | \
139           awk '{print $4 }'`
140    else
141        rcfile_perm=640;
142        rcfile_owner=`ls -ld ${basedir} | awk '{print $3 }'`
143        rcfile_group=`ls -ld ${basedir} | awk '{print $4 }'`
144    fi
145
146
147    if test -f "${DATABASE}"
148    then
149       SStr1=`grep '<yule_db>' "${DATABASE}"`
150       if test "x${SStr1}" != "x"
151       then
152
153	SStr2=`grep "<client_host>${host}</client_host>" "${DATABASE}"`
154
155	SStr3=
156
157	if test "x${SStr2}" != "x"
158	then
159	    # REPLACE
160
161	    printINFO "Replace ${host} in ${DATABASE}"
162
163	    exec 3<&0 <"${DATABASE}"
164	    while
165		read line
166	    do
167		# for some reason, var=xx only works in a function call (why?)
168		#
169		# here we test if we are still in the same client block
170		# (set_flag will return 0 for </client> and following)
171		set_flag "$line"
172
173		if test "x$?" = "x1"
174		then
175		    #
176		    # Write the full entry when client_os_machine is found
177		    #
178		    case "$line" in
179		    *\<client_os_machine\>*\</client_os_machine\>)
180		    echo "    <client_group>${hostgroup}</client_group>"           >>"${tmpF}"
181		    echo "    <client_os_machine>${arch}</client_os_machine>"           >>"${tmpF}"
182		    echo "    <client_install_status>${install_entry}</client_install_status>"    >>"${tmpF}"
183                    echo "    <client_install_date>${IDATE}</client_install_date>"         >>"${tmpF}"
184		    echo "    <client_install_name>${SH_NAME}</client_install_name>"       >>"${tmpF}"
185		    echo "    <client_install_prefix>${SH_PREFIX}</client_install_prefix>" >>"${tmpF}"
186		    echo "    <client_install_version>${src_version}.${realformat}</client_install_version>" >>"${tmpF}"
187		    ;;
188
189		    *\<client_group\>*\</client_group\>)
190		    :
191		    ;;
192
193		    *\<client_install_status\>*\</client_install_status\>)
194		    :
195		    ;;
196
197		    *\<client_install_date\>*\</client_install_date\>)
198		    :
199	            ;;
200
201		    *\<client_install_name\>*\</client_install_name\>)
202		    :
203		    ;;
204
205		    *\<client_install_prefix\>*\</client_install_prefix\>)
206		    :
207		    ;;
208
209		    *\<client_install_version\>*\</client_install_version\>)
210		    :
211		    ;;
212
213		    *)
214		    echo "$line" >>"${tmpF}"
215		    ;;
216
217		    esac
218		else
219		    echo "$line" >>"${tmpF}"
220		fi
221
222	    done
223	    exec 0<&3 3<&-
224	    cp "${tmpF}" "${DATABASE}"
225	else
226	    # WRITE NEW CLIENT RECORD
227
228	    printINFO "Write record for ${host} in ${DATABASE}"
229
230	    exec 3<&0 <"${DATABASE}"
231	    while
232		read line
233	    do
234		if test "x$line" = "x<yule_db>"
235		then
236		    echo "$line" >>"${tmpF}"
237		    writerecord  >>"${tmpF}"
238		else
239		    echo "$line" >>"${tmpF}"
240		fi
241	    done
242	    exec 0<&3 3<&-
243	    cp "${tmpF}" "${DATABASE}"
244        fi
245     else
246	# COMPLAIN
247	printLOG "File ${DATABASE} exists, but has wrong format";
248     fi
249    else
250     # WRITE XML FROM SCRATCH
251     printINFO "Write ${DATABASE} from scratch"
252     echo '<?xml version="1.0" encoding="ISO-8859-1"?>' >"${tmpF}"
253     echo '<!DOCTYPE yule_db SYSTEM "http://la-samhna.de/yule_db-0.2.dtd">' \
254	  >>"${tmpF}"
255     echo "<yule_db>"   >>"${tmpF}"
256     writerecord        >>"${tmpF}"
257     echo "</yule_db>"  >>"${tmpF}"
258     cp "${tmpF}" "${DATABASE}"
259    fi
260
261    chown ${rcfile_owner}:${rcfile_group} "${DATABASE}"
262    if [ $? -ne 0 ]; then
263    	rm -rf "${updlock}"
264    	printFATAL "Could not chown ${rcfile_owner}:${rcfile_group} ${DATABASE}"
265    fi
266    chmod ${rcfile_perm} "${DATABASE}"
267    if [ $? -ne 0 ]; then
268    	rm -rf "${updlock}"
269    	printFATAL "Could not chmod ${rcfile_perm} ${DATABASE}"
270    fi
271
272    rm -rf "${updlock}"
273}
274
275
276ageFILE() {
277    file="$1"
278
279    if test -f "${file}"
280    then
281	test -f "${file}.9" && { rm -f "${file}.9" || printFATAL "rm -f ${file}.9 failed."; }
282	test -f "${file}.8" && { mv "${file}.8" "${file}.9" || printFATAL "mv ${file}.8 ${file}.9 failed."; }
283	test -f "${file}.7" && { mv "${file}.7" "${file}.8" || printFATAL "mv ${file}.7 ${file}.8 failed."; }
284	test -f "${file}.6" && { mv "${file}.6" "${file}.7" || printFATAL "mv ${file}.6 ${file}.7 failed."; }
285	test -f "${file}.5" && { mv "${file}.5" "${file}.6" || printFATAL "mv ${file}.5 ${file}.6 failed."; }
286	test -f "${file}.4" && { mv "${file}.4" "${file}.5" || printFATAL "mv ${file}.4 ${file}.5 failed."; }
287	test -f "${file}.3" && { mv "${file}.3" "${file}.4" || printFATAL "mv ${file}.3 ${file}.4 failed."; }
288	test -f "${file}.2" && { mv "${file}.2" "${file}.3" || printFATAL "mv ${file}.2 ${file}.3 failed."; }
289	test -f "${file}.1" && { mv "${file}.1" "${file}.2" || printFATAL "mv ${file}.1 ${file}.2 failed."; }
290	test -f "${file}"   && { mv "${file}"   "${file}.1" || printFATAL "mv ${file}   ${file}.1 failed."; }
291     fi
292     return 0;
293}
294
295#------------------------------------------------------------------------
296# The path to yule data
297#------------------------------------------------------------------------
298pathYDATA() {
299    if test "x${yule_data}" = x
300    then
301	promptINPUT "Please enter the path to your yule executable"
302        yule_data="$INPUT"; export yule_data
303    fi
304    if test -d "${yule_data}"
305    then
306	:
307    else
308	printFATAL "Path to yule data directory not given."
309    fi
310}
311
312#------------------------------------------------------------------------
313# The path to yule
314#------------------------------------------------------------------------
315pathYULE() {
316
317    if test "x${yule_exec}" = x
318    then
319	findEXE yule
320	if test -n "$EXECUTABLE"
321	then
322	    yule_exec="$EXECUTABLE"
323	    export yule_exec
324	fi
325    else
326	if test -f "${yule_exec}"
327	then
328	    :
329	else
330	    yule_exec=""
331	    findEXE yule
332	    if test -n "$EXECUTABLE"
333	    then
334	        yule_exec="$EXECUTABLE"
335	        export yule_exec
336	    fi
337	fi
338    fi
339    if test "x${yule_exec}" = x
340    then
341	promptINPUT "Please enter the path to your yule executable"
342        yule_exec="$INPUT"; export yule_exec
343    fi
344    if test -f "${yule_exec}"
345    then
346	if "${yule_exec}" --help 2>&1 | grep qualified >/dev/null 2>&1
347	then
348	    :
349	else
350	    printFATAL "${yule_exec} is not Yule, or not executable."
351	fi
352    else
353	printFATAL "Path to yule executable directory not given."
354    fi
355}
356
357#------------------------------------------------------------------------
358# Select operating system
359#------------------------------------------------------------------------
360selbinARCH() {
361    #---------------------------------------------------------------------
362    # Select arch to build
363    #---------------------------------------------------------------------
364    if test x"$arch" = x
365    then
366	if test x"$assumeyes" = x1
367	then
368	    printFATAL "No operating system selected, aborting."
369	fi
370	cd "$basedir/archpkg" || printFATAL "Cannot cd to $basedir/archpkg !"
371	LIST=`ls 2>/dev/null`
372	if test x"$LIST" = x
373	then
374		printFATAL "No OS directories found in ${basedir}/archpkg."
375        fi
376
377	n=0
378	command="promptMENU 'Please select operating system of host' "
379	ALIST=""
380	FLIST=""
381	for ff in $LIST
382	do
383	    haspkg=`ls $ff/samhain-* 2>/dev/null`
384	    if test x"$haspkg" = x
385	    then
386		:
387	    else
388	        n=`expr $n + 1`
389	        osp="$ff"
390	        ALIST="$ALIST $ff"
391	        FLIST="$FLIST $ff"
392	        if test $n -lt 8
393	        then
394		    command="$command '${ff}'"
395                fi
396	    fi
397	done
398	if test $n -ge 8
399	then
400	   command="$command other"
401	fi
402        if test $n -eq 0
403        then
404            printFATAL "No binary packages built yet !"
405        fi
406
407	eval ${command}
408	m=$?
409	if test x$m = x1
410	then
411	    (exit 0); exit 0;
412	elif test x$m = "x-1"
413	then
414	    printFATAL "Something went wrong !"
415	else
416	    arch="$MENU"; export arch
417	    if test x"$arch" = xother
418	    then
419		promptINPUT "Please select operating system of host from $FLIST"
420		if test x$m = x1
421		then
422		    (exit 0); exit 0;
423		elif test x$m = "x-1"
424		then
425		    printFATAL "Something went wrong !"
426		else
427		    found=`echo $FLIST | sed -n /$INPUT/p 2>/dev/null`
428		    if test x"$found" = x
429		    then
430			printFATAL "There is no package for $INPUT"
431		    fi
432		    arch="$INPUT"; export arch
433		fi
434            fi
435	fi
436    fi
437    # arch selected or exited
438}
439
440selbinVERSION() {
441
442    OKVERLIST=""
443
444    #---------------------------------------------------------------------
445    # Select version
446    #---------------------------------------------------------------------
447    if test x"$src_version" = x
448    then
449	if test x"$assumeyes" = x1
450	then
451	    printFATAL "No version selected, aborting."
452	fi
453	cd "${basedir}/archpkg/${arch}" || printFATAL "Cannot cd to ${basedir}/archpkg/${arch} !"
454	LIST=`ls samhain-* 2>/dev/null`
455	if test x"$LIST" = x
456	then
457	    printFATAL "No binary package found in ${basedir}/archpkg/${arch}."
458        fi
459
460	# --------------------------------------------------
461	# Build a list of ${version}.${format}
462	# --------------------------------------------------
463
464	for ff in $LIST
465	do
466	    sh_version=`echo "$ff" | sed 's/samhain\-//g'`
467	    if test -f "install-${sh_version}"
468	    then
469	        OKVERLIST="$OKVERLIST ${sh_version}"
470	    fi
471	done
472
473	rm -f "$tmpF" && touch "$tmpF"
474
475        for dd in $OKVERLIST
476        do
477            echo "$dd" >>"$tmpF"
478        done
479
480        OKVERLIST=`cat "$tmpF" | sort -r`
481
482        rm -f "$tmpF" && touch "$tmpF"
483
484	command="promptMENU 'Please select version to install' "
485	for word in $OKVERLIST
486	do
487	    command="$command '${word}'"
488	done
489
490	eval ${command}
491	m=$?
492	if test x$m = x1
493	then
494	    (exit 0); exit 0;
495	elif test x$m = "x-1"
496	then
497	    printFATAL "Something went wrong !"
498	else
499	    first_version="$MENU";
500	fi
501
502	src_version=`echo ${first_version} | sed s%\.run%% | sed s%\.rpm%% | sed s%\.deb%% | sed s%\.tbz2%% | sed s%\.depot%% | sed s%\.pkg%%`
503	export src_version
504
505	format=`echo ${first_version} | sed '/^\(.*\)\.\([0-9a-zA-Z]*\)$/{ s//\2/; q; }'`
506	if test "x$format" = xpkg
507	then
508	    format="solaris-pkg"
509        fi
510	export format
511
512    fi
513}
514