/[baselayout]/trunk/sbin/runscript.sh
Gentoo

Contents of /trunk/sbin/runscript.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1959 - (show annotations) (download) (as text)
Wed Apr 5 17:44:34 2006 UTC (8 years, 8 months ago) by uberlord
File MIME type: text/x-sh
File size: 17814 byte(s)
    runscript.sh now stores the fact that it failed to to /dev/.rcsysinit
    existing in the directory /dev/.rcafterinit. rc adds services in
    /dev/.rcafterinit to the boot list and then rm -f's that directory. This
    solves the issue of udev-089 forcing coldplug removal.
1 #!/bin/bash
2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # Common functions
6 [[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
7
8 # User must be root to run most script stuff (except status)
9 if [[ ${EUID} != "0" ]] && ! [[ $2 == "status" && $# -eq 2 ]] ; then
10 eerror "$0: must be root to run init scripts"
11 exit 1
12 fi
13
14 myscript="$1"
15 if [[ -L $1 && ! -L "/etc/init.d/${1##*/}" ]] ; then
16 SVCNAME="$(readlink "$1")"
17 else
18 SVCNAME="$1"
19 fi
20
21 declare -r SVCNAME="${SVCNAME##*/}"
22 export SVCNAME
23 # Support deprecated myservice variable
24 myservice="${SVCNAME}"
25
26 # Stop init scripts from working until sysinit completes
27 if [[ -e /dev/.rcsysinit ]] ; then
28 eerror "ERROR: cannot run ${SVCNAME} until sysinit completes"
29 # Try to add this service to a queue when sysinit has completed
30 [[ ! -d /dev/.rcafterinit ]] && mkdir /dev/.rcafterinit
31 ln -snf "$1" /dev/.rcafterinit/"${SVCNAME}"
32 exit 1
33 fi
34
35 svc_trap() {
36 trap 'eerror "ERROR: ${SVCNAME} caught an interrupt"; exit 1' \
37 INT QUIT TSTP
38 }
39
40 # Setup a default trap
41 svc_trap
42
43 # State variables
44 svcpause="no"
45 svcrestart="no"
46
47 # Functions to handle dependencies and services
48 [[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
49 # Functions to control daemons
50 [[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh"
51
52 if [[ ${SVCNAME%%.*} == "net" && ${SVCNAME#*.} != "${SVCNAME}" ]] ; then
53 NETSERVICE="yes"
54 else
55 NETSERVICE="no"
56 fi
57
58 # Check if the textdomain is non-default
59 search_lang="${LC_ALL:-${LC_MESSAGES:-${LANG}}}"
60 [[ -f ${TEXTDOMAINDIR}/${search_lang%.*}/LC_MESSAGES/${myservice}.mo ]] \
61 && TEXTDOMAIN="${myservice}"
62
63 # Source configuration files.
64 # (1) Source /etc/conf.d/net if it is a net.* service
65 # (2) Source /etc/conf.d/${SVCNAME} to get initscript-specific
66 # configuration (if it exists).
67 # (3) Source /etc/rc.conf to pick up potentially overriding
68 # configuration, if the system administrator chose to put it
69 # there (if it exists).
70 if [[ ${NETSERVICE} == "yes" ]] ; then
71 conf="$(add_suffix /etc/conf.d/net)"
72 [[ -e ${conf} ]] && source "${conf}"
73 fi
74 conf="$(add_suffix "/etc/conf.d/${SVCNAME}")"
75 [[ -e ${conf} ]] && source "${conf}"
76 conf="$(add_suffix /etc/rc.conf)"
77 [[ -e ${conf} ]] && source "${conf}"
78
79 mylevel="${SOFTLEVEL}"
80 [[ ${SOFTLEVEL} == "${BOOTLEVEL}" \
81 || ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] \
82 && mylevel="${DEFAULTLEVEL}"
83
84 # Call svc_quit if we abort AND we have obtained a lock
85 service_started "${SVCNAME}"
86 svcstarted="$?"
87 service_inactive "${SVCNAME}"
88 svcinactive="$?"
89 svc_quit() {
90 eerror "ERROR: ${SVCNAME} caught an interrupt"
91 if service_inactive "${SVCNAME}" || [[ ${svcinactive} == "0" ]] ; then
92 mark_service_inactive "${SVCNAME}"
93 elif [[ ${svcstarted} == "0" ]] ; then
94 mark_service_started "${SVCNAME}"
95 else
96 mark_service_stopped "${SVCNAME}"
97 fi
98 exit 1
99 }
100
101 usage() {
102 local IFS="|"
103 myline="Usage: ${SVCNAME} { $* "
104 echo
105 eerror "${myline}}"
106 eerror " ${SVCNAME} without arguments for full help"
107 }
108
109 stop() {
110 # Return success so the symlink gets removed
111 return 0
112 }
113
114 start() {
115 eerror "ERROR: ${SVCNAME} does not have a start function."
116 # Return failure so the symlink doesn't get created
117 return 1
118 }
119
120 restart() {
121 svc_restart
122 }
123
124 status() {
125 # Dummy function
126 return 0
127 }
128
129 svc_schedule_start() {
130 local service="$1" start="$2"
131 [[ ! -d "${svcdir}/scheduled/${service}" ]] \
132 && mkdir -p "${svcdir}/scheduled/${service}"
133 [[ ! -e "${svcdir}/scheduled/${service}/${start}" ]] \
134 && ln -snf "/etc/init.d/${service}" \
135 "${svcdir}/scheduled/${service}/${start}"
136 }
137
138 svc_start_scheduled() {
139 [[ ! -d "${svcdir}/scheduled/${SVCNAME}" ]] && return
140 local x= services=
141
142 for x in $(dolisting "${svcdir}/scheduled/${SVCNAME}/") ; do
143 services="${services} ${x##*/}"
144 done
145
146 for x in ${services} ; do
147 service_stopped "${x}" && start_service "${x}"
148 rm -f "${svcdir}/scheduled/${SVCNAME}/${x}"
149 done
150
151 rmdir "${svcdir}/scheduled/${SVCNAME}"
152 }
153
154 svc_stop() {
155 local x= mydep= mydeps= retval=0
156 local -a servicelist=()
157
158 # Do not try to stop if it had already failed to do so
159 if is_runlevel_stop && service_failed "${SVCNAME}" ; then
160 return 1
161 elif service_stopped "${SVCNAME}" ; then
162 ewarn "WARNING: ${SVCNAME} has not yet been started."
163 return 0
164 fi
165 if ! mark_service_stopping "${SVCNAME}" ; then
166 eerror "ERROR: ${SVCNAME} is already stopping."
167 return 1
168 fi
169
170 # Ensure that we clean up if we abort for any reason
171 trap "svc_quit" INT QUIT TSTP
172
173 mark_service_starting "${SVCNAME}"
174 service_message "Service ${SVCNAME} stopping"
175
176 if in_runlevel "${SVCNAME}" "${BOOTLEVEL}" && \
177 [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" && \
178 ${SOFTLEVEL} != "single" ]] ; then
179 ewarn "WARNING: you are stopping a boot service."
180 fi
181
182 if [[ ${svcpause} != "yes" && ${RC_NO_DEPS} != "yes" ]] ; then
183 if [[ ${NETSERVICE} == "yes" ]] ; then
184 # A net.* service
185 if in_runlevel "${SVCNAME}" "${BOOTLEVEL}" || \
186 in_runlevel "${SVCNAME}" "${mylevel}" ; then
187 # Only worry about net.* services if this is the last one
188 # running or if RC_NET_STRICT_CHECKING is set ...
189 ! is_net_up && mydeps="net"
190 fi
191 mydeps="${mydeps} ${SVCNAME}"
192 else
193 mydeps="${SVCNAME}"
194 fi
195 fi
196
197 # Save the IN_BACKGROUND var as we need to clear it for stopping depends
198 local ib_save="${IN_BACKGROUND}"
199 unset IN_BACKGROUND
200
201 for mydep in ${mydeps} ; do
202 for x in $(needsme "${mydep}") ; do
203 # Service not currently running, continue
204 if service_started "${x}" ; then
205 stop_service "${x}"
206 service_list=( "${service_list[@]}" "${x}" )
207 fi
208 done
209 done
210
211 for x in "${service_list[@]}" ; do
212 # We need to test if the service has been marked stopped
213 # as the fifo may still be around if called by custom code
214 # such as postup from a net script.
215 service_stopped "${mynetservice}" && continue
216
217 wait_service "${x}"
218 if ! service_stopped "${x}" ; then
219 retval=1
220 break
221 fi
222 done
223
224 IN_BACKGROUND="${ib_save}"
225
226 if [[ ${retval} != "0" ]] ; then
227 eerror "ERROR: problems stopping dependent services."
228 eerror " ${SVCNAME} is still up."
229 else
230 # Now that deps are stopped, stop our service
231 (
232 exit() {
233 RC_QUIET_STDOUT="no"
234 eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
235 eerror "This IS a bug, please fix your broken init.d"
236 unset -f exit
237 exit "$@"
238 }
239 # Stop einfo/ebegin/eend from working as parallel messes us up
240 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
241 stop
242 )
243 retval="$?"
244
245 # If a service has been marked inactive, exit now as something
246 # may attempt to start it again later
247 if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
248 svcinactive=0
249 return 0
250 fi
251 fi
252
253 if [[ ${retval} != 0 ]] ; then
254 # Did we fail to stop? create symlink to stop multible attempts at
255 # runlevel change. Note this is only used at runlevel change ...
256 is_runlevel_stop && mark_service_failed "${SVCNAME}"
257
258 # If we are halting the system, do it as cleanly as possible
259 if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
260 mark_service_stopped "${SVCNAME}"
261 else
262 if [[ ${svcinactive} == "0" ]] ; then
263 mark_service_inactive "${SVCNAME}"
264 else
265 mark_service_started "${SVCNAME}"
266 fi
267 fi
268
269 service_message "eerror" "ERROR: ${SVCNAME} failed to stop"
270 else
271 svcstarted=1
272 if service_inactive "${SVCNAME}" ; then
273 svcinactive=0
274 else
275 mark_service_stopped "${SVCNAME}"
276 fi
277 service_message "Service ${SVCNAME} stopped"
278 fi
279
280 # Reset the trap
281 svc_trap
282
283 return "${retval}"
284 }
285
286 svc_start() {
287 local x= y= retval=0 startfail= startinactive=
288
289 # Do not try to start if i have done so already on runlevel change
290 if is_runlevel_start && service_failed "${SVCNAME}" ; then
291 return 1
292 elif service_started "${SVCNAME}" ; then
293 ewarn "WARNING: ${SVCNAME} has already been started."
294 return 0
295 elif service_inactive "${SVCNAME}" ; then
296 if [[ ${IN_BACKGROUND} != "true" ]] ; then
297 ewarn "WARNING: ${SVCNAME} has already been started."
298 return 0
299 fi
300 fi
301
302 if ! mark_service_starting "${SVCNAME}" ; then
303 if service_stopping "${SVCNAME}" ; then
304 eerror "ERROR: ${SVCNAME} is already stopping."
305 else
306 eerror "ERROR: ${SVCNAME} is already starting."
307 fi
308 return 1
309 fi
310
311 # Ensure that we clean up if we abort for any reason
312 trap "svc_quit" INT QUIT TSTP
313
314 service_message "Service ${SVCNAME} starting"
315
316 if broken "${SVCNAME}" ; then
317 eerror "ERROR: Some services needed are missing. Run"
318 eerror " './${SVCNAME} broken' for a list of those"
319 eerror " services. ${SVCNAME} was not started."
320 retval=1
321 fi
322
323 # Save the IN_BACKGROUND var as we need to clear it for starting depends
324 local ib_save="${IN_BACKGROUND}"
325 unset IN_BACKGROUND
326
327 if [[ ${retval} == "0" && ${RC_NO_DEPS} != "yes" ]] ; then
328 local startupservices="$(ineed "${SVCNAME}") $(valid_iuse "${SVCNAME}")"
329 local netservices=
330 for x in $(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
331 $(dolisting "/etc/runlevels/${mylevel}/net.*") ; do
332 netservices="${netservices} ${x##*/}"
333 done
334
335 # Start dependencies, if any.
336 if ! is_runlevel_start ; then
337 for x in ${startupservices} ; do
338 if [[ ${x} == "net" && ${NETSERVICE} != "yes" ]] && ! is_net_up ; then
339 for y in ${netservices} ; do
340 service_stopped "${y}" && start_service "${y}"
341 done
342 elif [[ ${x} != "net" ]] ; then
343 if service_stopped "${x}" ; then
344 start_service "${x}"
345 fi
346 fi
347 done
348 fi
349
350 # We also wait for any services we're after to finish incase they
351 # have a "before" dep but we don't dep on them.
352 if is_runlevel_start ; then
353 startupservices="${startupservices} $(valid_iafter "${SVCNAME}")"
354 fi
355
356 if [[ " ${startupservices} " == *" net "* ]] ; then
357 startupservices=" ${startupservices} "
358 startupservices="${startupservices/ net / ${netservices} }"
359 startupservices="${startupservices// net /}"
360 fi
361
362 # Wait for dependencies to finish.
363 for x in ${startupservices} ; do
364 service_started "${x}" && continue
365 wait_service "${x}"
366 if ! service_started "${x}" ; then
367 # A 'need' dependency is critical for startup
368 if ineed -t "${SVCNAME}" "${x}" >/dev/null \
369 || net_service "${x}" && ineed -t "${SVCNAME}" net \
370 && ! is_net_up ; then
371 if service_inactive "${x}" || service_wasinactive "${x}" || \
372 [[ -n $(ls "${svcdir}"/scheduled/*/"${x}" 2>/dev/null) ]] ; then
373 svc_schedule_start "${x}" "${SVCNAME}"
374 [[ -n ${startinactive} ]] && startinactive="${startinactive}, "
375 startinactive="${startinactive}${x}"
376 else
377 startfail="${x}"
378 break
379 fi
380 fi
381 fi
382 done
383
384 if [[ -n ${startfail} ]] ; then
385 eerror "ERROR: Problem starting needed service ${startfail}"
386 eerror " ${SVCNAME} was not started."
387 retval=1
388 elif [[ -n ${startinactive} ]] ; then
389 # Change the last , to or for correct grammar.
390 x="${startinactive##*, }"
391 startinactive="${startinactive/%, ${x}/ or ${x}}"
392 ewarn "WARNING: ${SVCNAME} is scheduled to start when ${startinactive} has started."
393 retval=1
394 fi
395 fi
396
397 if [[ ${retval} == "0" ]] ; then
398 IN_BACKGROUND="${ib_save}"
399 (
400 exit() {
401 RC_QUIET_STDOUT="no"
402 eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
403 eerror "This IS a bug, please fix your broken init.d"
404 unset -f exit
405 exit "$@"
406 }
407
408 # Apply any ulimits if defined
409 [[ -n ${RC_ULIMIT} ]] && ulimit ${RC_ULIMIT}
410
411 # Stop einfo/ebegin/eend from working as parallel messes us up
412 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && RC_QUIET_STDOUT="yes"
413
414 start
415 )
416 retval="$?"
417
418 # If a service has been marked inactive, exit now as something
419 # may attempt to start it again later
420 if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
421 svcinactive=0
422 service_message "ewarn" "WARNING: ${SVCNAME} has started but is inactive"
423 return 1
424 fi
425 fi
426
427 if [[ ${retval} != "0" ]] ; then
428 if [[ ${svcinactive} == "0" ]] ; then
429 mark_service_inactive "${SVCNAME}"
430 else
431 mark_service_stopped "${SVCNAME}"
432 fi
433
434 if [[ -z ${startinactive} ]] ; then
435 is_runlevel_start && mark_service_failed "${SVCNAME}"
436 service_message "eerror" "ERROR: ${SVCNAME} failed to start"
437 fi
438 else
439 svcstarted=0
440 mark_service_started "${SVCNAME}"
441 service_message "Service ${SVCNAME} started"
442 fi
443
444 # Reset the trap
445 svc_trap
446
447 return "${retval}"
448 }
449
450 svc_restart() {
451 if ! service_stopped "${SVCNAME}" ; then
452 svc_stop || return "$?"
453 fi
454 svc_start
455 }
456
457 svc_status() {
458 # The basic idea here is to have some sort of consistent
459 # output in the status() function which scripts can use
460 # as an generic means to detect status. Any other output
461 # should thus be formatted in the custom status() function
462 # to work with the printed " * status: foo".
463 local efunc="" state=""
464
465 # If we are effectively root, check to see if required daemons are running
466 # and update our status accordingly
467 [[ ${EUID} == 0 ]] && update_service_status "${SVCNAME}"
468
469 if service_stopping "${SVCNAME}" ; then
470 efunc="eerror"
471 state="stopping"
472 elif service_starting "${SVCNAME}" ; then
473 efunc="einfo"
474 state="starting"
475 elif service_inactive "${SVCNAME}" ; then
476 efunc="ewarn"
477 state="inactive"
478 elif service_started "${SVCNAME}" ; then
479 efunc="einfo"
480 state="started"
481 else
482 efunc="eerror"
483 state="stopped"
484 fi
485 [[ ${RC_QUIET_STDOUT} != "yes" ]] \
486 && ${efunc} "status: ${state}"
487
488 status
489 # Return 0 if started, otherwise 1
490 [[ ${state} == "started" ]]
491 }
492
493 rcscript_errors="$(bash -n "${myscript}" 2>&1)" || {
494 [[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
495 eerror "ERROR: ${myscript} has syntax errors in it; aborting ..."
496 exit 1
497 }
498
499 # set *after* wrap_rcscript, else we get duplicates.
500 opts="start stop restart"
501
502 source "${myscript}"
503
504 # make sure whe have valid $opts
505 if [[ -z ${opts} ]] ; then
506 opts="start stop restart"
507 fi
508
509 svc_homegrown() {
510 local x arg="$1"
511 shift
512
513 # Walk through the list of available options, looking for the
514 # requested one.
515 for x in ${opts} ; do
516 if [[ ${x} == "${arg}" ]] ; then
517 if typeset -F "${x}" &>/dev/null ; then
518 # Run the homegrown function
519 "${x}"
520
521 return $?
522 fi
523 fi
524 done
525 x=""
526
527 # If we're here, then the function wasn't in $opts.
528 [[ -n $* ]] && x="/ $* "
529 eerror "ERROR: wrong args ( "${arg}" ${x})"
530 # Do not quote this either ...
531 usage ${opts}
532 exit 1
533 }
534
535 shift
536 if [[ $# -lt 1 ]] ; then
537 eerror "ERROR: not enough args."
538 usage ${opts}
539 exit 1
540 fi
541 for arg in $* ; do
542 case "${arg}" in
543 --quiet)
544 RC_QUIET="yes"
545 RC_QUIET_STDOUT="yes"
546 ;;
547 # We check this in functions.sh ...
548 # --nocolor)
549 # RC_NOCOLOR="yes"
550 # ;;
551 --nodeps)
552 RC_NO_DEPS="yes"
553 ;;
554 --verbose)
555 RC_VERBOSE="yes"
556 ;;
557 esac
558 done
559
560 retval=0
561 for arg in $* ; do
562 case "${arg}" in
563 stop)
564 if [[ -e "${svcdir}/scheduled/${SVCNAME}" ]] ; then
565 rm -Rf "${svcdir}/scheduled/${SVCNAME}"
566 fi
567
568 # Stoped from the background - treat this as a restart so that
569 # stopped services come back up again when started.
570 if [[ ${IN_BACKGROUND} == "true" ]] ; then
571 rm -rf "${svcdir}/snapshot/$$"
572 mkdir -p "${svcdir}/snapshot/$$"
573 cp -pP "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
574 rm -f "${svcdir}/snapshot/$$/${SVCNAME}"
575 fi
576
577 svc_stop
578 retval="$?"
579
580 if [[ ${IN_BACKGROUND} == "true" ]] ; then
581 for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
582 if service_stopped "${x##*/}" ; then
583 svc_schedule_start "${SVCNAME}" "${x##*/}"
584 fi
585 done
586 else
587 rm -f "${svcdir}"/scheduled/*/"${SVCNAME}"
588 fi
589
590 ;;
591 start)
592 svc_start
593 retval="$?"
594 service_started "${SVCNAME}" && svc_start_scheduled
595 ;;
596 needsme|ineed|usesme|iuse|broken)
597 trace_dependencies "-${arg}"
598 ;;
599 status)
600 svc_status
601 retval="$?"
602 ;;
603 zap)
604 einfo "Manually resetting ${SVCNAME} to stopped state."
605 mark_service_stopped "${SVCNAME}"
606 ;;
607 restart)
608 svcrestart="yes"
609
610 # We don't kill child processes if we're restarting
611 # This is especically important for sshd ....
612 RC_KILL_CHILDREN="no"
613
614 # Create a snapshot of started services
615 rm -rf "${svcdir}/snapshot/$$"
616 mkdir -p "${svcdir}/snapshot/$$"
617 cp -pP "${svcdir}"/started/* "${svcdir}/snapshot/$$/"
618 rm -f "${svcdir}/snapshot/$$/${SVCNAME}"
619
620 # Simple way to try and detect if the service use svc_{start,stop}
621 # to restart if it have a custom restart() funtion.
622 if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${SVCNAME}") ]] ; then
623 if [[ -z $(egrep 'svc_stop' "/etc/init.d/${SVCNAME}") || \
624 -z $(egrep 'svc_start' "/etc/init.d/${SVCNAME}") ]] ; then
625 echo
626 ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
627 ewarn "restart the service in its custom 'restart()' function."
628 ewarn "Run ${SVCNAME} without arguments for more info."
629 echo
630 svc_restart
631 else
632 restart
633 fi
634 else
635 restart
636 fi
637 retval="$?"
638
639 [[ -e "${svcdir}/scheduled/${SVCNAME}" ]] \
640 && rm -Rf "${svcdir}/scheduled/${SVCNAME}"
641
642 # Restart dependencies as well
643 for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
644 if service_stopped "${x##*/}" ; then
645 if service_inactive "${SVCNAME}" \
646 || service_wasinactive "${SVCNAME}" ; then
647 svc_schedule_start "${SVCNAME}" "${x##*/}"
648 ewarn "WARNING: ${x##*/} is scheduled to start when ${SVCNAME} has started."
649 elif service_started "${SVCNAME}" ; then
650 start_service "${x##*/}"
651 fi
652 fi
653 done
654 rm -rf "${svcdir}/snapshot/$$"
655
656 service_started "${SVCNAME}" && svc_start_scheduled
657
658 # Wait for services to come up
659 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
660
661 svcrestart="no"
662 ;;
663 pause)
664 svcpause="yes"
665 svc_stop
666 retval="$?"
667 svcpause="no"
668 ;;
669 --quiet|--nocolor|--nodeps)
670 ;;
671 help)
672 exec "${svclib}"/sh/rc-help.sh "${myscript}" help
673 ;;
674 *)
675 # Allow for homegrown functions
676 svc_homegrown ${arg}
677 retval="$?"
678 ;;
679 esac
680 done
681
682 exit "${retval}"
683
684 # vim:ts=4

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20