/[gentoo-x86]/eclass/webapp.eclass
Gentoo

Contents of /eclass/webapp.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.40 - (hide annotations) (download)
Mon Mar 6 08:36:51 2006 UTC (8 years, 9 months ago) by wrobel
Branch: MAIN
Changes since 1.39: +11 -11 lines
Fixed quoting issue in the webapp.eclass. Allows paths with whitespace.

1 rl03 1.39 # Copyright 1999-2006 Gentoo Foundation
2 stuart 1.1 # Distributed under the terms of the GNU General Public License v2
3 wrobel 1.40 # $Header: /var/cvsroot/gentoo-x86/eclass/webapp.eclass,v 1.39 2006/01/11 15:19:42 rl03 Exp $
4 stuart 1.1 #
5     # eclass/webapp.eclass
6     # Eclass for installing applications to run under a web server
7     #
8     # Part of the implementation of GLEP #11
9     #
10     # Author(s) Stuart Herbert <stuart@gentoo.org>
11 stuart 1.37 # Renat Lumpau <rl03@gentoo.org>
12 rl03 1.39 # Gunnar Wrobel <wrobel@gentoo.org>
13 stuart 1.1 #
14     # ------------------------------------------------------------------------
15     #
16 stuart 1.37 # The master copy of this eclass is held in our subversion repository.
17     # http://svn.gnqs.org/projects/vhost-tools/browser/
18 stuart 1.18 #
19 stuart 1.37 # If you make changes to this file and don't tell us, chances are that
20     # your changes will be overwritten the next time we release a new version
21 stuart 1.18 # of webapp-config.
22 stuart 1.1 #
23     # ------------------------------------------------------------------------
24    
25     SLOT="${PVR}"
26 swegener 1.36 IUSE="vhosts"
27 stuart 1.37 DEPEND="app-admin/webapp-config"
28     RDEPEND="${DEPEND}"
29 stuart 1.1
30 stuart 1.18 EXPORT_FUNCTIONS pkg_postinst pkg_setup src_install pkg_prerm
31 stuart 1.1
32 stuart 1.37 INSTALL_DIR="/${PN}"
33 stuart 1.14 IS_UPGRADE=0
34     IS_REPLACE=0
35    
36 stuart 1.19 INSTALL_CHECK_FILE="installed_by_webapp_eclass"
37    
38 stuart 1.37 ETC_CONFIG="${ROOT}/etc/vhosts/webapp-config"
39     WEBAPP_CONFIG="${ROOT}/usr/sbin/webapp-config"
40    
41     # ------------------------------------------------------------------------
42     # INTERNAL FUNCTION - USED BY THIS ECLASS ONLY
43     #
44     # Load the config file /etc/vhosts/webapp-config
45     #
46     # Supports both the old bash version, and the new python version
47     #
48     # ------------------------------------------------------------------------
49    
50     function webapp_read_config ()
51     {
52     if has_version '>=app-admin/webapp-config-1.50'; then
53     ENVVAR=$(${WEBAPP_CONFIG} --query ${PN} ${PVR}) || die "Could not read settings from webapp-config!"
54     eval ${ENVVAR}
55     else
56     . ${ETC_CONFIG} || die "Unable to read ${ETC_CONFIG}"
57     fi
58     }
59 stuart 1.21
60 stuart 1.1 # ------------------------------------------------------------------------
61     # INTERNAL FUNCTION - USED BY THIS ECLASS ONLY
62     #
63     # Check whether a specified file exists within the image/ directory
64     # or not.
65     #
66     # @param $1 - file to look for
67 stuart 1.3 # @param $2 - prefix directory to use
68 stuart 1.1 # @return 0 on success, never returns on an error
69     # ------------------------------------------------------------------------
70    
71     function webapp_checkfileexists ()
72     {
73 stuart 1.9 local my_prefix
74    
75 stuart 1.37 [ -n "${2}" ] && my_prefix="${2}/" || my_prefix=
76 stuart 1.9
77 stuart 1.37 if [ ! -e "${my_prefix}${1}" ]; then
78     msg="ebuild fault: file '${1}' not found"
79 stuart 1.1 eerror "$msg"
80     eerror "Please report this as a bug at http://bugs.gentoo.org/"
81     die "$msg"
82     fi
83     }
84    
85     # ------------------------------------------------------------------------
86 stuart 1.3 # INTERNAL FUNCTION - USED BY THIS ECLASS ONLY
87     # ------------------------------------------------------------------------
88    
89 stuart 1.14 function webapp_check_installedat
90     {
91     local my_output
92    
93 stuart 1.37 ${WEBAPP_CONFIG} --show-installed -h localhost -d "${INSTALL_DIR}" 2> /dev/null
94 stuart 1.3 }
95    
96     # ------------------------------------------------------------------------
97     # INTERNAL FUNCTION - USED BY THIS ECLASS ONLY
98 stuart 1.1 #
99     # ------------------------------------------------------------------------
100    
101 stuart 1.3 function webapp_strip_appdir ()
102     {
103 stuart 1.37 local my_stripped="${1}"
104     echo "${1}" | sed -e "s|${MY_APPDIR}/||g;"
105 stuart 1.3 }
106    
107     function webapp_strip_d ()
108     {
109 stuart 1.37 echo "${1}" | sed -e "s|${D}||g;"
110 stuart 1.3 }
111    
112     function webapp_strip_cwd ()
113 stuart 1.1 {
114 stuart 1.37 local my_stripped="${1}"
115     echo "${1}" | sed -e 's|/./|/|g;'
116 stuart 1.1 }
117    
118     # ------------------------------------------------------------------------
119     # EXPORTED FUNCTION - FOR USE IN EBUILDS
120     #
121     # Identify a config file for a web-based application.
122     #
123     # @param $1 - config file
124     # ------------------------------------------------------------------------
125    
126     function webapp_configfile ()
127     {
128 rl03 1.39 local m=""
129     for m in "$@" ; do
130     webapp_checkfileexists "${m}" "${D}"
131 stuart 1.27
132 wrobel 1.40 local MY_FILE="$(webapp_strip_appdir "${m}")"
133     MY_FILE="$(webapp_strip_cwd "${MY_FILE}")"
134 stuart 1.3
135 rl03 1.39 einfo "(config) ${MY_FILE}"
136     echo "${MY_FILE}" >> ${D}/${WA_CONFIGLIST}
137     done
138 stuart 1.1 }
139    
140     # ------------------------------------------------------------------------
141     # EXPORTED FUNCTION - FOR USE IN EBUILDS
142     #
143 stuart 1.18 # Install a script that will run after a virtual copy is created, and
144     # before a virtual copy has been removed
145     #
146     # @param $1 - the script to run
147     # ------------------------------------------------------------------------
148    
149     function webapp_hook_script ()
150     {
151 stuart 1.37 webapp_checkfileexists "${1}"
152 stuart 1.18
153 stuart 1.37 einfo "(hook) ${1}"
154 wrobel 1.40 cp "${1}" "${D}/${MY_HOOKSCRIPTSDIR}/$(basename "${1}")" || die "Unable to install ${1} into ${D}/${MY_HOOKSCRIPTSDIR}/"
155     chmod 555 "${D}/${MY_HOOKSCRIPTSDIR}/$(basename "${1}")"
156 stuart 1.18 }
157    
158     # ------------------------------------------------------------------------
159     # EXPORTED FUNCTION - FOR USE IN EBUILDS
160     #
161 stuart 1.5 # Install a text file containing post-installation instructions.
162     #
163     # @param $1 - language code (use 'en' for now)
164     # @param $2 - the file to install
165     # ------------------------------------------------------------------------
166    
167 stuart 1.31 function webapp_postinst_txt ()
168 stuart 1.5 {
169 stuart 1.37 webapp_checkfileexists "${2}"
170 stuart 1.5
171 stuart 1.37 einfo "(info) ${2} (lang: ${1})"
172     cp "${2}" "${D}/${MY_APPDIR}/postinst-${1}.txt"
173 stuart 1.5 }
174    
175     # ------------------------------------------------------------------------
176     # EXPORTED FUNCTION - FOR USE IN EBUILDS
177     #
178 stuart 1.31 # Install a text file containing post-upgrade instructions.
179 stuart 1.1 #
180 stuart 1.31 # @param $1 - language code (use 'en' for now)
181     # @param $2 - the file to install
182     # ------------------------------------------------------------------------
183    
184     function webapp_postupgrade_txt ()
185     {
186 stuart 1.37 webapp_checkfileexists "${2}"
187 stuart 1.31
188 stuart 1.37 einfo "(info) ${2} (lang: ${1})"
189     cp "${2}" "${D}/${MY_APPDIR}/postupgrade-${1}.txt"
190 stuart 1.3 }
191    
192     # ------------------------------------------------------------------------
193     # EXPORTED FUNCTION - FOR USE IN EBUILDS
194     #
195     # Identify a file which must be owned by the webserver's user:group
196     # settings.
197     #
198     # The ownership of the file is NOT set until the application is installed
199     # using the webapp-config tool.
200 swegener 1.38 #
201 stuart 1.3 # @param $1 - file to be owned by the webserver user:group combo
202     #
203     # ------------------------------------------------------------------------
204    
205     function webapp_serverowned ()
206     {
207 rl03 1.39 local a=""
208     local m=""
209 wrobel 1.40 if [ "${1}" = "-R" ]; then
210 rl03 1.39 shift
211     for m in "$@" ; do
212     for a in $(find ${D}/${m}); do
213     a=${a/${D}\/\///}
214     webapp_checkfileexists "${a}" "$D"
215 wrobel 1.40 local MY_FILE="$(webapp_strip_appdir "${a}")"
216     MY_FILE="$(webapp_strip_cwd "${MY_FILE}")"
217 rl03 1.39
218     einfo "(server owned) ${MY_FILE}"
219     echo "${MY_FILE}" >> "${D}/${WA_SOLIST}"
220     done
221     done
222     else
223     for m in "$@" ; do
224     webapp_checkfileexists "${m}" "$D"
225 wrobel 1.40 local MY_FILE="$(webapp_strip_appdir "${m}")"
226     MY_FILE="$(webapp_strip_cwd "${MY_FILE}")"
227 rl03 1.39
228     einfo "(server owned) ${MY_FILE}"
229     echo "${MY_FILE}" >> "${D}/${WA_SOLIST}"
230     done
231     fi
232 stuart 1.3 }
233    
234     # ------------------------------------------------------------------------
235     # EXPORTED FUNCTION - FOR USE IN EBUILDS
236     #
237 stuart 1.18 # @param $1 - the webserver to install the config file for
238     # (one of apache1, apache2, cherokee)
239     # @param $2 - the config file to install
240     # @param $3 - new name for the config file (default is `basename $2`)
241     # this is an optional parameter
242     #
243     # NOTE:
244     # this function will automagically prepend $1 to the front of your
245     # config file's name
246     # ------------------------------------------------------------------------
247    
248 stuart 1.26 function webapp_server_configfile ()
249 stuart 1.18 {
250 stuart 1.37 webapp_checkfileexists "${2}"
251 stuart 1.18
252     # sort out what the name will be of the config file
253    
254     local my_file
255    
256 stuart 1.37 if [ -z "${3}" ]; then
257 wrobel 1.40 my_file="${1}-$(basename "${2}")"
258 stuart 1.18 else
259 stuart 1.37 my_file="${1}-${3}"
260 stuart 1.18 fi
261    
262     # warning:
263     #
264     # do NOT change the naming convention used here without changing all
265     # the other scripts that also rely upon these names
266 swegener 1.38
267 stuart 1.37 einfo "(${1}) config file '${my_file}'"
268     cp "${2}" "${D}/${MY_SERVERCONFIGDIR}/${my_file}"
269 stuart 1.18 }
270    
271     # ------------------------------------------------------------------------
272     # EXPORTED FUNCTION - FOR USE IN EBUILDS
273 stuart 1.3 #
274     # @param $1 - the db engine that the script is for
275     # (one of: mysql|postgres)
276     # @param $2 - the sql script to be installed
277     # @param $3 - the older version of the app that this db script
278     # will upgrade from
279     # (do not pass this option if your SQL script only creates
280     # a new db from scratch)
281     # ------------------------------------------------------------------------
282    
283     function webapp_sqlscript ()
284     {
285 stuart 1.37 webapp_checkfileexists "${2}"
286 stuart 1.3
287     # create the directory where this script will go
288     #
289     # scripts for specific database engines go into their own subdirectory
290     # just to keep things readable on the filesystem
291    
292 stuart 1.37 if [ ! -d "${D}/${MY_SQLSCRIPTSDIR}/${1}" ]; then
293     mkdir -p "${D}/${MY_SQLSCRIPTSDIR}/${1}" || die "unable to create directory ${D}/${MY_SQLSCRIPTSDIR}/${1}"
294 stuart 1.3 fi
295    
296     # warning:
297     #
298     # do NOT change the naming convention used here without changing all
299     # the other scripts that also rely upon these names
300 swegener 1.38
301 stuart 1.3 # are we dealing with an 'upgrade'-type script?
302 stuart 1.37 if [ -n "${3}" ]; then
303 stuart 1.3 # yes we are
304 stuart 1.37 einfo "(${1}) upgrade script from ${PN}-${PVR} to ${3}"
305     cp "${2}" "${D}${MY_SQLSCRIPTSDIR}/${1}/${3}_to_${PVR}.sql"
306     chmod 600 "${D}${MY_SQLSCRIPTSDIR}/${1}/${3}_to_${PVR}.sql"
307 stuart 1.3 else
308     # no, we are not
309 stuart 1.37 einfo "(${1}) create script for ${PN}-${PVR}"
310     cp "${2}" "${D}/${MY_SQLSCRIPTSDIR}/${1}/${PVR}_create.sql"
311     chmod 600 "${D}/${MY_SQLSCRIPTSDIR}/${1}/${PVR}_create.sql"
312 stuart 1.3 fi
313 stuart 1.1 }
314    
315     # ------------------------------------------------------------------------
316     # EXPORTED FUNCTION - call from inside your ebuild's src_install AFTER
317     # everything else has run
318     #
319     # For now, we just make sure that root owns everything, and that there
320 stuart 1.37 # are no setuid files.
321 stuart 1.1 # ------------------------------------------------------------------------
322    
323     function webapp_src_install ()
324     {
325 stuart 1.22 chown -R "${VHOST_DEFAULT_UID}:${VHOST_DEFAULT_GID}" "${D}/"
326     chmod -R u-s "${D}/"
327     chmod -R g-s "${D}/"
328    
329     keepdir "${MY_PERSISTDIR}"
330     fowners "root:root" "${MY_PERSISTDIR}"
331     fperms 755 "${MY_PERSISTDIR}"
332 stuart 1.15
333 stuart 1.19 # to test whether or not the ebuild has correctly called this function
334     # we add an empty file to the filesystem
335     #
336     # we used to just set a variable in the shell script, but we can
337     # no longer rely on Portage calling both webapp_src_install() and
338     # webapp_pkg_postinst() within the same shell process
339    
340 stuart 1.22 touch "${D}/${MY_APPDIR}/${INSTALL_CHECK_FILE}"
341 stuart 1.1 }
342    
343     # ------------------------------------------------------------------------
344 stuart 1.3 # EXPORTED FUNCTION - call from inside your ebuild's pkg_config AFTER
345 stuart 1.1 # everything else has run
346     #
347     # If 'vhosts' USE flag is not set, auto-install this app
348     #
349     # ------------------------------------------------------------------------
350    
351     function webapp_pkg_setup ()
352     {
353 stuart 1.15 # add sanity checks here
354    
355 stuart 1.37 if [ "${SLOT}+" != "${PVR}+" ]; then
356     # special case - some ebuilds *do* need to overwride the SLOT
357     if [ "${WEBAPP_MANUAL_SLOT}" != "yes" ]; then
358 dju 1.35 die "ebuild sets SLOT, overrides webapp.eclass"
359 stuart 1.37 else
360     ewarn
361     ewarn "This ebuild overrides the default SLOT behaviour for webapps"
362     ewarn "If this package installs files into the htdocs dir, this is"
363     ewarn "probably a bug in the ebuild."
364     ewarn
365 dju 1.35 fi
366 stuart 1.15 fi
367    
368 stuart 1.8 # pull in the shared configuration file
369    
370 stuart 1.18 G_HOSTNAME="localhost"
371 stuart 1.37 webapp_read_config
372 stuart 1.18
373 swegener 1.34 # are we installing a webapp-config solution over the top of a
374 stuart 1.18 # non-webapp-config solution?
375    
376     if ! use vhosts ; then
377 stuart 1.37 local my_dir="${ROOT}${VHOST_ROOT}/${MY_HTDOCSBASE}/${PN}"
378 stuart 1.18 local my_output
379    
380 stuart 1.37 if [ -d "${my_dir}" ] ; then
381     einfo "You already have something installed in ${my_dir}"
382 stuart 1.18 einfo "Are you trying to install over the top of something I cannot upgrade?"
383    
384 stuart 1.37 my_output="$(webapp_check_installedat)"
385 stuart 1.18
386     if [ "$?" != "0" ]; then
387    
388     # okay, whatever is there, it isn't webapp-config-compatible
389     ewarn
390 stuart 1.37 ewarn "Whatever is in ${my_dir}, it's not"
391 stuart 1.18 ewarn "compatible with webapp-config."
392     ewarn
393 stuart 1.20 ewarn "This ebuild may be overwriting important files."
394     ewarn
395 stuart 1.37 elif [ "$(echo ${my_output} | awk '{ print $1 }')" != "${PN}" ]; then
396     eerror "${my_dir} contains ${my_output}"
397 stuart 1.18 eerror "I cannot upgrade that"
398 stuart 1.37 die "Cannot upgrade contents of ${my_dir}"
399 stuart 1.18 else
400     einfo
401 stuart 1.37 einfo "I can upgrade the contents of ${my_dir}"
402 stuart 1.18 einfo
403     fi
404     fi
405     fi
406 stuart 1.14 }
407 stuart 1.6
408 stuart 1.18 function webapp_getinstalltype ()
409     {
410 stuart 1.14 # or are we upgrading?
411    
412     if ! use vhosts ; then
413     # we only run webapp-config if vhosts USE flag is not set
414    
415     local my_output
416    
417 stuart 1.37 my_output="$(webapp_check_installedat)"
418 stuart 1.14
419 stuart 1.37 if [ "${?}" = "0" ] ; then
420 stuart 1.14 # something is already installed there
421     #
422     # make sure it isn't the same version
423    
424 stuart 1.37 local my_pn="$(echo ${my_output} | awk '{ print $1 }')"
425     local my_pvr="$(echo ${my_output} | awk '{ print $2 }')"
426 stuart 1.14
427     REMOVE_PKG="${my_pn}-${my_pvr}"
428    
429 stuart 1.37 if [ "${my_pn}" == "${PN}" ]; then
430     if [ "${my_pvr}" != "${PVR}" ]; then
431 stuart 1.14 einfo "This is an upgrade"
432     IS_UPGRADE=1
433     else
434     einfo "This is a re-installation"
435     IS_REPLACE=1
436     fi
437 stuart 1.18 else
438 stuart 1.37 einfo "${my_output} is installed there"
439 stuart 1.14 fi
440 stuart 1.18 else
441     einfo "This is an installation"
442 stuart 1.14 fi
443     fi
444 stuart 1.9 }
445 stuart 1.3
446 stuart 1.9 function webapp_src_preinst ()
447     {
448 stuart 1.3 # create the directories that we need
449    
450 stuart 1.22 dodir "${MY_HTDOCSDIR}"
451     dodir "${MY_HOSTROOTDIR}"
452     dodir "${MY_CGIBINDIR}"
453     dodir "${MY_ICONSDIR}"
454     dodir "${MY_ERRORSDIR}"
455     dodir "${MY_SQLSCRIPTSDIR}"
456 stuart 1.25 dodir "${MY_HOOKSCRIPTSDIR}"
457 stuart 1.26 dodir "${MY_SERVERCONFIGDIR}"
458 stuart 1.3 }
459    
460 stuart 1.5 function webapp_pkg_postinst ()
461 stuart 1.3 {
462 stuart 1.37 webapp_read_config
463 stuart 1.21
464 stuart 1.15 # sanity checks, to catch bugs in the ebuild
465    
466 stuart 1.37 if [ ! -f "${ROOT}${MY_APPDIR}/${INSTALL_CHECK_FILE}" ]; then
467 stuart 1.15 eerror
468     eerror "This ebuild did not call webapp_src_install() at the end"
469     eerror "of the src_install() function"
470     eerror
471     eerror "Please log a bug on http://bugs.gentoo.org"
472     eerror
473     eerror "You should use emerge -C to remove this package, as the"
474     eerror "installation is incomplete"
475     eerror
476     die "Ebuild did not call webapp_src_install() - report to http://bugs.gentoo.org"
477     fi
478    
479 stuart 1.10 # if 'vhosts' is not set in your USE flags, we install a copy of
480 stuart 1.37 # this application in ${ROOT}/var/www/localhost/htdocs/${PN}/ for you
481 swegener 1.38
482 stuart 1.10 if ! use vhosts ; then
483 stuart 1.14 echo
484 stuart 1.11 einfo "vhosts USE flag not set - auto-installing using webapp-config"
485    
486 stuart 1.14 webapp_getinstalltype
487    
488 stuart 1.10 G_HOSTNAME="localhost"
489     local my_mode=-I
490 stuart 1.37 webapp_read_config
491 stuart 1.10
492 stuart 1.37 if [ "${IS_REPLACE}" = "1" ]; then
493 stuart 1.14 einfo "${PN}-${PVR} is already installed - replacing"
494 stuart 1.27 my_mode=-I
495 stuart 1.37 elif [ "${IS_UPGRADE}" = "1" ]; then
496     einfo "${REMOVE_PKG} is already installed - upgrading"
497 stuart 1.14 my_mode=-U
498 stuart 1.11 else
499     einfo "${PN}-${PVR} is not installed - using install mode"
500 stuart 1.10 fi
501 swegener 1.38
502 stuart 1.37 my_cmd="${WEBAPP_CONFIG} ${my_mode} -h localhost -u root -d ${INSTALL_DIR} ${PN} ${PVR}"
503     einfo "Running ${my_cmd}"
504     ${my_cmd}
505 stuart 1.14
506     # remove the old version
507     #
508     # why do we do this? well ...
509     #
510     # normally, emerge -u installs a new version and then removes the
511     # old version. however, if the new version goes into a different
512     # slot to the old version, then the old version gets left behind
513     #
514     # if USE=-vhosts, then we want to remove the old version, because
515     # the user is relying on portage to do the magical thing for it
516    
517 stuart 1.37 if [ "${IS_UPGRADE}" = "1" ] ; then
518     einfo "Removing old version ${REMOVE_PKG}"
519 stuart 1.14
520 stuart 1.37 emerge -C "${REMOVE_PKG}"
521 stuart 1.14 fi
522 stuart 1.18 else
523     # vhosts flag is on
524     #
525     # let's tell the administrator what to do next
526    
527     einfo
528     einfo "The 'vhosts' USE flag is switched ON"
529     einfo "This means that Portage will not automatically run webapp-config to"
530     einfo "complete the installation."
531     einfo
532 stuart 1.37 einfo "To install ${PN}-${PVR} into a virtual host, run the following command:"
533 stuart 1.18 einfo
534 stuart 1.37 einfo " webapp-config -I -h <host> -d ${PN} ${PN} ${PVR}"
535 stuart 1.18 einfo
536     einfo "For more details, see the webapp-config(8) man page"
537 stuart 1.10 fi
538 stuart 1.11
539     return 0
540 stuart 1.2 }
541 stuart 1.18
542     function webapp_pkg_prerm ()
543     {
544     # remove any virtual installs that there are
545    
546     local my_output
547     local x
548    
549 stuart 1.37 my_output="$(${WEBAPP_CONFIG} --list-installs ${PN} ${PVR})"
550 stuart 1.18
551 stuart 1.37 if [ "${?}" != "0" ]; then
552 stuart 1.18 return
553     fi
554    
555 stuart 1.37 for x in ${my_output} ; do
556     [ -f ${x}/.webapp ] && . ${x}/.webapp || ewarn "Cannot find file ${x}/.webapp"
557 stuart 1.18
558 stuart 1.37 if [ -z "${WEB_HOSTNAME}" -o -z "${WEB_INSTALLDIR}" ]; then
559 stuart 1.18 ewarn "Don't forget to use webapp-config to remove the copy of"
560     ewarn "${PN}-${PVR} installed in"
561     ewarn
562 stuart 1.37 ewarn " ${x}"
563 stuart 1.18 ewarn
564     else
565     # we have enough information to remove the virtual copy ourself
566    
567 stuart 1.37 ${WEBAPP_CONFIG} -C -h ${WEB_HOSTNAME} -d ${WEB_INSTALLDIR}
568 stuart 1.18
569     # if the removal fails - we carry on anyway!
570     fi
571     done
572     }

  ViewVC Help
Powered by ViewVC 1.1.20