source: npl/X/mkxf86config/functions.sh

Last change on this file was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100755
File size: 17.1 KB
Line 
1# Copyright 1999-2005 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2
3# $Header$
4
5RC_GOT_FUNCTIONS="yes"
6
7# daemontools dir
8SVCDIR="/var/lib/supervise"
9
10# Check /etc/conf.d/rc for a description of these ...
11svcdir="/var/lib/init.d"
12svclib="/lib/rcscripts"
13svcmount="no"
14svcfstype="tmpfs"
15svcsize=1024
16
17# Different types of dependencies
18deptypes="need use"
19# Different types of order deps
20ordtypes="before after"
21
22#
23# Internal variables
24#
25
26# Dont output to stdout?
27RC_QUIET_STDOUT="no"
28RC_VERBOSE=${RC_VERBOSE:-no}
29
30# Should we use color?
31RC_NOCOLOR=${RC_NOCOLOR:-no}
32# Can the terminal handle endcols?
33RC_ENDCOL="yes"
34
35#
36# Default values for rc system
37#
38RC_TTY_NUMBER=11
39RC_NET_STRICT_CHECKING="no"
40RC_PARALLEL_STARTUP="no"
41RC_USE_CONFIG_PROFILE="yes"
42
43#
44# Default values for e-message indentation and dots
45#
46RC_INDENTATION=''
47RC_DEFAULT_INDENT=2
48#RC_DOT_PATTERN=' .'
49RC_DOT_PATTERN=''
50
51# Override defaults with user settings ...
52[ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
53
54# void import_addon(char *addon)
55#
56#  Import code from the specified addon if it exists
57#
58import_addon() {
59        local addon=${svclib}/addons/$1
60        if [[ -r ${addon} ]] ; then
61                source "${addon}"
62                return 0
63        fi
64        return 1
65}
66
67# void splash(...)
68#
69#  Notify bootsplash/splashutils/gensplash/whatever about
70#  important events.
71#
72splash() {
73        return 0
74}
75# This will override the splash() function...
76if ! import_addon splash-functions.sh ; then
77        [ -f /sbin/splash-functions.sh ] && source /sbin/splash-functions.sh
78fi
79
80# void profiling(...)
81#
82#  Notify bootsplash/whatever about important events.
83#
84profiling() {
85        return 0
86}
87import_addon profiling-functions.sh
88
89# void bootlog(...)
90#
91#  Notify bootlogger about important events.
92bootlog() {
93        return 0
94}
95import_addon bootlogger.sh
96
97# void get_bootconfig()
98#
99#    Get the BOOTLEVEL and SOFTLEVEL by setting
100#    'bootlevel' and 'softlevel' via kernel
101#    parameters.
102#
103get_bootconfig() {
104        local copt=
105        local newbootlevel=
106        local newsoftlevel=
107
108        if [[ -r /proc/cmdline ]] ; then
109                for copt in $(</proc/cmdline) ; do
110                        case "${copt%=*}" in
111                                bootlevel)
112                                        newbootlevel=${copt##*=}
113                                        ;;
114                                softlevel)
115                                        newsoftlevel=${copt##*=}
116                                        ;;
117                        esac
118                done
119        fi
120
121        if [[ -n ${newbootlevel} ]] ; then
122                export BOOTLEVEL=${newbootlevel}
123        else
124                export BOOTLEVEL="boot"
125        fi
126
127        if [[ -n ${newsoftlevel} ]] ; then
128                export DEFAULTLEVEL=${newsoftlevel}
129        else
130                export DEFAULTLEVEL="default"
131        fi
132
133        return 0
134}
135
136setup_defaultlevels() {
137        get_bootconfig
138
139        if get_bootparam "noconfigprofile" ; then
140                export RC_USE_CONFIG_PROFILE="no"
141
142        elif get_bootparam "configprofile" ; then
143                export RC_USE_CONFIG_PROFILE="yes"
144        fi
145
146        if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -n "${DEFAULTLEVEL}" ] && \
147           [ -d "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" -o \
148             -L "/etc/runlevels/${BOOTLEVEL}.${DEFAULTLEVEL}" ]
149        then
150                export BOOTLEVEL="${BOOTLEVEL}.${DEFAULTLEVEL}"
151        fi
152
153        if [ -z "${SOFTLEVEL}" ] ; then
154                if [ -f "${svcdir}/softlevel" ] ; then
155                        export SOFTLEVEL="$(< ${svcdir}/softlevel)"
156                else
157                        export SOFTLEVEL="${BOOTLEVEL}"
158                fi
159        fi
160
161        return 0
162}
163
164# void get_libdir(void)
165#
166#    prints the current libdir {lib,lib32,lib64}
167#
168get_libdir() {
169        if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
170                CONF_LIBDIR="${CONF_LIBDIR_OVERRIDE}"
171        elif [ -x "/usr/bin/portageq" ] ; then
172                CONF_LIBDIR="$(/usr/bin/portageq envvar CONF_LIBDIR)"
173        fi
174        echo ${CONF_LIBDIR:=lib}
175}
176
177# void esyslog(char* priority, char* tag, char* message)
178#
179#    use the system logger to log a message
180#
181esyslog() {
182        local pri=
183        local tag=
184
185        if [ -x /usr/bin/logger ]
186        then
187                pri="$1"
188                tag="$2"
189
190                shift 2
191                [[ -z "$*" ]] && return 0
192
193                /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
194        fi
195
196        return 0
197}
198
199# void eindent(int num)
200#
201#    increase the indent used for e-commands.
202#
203eindent() {
204        local i=$1
205        (( i > 0 )) || (( i = RC_DEFAULT_INDENT ))
206        esetdent $(( ${#RC_INDENTATION} + i ))
207}
208
209# void eoutdent(int num)
210#
211#    decrease the indent used for e-commands.
212#
213eoutdent() {
214        local i=$1
215        (( i > 0 )) || (( i = RC_DEFAULT_INDENT ))
216        esetdent $(( ${#RC_INDENTATION} - i ))
217}
218
219# void esetdent(int num)
220#
221#    hard set the indent used for e-commands.
222#    num defaults to 0
223#
224esetdent() {
225        local i=$1
226        (( i < 0 )) && (( i = 0 ))
227        RC_INDENTATION=$(printf "%${i}s" '')
228}
229
230# void einfo(char* message)
231#
232#    show an informative message (with a newline)
233#
234einfo() {
235        einfon "$*\n"
236        LAST_E_CMD=einfo
237        return 0
238}
239
240# void einfon(char* message)
241#
242#    show an informative message (without a newline)
243#
244einfon() {
245        [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
246        [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
247        echo -ne " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
248        LAST_E_CMD=einfon
249        return 0
250}
251
252# void ewarn(char* message)
253#
254#    show a warning message + log it
255#
256ewarn() {
257        if [[ ${RC_QUIET_STDOUT} == yes ]]; then
258                echo " $*"
259        else
260                [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
261                echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}$*"
262        fi
263
264        # Log warnings to system log
265        esyslog "daemon.warning" "rc-scripts" "$*"
266
267        LAST_E_CMD=ewarn
268        return 0
269}
270
271# void eerror(char* message)
272#
273#    show an error message + log it
274#
275eerror() {
276        if [[ ${RC_QUIET_STDOUT} == yes ]]; then
277                echo " $*" >/dev/stderr
278        else
279                [[ ${RC_ENDCOL} != yes && ${LAST_E_CMD} == ebegin ]] && echo
280                echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}$*"
281        fi
282
283        # Log errors to system log
284        esyslog "daemon.err" "rc-scripts" "$*"
285
286        LAST_E_CMD=eerror
287        return 0
288}
289
290# void ebegin(char* message)
291#
292#    show a message indicating the start of a process
293#
294ebegin() {
295        local msg="$*" dots spaces=${RC_DOT_PATTERN//?/ }
296        [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
297
298        if [[ -n ${RC_DOT_PATTERN} ]]; then
299                dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')
300                dots=${dots//${spaces}/${RC_DOT_PATTERN}}
301                msg="${msg}${dots}"
302        else
303                msg="${msg} ..."
304        fi
305        einfon "${msg}"
306        [[ ${RC_ENDCOL} == yes ]] && echo
307
308        LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
309        LAST_E_CMD=ebegin
310        return 0
311}
312
313# void _eend(int error, char *efunc, char* errstr)
314#
315#    indicate the completion of process, called from eend/ewend
316#    if error, show errstr via efunc
317#
318#    This function is private to functions.sh.  Do not call it from a
319#    script.
320#
321_eend() {
322        local retval=${1:-0} efunc=${2:-eerror} msg
323        shift 2
324
325        if [[ ${retval} == 0 ]]; then
326                [[ ${RC_QUIET_STDOUT} == yes ]] && return 0
327                msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
328        else
329                if [[ -c /dev/null ]]; then
330                        rc_splash "stop" &>/dev/null &
331                else
332                        rc_splash "stop" &
333                fi
334                if [[ -n "$*" ]]; then
335                        ${efunc} "$*"
336                fi
337                msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
338        fi
339
340        if [[ ${RC_ENDCOL} == yes ]]; then
341                echo -e "${ENDCOL}  ${msg}"
342        else
343                [[ ${LAST_E_CMD} == ebegin ]] || LAST_E_LEN=0
344                printf "%$(( COLS - LAST_E_LEN - 6 ))s%b\n" '' "${msg}"
345        fi
346
347        return ${retval}
348}
349
350# void eend(int error, char* errstr)
351#
352#    indicate the completion of process
353#    if error, show errstr via eerror
354#
355eend() {
356        local retval=${1:-0}
357        shift
358
359        _eend ${retval} eerror "$*"
360
361        LAST_E_CMD=eend
362        return $retval
363}
364
365# void ewend(int error, char* errstr)
366#
367#    indicate the completion of process
368#    if error, show errstr via ewarn
369#
370ewend() {
371        local retval=${1:-0}
372        shift
373
374        _eend ${retval} ewarn "$*"
375
376        LAST_E_CMD=ewend
377        return $retval
378}
379
380# v-e-commands honor RC_VERBOSE which defaults to no.
381# The condition is negated so the return value will be zero.
382veinfo() { [[ "${RC_VERBOSE}" != yes ]] || einfo "$@"; }
383veinfon() { [[ "${RC_VERBOSE}" != yes ]] || einfon "$@"; }
384vewarn() { [[ "${RC_VERBOSE}" != yes ]] || ewarn "$@"; }
385veerror() { [[ "${RC_VERBOSE}" != yes ]] || eerror "$@"; }
386vebegin() { [[ "${RC_VERBOSE}" != yes ]] || ebegin "$@"; }
387veend() {
388        [[ "${RC_VERBOSE}" == yes ]] && { eend "$@"; return $?; }
389        return ${1:-0}
390}
391veend() {
392        [[ "${RC_VERBOSE}" == yes ]] && { ewend "$@"; return $?; }
393        return ${1:-0}
394}
395
396# char *KV_major(string)
397#
398#    Return the Major (X of X.Y.Z) kernel version
399#
400KV_major() {
401        [[ -z $1 ]] && return 1
402
403        local KV=$@
404        echo ${KV%%.*}
405}
406
407# char *KV_minor(string)
408#
409#    Return the Minor (Y of X.Y.Z) kernel version
410#
411KV_minor() {
412        [[ -z $1 ]] && return 1
413
414        local KV=$@
415        KV=${KV#*.}
416        echo ${KV%%.*}
417}
418
419# char *KV_micro(string)
420#
421#    Return the Micro (Z of X.Y.Z) kernel version.
422#
423KV_micro() {
424        [[ -z $1 ]] && return 1
425
426        local KV=$@
427        KV=${KV#*.*.}
428        echo ${KV%%[^[:digit:]]*}
429}
430
431# int KV_to_int(string)
432#
433#    Convert a string type kernel version (2.4.0) to an int (132096)
434#    for easy compairing or versions ...
435#
436KV_to_int() {
437        [[ -z $1 ]] && return 1
438
439        local KV_MAJOR=$(KV_major "$1")
440        local KV_MINOR=$(KV_minor "$1")
441        local KV_MICRO=$(KV_micro "$1")
442        local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))
443
444        # We make version 2.2.0 the minimum version we will handle as
445        # a sanity check ... if its less, we fail ...
446        if [[ ${KV_int} -ge 131584 ]] ; then
447                echo "${KV_int}"
448                return 0
449        fi
450
451        return 1
452}
453
454# int get_KV()
455#
456#    Return the kernel version (major, minor and micro concated) as an integer.
457#    Assumes X and Y of X.Y.Z are numbers.  Also assumes that some leading
458#    portion of Z is a number.
459#    e.g. 2.4.25, 2.6.10, 2.6.4-rc3, 2.2.40-poop, 2.0.15+foo
460#
461get_KV() {
462        local KV=$(uname -r)
463
464        echo $(KV_to_int "${KV}")
465
466        return $?
467}
468
469# bool get_bootparam(param)
470#
471#   return 0 if gentoo=param was passed to the kernel
472#
473#   EXAMPLE:  if get_bootparam "nodevfs" ; then ....
474#
475get_bootparam() {
476        local x copt params retval=1
477
478        [ ! -r "/proc/cmdline" ] && return 1
479
480        for copt in $(< /proc/cmdline)
481        do
482                if [ "${copt%=*}" = "gentoo" ]
483                then
484                        params="$(gawk -v PARAMS="${copt##*=}" '
485                                BEGIN {
486                                        split(PARAMS, nodes, ",")
487                                        for (x in nodes)
488                                                print nodes[x]
489                                }')"
490
491                        # Parse gentoo option
492                        for x in ${params}
493                        do
494                                if [ "${x}" = "$1" ]
495                                then
496#                                       echo "YES"
497                                        retval=0
498                                fi
499                        done
500                fi
501        done
502
503        return ${retval}
504}
505
506# Safer way to list the contents of a directory,
507# as it do not have the "empty dir bug".
508#
509# char *dolisting(param)
510#
511#    print a list of the directory contents
512#
513#    NOTE: quote the params if they contain globs.
514#          also, error checking is not that extensive ...
515#
516dolisting() {
517        local x=
518        local y=
519        local tmpstr=
520        local mylist=
521        local mypath="$*"
522
523        if [ "${mypath%/\*}" != "${mypath}" ]
524        then
525                mypath="${mypath%/\*}"
526        fi
527
528        for x in ${mypath}
529        do
530                [ ! -e "${x}" ] && continue
531
532                if [ ! -d "${x}" ] && ( [ -L "${x}" -o -f "${x}" ] )
533                then
534                        mylist="${mylist} $(ls "${x}" 2> /dev/null)"
535                else
536                        [ "${x%/}" != "${x}" ] && x="${x%/}"
537
538                        cd "${x}"; tmpstr="$(ls)"
539
540                        for y in ${tmpstr}
541                        do
542                                mylist="${mylist} ${x}/${y}"
543                        done
544                fi
545        done
546
547        echo "${mylist}"
548}
549
550# void save_options(char *option, char *optstring)
551#
552#    save the settings ("optstring") for "option"
553#
554save_options() {
555        local myopts="$1"
556
557        shift
558        if [ ! -d "${svcdir}/options/${myservice}" ]
559        then
560                mkdir -p -m 0755 "${svcdir}/options/${myservice}"
561        fi
562
563        echo "$*" > "${svcdir}/options/${myservice}/${myopts}"
564
565        return 0
566}
567
568# char *get_options(char *option)
569#
570#    get the "optstring" for "option" that was saved
571#    by calling the save_options function
572#
573get_options() {
574        if [ -f "${svcdir}/options/${myservice}/$1" ]
575        then
576                echo "$(< ${svcdir}/options/${myservice}/$1)"
577        fi
578
579        return 0
580}
581
582# char *add_suffix(char * configfile)
583#
584#    Returns a config file name with the softlevel suffix
585#    appended to it.  For use with multi-config services.
586add_suffix() {
587        if [ "${RC_USE_CONFIG_PROFILE}" = "yes" -a -e "$1.${DEFAULTLEVEL}" ]
588        then
589                echo "$1.${DEFAULTLEVEL}"
590        else
591                echo "$1"
592        fi
593
594        return 0
595}
596
597# char *get_base_ver()
598#
599#    get the version of baselayout that this system is running
600#
601get_base_ver() {
602        [[ ! -r /etc/gentoo-release ]] && return 0
603        local ver=$(</etc/gentoo-release)
604        echo ${ver##* }
605}
606
607# Network filesystems list for common use in rc-scripts.
608# This variable is used in is_net_fs and other places such as
609# localmount.
610NET_FS_LIST="afs cifs coda davfs gfs ncpfs nfs nfs4 shfs smbfs"
611
612# bool is_net_fs(path)
613#
614#   return 0 if path is the mountpoint of a networked filesystem
615#
616#   EXAMPLE:  if is_net_fs / ; then ...
617#
618is_net_fs() {
619        local fstype
620        # /proc/mounts is always accurate but may not always be available
621        if [[ -e /proc/mounts ]]; then
622                fstype=$( sed -n -e '/^rootfs/!s:.* '"$1"' \([^ ]*\).*:\1:p' /proc/mounts )
623        else
624                fstype=$( mount | sed -n -e 's:.* on '"$1"' type \([^ ]*\).*:\1:p' )
625        fi
626        [[ " ${NET_FS_LIST} " == *" ${fstype} "* ]]
627        return $?
628}
629
630# bool is_uml_sys()
631#
632#   return 0 if the currently running system is User Mode Linux
633#
634#   EXAMPLE:  if is_uml_sys ; then ...
635#
636is_uml_sys() {
637        grep -qs 'UML' /proc/cpuinfo
638        return $?
639}
640
641# bool is_vserver_sys()
642#
643#   return 0 if the currently running system is a Linux VServer
644#
645#   EXAMPLE:  if is_vserver_sys ; then ...
646#
647is_vserver_sys() {
648        grep -qs '^s_context:[[:space:]]*[1-9]' /proc/self/status
649        return $?
650}
651
652# bool is_xenU_sys()
653#
654#   return 0 if the currently running system is an unprivileged Xen domain
655#
656#   EXAMPLE:  if is_xenU_sys ; then ...
657#
658is_xenU_sys() {
659        [[ -d /proc/xen && ! -f /proc/xen/privcmd ]]
660}
661
662# bool get_mount_fstab(path)
663#
664#   return the parameters to pass to the mount command generated from fstab
665#
666#   EXAMPLE: cmd=$( get_mount_fstab /proc )
667#            cmd=${cmd:--t proc none /proc}
668#            mount -n ${cmd}
669#
670get_mount_fstab() {
671        awk '$1 ~ "^#" { next }
672             $2 == "'$*'" { if (found++ == 0) { print "-t "$3,"-o "$4,$1,$2 } }
673             END { if (found > 1) { print "More than one entry for '$*' found in /etc/fstab!" > "/dev/stderr" } }
674        ' /etc/fstab
675}
676
677# char *reverse_list(list)
678#
679#   Returns the reversed order of list
680#
681reverse_list() {
682        for (( i = $# ; i > 0 ; --i )); do
683                echo -n "${!i} "
684        done
685}
686
687# void start_addon(addon)
688#
689#   Starts addon.
690#
691start_addon() {
692        local addon=$1
693        (import_addon ${addon}-start.sh)
694        return 0
695}
696
697# void start_volumes()
698#
699#   Starts all volumes in RC_VOLUME_ORDER.
700#
701start_volumes() {
702        local x=
703
704        for x in ${RC_VOLUME_ORDER}; do
705                start_addon "${x}"
706        done
707
708        return 0
709}
710
711# void stop_addon(addon)
712#
713#   Stops addon.
714#
715stop_addon() {
716        local addon=$1
717        (import_addon ${addon}-stop.sh)
718        return 0
719}
720
721# void stop_volumes()
722#
723#   Stops all volumes in RC_VOLUME_ORDER (reverse order).
724#
725stop_volumes() {
726        local x=
727
728        for x in $(reverse_list ${RC_VOLUME_ORDER}); do
729                stop_addon "${x}"
730        done
731
732        return 0
733}
734
735# bool is_older_than(reference, files/dirs to check)
736#
737#   return 0 if any of the files/dirs are newer than
738#   the reference file
739#
740#   EXAMPLE: if is_older_than a.out *.o ; then ...
741is_older_than() {
742        local x=
743        local ref="$1"
744        shift
745
746        for x in "$@" ; do
747                [[ ${x} -nt ${ref} ]] && return 0
748
749                if [[ -d ${x} ]] ; then
750                        is_older_than "${ref}" "${x}"/* && return 0
751                fi
752        done
753
754        return 1
755}
756
757
758##############################################################################
759#                                                                            #
760# This should be the last code in here, please add all functions above!!     #
761#                                                                            #
762# *** START LAST CODE ***                                                    #
763#                                                                            #
764##############################################################################
765
766if [ -z "${EBUILD}" ] ; then
767        # Setup a basic $PATH.  Just add system default to existing.
768        # This should solve both /sbin and /usr/sbin not present when
769        # doing 'su -c foo', or for something like:  PATH= rcscript start
770        PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:${PATH}"
771
772        if [ "$(/sbin/consoletype 2> /dev/null)" = "serial" ] ; then
773                # We do not want colors/endcols on serial terminals
774                RC_NOCOLOR="yes"
775                RC_ENDCOL="no"
776        fi
777
778        for arg in "$@" ; do
779                case "${arg}" in
780                        # Lastly check if the user disabled it with --nocolor argument
781                        --nocolor|-nc)
782                                RC_NOCOLOR="yes"
783                                ;;
784                esac
785        done
786
787        if [ -r "/proc/cmdline" ] ; then
788                setup_defaultlevels
789        fi
790else
791        # Should we use colors ?
792        if [[ $* != *depend* ]]; then
793                # Check user pref in portage
794                RC_NOCOLOR="$(portageq envvar NOCOLOR 2>/dev/null)"
795                [ "${RC_NOCOLOR}" = "true" ] && RC_NOCOLOR="yes"
796        else
797                # We do not want colors during emerge depend
798                RC_NOCOLOR="yes"
799                # No output is seen during emerge depend, so this is not needed.
800                RC_ENDCOL="no"
801        fi
802fi
803
804if [[ -n ${EBUILD} && $* == *depend* ]]; then
805        # We do not want stty to run during emerge depend
806        COLS=80
807else
808        # Setup COLS and ENDCOL so eend can line up the [ ok ]
809        COLS=${COLUMNS:-0}              # bash's internal COLUMNS variable
810        (( COLS == 0 )) && COLS=$(stty size 2>/dev/null | cut -d' ' -f2)
811        (( COLS > 0 )) || (( COLS = 80 ))       # width of [ ok ] == 7
812fi
813
814if [[ ${RC_ENDCOL} == yes ]]; then
815        ENDCOL=$'\e[A\e['$(( COLS - 7 ))'G'
816else
817        ENDCOL=''
818fi
819
820# Setup the colors so our messages all look pretty
821if [[ ${RC_NOCOLOR} == yes ]]; then
822        unset GOOD WARN BAD NORMAL HILITE BRACKET
823else
824        GOOD=$'\e[32;01m'
825        WARN=$'\e[33;01m'
826        BAD=$'\e[31;01m'
827        NORMAL=$'\e[0m'
828        HILITE=$'\e[36;01m'
829        BRACKET=$'\e[34;01m'
830fi
831
832##############################################################################
833#                                                                            #
834# *** END LAST CODE ***                                                      #
835#                                                                            #
836# This should be the last code in here, please add all functions above!!     #
837#                                                                            #
838##############################################################################
839
840
841# vim:ts=4
Note: See TracBrowser for help on using the repository browser.