summaryrefslogtreecommitdiffstats
path: root/usr.sbin/i4b
diff options
context:
space:
mode:
authorhm <hm@FreeBSD.org>1999-12-14 21:14:28 +0000
committerhm <hm@FreeBSD.org>1999-12-14 21:14:28 +0000
commita53726a684bbbe7c65bcfeb9aca85f45a8eaf1e2 (patch)
tree7b7208891a81f877dc85f37d5afec02a17f8bde5 /usr.sbin/i4b
parente5044a69c99727fc68f6b7f09689aeb5244d9549 (diff)
downloadFreeBSD-src-a53726a684bbbe7c65bcfeb9aca85f45a8eaf1e2.zip
FreeBSD-src-a53726a684bbbe7c65bcfeb9aca85f45a8eaf1e2.tar.gz
update to isdn4bsd beta release 0.90
Diffstat (limited to 'usr.sbin/i4b')
-rw-r--r--usr.sbin/i4b/dtmfdecode/Makefile10
-rw-r--r--usr.sbin/i4b/dtmfdecode/dtmfdecode.117
-rw-r--r--usr.sbin/i4b/dtmfdecode/dtmfdecode.c2
-rw-r--r--usr.sbin/i4b/dtmfdecode/dtmfsounds.al.uu2098
-rw-r--r--usr.sbin/i4b/g711conv/g711conv.112
-rw-r--r--usr.sbin/i4b/g711conv/g711conv.c4
-rw-r--r--usr.sbin/i4b/isdnd/alias.c12
-rw-r--r--usr.sbin/i4b/isdnd/config.h6
-rw-r--r--usr.sbin/i4b/isdnd/controller.c145
-rw-r--r--usr.sbin/i4b/isdnd/curses.c6
-rw-r--r--usr.sbin/i4b/isdnd/dial.c6
-rw-r--r--usr.sbin/i4b/isdnd/exec.c12
-rw-r--r--usr.sbin/i4b/isdnd/fsm.c18
-rw-r--r--usr.sbin/i4b/isdnd/isdnd.831
-rw-r--r--usr.sbin/i4b/isdnd/isdnd.acct.522
-rw-r--r--usr.sbin/i4b/isdnd/isdnd.h35
-rw-r--r--usr.sbin/i4b/isdnd/isdnd.rates.524
-rw-r--r--usr.sbin/i4b/isdnd/isdnd.rc.570
-rw-r--r--usr.sbin/i4b/isdnd/log.c46
-rw-r--r--usr.sbin/i4b/isdnd/main.c94
-rw-r--r--usr.sbin/i4b/isdnd/monitor.c1037
-rw-r--r--usr.sbin/i4b/isdnd/msghdl.c217
-rw-r--r--usr.sbin/i4b/isdnd/pathnames.h8
-rw-r--r--usr.sbin/i4b/isdnd/pcause.c5
-rw-r--r--usr.sbin/i4b/isdnd/process.c6
-rw-r--r--usr.sbin/i4b/isdnd/rates.c6
-rw-r--r--usr.sbin/i4b/isdnd/rc_config.c89
-rw-r--r--usr.sbin/i4b/isdnd/rc_parse.y73
-rw-r--r--usr.sbin/i4b/isdnd/rc_scan.l10
-rw-r--r--usr.sbin/i4b/isdnd/support.c124
-rw-r--r--usr.sbin/i4b/isdnd/timer.c8
-rw-r--r--usr.sbin/i4b/isdnd/vararray.h120
-rw-r--r--usr.sbin/i4b/isdndebug/Makefile1
-rw-r--r--usr.sbin/i4b/isdndebug/isdndebug.810
-rw-r--r--usr.sbin/i4b/isdndebug/main.c6
-rw-r--r--usr.sbin/i4b/isdndecode/Makefile1
-rw-r--r--usr.sbin/i4b/isdndecode/decode.h4
-rw-r--r--usr.sbin/i4b/isdndecode/facility.c4
-rw-r--r--usr.sbin/i4b/isdndecode/facility.h4
-rw-r--r--usr.sbin/i4b/isdndecode/isdndecode.817
-rw-r--r--usr.sbin/i4b/isdndecode/layer1.c4
-rw-r--r--usr.sbin/i4b/isdndecode/layer2.c4
-rw-r--r--usr.sbin/i4b/isdndecode/layer3.c4
-rw-r--r--usr.sbin/i4b/isdndecode/layer3_subr.c4
-rw-r--r--usr.sbin/i4b/isdndecode/main.c4
-rw-r--r--usr.sbin/i4b/isdndecode/pcause.c4
-rw-r--r--usr.sbin/i4b/isdndecode/pcause.h4
-rw-r--r--usr.sbin/i4b/isdnmonitor/Makefile5
-rw-r--r--usr.sbin/i4b/isdnmonitor/curses.c624
-rw-r--r--usr.sbin/i4b/isdnmonitor/isdnmonitor.8185
-rw-r--r--usr.sbin/i4b/isdnmonitor/main.c897
-rw-r--r--usr.sbin/i4b/isdnmonitor/monitor.h148
-rw-r--r--usr.sbin/i4b/isdnmonitor/monprivate.h210
-rw-r--r--usr.sbin/i4b/isdntel/alias.c14
-rw-r--r--usr.sbin/i4b/isdntel/alias.h4
-rw-r--r--usr.sbin/i4b/isdntel/defs.h6
-rw-r--r--usr.sbin/i4b/isdntel/display.c6
-rw-r--r--usr.sbin/i4b/isdntel/files.c6
-rw-r--r--usr.sbin/i4b/isdntel/isdntel.812
-rw-r--r--usr.sbin/i4b/isdntel/main.c9
-rw-r--r--usr.sbin/i4b/isdntelctl/Makefile1
-rw-r--r--usr.sbin/i4b/isdntelctl/isdntelctl.816
-rw-r--r--usr.sbin/i4b/isdntelctl/main.c4
-rw-r--r--usr.sbin/i4b/isdntest/Makefile1
-rw-r--r--usr.sbin/i4b/isdntest/isdntest.820
-rw-r--r--usr.sbin/i4b/isdntest/main.c45
-rw-r--r--usr.sbin/i4b/isdntrace/1tr6.c6
-rw-r--r--usr.sbin/i4b/isdntrace/Makefile1
-rw-r--r--usr.sbin/i4b/isdntrace/cable.txt6
-rw-r--r--usr.sbin/i4b/isdntrace/isdntrace.816
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_1tr6.c4
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_1tr6.h4
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_q850.c4
-rw-r--r--usr.sbin/i4b/isdntrace/pcause_q850.h4
-rw-r--r--usr.sbin/i4b/isdntrace/q921.c13
-rw-r--r--usr.sbin/i4b/isdntrace/q931.c6
-rw-r--r--usr.sbin/i4b/isdntrace/q931_util.c6
-rw-r--r--usr.sbin/i4b/isdntrace/q932_fac.c6
-rw-r--r--usr.sbin/i4b/isdntrace/q932_fac.h6
-rw-r--r--usr.sbin/i4b/isdntrace/trace.c17
-rw-r--r--usr.sbin/i4b/isdntrace/trace.h7
-rw-r--r--usr.sbin/i4b/man/Makefile1
-rw-r--r--usr.sbin/i4b/man/daic.48
-rw-r--r--usr.sbin/i4b/man/i4b.410
-rw-r--r--usr.sbin/i4b/man/i4bctl.410
-rw-r--r--usr.sbin/i4b/man/i4bipr.416
-rw-r--r--usr.sbin/i4b/man/i4bisppp.426
-rw-r--r--usr.sbin/i4b/man/i4bq921.410
-rw-r--r--usr.sbin/i4b/man/i4bq931.410
-rw-r--r--usr.sbin/i4b/man/i4brbch.412
-rw-r--r--usr.sbin/i4b/man/i4btel.418
-rw-r--r--usr.sbin/i4b/man/i4btrc.412
-rw-r--r--usr.sbin/i4b/man/isic.433
93 files changed, 5755 insertions, 1178 deletions
diff --git a/usr.sbin/i4b/dtmfdecode/Makefile b/usr.sbin/i4b/dtmfdecode/Makefile
index 792b2ef..03e804bf 100644
--- a/usr.sbin/i4b/dtmfdecode/Makefile
+++ b/usr.sbin/i4b/dtmfdecode/Makefile
@@ -2,14 +2,20 @@
#
# $FreeBSD$
#
-# last edit-date: [Thu May 20 12:04:05 1999]
+# last edit-date: [Tue Dec 14 21:17:46 1999]
#
#---------------------------------------------------------------------------
PROG = dtmfdecode
SRC = dtmfdecode.c
-#LDADD += -lm
+
+# libm is only necessary if USE_COS is defined in the source
+#LDADD += -lm
+
CFLAGS += -Wall -g -DDEBUG
MAN1 = dtmfdecode.1
+test: ${PROG}
+ uudecode -p < dtmfsounds.al.uu | ./${PROG}
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/i4b/dtmfdecode/dtmfdecode.1 b/usr.sbin/i4b/dtmfdecode/dtmfdecode.1
index 42cd5be..6aa1832 100644
--- a/usr.sbin/i4b/dtmfdecode/dtmfdecode.1
+++ b/usr.sbin/i4b/dtmfdecode/dtmfdecode.1
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: dtmfdecode.1,v 1.6 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Mon Apr 26 13:42:15 1999]
+.\" last edit-date: [Mon Dec 13 22:53:13 1999]
.\"
.\"
.Dd February, 15 1999
@@ -46,6 +48,7 @@ numbers values as ASCII charcters to stdout.
The detector is implemented as 8 narrow band-pass filters realized with
an integer double-cross recursive algorithm. Various ad-hoc methods are
employed to provide hysteresis and anti-bounce for the detected signals.
+
.Sh EXAMPLES
The command:
.Bd -literal -offset indent
@@ -53,12 +56,14 @@ dtmfdecode < beep.al
.Ed
.Pp
will print a "1" to stdout.
+
.Sh STANDARDS
ITU Recommendations G.711
-.Sh AUTHORS
+
+.Sh AUTHOR
The
.Nm
-utility was written by
-.An Poul-Henning Kamp Aq phk@FreeBSD.org .
-This man page was written by
-.An Hellmuth Michaelis Aq hm@FreeBSD.org .
+utility was written by
+.An Poul-Henning Kamp Aq phk@freebsd.org .
+This man page was written by
+.An Hellmuth Michaelis Aq hm@freebsd.org .
diff --git a/usr.sbin/i4b/dtmfdecode/dtmfdecode.c b/usr.sbin/i4b/dtmfdecode/dtmfdecode.c
index f96bacd..1ef49a9 100644
--- a/usr.sbin/i4b/dtmfdecode/dtmfdecode.c
+++ b/usr.sbin/i4b/dtmfdecode/dtmfdecode.c
@@ -6,6 +6,8 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
+ * $Id: dtmfdecode.c,v 1.6 1999/12/13 21:25:24 hm Exp $
+ *
* $FreeBSD$
*
* Extract DTMF signalling from ISDN4BSD A-law coded audio data
diff --git a/usr.sbin/i4b/dtmfdecode/dtmfsounds.al.uu b/usr.sbin/i4b/dtmfdecode/dtmfsounds.al.uu
new file mode 100644
index 0000000..f4e0c07
--- /dev/null
+++ b/usr.sbin/i4b/dtmfdecode/dtmfsounds.al.uu
@@ -0,0 +1,2098 @@
+$FreeBSD$
+begin 666 dtmfsounds.al
+M5555U=74U-564-34UU%5U-?1UM'7UM37U=5555145%545%155%555%555=75
+M5575U=75U-15U5555575U575U=75U=75U=34U-35U-35U=75U=55U=5555%0
+MU-374535U-;7T=?6U]?4U-75U555551555555555555555555%5555145=75
+MU-34U-34U-35U=75U=75U=55U=75U=55555555755=5545/4U-=15-37T=;1
+MU];7U]34U=5555555%145%145%555555U555U=55U=34U=75U=75U-75U=35
+MU-74U=74U-75U=75U=75U=55U=75U=564-34UU!4U-36U]'6UM?7U-35U555
+M55555555555455155555555555545%55U-74U-34U-34U=74U-35U=35U=75
+MU=75U=75U=75U=75U590U-374534U-'6T=;6U]?5U-555%145%155%545555
+M5555U555U=75U=74U-5555755=75U=74U=75U=75U=35U=34U=74U-35U=75
+M555545/4U-=15-34T=;1U];7U]34U=55555555555%555%545%555=555575
+M5535U=34U-34U-34U-34U-75U=555555555555555555U=75U=514]34UU%4
+MU-?1UM'6UM?6U-15U51555155514551455555=75U=75U=75U=35U=75U=75
+MU=75U-34U-34U-75U=75U=75U=74U=75U=5555%0U-374535U-'6T=;1UM;4
+MU-75555555145%555555555555555575U5555=75U-34U-34U-74U=75U-74
+MU=75U=5555555=55U=75U=755E#4U-=15-34T=;1UM;7U]34U=5555555514
+M5%555%5555155575U=74U=74U55555555=75U-35U-34U-75U=75U-75U=75
+M5555555555104]74UU%5U-;0UM#6UM?7U=35U-755554551455155%155575
+MU=75U=155U755=75U-34U-34U-34U-75U575U555U=55U5555575U=75U5%3
+MU-375E74U]'6T=?6U]?4U-755=5555145%5555555555U=55U555U575U-55
+MU=75U=75U=34U=35U=75U=75U-75U=74U-75U=75U=7545/4U-=15-74UM36
+MU];7U]34U=75U5555%5455555555555555555%5555=4U=74U-34U]34U-35
+MU=75U=75U555555555555555U555U5564]34UU94U-?1U]'7UM37U-35U=75
+M555555145%5455155575U=75U=75U=?4U=75U=75U=75U=75U=75U-35U-75
+MU=75U=35U=75U=7555%3U-?74534U-;7UM?6U]?7U-35U555555555545%14
+M55555575U=75U5545%55U=74U]?7U-34U-35U=75U=75U=75U=75U=75U=75
+MU=5545/5U-965=?7T=;1U];4U]75U5555555555555155%5555555=75U=35
+MU=74U-75U=75U-74U=75U=75U=35U=35U-74U=75U=75555555514]37UE95
+MU-31UM'7UM?7U-35U-5555555%545%145%155575U575U=345%75U=34U-34
+MU-34U=75U=75U=75U=75555555555=55U575U5%3U-374534U]'6T=;1U]?4
+MU-755554551555555555555555555=75U575U-35U=75U=35U-75U-75U-34
+MU=75U=75U=75U=75U=75U55545/5U-=15-74UM;6U];4U]34U=5555555555
+M55555%1555555=55U=75U5145575U=77U-?7U]34U-35U=75U=75U=55U=55
+MU=75U=75U=564]34UU%4U=36U];7U]37U=35U=75555555555%555%555%55
+M5=75U=75U=34U=55U=75U=75U-75U=74U=74U-35U=75U-34U-75U57555%3
+MU=774534U-'6T=;6U];4U-74U555551555545514555555555=75U=155-75
+MU-34U-34U-35U=75U=75U=755=5555555=75U=755=5545#5U-=15=37T=;1
+MU];7U]74U=5555155%555%155%145575U=75U=75U=74U-35U=75U=35U=75
+MU=74U=75U=75U=74U=75U=55U555U5514]75UU%4U=31U]'7UM?7U-35U555
+M5%1455155%55555555555=75U=355515U=75U-34U-37U-35U=75U=35U-75
+M555555555575U=75U590U-375E77U]'6T=;1U]?4U-755555555555555514
+M555455155555U=55U-35U=75U-74U-74U-74U=75U=75U=35U=75U=75U=55
+MU55545+5U=115-37T=;0UM;7UM37U-15U5555%5455555%555%555=75U575
+MU%54U=75U-75U-34U-35U=75U=74U=74U=75U575U=75U=75U=514-34UU%4
+MU-?1UM'6UM?7U-35U5755555551555145515555555755=75U=34U=75U575
+MU555U=55U=75U=75U=75U=34U-75U=75U=75U590U-?65E37U-'6T=?6U];4
+MU]3555545%145U145%1455555575U=55U=555-75U-34U-37U-34U-34U=35
+MU=75U=75U555555555555=755E#4U]965=37T-;1UM;4U]745=55U5555514
+M5%1455155=755=75U=75U=74U]75U=75U=75U=75U=75U=75U=74U-35U-35
+MU=75U555U5514]75UU%4U-31UM'7UM?7U-?4U-7555555%145%=455555575
+MU=755=755%15U=74U-34U-34U-34U-75U=75U=55U=55U=55U=75U=75U590
+MU]365E77U];6T=?7U=35U5755555555555555%5555555=55U555U=75U-?5
+MU=75U-75U-35U-34U=75U=75U=75U=75U=555=55U=7545/5U-=65=37T=;1
+MU]'7UM34U=7555555%1455555%555555U=755=75U5545=75U-34U-34U-75
+MU=75U=75U=755=75U=55U=75U=75U=564-37UE95U-31UM'6UM?7U-35U=75
+M55555%155%14551555555555U=75U=37U]35U=35U=755=75U=74U-35U-75
+MU=75U=75U=75U=75U5%3U=374534U-;7UM?6U-?4U]345=5555545%545555
+M55555555U555U=555%55U=74U-34U]34U-35U=75U=75U=75U=75U=75U=75
+MU=7545/5U-=15-37T='0UM'7U]34U=35U5555%145%14555455555555U=74
+MU-74U]35U5755555U575U=74U-34U-75U=75U=74U=74U=74U-164]34UU%4
+MU-31U]'6T=?7U-35U=755=75555555545%15551555555575U515U-34U-34
+MU-35U-34U-34U-75U55555555555U=75U=75U590U-364534U-;6T=;1U];7
+MU-7555555555555555555%5555755555U555U=34U=75U-74U-35U=35U-74
+MU-74U-35U=75U=75U=75U=755E#4U-=15-34UM?1U]'7UM?7U-3555555%55
+M55555%155%1555555575U=545=34U-?7U-34U-35U=755=75U=75U=35U=75
+MU=75U=74U=564-37UE94U-31UM'7UM37U-35U%5555545%145%555%555575
+MU=75U=75U=74U]75U=75U-74U=74U=75U=75U=75U=75U=35U=75U=75U5%3
+MU=374534U-'6T=?6U-?4U-7555555%145%145%145%55U575U-75U=355%75
+MU=75U=35U=34U-35U-35U=75U-75U=75U=75U=75U=755E/4U-965=37T=;1
+MUM;7U]74U=75555555545%=45%145%155575U=75U=75U-?5U=75U=34U=75
+MU-?5U-15U]=5U=55U-?4U=355=555%534-54UM57U]'4UM#4U]37U577UE+4
+MU432V5?%4U]40-!5U]I4U%-0U=77UE;3UU/64-'24M'45]W55]'1UU574%'5
+MUM34TU14UU!75E'7UM%5U=!77E=4T=+3W];65%]15U70T=S15%105U16UE!6
+MT]7655Q55%?1U-957UU7V<?;TE]#6=39S=A564-15MS:5]944-95U-=65E%4
+MT=#3UU)45U97U];1UM34U=;0T-564577T-;75%%04577U]?555=75U35U-34
+M55175%555]375=?6T]/755155=75U]15U-37U]545%145=74U=174]75U5%4
+MU-?6U-?4UM#0UM?5U5545=545%975555U=545%75U=755575U=36UM75U555
+M5=7455555=74U]?4U-75U]74U-74U-75U57555%0U=774%15U=;7UM;6U];4
+MU-355=35U=5555175%54557555145=755=355U75U=34U=34U-35U-75U-34
+MU]35U=75U=7555755=75U=555E/5U-=15-37T]'3T=;7U-74U=75U5545%54
+M5555U=755%=45%555%55U575U-?555555=75U=74U-74U-?7U=755=755=55
+MU=75U-34U5514]37UE%4U-?1UM#7UM?7U]?5U=7555555%14555555555%55
+M5=75U=75U515U=74U-37U]34U=755=75U=35U=35U=75U=75U=75U=74U%90
+MU=374577U]'1T-;1UM?4U-755=75U5545%545=55555555555%555=55U=34
+MU=555=75U-35U=75U-74U=74U=35U=74U=74U=75U=755E/5U-=15-34T='1
+MUM'7UM37U=75U555555555145U=45%555=7555555=545-75U-37U]34U-34
+MU-74U=75U-355575U=555=75U=35U=114-34UE%5U]31U]'7T=;4U-15U-55
+MU55555=75555U51555555=75U=35U=74U]355=555=755575U=34U-34U-75
+MU-75U=75U=75U=55U5%3U-375E34U]'6T=?1U]?4U]34U555U5555%145%15
+M55555555U=75U=755535U=37U-34U-35U-35U-75U=55U=75U=75U=75U=34
+MU-755E#4U-=15-37T=;1UM;7U]34U=555555555455155555555455555=75
+MU=75U-;7U-545=36U%35U];65U345U355=35T-?4UE-4U5#0T=154]35U5!7
+MU]71UM37UM745%545=37UM9555=75U35U=34U%575U975577U]355575U=?7
+MUM;7U]34U%555574U=555-75U=35U=74U575U%=1U-774577UM/1T-;7U=55
+MU5755575U5555U145%555=555=55U=75U-35U=74U-75U=75U-74U=74U-74
+MU=74U=75U=34U-?4U=55555545/4U-=15-37T=;1UM;4UM34U=35U5545%14
+M5%15555555555=55U=75U=755%75U=34U-37U-?4U-34U=755=7555555=55
+M5=55U=75U5514M74UU95U-?1UM#6UM?7U=75U-7555545%15555555555555
+MU=75U=74U575U-75U=755=75U=75U=75U=75U=34U-74U=34U=35U=7555!3
+M5=774%?5U]#0T=?6U-?7U]745=7555155554U554U5155555U=75U=3455=5
+MU=34U=34U-34U-74U575U=75U=75U575U=555=75U=5545/5U-915=37T-;0
+MUM'4U]74U554U555555555145%1455555575U555U=74U]?55-?6U=;75=17
+M5];4UM94T=14UU!4U%'7U%?3U%31U==17=57U%=5UM31T-76T]70U=745M75
+M5M945]=75=17U%17U595UU37U%7555545-37U-37U]?4U=34U-34U]545%35
+MU575UM1555155=75U%=3U=?65E35U-?7UM31U];7U-755=555%15U5145514
+M5%35U=75U5555-74U=37U]155=75U=77U]34U-75U=75U=75U=345575U-35
+MU]?55E/5U-105-74UM?1UM'7UM?7U-35U5555%175%555%555555U=75U=75
+MU=355=75U=35U-34U-34U-35U-75U5555=55U5755575U=75U5514M74UE95
+MU-31UM'7T=?7U-35U575555555555%545%145=75U=35U=74U=75U-35U575
+M5575U=74U-34U-35U=75U575U=75U=75U=7555%0U=374574U]'6T-?1U-?4
+MU=755=555555555555555%55555555555=75U515U=74U-34U-34U=34U-35
+MU-75U=75U55555155=75U=755E/4U-965-?4T=;1UM'7UM34U=5555155%14
+M555555555=5555555555U=75U=?7U-35U-75U-35U=35U-75U=35U=75U=75
+MU=75557555514E74UU%4U-?1UM'6T=?6U]?4U=7555155%15555555555554
+M5575U=75U=545-75U=34U-?4U-34U-34U=75U=75U=75U=75U=75U=7555%2
+MU=774537U]'6T-;1U]?4U-755=5555555%545%145%555575U=75U=75U=74
+MU]35U=35U-75U=75U=75U=75U=74U-74U=34U=75U55545/5U]965=34UM;1
+MU];4U]34U=75U5555554555555555555U575U=75U=755%35U=34U]?7U-34
+MU=75U=75U=75U=75U=555=75U=35U=514]34UE95U]?1UM'6T=?7U-?4U-75
+M555555145%145%155555U=75U=74U575U-?4U=75U=75U=55U=75U=75U=34
+MU-74U=34U-35U=75U5%3U=?65E74U]'6T=?7U-?5U-75U555U55555555555
+M555555755=75U=75U5545=75U-34U]?7U]34U=75U=75U=755=555=75U=75
+MU=7545/4U]975=?4T=;1U];4U]34U=75U555555555155555555555555=75
+MU=35U=37U-75U=75U=75U=75U=74U=34U-75U=34U-35U=35U5504E74UU%4
+MU-31UM'6T=?7U=34U=75555555555%54555555555575U=75U=155=75U=35
+MU-34U-34U-35U-75U=75U=75U=75U=75U=75U5%3U=365U77U]'6T=;6U-?4
+MU=75555555555%555%555555U=75U=75U=34U=74U]355=755=75U=75U=75
+MU=75U=75U=74U-34U-35U=7545+5U-965=37T=?1U]?7U]745=75U5555554
+M5%14551455155=75U-34U-34U575U=74U-34U-34U-34U=75U=7555555=55
+MU=75U=55U5104E74UU95U]?1UM#1UM?4U=35U5555555555555145%155575
+MU=75U=35U-55U-35U=75U=75U=75U-75U=75U=75U=34U-34U-34U=7555%2
+MU=375E74U]'6T=?6U-?5U-75U=55U5555554555455555575U=75U=74U554
+M5=75U-34U-34U-34U-75U=75U=75U=75U=75U575U=5545+5U-975=?7T=;1
+MUM;4U]74U=75U5555%1455145555555555555555U=75U=37U-75U=75U=75
+MU=34U=34U-35U-75U=75U=74U=5555504E75UE95U-31UM'6T=?7U-34U-75
+M555555155555555555555555U555U=555%75U=34U-37U-34U=74U-75U=75
+MU=55U=75U=75U=75U593U=?65E74U]'6T=?6U-?4U-755555551555145555
+M5555U=75U=75U=75U575U]35U=75U=75U=75U=75U-34U=75U=75U=74U-35
+MU=355E/5U-965=?7T=;1UM;7U]74U=5555545%145%1455155%555575U=75
+MU=35U555U-34U-34U-34U-74U=35U=75U=75U=75U=75U=75U5514E74UE95
+MU-?1UM'6T=?6U-35U555555555155%5455145%155=75U=75U=75U=?4U=75
+MU=75U=75U=75U=34U=75U=34U-75U-34U=75U%93U-?15U77U]#1T-;6U]?4
+MU-35U55555555%145%155%145%555575U=75U5545=74U-34U]?4U]34U]34
+MU-34U=75U=75U575U575U57545+5U-965=37T=;1U];4U]34U55555545%55
+M55555555U55555755=74U=35U=77U]75U=75U=74U=74U=74U=75U=75U=75
+MU-34U-34U=564]77UE95U-?1UM'7UM37U-35U=755=555%55555555555575
+M55555=55U5755574U-?7U]34U-34U=75U=75U=75U=7555555%155=75U5%3
+MU=365E77U]#6T=;6U]?4U-55555555145%1455555555U5755=755=755575
+MU-34U-74U=34U-35U-35U-75U=75U=35U=74U-75U=755E/5U-965=37T=;1
+MUM;7U-34U555U555551455145%145%545555U=75U=74U%75U-74U-34U=34
+MU=35U-74U=75U=75U=74U=74U=74U-564]37UE95U-?1UM'7UM;7U-35U555
+M5%145%155%55551555555=75U=34U-35U=?7U-35U-75U=75U=75U-74U=75
+MU=75U=74U-35U=74U593U=?15U77U]'7T=?6U-35U-755555555555545%54
+M555555555=75U=75U=555=75U-34U]?7U]?7U]34U=755=55U575U=55U555
+MU57545+5U-965=?7T-;0UM;4U]755555551555555=5555155555U=75U=75
+MU-755574U]75U=75U=75U=74U-74U=75U=75U=74U-34U-35U=564]74UU95
+MU-36UM'7T=?7U-35U575U=5455155%145%155%555=55U=75U=755574U-34
+MU=34U-34U-34U=35U=75U=55U575U575U=755514U=745=75U=35U=34U-34
+MU-75U=75U=74U-75U5755=55U=75U=75U=755555U=35U=755=5555555575
+MU=75U-75U-34U-34U-35U=755%15U-15U=74U-34U-75U=755555U=555=75
+MU5755=75U=75U=74U=35U-75U5545575U=75U=55U=75U=75U-74U=75U575
+MU=74U-74U-555-74U%75U=34U-34U-34U-7555555555U=75U=55U=75U=75
+MU=555=75U=75U=37U=555555U5555=75U-74U-34U-74U=74U=74U=75U554
+MU=355575U=34U-34U-34U-35U=5555555=75U555U=75U=75U=55U5555554
+M5-75U=34U-34U=35U-34U-74U=55U=55U555555555755%35U-15U=75U-74
+MU-34U-35U-75U=7555555=555555U=75U=55U=75U5555574U]35U=555=55
+M5575U=75U=75U575U=755=75555555545-75U%75U-74U=35U=34U=75U-34
+MU-35U=35U=75U=75U5555575U=7555755515U=74U=75U-74U=75U=75U=75
+MU=75U=35U=75U=75U555U=745=74U-35U-74U=75U=55U5555575U=75U=75
+MU=75U=75U=74U=35U555U=34U=75U-35U-75U=75U=75U=75U=74U-74U-35
+MU=755535U=15U=75U-34U=75U=74U=34U=34U=75U=755575U575U=75U=34
+MU55555175555U=75U-35U-34U-35U-75U=75U=74U=75U=75U=555-74U%75
+MU-34U]35U=75U=55U5555555U=75U5555555U=75U=34U-75U=75U=37U]75
+MU=75U=755=75U=75U=75U=74U-34U-34U=5555175=745=74U-34U-34U=75
+MU=555=555575U555U575U=75U=74U-34U-34U5555%35U=37U-?4U]?4U-35
+MU=5555145%155575U=74U-34U574U-15U=74U]37U-35U5555575U=75U=75
+MU-75U55555145575U=75U-75U=74U]?5U-755=55U=75U=75U-34U-34U-15
+MU=75U=75U=355=35U%15U=74U=34U]34U-34U-75U=75U575U=75U=74U=34
+MU=555%145%145%=4U=34U]34U]35U-55U575U=74U=35U=55U555U=75U%55
+MU-375=75U=35U-74U-?4U-35U=75555555555575U=75U=75U=35U-35U=35
+MU=34U=75U=75U=75U=75U=75U=74U=75U=75U-34U5755534U-35U=35U-34
+MU=75U=75U=35U-75U=75U5755=5555555=55U=74U=75U5545=55U-34U-35
+MU-35U=75U555U=75U=75U=74U-35U=545]75U%75U-34U-34U-35U=75U575
+MU=75U=5555555575U=75U=74U-75U575U=74U-555575U=75U575U=75U-34
+MU-35U=74U=74U=75U5545=745=74U-?4U]34U-75U=755=55U=75U5555=75
+MU=75U=75U555U=5555555%35U=34U=74U-74U-75U-75U=75U=75U=755=75
+MU=355%35U=15U=74U-74U-34U-35U=75U5555=75U=75U=75U=75U=55U575
+M5575U=75U-?5U=75U=75U-35U-74U=75U=75U=75U=34U=75U=545-75U%75
+MU=74U=34U-75U=75U=75U=75U=75U=75U-75U=75U=755=55551555=5U=74
+MU-34U-35U=35U=75U=75U=35U=75U=755555U514U-345=74U-34U=34U=75
+MU=75U=5555555575U=75U=75U-75U=75U=75U=35U-?7U-75U=755=755=75
+MU=35U=75U=75U555U=74U-755574U-=55=75U-74U=35U-34U=75U5555555
+M5575U575U=75U5555-74U=55U=555=74U-75U-35U=35U=34U-75U=755575
+MU=755575U=555=75U%75U-74U-?4U]34U=75U=75555555555555U575U=75
+MU=75U=75U=75U=74U]5555555=75U=75U=35U-75U-35U=75U=74U-75U555
+MU=755%55U=75U-35U-35U-34U-74U-74U=75U=75U=75U=75U=75U=755=75
+M5535U=75U=75U=75U=75U=74U-34U=755575U=75U=755575U=155=75U=74
+MU-35U]34U-75U-74U574U=74U=34U=35U=75U=75U=55U575U=?5U=755555
+M5555U5555=75U-75U=34U-34U-74U=555-75U515U=74U=75U-75U=75U=75
+MU5555=555575U=75U=555=755=75U=75U%55U=75U-75U-74U=74U=75U=75
+MU=75U-55U555U575U5545=745-74U-37U]?7U-35U=75U=75U=555555U555
+M5575U=74U=74U-35U=755=77U=75U=34U-75U=75U575U=75U=35U-75U=75
+MU=755574U-?5U=34U-34U=75U=75U=75U=75U=55U5555575U=75U575U=74
+MU-75U=155-75U=34U-34U-74U=75U=5555555=55U=555=55U=555-75U515
+MU=74U-37U-75U=75U=75U=75U=75U=55U=75U=75U=75U=75U=75U574U]75
+M55555%555=75U=74U=35U=75U=75U=74U-75U=54U=345575U=34U-34U=75
+MU-75U575U55555555555U=75U=75U=75U=755=755535U=34U-34U-74U=75
+MU=555555U=75U=75U575U=74U574U-155=74U=34U-35U=34U-75U=75U=75
+M55755=75U=75U=75U=75U=75U=55U=35U55555555555U=75U-74U-35U-75
+MU=75U-34U=355=74U515U=74U=34U-35U=75U=75U-75U=555575U=75U=55
+M55555=75U=75U=545=75U-35U-35U-35U=74U=74U=755=5555555=55U555
+MU-345575U=35U-34U=34U-75U=75U=75U=75U=74U=75U=55U55555555=55
+M5=77U-75U555557555755=75U=75U=75U=75U=35U=755574U-55U=75U-74
+MU=35U=75U=75U-75U-35U=75U57555555=75U=75U55555555U75U=35U-35
+MU-74U=35U=35U=74U=74U-75U-75U%555=74U%74U-?4U-34U=755=75U=55
+M5=55U575U57555555575U=34U-35U=75U=75U]?5U=35U=75U555U=75U=75
+MU=35U=34U=74U=75U555U-345574U=34U-74U=35U=75U=75U=75U=75U=75
+MU=755=555575U=755=7555=45=74U-74U-75U=75U575U=75U=75U=55U575
+MU=755575U=545=74U-34U-?4U-75U=55U55555555=75U-34U-34U-34U=75
+MU=555575U=34U555551555555575U=75U=34U=34U-34U-74U=555=35U575
+MU=34U-34U-34U=35U=75U=755=7555555=55U57555555=755555U=545=75
+MU=75U-34U-35U=3555555=555=75U=75U574U555U=755%75U=35U-34U-35
+MU=75U=35U=75U=75U=75U=55U=55U555U-555555U574U%55555555755=75
+M5555U575U=74U-74U=34U=74U577U-15U=75U-34U-?4U-75U=75U=74U=75
+MU=75U=75U=75U=555575U5555=755%15U=74U-34U-35U-75U=755=75U=35
+MU=75U=75U=555=3555=5U=74U-36U-34U-75U5755=75U=7555555575U=75
+MU=35U=755=75U=55U-?555555=75U-74U-75U5555=75U=34U-34U-74U575
+MU-355%55U=74U-74U=35U=74U=74U-75U=75U=755=75U=75U=75U=755575
+M55145=75U=35U=35U=755=75U575U=74U-75U=5555555%75U555U=74U]34
+MU=34U-35U=75U=55U5755=75U555U=75U=55U575U-755=555=3755555555
+M5=755555U555U=34U]34U-34U-75U=555=55U514U=34U-34U%75U=75U=74
+MU-35U=55557555755=55U=55U=34U=75U=545=75U-?4U-34U-35U=75U=75
+MU555U=75U=75U=75U555U=755%75U=34U-35U-34U=75U=555555U575U=75
+MU=75U575U=75U=555555U=74U]355=55U=55U=74U-34U=75U=75U=75U=34
+MU=355=77U-545=75U=35U=35U-35U-75U575U=75U=75U555U5755575U-75
+MU555U=74U535U=74U-34U=74U=74U-34U=75U=755=75U=75U=555=35U515
+MU=74U-34U]75U=75U=755=75U575U=34U=75U575U555U=75U=75U=75U-35
+MU555555555555=75U=74U-74U-74U-34U-35U=55U-355=55U=55U=755=74
+MU=34U-34U-75U575U=75U=55U555U5555=755575U515U-34U-34U=75U-75
+MU=75U=34U=35U=75U=75U5555574U-54U555U-75U-34U-34U-34U-75U=75
+MU5555%555575U=74U-34U=75U=55U=36U]34U575U5755555U=75U=34U-74
+MU-34U-35U=555=34U%35U=75U=75U=35U-35U-35U=75U575U5555575U575
+MU%75U=755=55U=55U=35U-34U-74U=74U-74U-75U-55U575U5755515U575
+MU-345=55U=34U-37U-35U-55U=75U=75U=7555555=75U=75U=7555555575
+MU=75U]1555755575U575U=75U575U=74U=74U=75U=155=75U=545575U-34
+MU-35U-35U=75U=35U=355=55555555555=55U=75U535U=75U575U=74U-34
+MU-74U-74U=75U=755=55U=35U-55U-555=35U555U=74U=34U-34U-75U=55
+M5=555=555=55U=55U555U555U=75U=75U=75U-35U=755%755=55U=155555
+M5=75U=755=55U=755575U-755%155=75U-37U-?4U=74U=75U=5555555=75
+MU=75U=75U=75U-74U-75U-545=35U=35U=75U=75U-75U=75U=75U=555554
+M5=355574U%545575U-74U-34U-34U-?4U-34U=55557555555575U=74U=75
+MU=75U=355=77U-55U555U575U-75U575U-77U=745575U=555=155-35U515
+MU-75U]34U-75U=75U=75U=74U=75U=55U=35U555U=55U=75U=55U=145=75
+MU-75U-34U-35U%75U-74U=74U=74U=75U=35U=55U=545%35U=34U-34U=34
+MU=155575U=55U=55U=355=755=75U=75U=?5U=35U=55U]?5U575U=74U=74
+M5=345=75U=75U-75U-74U-34U574U-545%75U-75U-75U=74U=74U-35U=35
+MU=75U=75U=75U575U=75U=355=745554U=35U-74U]35U-75U=75U=755=74
+MU=755555U=155=35U575U=74U]34U-35U=75U=75U=55U-75U=7555555555
+MU=55U=75U=75U=75U=34U55555555=75U=55U=75U=75U]34U-75U-34U575
+MU-555%75U-35U-34U-75U=34U=75U555U515U=55U5555=755=75U-74U574
+M5=555=55U-75U-35U-55U5755=755=555=555=15U=55U535U-575575U=77
+MU-74U-35U=755=745575U=55U=75U=555=555=75U=7555555=37U]?5U555
+MU515U=755=74U575U-75U=35U=15U=55U=34U%75U-74U=34U-35U-35U=75
+M5575U5155=75U=35U-5555155574U=77U-?45=75U=75U=75U=34U-37U-74
+MU=75U=5555555575U555U-345-755=74U=75U-35U=745=74U-745=75U=75
+MU=75U=74U=755=755=755575U]?5U=5555555575U-55U=755-775-76U=74
+M5=155=34U==55%755=77U=75U-355=75U=74U-34U=75U555U=74U5755=74
+MU-35U=75U5545=75U-355=?5U=35U-75U575U=75U=34U=755=555=75U535
+MU-34U-34U=75U=355=75U555U-35U-75U=55U555U555U=35U-55U-75U-37
+MU5555555U555U=75U-75U-35U=755555U=755=555=75U=55U-34U]74U575
+MU=75U-75U5555=555=155=55U=55U-55U-155=?6U=54U==5U-15U=75UM?4
+MU537U5755=545-=7U-94U-55U=555=145%74U-35U=?4U-745=555=74U-74
+MU=34U-545517U575U%74U]37U=34U=74U%555%75U=35U=555=34U=15U-35
+MU]75U%75U%755=755535U-76U-34U=355575U555U515U577U=745-745=74
+M5%755=35U=355=755%34U-35U=35U-74U=74U=75U-74U-35U=75U555U514
+MU=755=75U=35U-34U-35U-75U=75U55555555575U=75U=55U=75U5755%15
+M5=75U-?4U=35U=7555555575U5555575U575U575U=755%75U=545=75U-75
+MU-75U-35U-34U-35U=755=55U575U=75U=75U=755=755%1555=45575U=75
+MU-34U-34U=34U=34U-3555755575U=755=75U5755=755=75U=75U=755=75
+M5=75U=555=55U=355=35U=35U-34U%55U=75U=37U-35U=5555555=55U575
+MU575U=74U=34U=15U554U=74U=75U=?4U-355=155=75U=74U-755555U555
+M5575U=555=75U-75U555U=555%75U-74U-34U=75557555755=75U=75U=75
+MU-35U=75U=15U=34U-75U=35U575U57555755=75U=75U=34U=55U=75U=75
+MU=55U=75U=74UM35U=555=75U=75U-75U=75U=74U-35U=75U=555=74U-75
+MU=34U-?4U=155=155-555=75U=75U=55U=55U=75U=75U57555555575U515
+M5=34U-?4U-?4U=555=755=35U=75U=55U=7555755-765-77U=74U577U534
+MU%34U%75U%74U57555555575U=55U=75U=355=555=55U-?5U-75U555U=55
+MU=75U=75U=35U=75U=74U=355555U=15U=34U-?4U=35U=74U=74U=745575
+MU5545=55U=75U=75U=74U-555%75U=55U-35U=75U=35U-35U-75U-55U-74
+MU-75U5555%555-75U575U575U=35U-75U=35U=75U=7555755555U=35U=75
+MU575U=75U5545555U=74U]55U=55U5555=75U=75U=75U=35U=75U-75U%55
+MU=345=74U=75U-75U=75U-74U-75U-75U=555=555=75U=75U555U=555515
+M5=555=74U-?7U]34U-34U-75U=75U=755=5555555=555515U=75U=74U-34
+MU=34U=75U=74U=75U=55U5555=75U=75U=75U=74U=555%15U=75U]34U575
+M55755575U=74U-35U-35U-55U=55U=555=75U-75U-34U=35U=75U=74U=34
+MU=75U=555555U=555575U=75U=34U%545=75U535U-37U-34U=35U=75U=74
+MU=75U575U=555555U555U-74U=74U-34U-34U-35U=75U=74U=75U=74U=75
+M5=75U=755555U-355575U=75U=345=755=75U=75U=75U=55U=75U=75U=35
+MU=345%75U=155=75U=34U-35U-75U=75U=755555U555U=75U=75U=55U=74
+MU-555U15U=555=75U-35U-34U-35U=74U=74U=75U=75U=75U=555=75U-74
+MU-37U]?4U-35U=75U=555555555555355555U=75U=75U=?7U=545=75U=77
+MU]74U=75U575U=755=75U=75U=75U=75U=35U5555=74U=75U-34U-355575
+MU-755=75U-75U555U=555=555=755=75U-?45%355=555=74U-?7U-34U=75
+MU=75U=75U55455555=75U=755535U=555=74U]?7U-34U]34U-75U555U=75
+MU%75555555555=75U=34U]755%15U=75U]?4U=35U=75U=75U=75U=35U-75
+MU=75U=75U-555-74U-75U=75U=34U-74U-75U575U=75U=75U575U575U=55
+M5=75U=37U5175%75U555U-34U-37U-34U-755=555=35U=75U575U555U554
+MU5755=75U=75U=75U=74U=75U=755555U5755=75U=75U=75U=75U-?45U=5
+M5=755=?4U=55U555U=75U=75U-75U=35U=75U=75U-355574U-155=74U-77
+MU-35U=35U=75U=34U=75U=75U=75U=755=555=74U]545U555=155=35U=35
+MU-35U-75U-34U-74U=75U=75U=75U5555%75U575U-74U-34U-34U-74U555
+M555555755575U575U=75U=75U=?7U5575575U=74U-75U=75U=75U=75U=55
+MU=75U=75U=74U-75U=55U=74U574U=34U-34U=35U=75U=35U=74U=75U=75
+MU-75U=55U575U-355%145=555575U=34U-34U-74U-74U-35U=75U-74U-34
+MU=755535U=35U=34U]?7U-35U=5555555555U=555=75U=75U=75U=75U=74
+MU]545U15U=75U];4U-75U=755=75U=75U=35U=75U=75U=75U=555%75U%55
+MU=37U-34U-?55=75U=75U=5555555555U=75U=75U=74U-?7U5175%15U555
+MU-34U]?4U-35U=75U=75U=75U=75U575U=75U555U=755=74U=35U=75U=34
+MU-75U-74U=75U=7555155575U=75U=74U]?45%=455555=77U-75U=75U=75
+MU=75U-75U=35U=75U=75U=755575U-35U=34U]34U=75U=755575U=555=75
+M55555=75U=75U=55U=77U]575U15U=755-77U]355=37U-145-75U-75U=37
+MU-355%!6T]'4UE95T]75U5%4U]?5U5=5U]155515U-155%15U=555=74U-35
+M5=74U-;6U%145%755=77UM?4U=35U=555=74U=35U=34U-75U=75U-35U=55
+MU=74U=74U-55U=74U-75U-74U=74U=755-74U=555=34U=555=75U-145%17
+M5%55U-75U]34U]74U]75U-34U-75U=55U=755575U=555%?5U-155=37UM34
+MU=75U-75U=77U-755575U=755=75U=755%75U=34U-545U545=75U]?4U]?4
+MU%75U-355555U-55U=75U-55U-75U]55U=75UU75U-75U-74U%74U=74U=74
+MU-34U=75U=555515U575U575U-?7U5165%55U557U=74U-34U]34U-355555
+M5=555575U5555515U514U=74U=74U=75U-34U=35U-75U-75U=75U555U=75
+M5575U=75U=75U]?55%=45=75U=?7U-155=55U=155=75U%55U=75U=75U=75
+MU=755555U=35U=34U-75U-355=74U=755-74U5555=75U=555=75U=755=77
+MU]575U145=555=75U]35U-75U-35U-75U-75U=74U-75U=55U=555-75U-75
+MU-34U=35U-35U-34U=7555555%555=75U=55U-55U555U-?7U%175%55U=74
+MUM?4U-75U=75U515U=75U%54U=75U=55U=7555175=345575U-?5U=34U=15
+M5=55U-35U-75U-74U574U57555555=74U]?55%=75%75U575U-77U=34U=75
+MU-35U-55U-55U554U%55U575U535U-35U=75U-74U-34U-75U=74U-75U=74
+MU%54U575U515U-74U%77UM545E=55575U=34U=75U575U555U555U=55U=74
+MU-75U-74U-555575U]74U=76U-77U-775=755%755%755=755=755=155=15
+MU=54U=?7UU565%15U5565-35U-15U-?4U]15U-?5U-14U=55U=54U=75U554
+M5=74U=34U-35U-74U-74U-74U57455755=755%55U=555=15U-35U];455=6
+M5%555=34U]34U=35U=355=75U=75U=34U=355=75U-355515U-75U=74U]?4
+MU=55U-35U=75U-34U=75U575U575U5555=555-77U]545U1455755%77U-?7
+MU=74U-75U=55U=75U575U=75U=75U5555%74U-75U=34U-35U=75U-35U-75
+MU-55U=755555U=755=755=75U=3455175%55U=74UM;4U-745=74U=75U=35
+MU=34U=55U=75U=34U%54U=745575U=74U=34U-35U-35U=75U=75U=75U=75
+MU=755=75U=35U-?55%=45-75U514U=75U]34U-34U-74U575U57555755=75
+M5=755515U=555=75U-34U-35U-75U=55U5755555U=75U=75U5755=75U=74
+MU]545E145555U=34U-75U575U-75U%75U-74U%75U=74U574U=745=74U-74
+MU=74U=34U-75U=75U=755575U=74U=35U=35U=35U=35U-?7U5165%=55=55
+M5=75U-?4U-?4U-34U-75U=75U-75U575U55555145=745=74U-34U-34U=34
+MU-35U=75U=75U=75U=75U=55U=555=75U-?55%=55-75U=74U]75U=55U555
+M5575U=75U-74U-34U-35U=745575U=35U-35U-34U=35U=75U=755555U=75
+MU=5555555575U=75U=74U]545U55U=355574U=34U-34U-34U=75U=75U=55
+MU555555555555575U%75U=74U=35U=75U=35U=75U=75U=555=75U=755=75
+MU=75U-?7U5175%35U=75U-?4U=75U=75U-75U=35U-74U-35U=75U=75U=55
+MU=345=75U=35U=75U=75U=75U-34U=74U-75U=75U=75U=75U=75U-?55U=4
+M5%75U555U=74U-34U-75U-75U=35U=34U=75U=75U=755575U=15U=75U-34
+MU=35U-75U=75U=75U-555=755=555=75U=75U=77U]545E145=555=37U=75
+MU=55U=555=75U=75U=75U=75U=75U=555-75U575U-34U-34U-75U=75U=74
+MU=75U=75U=75U=55U=75U=75U=?7U5175%55U=555-75U-34U-34U-34U-34
+MU=75U-75U=74U-34U=75U=355575U=75U-34U-75U=34U=75U=755=555555
+M55755575U=75U-?55%=45-75U=74U]35U=55U=75U575U=75U=75U555U=75
+MU-34U574U-15U-34U-74U=75U=75U=75U=75U=75U=35U-34U=75U5555=77
+MU]545E145575U575U-34U-34U-34U-35U=75U575U=55U5555=555-75U575
+MU-34U=34U-34U=35U-75U55555555575U=75U=55U555U=?7U5175%155575
+MU=34U=75U=75U=75U=75U-75U=75U=75U=74U-55U-755575U=34U-34U-75
+MU=75U=75U=75U=75U=75U=35U=755=75U-?55%=45%75U554U=34U-35U-34
+MU-34U=74U=75U=55U55555555%35U=555=75U-34U=35U=75U=35U=75U=55
+M5555U555U=75U=75U=74U]545U145=75U=77U]75U=75U=34U=34U=75U=35
+MU=35U=75U=555=75U-75U-34U-35U-35U-35U-7555755=755=75U=555=75
+MU=75U=?7U%175555U=555-75U=34U-34U-34U-74U-75U=75U=75U=34U555
+MU=34U=75U=35U=75U=75U=75U-75U=55U575U=75U=755=75U=75U-?55%=4
+M5%74U=74U]34U=555=75U=75U=75U575U5755=75U=74U575U=55U=74U-34
+MU-35U-75U=75U=75U=75U575U=75U=75U=75U=74U]575U145=74U575U-37
+MU-34U-75U-75U=55U5555555U=7555555-75U5555=74U=35U-34U=75U=35
+MU=75U=55U5555=7555555=75U=34U5175575U=75U=?4U=755=75U=555=75
+MU=75U=75U=75U=75U-55U=345=75U=35U-34U-34U-75U=75U-74U-75U-34
+MU-75U=75U575U-?55%=45-75U=545=75U-35U-35U-35U-75U-75U-74U-75
+MU=755575U=35U=75U-35U-35U=75U555U=75U=75U=74U=75U=755575U=77
+MU]545U145=75U=77U-34U-75U=74U=74U=34U=75U=75U-75U=555%55U555
+MU=74U=35U=75U=75U=74U=34U=75U=75U=75U=75U=75U=?7U5175515U=75
+M5=74U-34U-34U=75U=75U=75U=75U=755=755555U=755=75U=35U-75U=75
+MU=74U=75U5555=755555U5555=75U=75U-355%=45%755=75U-?5U=75U=75
+MU=75U=75U=75U=75U=55U=755575U=55U=74U-34U-34U-34U=35U=75U=55
+MU=5555555=55U=75U=77U]545U55U=74U555U=74U-37U-34U=34U=75U=75
+MU=55U575U5555-75U515U=74U=35U-34U=35U=755575U=35U=7555555554
+M5575U=37U%145575U=75U=37U=75U=75U=75U=75U=75U-35U-74U=75U=55
+MU=755=75U=34U-34U=75U=75U=34U-35U-35U-75U575U575U=74U]?55%=4
+M5%75U=155=35U-35U=75U=75U=75U555U=75U=55U=755575U=555=75U-34
+MU-34U-35U=75U=75U=55U5555=55U=75U=75U=74U]545U145=75U=37U]75
+MU=35U=75U=75U=35U=75U=75U=75U=75U=75U-75U-34U-34U-75U=74U-75
+MU574U=75U=75U=75U-75U=75U=?7U5575555U=7555755=74U=34U-74U=75
+MU=75U-75U=35U=74U555U=34U=34U=35U-35U=35U=55U555U555U=75U=75
+M5555U=55U=75U-?455=45555U=75U]?4U-34U=75U=75U=75U=75U=55U=74
+MU=74U=75U=55U=74U]74U-35U=34U=75U=35U=35U=75U=35U-75U=35U-37
+MUM155%555575U514U=75U-35U-34U-74U=35U=555=75U=75U=555=75U515
+MU=75U=75U=34U=75U=75U=75U=75U=75U575557555555=34U5175%555=75
+MU=37U=75U555U555U=75U=75U=75U-75U=34U-55U=755-75U=35U=74U=55
+MU=75U-35U-74U-35U-75U=75U=75U=75U]?55%=45555U=545-75U-34U-34
+MU-35U=75U=55U=75U=75U5755535U=555=74U-34U-34U=75U=75U=75U=75
+MU575U=75U555U=75U=77U]155%55U=74U=74U]34U-755=755575U=35U=75
+MU=74U=35U-755=75U575U=75U=34U-34U-75U=7555555575U5755575U=55
+MU=75U=34U5=75U155=34U-74U]37U-34U-75U=75U=75U=75U57555555514
+M55755%75U=34U-34U=75U=75U=75U=75U5555=75U=75U=555575U-355%94
+M5575U-75U];4U=755=75U=75U=755=55555555555=75U535U=55U=34U-74
+MU=75U=75U=55U5555=555555U=75U=75U-75U=74U]575D!F9'!Q1EK4T-IC
+M)"`_,0T4^)B-L[.UBK>VNJ6]CXFTM)(6$H6RLUP^)C]FB)D/.SLW!`$*"Q&2
+MZ@PX.P6VN[4&/#;DM[:%4N:'AW0`&X"XNX0W.0F/N++D#@]ME_X1%)RTCQX\
+M/QVQNXH#/C!XCXSD$7V1Z!HT#I*\OY`P.C6!O['.#@UFE=,=:H6VB!T\/Q"S
+MNK4&/#9TC(+_%<69E`0V")*_OI$P.C6'O+;9#`-Y[WX:%(>QBAP_/A.PNK4&
+M/3=*@H;`;N:$E@8Q"YV^OI,P.C6'LK?=`@=/X&X&%H&SM1P_/A*PNK4',C1)
+M@85<8I6`D0`S-9V^N9,P.S6%L[37`1O?Y!$#$8.RM!P^/AVPN[4$,S5-AYQQ
+M9Y.-DP(R-)VYN9(Q.PJ:L(I1!Q+S^1\,$X*]MQP^.1RQNXH%,0M$FI1F>)B.
+MG0T]-)VYN9TQ.`N8L8E>!6KA\`4)'8R_MQPY.1RVN(L:-@Y2GN!I<(2+GP\\
+M-YVYN9PV.0B>MXQ`'F7KRP8*'(^^MATY.1^VN8@8-PW5D\P72H"TF0X_-I*Y
+MN9PV/@F<M(-+$U*1Q@,U'HZYMATY.1^WOHD9-0#9EW421H*WFPD^-I*YN9PW
+M/PZ2BH9Q%_^<WPPW&(FYL1(Y.1ZWOX\?"P?"[F(>7(^VA0@Y,9.YN9\W/`^0
+MB85_;^F;UPXV!8BXL!,Y/AZTO(P=#AKWYQ<%5XBPA`LX,9"YN9\T/0V1C)]E
+M9)"$5@LQ!8N[L!,^/AZUO8(2#1S_]AP'T+6SAPHX,9&^N9\U,@*7@)%F=)B!
+M7C4P!(J[L!`^/AZ*LX`0`!?DTP4!W+2RA@H[,):^OI\U,`"4A^]B58>"7C0R
+M!XJZLQ$^/QZ(L(81!V+@308"V+>\@34[,)2_OIP+,0;JFO)I]8.,63<]!HJZ
+MLQ8_/!Z.MH06&W?O?@(,V[:_@34[,)6_OYT)-@3HG5!J^HR)6#8\`8JZLQ<\
+M/!^/MYH4'<&58`\.V+&^@#4Z,.J\O)T.-!KNEG@7XHF+63$_`(JZLQ0\/1R-
+MM9\5%.:7:0@+WK"^@S4Z,.F]O9,,"A_L[&D1Z[6U7C`_`XJZLVH],AV#B)!K
+M8Y20%#4UW;"Y@C4Z,.RRLI`""1#M_Q`2E[2T73`^`HJZLV@R,Q*!CY5H<9V=
+M$30TT+.XC0H[,.*SLY$`#!7BT1D<D+:W5C,Y#8NZLVDS,!.&@N)NW9J9$C<W
+MU;*XC0H[,."PL)8&`&/C<`09DK&VU3,X#8NZL&\P,1&$AO]L^8::'#$V4+*[
+MC`L[,.>QL94'!WW@8P$:G["QTC(X#(B[L&TQ-A>:FMQM[X*$&3`Q1;*[C`@X
+M,>6VM^@%&%'@%0T$F;*PV#(X#(FXL6,V-!6>G71BEX^'&S,P0+VZCP@X,?ZW
+MM.P8$_#@$PX'F[VSPS([#XFXL6$W-6F=E&9BG8B!!3(P3KVZCPDY-OVTBN$<
+M:N/@'@L!A;RRR#T[#XZYMF8T"&*0X6IBF+6#!3TS=KVZCPX^-_&*B?L3993C
+M!34`A;^]]ST[#XR^MV<*#V>7PA!MA+>-!#PR<KVZCP\_-_>(C?867)+B!S<"
+MA+^]\CT[#XV_MV4(`GSK2AYMAK:,!#\]>+VZCPP\-/6/@-IJ_9OM`38-A+Z\
+M_C([#X*\M&4/`4[M8`5M@[".!SX]9;*[CPT]-<B"A%]L[X?O`C$/A[F\Y3(X
+M#X.]M7H-!=?G%`9OC;.)!SX\9K*[CP(R"LB`F7=FD8#I#3,.A[F_Y#(X#X"X
+MKJ&YMX;G:P0,"C<R/#X^.3\\,S$U"0$8:4[AEIJ&@H^)BXJ*M8J+B(Z,@H&'
+MFI^1ZN'SW4)^86]J%!80$!,3$Q,0$187%&II;&-G>GQV2$!?U=_$P\[*]/?W
+M]_?W]/3UR,[-P,?:V=S3T=155U%04U)=7%Q?7U]?7%Q=4E-345%65U=45575
+MU-37UM;6UM;6UM;6UM;6UM;6UM?7U]355U34UM;7UM?7U-35U=75U=75U=75
+MU=75U=75U=74U=34U-34U-34U-74U-34U-34U-34U=34U-35U-34U-34U-35
+MU-34U-34U-34U-34U5565-76UM?7U]?4U-75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U-34U=35U=75U=75U=75U-75U-75U=75U=75U-34U=75
+MU=755594U=;6U]?4U-35U=75U=75U=75U=75U=75U=75U=74U=75U=75U=75
+MU=74U-75U=75U575U=55U=75U=75U5555=75U=75U=75U=75U=545E?5UM?7
+MU]34U=75U=755=75U5755=5555555575U=75U=75U=75U=75U=34U-35U-75
+MU=75U=75U=75U=755575U=75U=75U=75U=55U5165]76U]?7U-35U=75U=75
+MU=75U575555555555=75U=75U=755=75U=75U=75U=75U555U=75U=75U=75
+MU=75U575U=75U=755=755=555%%75=;7U]?4U-75U=75U=75U=75U5755=55
+MU=75U=75U=75U575U=75U=74U=35U=55U575U=75U=75U=75U=755=75U=75
+MU=75U=555=545E?5UM?7U]34U=35U=75U=55U555555555555=3ED.GF^<71
+M271^>65E9V1D97A_<G9*3$1>5]?2WMK&P\W.R<C(R\C)SL_"P\;'VMC>W-/6
+MU]555E914%-34U)24E)24U)34U!045%65E=75%555=75U-74U-37UM?4U535
+MU=35U-34U575U=74U=75U5555555555555555%145%155%15U=155=75U-74
+MU=75U=755=75U=74U-55U55555545555U=75U=37U]545E155=75U=75U-?7
+MU-75U=7555545555U=75U=75U=75U=555=75U575U-34U-34U]35U=555555
+M5=75U-34U-74U=7555555=55U=37U5575%755=75U=545=75U=75U=74U=75
+MU=75U575U=75U=75U554U=745=75U=34U-34U-34U-75U=75U555U5555555
+MU575U=75U=75U]?55%=55=75U-34U-36U]755555U5755=75U=75U=755=75
+M55755535U-35U=55U=75U-35U=755555U=75U=75U=7555555555U=75U=37
+MU]155%155=75U=755=34U-?4U-35U5555555U=74U-34U=755=555%75U575
+M5=75U=75U=755555U575U=75U=75U=75U=55U5555555U=36U%54U=555=55
+M5555U-34U=34U=755555U=75U=75U=75U=75U515U=745=74U=75U=755=75
+MU=74U=75U5555555U=75U=35U-555555U=555%?5U=34U-37U%35U-74U-34
+MU-34U-755=75U=34U=75U5555U945=55U=74U]34U-34U=75U=74U-34U=34
+MU5555%555575U-34U]37U]545E155=34U-35U-?4U=55U=75U=74U=555%15
+M5=75U-34U-355=75U515U=74U-?7U]?7U-75U555U=55U=34U-5555555515
+M5=74U=37U%145%15U=75U-15U=35U=55U=34U=34U]?4U-75U5545%55U555
+MU-3455555=55U=75U=34U-34U=75U=75U=75U=75U=7555555=75U]?55515
+M55555=75U=77U]34U=7555155-75U=34U-34U=5555555%35U=35U=34U]34
+MU=55U=74U=75U=75555555755=75U=75U5555%75U-545%55U=55U=555%15
+MU=74U]?7U]34U55555555=75U=75U=555=75U5755=74U=34U=34U=75U555
+MU5555=5555555575U=555575U=75551755155=74U-75U-?5U=555555U=75
+MU-75U-75U=75U=75U555U-745575U=75U=74U=75U=755=755=755=755=75
+MU555U555U555U-?4U5155=75U=75U555U=75U-34U-75U57555555575U=55
+M55555%=45=555=75U=74U-35U=755=755=75U55555155%555575U=755574
+MU]155U555=75U=75U=?4U555U55555555=7555555%555574U-755=75U555
+M5=75U=55U=75U=555=75U=75U=74U-55U555U=75U=75U=37U%545%155=55
+MU=555-75U=75U=74U=75U=34U=35U=555575U554U=755=74U-75U-34U-74
+MU-34U=75U555U=75U=755=75U=75U=75U]?555145555U=75U=74UM34U-75
+MU=555=755555U=75U=75U5555575U=15U=35U-34U-34U-74U-75U=75U=75
+MU=75U=5555555=555=74U]155%55U=5555755%35U-37U]34U-75U=34U=75
+MU=34U-7555555%55U575U=74U-34U-75U=35U=75U=35U=55555555555=75
+MU=75U-?7U%545=75U-34U]35U-34U=7555755=75U=75U=75U=555=75U=55
+MU-345575U-34U-34U-75U-75U-75U=75U=75U=34U=75U=74U=75U]?45514
+M5=75U=75U-55U-74U-35U-55U=35U575U=75U55555555515U=55U=75U-34
+MU-34U=34U=74U=75U5555575U5555=75U=75U=74U-545U55U555U=34U=37
+MU-74U=55U=75U=75U=75U=34U-34U=755=74U-75U=74U-75U=75U-35U=75
+MU=555=75U=7555555575U=75U=34U5175575U=75U=155%75U-34U=75U=34
+MU-75U=75U=75U575U554U=345=75U-?4U-74U=75U-75U-75U=75U555U=75
+MU=34U=35U=75U-355%=55575U=75U=75U]35U-75U=75U5755=555555U=75
+MU=755574U-155=75U-35U=74U=75U=75U=75U=74U=75U=75U-75U=75U=37
+MU]155%555=75U=74U555U=74U-34U-34U-34U-74U=74U=75U=555-75U555
+MU=74U-34U-75U=75U-75U=55U=75U575U=755=75U=75U=34U554U575U=74
+MU-35U-?4U=5555755555U=75U=75U=75U-35U555U-355575U=34U-34U=75
+MU=75U=75U=75U=75U=75U=75U-75U=75U-355%=45575U=74U%55U=34U]35
+MU-34U-34U=755=755=755=555%1555545=74U-34U-?4U-35U-75U=755=55
+M5-555=75U575U=74U=77U]545%55U574U-77U=76U=755=15U%75U535U574
+M5%745%75U==4U=17UU55U-75U-?5U-75UU75UU75U-755=74U=355=555=35
+M5=755=3455175515U575U-34U=77U=34U=75U-75UU75U575U%755=755514
+MU=755555U=34U-35U=35U-35U=75U=74U=75U575U=75U5555=75U-755515
+M5=75U=74U-34U]?5U=75U=55U575U=75U-34U=75U=755574U-35U=75U-34
+MU-75U%75U=55U555U555U575U=75U5755=755=74U-545U555=75U=75U515
+MU-74U=75U-75U=755=75U=75U575U5555575U53555755=74U-34U=34U=35
+MU575U=75U=55U5555=555555U=34U5545%75U=75U-35U-?7U=75U575U=74
+MU575U=35U=75U=755=75U-35=V!^<W5$7]?2Q`4C)S(T&F>5A8V+MKNGOH^!
+M@[>SM)Z5AKRDO/8R)#D-_U8$-0D4XFDP)B,Y;(NUE`8,$N'E!#8Q;K&DI8T%
+M-0'AAI!B%)RSI;+T,#DTYHJ*DF??AK6%`#X["(:\O809`A/D]@<Q-F^WNKR4
+M-3T*99+Z$AGIMKZT$#\[-.NTM9U@1X2)G0(^/@&)N+R%!0P<^?,%-S74L*6R
+M\38\-768Z143E+>]C@0Y.@J?MK>=;GJ?@ND//SP?M+N\G0`+&O7S&S4/XK.Z
+ML60S/PK#AY-F%):TLX$".#L/AK.VDA=NEH?]"3PS;[&ZO>@.-`3`^1P.`)"R
+MN[<3/#X(XX.;=6Z6M;&9"#LY`8^]L9$2$>.95`@]-M*SI;/.-38&S>$1`@68
+MO;B(!SX^#Y&.AM5BEXNTE34[/QZUO['J&QG(D'<),S7IO:6Q9#8Q`?/H;@82
+MA+V^@@PX/@.:M8/#8NN.B_$W.SUOMKFQY`8'295Y#C$/G[^EM!`P,`'AD7\:
+M%8:RO84*.S\$@+>,]6_@@HUT-C@PT;.XMM0-`V;M>@\W`8>^NX@$/3,&E9[=
+M'6&!LK.6-SH\'8ZQCLP4\8:&;#$^-^B]N[1G"`QHX7X"-1N"N;B"#3\R!)*$
+MY1=R@+"V\C$Z/6RULXG1$UB:FQ8Q/PJ9OKN*%C0(%.%U`0D6CKF^A`LY,AF%
+M@.IN2(&QM7XS.C#5MKV)2AEDDY,2-CT-@;B[CAHV-1;M500-88NYO)`W.#,1
+M@8^08$R'MXX7/3LV[K._CF$$%>N5'S8S!X^[N(,`,#06ZO`>!D2UOK/^,#LP
+M8(^+GV1TA;6`&3TX-9Z\OXP4`!+DXAXW-AV*NKF%#C(T%9'B%AKUM;^V>#(Z
+M,=6*M)MG>)Z.A0<\.0Z!OKZ#'P\:R><?-31BM[J_D30\-VR>EVT=Y+6]M1$\
+M.C?BM[::8V*1@Y,`/#\!C[B^AP<+!]7E$@L(4+:ZLOXQ/C1^A)]P%N*ULH\%
+M/CLUG;"QFFL4[X?N`CTR'K6ZOYX"-`!%YQ8/#>>PN[!^,CDTTH"$T&OLB[&!
+M`SDX#H>RL)L1'?*9^`TR,&ZVI;V4"#8"1>UI`P:4L[BW$3PY"N&/@/!OXHZW
+MF0\X.0&,O[.<'AI%D,<-,S=0LZ6R\S0P#52590<8G;.YBP0^.0F1BHWD;>>-
+MBI0+.#\9M;FSE@0&9^I3#3$*XKVEL7XQ,PW(DUP8$YBSOX(".#D-A;>)X6GD
+MI:*DLHF23QP`"34P,C\^.3\_,C`W"@T$$&3(Z)R$@(V.B(JUM;6*BXF/C8.&
+MA)F2E^_ESE)V9&)H%1<1$!,3$Q,3$!$6%Q5K;F)A9'ES=$)84=;>Q,+.RO3T
+M]_?W]_3URLG/PL'$V][=T];45U)24U%04E)=75Q<7%Q<75U34U!15E=75%55
+MU=74U]?6UM;6T='1UM;6UM;6UM;6U]?7U-34U=75U=74U-75U=55U555U=75
+MU=74U=34U-155U34T=;6UM?7U-?4U-74U=74U-34U=35U=75U=74U=34U-34
+MU-35U=75U-74U-34U-34U=74U-34U-34U-34U-75U-75U=34U-35U-74U556
+M5]76UM?6U]?4U-75U=755=75U=75U=755575U=75U=35U-74U=75U=75U-34
+MU-35U=75U=75U=75U=75U=5555555575U=75U=75U=755597U=;6U]?4U-35
+MU=75U575U=75U=755555U=75U=75U=75U=75U=75U=75U=75U=75U575U=75
+MU=75U=75U=555575U575U=75U=75U55445?5UM;6UM?7U-35U-75U=75U=75
+MU=5555555555U=75U57555555575U=75U=75U=55U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U5115U76UM?7U-35U575U555U=55U555555555555=75
+MU=75U=75U=75U=75U=35U=75U575U=55U=75U=75U=555575U=75U=75U=75
+MU=755%97U='6U]?4U]34U=75U=75U=555555555555555=75U=75U<B7E^'F
+MS]M!=7UY961D9&5E>'ES<4I)1D535M'=V\3#S<G)R,O+R,C.S\W#QL?$VM_<
+MTM#1U]155U%14U)27%U<7%U=4E)34U!045%65U145=75U-?7U-55U=74U-34
+MU-34U%75U-34U-75U=75U57555755555555555145=555U555=75U=75U=75
+MU=75U=74U=75U=755=755=55U5555=75U-355%145575U575U=75U=34U=55
+M55555=55U=75U5755575U=755535U=155=75U=34U=75U-75U=75U=555=55
+MU=75U=75U=75U=75U=74U-545U14U=75U=75U5545=75U=75U=75U=75U-35
+MU=75U=75U=555%555515U=74U=34U-35U=75U=75U-74U=755=7555755=55
+M5575U=34U5145575U=75U-35U=74U]7555555=7555755=755=755=75U554
+MU=355%75U=34U]?7U-3555145%145%75U=74U-34U-35U=75U=55U-355%14
+M5=75U=75U=755%75U=34U=74U=75U=75U=755555U5755575U=55U=75U=34
+MU-34U-74U-35U=75U555555555555=555=75U=74U-555%15U=75U-34U-34
+MU]?4U=755575U=55U575U=555555U5545-74U555U=74U=75U-75U=75U555
+M55555=75U=75U-75U=75U=75U=34U5145%755=75U=74U515U=74U-34U-74
+MU-74U=34U=34U=75U554U=755-75U=35U-34U=75U=75U=35U=75U=755555
+MU=75U=75U=75U-3555145=75U=75U=75U=?7U=75U555U555U555U5555=55
+MU=755575U-15U=74U-34U=35U=74U=75U=75U=75U=75U-74U-35U=75U=75
+MU-555%55U=75U-75U=155=34U-34U-34U-34U55555555555U=555-75U515
+MU=74U=34U-34U-75U=75U=55U5555555U=75U=75U=75U=34U5175%75U=35
+MU-34U=74U]75U=75U=75U575U=75U=74U=75U-55U=345%75U=35U-75U-75
+MU=75U=55U55555555575U=755=75U=75U-?455155=55U=75U=355535U=74
+MU-34U-74U=75U=75555555555%155=545555U=75U=75U-75U=75U=75U=35
+M5=75U=75U=75U=75U=74U-155%55U=75U=74U]35U-?4U555555555555575
+M5=555555U5555=75U555U=75U=75U=74U=75U575U=755=74U=75U=75U=75
+MU=55U=34U5175555U=75U=75U%55U=75U=74U-35U=75U=75555555555514
+M55555U55U=75U-74U=75U=75U=75U=755555U=555%5555555555U-355%=4
+M5=75U=75U=75U=37U=755=7555555=75U=75U-35U=755575U=545=75U-74
+MU=35U=75555555555555U=75U=75U=75U=75U=74U-555%555575U=75U=55
+M5=75U=35U=75U=35U=34U575557555555%75U514U=74U-35U-75U=34U-34
+MU-35U=755=55U=75U=555555U=37U5545555U=75U=75U=74U-35U=755=75
+MU=75U5555=75U=75U=55U=345=75U=75U=75U=75U-75U=75U=75U=75U=75
+MU=74U-34U=35U-?555155=75U-34U-34U575U-37U-34U-35U=755=75U575
+MU=755574U-145=75U-34U-35U=74U=75U=75U-755575U575U=755=75U=74
+MU]145%55U=75U575U575U=?4U575U555U=75U=75U=55U=75U=555-74U%55
+MU=74U-34U-74U-34U-34U=75U=74U=35U-75U=755=75U=?7U%545575U-74
+MU-35U-54U=74U=34U-34U-34U-35U-75U=75U=55U-355=74U-?4U-34U=35
+MU-74U-75U-75555555555575U=555=75U-355%155-75U=34U=35U=77U%75
+M5555U=75U=75U=75U=75U=35U574U-15U=74U-34U-34U=75U=75U=555=55
+MU575U=75U575U555U=74U-545%155=74U-34U-345=74U-?4U-35U=75U555
+MU555U=55U=545=75U515U=75U=34U-34U-75U-75U=75U=75U=75U5555555
+M5575U=34U5545574U-74U-34U-74U]?5U-555=7555755575U5555575U555
+MU-345=75U-34U-35U=75U=75U=75U=75U575U575U=75U=75U=75U-355515
+M5555U=75U=74U555U=74U-75U-34U-75U=75U=74U=755574U=555=74U-34
+MU-35U=75U=75U=75U=555=75U=755=75U=55U=74U]555555U-34U-75U-35
+MU-?4U=75557555755=75U=75U=55U=555=75U575U=74U-34U-35U-75U=75
+MU=75U=75U=75U=75U=55U=55U=34U5545%55U=75U=75U5545575U-34U-34
+MU=75U=75U=75U=35U=55U-755=75U=34U-34U=35U=75U=75U=75U=555555
+M5=75U=75U=55U-3555155=75U=555=755=74U-755=75U575U=75U=55U575
+MU=75U574U=555=74U-34U-34U-74U=7555555=555=555=55U555U555U=74
+MU]155%75U575U-75U=755575U=34U-34U-34U=75U=75U=75U=755=75U515
+M5555U=35U-34U-34U-35U=75U=74U5755555U=75U=75U=?4U5545=75U-34
+MU-34U-74U]?5U=75U=75U-75U=75U=75U=74U555U-345=75U=34U-35U=75
+MU=75U=755575U=75U=75U=75U575U=74U-3455155555U=555=75U554U=74
+MU-34U-34U-75U=34U-35U=75U575U-55U=34U]34U-34U-75U-74U=75U=75
+MU5555=55U=75U=75U575U-545U15U=75U=34U-34U-37U=75U=75U=75U=35
+MU=34U=35U=35U=34U%55U=74U-35U-75U=55U=75U=75U=74U=755=755=55
+M5=75U=74U5175555U=75U-34U-155=75U-34U-34U-34U-74U=5555755555
+MU=7555755=75U=75U=34U=35U=74U=75U=555555U=55U=75U=75U-355%=5
+M5=75U=75U=74U=37U]35U=75U=75U=75U=74U=35U=75U574U-15U=75U-74
+MU-34U-75U=755=755=75U=75U=75U=55U=55U=75U-545%555=75U=74U=74
+M5574U=74U-34U-34U-35U-75U=7555555-755515U=37U]?4U-34U=75U=75
+MU=75U575U555555555555575U=37U5145575U=34U-34U-75U-?5U=75U=75
+M5555U575U=75U57555145=755575U=35U-34U-35U-34U=34U=75U-34U-75
+MU-35U=75U=74U-355%=45%75U=75U574U%55U=74U-34U-35U-74U=35U=55
+M55555535U=545=75U-34U-34U-75U=75U=75U=75U=75U=75U575U575U574
+MU-545%55U=75U=35U-75U=74U555555555555=75U=75U=75U=555=75U%75
+MU-74U-35U-75U-34U-75U555555555555555U=75U=75U=37U5145%55U=75
+MU-35U-355=75U-34U-75U=75U=75U55555555514U=555%75U=34U-34U=75
+MU=555=55U575U=75U=755=75U=75U=55U-3555155555U=75U=34U-37U]35
+MU=555=55U=75U=55U=75U%75U575U=555=75U=75U=55U575U=74U-754WEA
+M<G-,1%#6W]8W(B0R"1/1F(:+B[:POK.*B[6YHZ:W]7^2FQ<S/@J8L8,!/SXT
+M#38Z)36$L8T&/#(!=A8)"?*RI;-E-PI\A)UN%(>YI+8=,S=AAIAE%)BROH`(
+M.#(4AH1W%I&VL)0Q)3)RCH_E:96UM-\S)3'HMK>6;.:/CV(R.S6$O;"0$7:%
+MA!(R.0V.N;.5!1/HD1DS/1NTN[/R#0%>XAXV,6&PI;%E-0EMYQ$U"_B]I;0<
+M,#07[&0"`)"\NXD#/#$4D/T;&9B]OH8*.3!CA))N%(6RLI0Q.C'<CX#68YBV
+MME\R.C:5M(CG8Y&*B1<\.@J$L[?O%/F#AAL\.0*.O['A&6>>D@<]/!^WN+';
+M`![A[`<S,'ZSNK9C"P-`Y1HW->.\NK4>-@AAX1$(`I^_NX\",C1BE'D!&X>_
+MOH0U/C=XF.8=%(&\O>@Q.#?-@YYA88:SMG8].C27BH/6986WBQ,_.PF'L8CS
+M;):)@0<^.0&.O+3V$_6&G0,_/!*WN;=:!V^0[`(],$ZSN[1N#QK^_``P->N_
+MNHL8-`)!_04T#9JYNX(",PA][18/&H"YN9LU/#5/DW4$%(V^O>,P.37QA^X6
+M9(V\L6<].`N6CIIZ<8"PBAX^.`^'MX)<>X6T@`$Y.0>.LHE4:I2,G`PY/!:W
+MOXIQ&=":X@X_,%2RN(MJ`Q25RP\R-):_NXX;"@7VV@,V#(>XN(`",0)1_`4+
+M!8V[OI\U,@[7ZA0#%(FXO?LP/PCYF%89?XB^L6T\.0Z6@Y1J7XZRBAH^.0*$
+MM85Y6X.V@`(X/@6/L8-W99J+G`@X/&JWO8]Z$>B!X0HY,,ZROH\5!$^=W0H\
+M-)._N((;#Q'M0@DP#(&XN8<"-`3W5P,T!8Z[OI,U,`/(^QL/%;6[O?4Q/0WD
+MD6D'=;2YL6H]/P*6A,\3PK6\B@0Y/@&$CI%L](FP@`P[/AF,MX5E4(.TG34[
+M/&VTLX%F8)F,Y#0X,/RSO(,4'>"%03<^-)^_OH$8`7F7934R#(.XOIH#"!/G
+M>`DV!8NZOY0*-@3\5@`+:+2ZLM8Q,P'FX1X`7[:[L18]/0&7G6$9^+:^B@8^
+M/P2:@/\4X+2R@`D[/!*-BY!C^XFVDC0Z/62TMIIC4H"(_#8[,.:PLH05;IV&
+M?S$Y-)B_O(4>&/^=;S8\#(*XOYP``F'N:#0P&K6ZO.P(-1/D9@DU;[:ELTPV
+M-AOFU`$-VK"ZMA`R,P64[A(%[;"YBP$^/1F8FWT0E+&\@0L[/1:#C>=NE;2P
+MD#<Z,G"*M9%BYXZUR3`Z,>VQL9]J0X:"83,X-9J\LI\=%Y:8%C`_#8RXO98&
+M!,:4$S8S&+2ZLN0.#V+A%S4W8[&EL'PW-!#F9@\.\+.ZMQTS,1SKQP<&E+*X
+MB`,_,Q*<EQ<=DK._A@HX,VN!AT)JG;&SEC8Z,$2(CN9BEK2TT#,Z-NBVM)1N
+MY(R,:#([-86]L9<0<X6%'#(^`H^YL^@%$^N1&#,R'K2[L_0-`5#B&38V9+"E
+ML68U"6+G$34+Y+VEM!\P-!3L9P(`D[R[C@,\-A20\!L>F[V^AS4Y,6.$DVD5
+MA;*RE3$[,=V/@5%CF+&W1S(Z-Y6TB>5BD;6)%CP["X2SM.(4^8.'&SPY`(Z_
+MMN<99YZ3!ST]'+>DKJ&XMH'@:00,"C<R/#X^.3\\,S$T"``::G?DE)B'@HR)
+MBXJUM8J*B(Z,@H"'FI^0E>/\V$9\9FQJ%!80$Q,3$Q,0$!$7%!5I;&-F97]Q
+M24=<5=+;P<S(]?3W]_;W]_3UR\[-P\;%V-_=T-16459745!375U<7%Q<7%Q<
+M75U24U!15E=45575U=34U]?6UM;1T='1T='6UM;6UM?7U]?7U]34U-75U=75
+MU=75U=75U=75U=75U=75U-345594U=;6U];7U]?7U]?4U-35U=75U=75U-35
+MU=75U=75U=75U-34U-34U-35U=74U-34U-34U-34U=75U=34U=34U=34U=75
+MU=75U=74U=555E?5UM;7U]34U-?4U-35U=75U=75U=75U=75U=75U=75U=74
+MU-34U-75U=75U=75U=35U=75U=75U=75U=75U=75U=55U575U575U=75U511
+M5E77U]37U-34U-75U=75U55555555=75U57555555=75U=74U=75U=75U=75
+MU=75U=75U=75U575U=75U=75U=75U5555=75U=75U=755%%75=;6U]?4U]34
+MU-34U=55U5555=75U575555555555555U=755555555555755=75U=75U=55
+MU=75U=75U=75U=75U=55U=75U=75U=544595U]?4U]37U-35U=7555555555
+MU57555755555U555U=75U=75U=75U=75U=75U=75U=75555555555=75U=55
+MU5555=555=75U=75U5115U76U]?7U-?4U-35U=75U5555575555555555555
+M5555U=75U^20Z>'YQ==)='YY9&5G965Z>7QR=DM"1UE1U=#>VL;#S,[)R,C(
+MR,G.S,+#P<?8V-[<W=#6U-545E%04U)24EU=75U24E)34%!145965U155=74
+MU-155-74U-?7U]?7U-34U-545=75U=75U5555=555555U5545%175U5555=4
+M5575U=34U-75U=75U5555=555=5555555%555555U575U=37U5545%75U=34
+MU=34U=755=74U%55555555555555U555U575U555U-355=75U=34U-75U=74
+MU=75U=75U=55U=75U=75U=555=555=75U-?55%=45575U=74U-34U-355%75
+MU=75U=75U=34U=75U=555=555575U=545=75U-34U=75U-75U=35U=75U=75
+MU=5555555575U=75U-34U]155U145=55U=75U=75U-74U]35U=755=755555
+MU555U555U=555=75U575U=74U-34U-34U=35U=555=555=75U-75U=75U=75
+MU574U-?7U%145555U=75U=755=75U555U=74U=34U-35U=35U=75U=755514
+MU5555U15U=34U-34U-34U-75U575U575U=75U=75U=555=75U=75U]?55%14
+M5575U=34U-74U-34U-?7U-75U575555555555=75U=755575U5545=75U-74
+MU=75U=75U=75U=755=75U=75U=75U=75U=75U=74U-545U145=75U=75U=74
+MU-55U=34U-34U-34U-34U-74U-35U=555=75U5145=75U=34U=74U-34U-34
+MU-35U-75U=75U=5555555555U=34U5545=75U-75U-75U-35U=77U-755555
+M5=755=55U=75U=75U=75U-355=75U-34U-74U=75U=74U=35U=75U=75U=75
+MU=74U-34U-74U-?555155=75U=35U-75U=755575U=34U-34U-34U-75U=75
+MU=555575U5545=74U-34U-35U-74U=55U=5555555=555=75U=75U=75U=74
+MU%555U155575U=75U=34U=75U-35U5555=75U575U=75U575U5555=35U535
+MU=34U=35U=74U=35U=755=5555555555U=75U=5555555=3455175%75U=75
+MU=75U=75U555U=75U-34U-34U=75U=555575U575U=755%75U=35U-75U-35
+MU-75U=5555555575555555555=755=75U]?55%155=75U=75U=75U=75U=34
+MU=7555555=755575U=75U=755=74U=545=75U-34U=75U=755=75U=755=55
+MU555U55555555575U=74U-545U155575U=75U-75U-555=75U-75U=75U=75
+M5=75555555145-7555145=75U=75U=74U=35U=35U5755555555555145555
+MU555U=35U5175%755=75U=75U=34U=77U]7555555%5555555=5555555555
+MU=755%75U=75U=75U=75U=75U=55555555555=75U=75U=75U=75U-355%=4
+M5%555=75U=35U=755575U-34U-34U-75555555555=755575U=545575U-34
+MU-35U-34U=74U=75U=75U=55U5555575U575U=37U]555U145=75U=75U=75
+MU=75U-?5U=75U=55U5555=75U=75U=555=75U535U-34U-34U-35U=755=75
+M5=755=755=55U=75U=75U=55U=34U5545%55U=75U=74U=34U-55U=34U-34
+MU-35U=75U555U=55U555U-555%555=75U=75U=74U=75U=75U=75U=755=75
+M5=75U=755=75U];455145=75U=34U-35U=75U=37U-75U-75U=74U-34U=34
+MU=75U=74U-55U=75U-75U=35U=75U=75U=75U=55U555U=755=75U=75U=77
+MU-555U75U=75U-34U=75U=755-75U=34U=34U-35U-35U=75U=55U=35U555
+MU=37U-34U-74U=75U=75U=75U=75U=55U555U5755=75U=37U-545575U=74
+MU-34U-34U=74U]155%55555555755=75U575U555U-755=75U=35U-74U=35
+MU=75U=74U=75U=55U=55U=75U=74U=34U]?455155=75U=74U=35U=755515
+MU=74U-34U-75U-75U=75U=755574U=545=74U-34U-34U-34U-35U=75U=75
+MU575U=75U=75U=75U-77U%545U15U=74U-34U-34U=35U-?4U=75U=75U=75
+MU=75U575U=55U=34U515U=74U=75U=74U=35U=75U=35U=75U=75U=34U-75
+MU=75U=37U5175%55U=75U=74U=74U-54U=75U-35U-34U=35U=35U=75U=55
+MU-755%75U=34U-34U-34U-34U=75U=7555555=75U57555555575U-3555=5
+M5=55U=75U=75U-34U-37U-75U=75U=75U=34U=75U=755=74U=155=34U-35
+MU=75U=75U=75U=75U=75U=75U=55U=75U=755=74U-545U55U=74U=34U=75
+MU=355=75U=34U-35U=755575U=75U5555=75U5145=75U=35U-34U=34U-74
+MU=35U-74U=75U=75U=555=55U=34U5145575U=34U-34U-74U-75U]35U=75
+MU=75U=75U=75U=75U=55U-355=74U-74U-75U=75U-75U=75U=75U=74U=75
+MU=74U=75U=34U-?455155=74U=75U=75U=75U535U-34U-74U-75U=75U=75
+MU=755575U5545%55U=74U-34U-34U-75U=75U=75U-75U575555555555=74
+MU]155%55U=75U=74U=75U-75U=?4U=75U=75U=55U=75U575U=75U575U=75
+MU-74U=75U=75U=75U=75U=75U=75U=75U=35U=75U=75U=?7U%545575U=74
+MU-34U-35U=545=75U-34U-35U-55U=75U=75U=75U=75U=755575U=75U=75
+MU=55U=75U=75U=55U=75U=555=755555U=55U=74U=34U=35U-75U=55U=74
+MU-75U=755575U=75U=75U=75U=75U=75U=75U=74U=75U=75U=75U=75U=75
+MU=75U-75U-34U-75U=74U575U=75U=7555555=55U=755%355=75U=74U-74
+MU=74U=74U=75U=75U=755=755=55U5555=55U=75U=75U57555555=75U=74
+MU-34U-35U=75U555U=75U5555575U575U]?4U=755=755=75U=75U=75U=75
+MU=75U=34U-35U=75U=75U=55U=75U575U=75U=74U=75U=75U=74U-75U=75
+MU=34U=35U-34U=75U554U=74U-74U=35U=75U=75U=75U=75U=755555U555
+MU=75U=75U=75U=75U575U=75U=75U555U555U574U575U=75U=75U=35U=35
+MU=75U=?7U=75U575U=555=55U=75U=75U=75U=75U-34U-75U=74U=75U=75
+MU=75U=75U=75U=74U-35U-35U=355=75U=74U-75U=75U=75U=155=75U-34
+MU-34U=75U=75U=75U=75U=55U5545575U=75U=75U575U=75U=74U=75U575
+M55755=75U=75U-75U=74U-34U=35U=35U=34U=74U]75U555U=55U=75U=75
+MU=75U=75U=75U=74U=5555555575U=75U=35U=75U=75U=34U=75U=75U=74
+MU575U=75U-75U=75U-75U=755575U=34U-74U-74U-75U-75U=75U=755=75
+MU=55U=75U=75U=75U555U=755575U=75U=75U=555=55U=3555555555U=75
+MU-74U-74U-75U-3555555575U=75U=74U=75U=75U=75U=34U-35U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=74U]75U-34U=74U-55U=74U=74U-55
+MU-74U-34U-34U-75U=555=755575U55555555575U=75U=75U=75U=755=75
+MU=35U=5555555555U=74U575U=74U=74U-74U-34U-75U=37U-5555555=75
+MU=75U=75U575U=75U=74U=35U-75U=75U=55U=74U=75U=75U=75U=75U=75
+MU-74U-35U=75U57555555%75U555U=555=75U=75U-35U-35U-74U=755=75
+M557555555555U=35U=75U=75U=75U=75U-34U-75U=7555755575U5555555
+M5=75U=75U=75U-75U=74U]355575U=75U5555=55U=75U=74U=75U=74U-75
+M5555U=55U=55U=75U555U=75U=75U=55=&!Y<W1$7M?3Q!HC)C(T!6;KA8VT
+MO;*UL+ZEMY^2B;NGM.F5B(<,)"0*EI$'-03C93TC(37AY04&E+2##SH\;X*%
+M2OZVNK`1,S7AC99H[;.DL!TP",V3%P)/L*6T!#`.048/-VRPNHL$-`3V:#<P
+M;[.[B!X-9903,S)ML[F/$1V7F!L\/&RPO($538"&!CD_:;>QG&R4M8(#.S]N
+MBHCE9X>PC@([/&V-A&1]B;R+`C@S9H3F'W6TN8H#/S9_D6H#3K&ZM0$R"%CR
+M!@MUL[J*!S8&]GH*-W"RNH@%"13L$3$P>;*XC!\$_)`:/3UEL[^!$&^;F@8^
+M/&>QLYAJYXZ!`C@_9[2TZ&&;MH(,.SQDB8-;<HRRC@PX,GB`D1=!M;Z(##DQ
+M<YYQ!%&QNXL"/#5'[1L,U+.ZB``P`L-`#S54O;J)!C4?YQ4W-ER]NXP%`TN5
+M&#(S1K*^@!\2D9P&/SU+L[V%%E6#A0(X/'>VMI9LD[6!#SL]=K6.]7Z`L((.
+M.S)WC)IB1(J\CPXX,4B$\![?MKF.#S\T6)<6`,FSNXX-,@_8SP`(]+VZCP`V
+M!/]B-33*O+N-!PYO[!PP,<*\N(`:!>&6!SPSV[*\A!)FA9X".3+1L+"3%>Z)
+MA`X[/52WM>=GA+:!"#LR4(B!<$.)LH(+.S!3@)41Q[>^C0@Y-U>?9P3RL+B,
+M#CP(V^8%#/J]NXP,,`'Q?`D*Y+R[@@,U$.80-C?EO[B`!P#5ZP0R,?F\OH09
+M%I*0`CXS\K*RG!'*@ID..#+WL;?N;9ZUA`L[,\BTC-1TC;"&-3LPP(R?:<2T
+MO(`U.#;$A-P9^;"Y@PL_-<V4$@#@O;N""3(-]]4"#NR\NX,,-QCZ%30U[[^[
+M@0`/9^(:,S;MO[F$!!OOE`,\,..\O9\<?823#CDSYK.QE164B9D*.S/EMHOQ
+M>8&VA34Z,/Z+AV73B[*'-#LV\(#M$/BVOX$U.37VG&\$[;*X@0H\#_#X!P+J
+MO+N!"3$'_F$+")2^NX8-"A3G'S$TE+ZYA0$!R.\!/3:5O[^>&A6<E`\^,>N]
+MLY80Y8*3"CLP[K"TY&.%M)XT.C#BM()-7HZPFC<[-N:/DVO^M[R$-S@T^H5`
+M&>^SOH<T/PG^ZQX!E+RXAPHS`/Y,#`^1OKB$#C<<Y1$W"I.YN(4"#''@!S,T
+MD+Z_G@<?E>X,/S:1O+*1'T2'E`HX,9>RMN-JDXB0-#LQE;:)W':#MIPW.C;I
+MBX5A]K6RF#8[-..`^A#LL+^:-SX+YY(4!9:]N84T/0+E]`$#DKZXF@HQ&N5I
+M"@Z<N;B8#PMOY!HQ-9^YOIP`!_[@`CTWG+Z]D05LGNX+.3:=O+#O$>V-E30[
+M-I"PM?1GA[21-CHVEK2`<]J(L)(Q.S3JC)<5XK:]G#8X"NR%?QZ6LKZ>-S\,
+MX>P;!IR_N9XT,P?D?P\-F;FYGPLT$>4<-PB;N+Z2#`);Y``R-9NYO)8&$I?A
+M"3\TF+^S[A_;ANPT.#>>LK?_:9^(ZS8[-YVVC$5$C+:4,3LTD8N98N2TLY$Q
+M.#65@?40E[.\DS$^#N^0$1J<O+Z2-ST!X-P#`9JYN9,U-A_D%S4,A+B^D0D)
+M9OH',`B$N+^4`@3F^@\\-82YLNX%9YCG-3DTA;RV^Q&5C>`V.S28LXO1>8&U
+M[#`[-)^TAGKSBK'H,#LUD(SI%96QO94P.0F4FV$?G+V_ES$]B*^FOK2$_A4$
+M#`LQ,S\_/C\\,C`W"@P''6#3[).%@8*/B8N*BHJ+B(F/C8.&A)B=E^[D]%1U
+M>F-N%1<6$!`3$Q,3$!$6%Q5K;FUA9'AR=$Q;4]?<Q<#/R_7T]_?W]_3URLC/
+MPL''VMG<T]'455=64%-275U<7%]?7U]<75U24U!15E=45%555=34U-?6UM;1
+MT='1UM;6UM;6UM;7U]?7U-35U-34U-74U-74U=75U=75U=74U=34U-34U-74
+MU-34U-34U-34U-34U-35U=34U-34U-35U=75U=75U-34U-34U-35U=75U=74
+MU-34U-74U=74U=74U-34U-34U=75U=75U=74U-34U-74U=75U=75U=34U-75
+MU=75U=75U=75U-75U=75U=75U=75U-35U-75U=75U=75U=74U=75U=75U=55
+MU=75U-75U=75U=75U=75U=75U=75U555U555U=75U=75U=5555755575U=75
+MU=75U=75U=75U=75U-74U=35U=75U=74U-74U=75U575U5755=75U=75U555
+M5555U=75U=75U=75U575U=75U=34U=34U=75U=75U=74U-75U=75U=75U=75
+MU=75U=75U5555=75U=75U=755=5555755=75U=75U=755=75U=75U=35U=75
+MU=75U=75U=75U=75U=55555555555=75U57555555=75U=75U=75U=75U=75
+MU=75U=75U=75555555755=75U=55U5555=75U=75U=75U=75U=75U=75U=75
+MU=75U5555555U=75U=75U=755=75U=75U=75U=75U=75U=75U=74U=75U=75
+MU=75U=75U-34U-35U=75U=75U=34U=75U=75U=7:ZY'@X?7;64AP>7MD9&=E
+M9'AX?7-T2T%%4U?1TMO$P,+/SLC(RLO(R<[,PL''Q=C>W]+0UM?555=14%!2
+M4E)=4E%27UU24U!04%%65E=75%555=35U=?6U]?4U-35U-35U=34U-75U=75
+MU555555555555%155%5555555555555555755=755=75U=75U=74UM175575
+MU=75U=75U575U575U=555%75U=75U=55U=75U=75U575U555555555555575
+MU=75U=75U=75U=75U=75U=75U=555575U5555=76U5155=75U=35U=75U=35
+MU=75U=75U-75U55555555%755=75U=755=75U=75U=74U=75U=755=755=75
+MU=74U=75U=75U=75U=55U=75U=?55U14U575U=75U=75U-75U=75U5155575
+MU=75U=75U=355=75U=75U575U=355=75U=75U=75U=75U=55U=75U=755=75
+MU575U575U=74UM57U5155=75U=74U-34U-75U-75U=?4U57555555=755=75
+M5=755=75U=55U=35U=74U-75U=75U=75U=75U=75U=75U5555=555=55U=36
+MU5=55%55U575U=74U-75U]34U=545=74U-34U-35U=34U=34U=5555555=75
+MU=555=755=555=75U=75U=75U=75U=75U=75U575U=75U-;55U145575U=75
+M5=35U-75U-35U=77U-75U=55U=75U=55U=75U=75U=75U=75U=34U-35U=75
+MU555U575U=75U=555=755=75U575U=75U-75U=34U=75U=755=75U=55U=75
+M5%75U=35U=75U=35U=75U=75U=555555U5555=75U=75U=755575U575U=75
+MU575U555U=75U=75U=36U5=55=75U=35U-35U=75U=74U-75U]?5U=55U=75
+MU=75U=74U-34U-34U=74U=75U55555555=75U=75U-75U=75U=74U=75U-35
+MU-34U-;45-55U=75U=35U=555555555555=4U=75U-74U-75U=55U575U=75
+MU=75U=55U5555555U575U=74U=75U=55U=75U=35U=35U=35U=74UM145535
+MU=75U-75U-74U=755555U=345555551555555575U=75U=74U=75U=35U-75
+MU=555575U=555555557555555555U=75U=355=77U5=55=75U=34U=75U=75
+MU=75U=545=75U-34U-35U=5555555555U5555555555555755=55U=755=75
+MU-35U=75U=75U=74U=75U=55U=?55U55U=75U=74U=75U=74U=35U=74U-75
+M55555=555=55U5555575U575U=74U=34U=75U=755=75U=75U=75U5555555
+M55555=75U=74UM5755755=75U=74U=75U=55U=755%75U=75U-75U=75U=75
+MU575U575U=755=555555U=75U=75U=75U=75U=34U=75U=755555U=555=77
+MU5=55=75U=75U=75U=75U=74U=75U-35U555555555555=75U555U5555555
+M5=75U=75U=75U=55U=75U=75U=75U=75U=75U=75U=55U=?55%545555U575
+MU=75U-74U=75U555U=74U-34U-35U=74U=75U=74U=75U=55U=55U=35U-75
+MU=755=75U575U=75U=75U=555=75U-75UM575535U=74U=75U=75U=35U-75
+MU=77U=75U=75U=75U=75U=74U=35U=75U=75U=75U-75U-75U=75U-34U-34
+MU-34U=75U=75U-34U=36U%355=75U=75U=75U=34U=75U=155=75U=34U-34
+MU-34U=75U=75U=555=75U=55U=75U=75U-34U-34U-34U-75U=55U=55U575
+MU=75U=?55U15U=74U=74U=75U-35U=75U=74U-35U=755=55U=55U=75U-75
+MU=75U-75U-74U=75U=75U=75U-75U=75U=75U=74U-75U-75U-74UM175575
+M5=75U=35U-34U-75U=34U575U-34U-34U-35U=55U=75U=75U-75U-74U-75
+MU=75U575U=75U=75U-75U=755575U=74U=755=7755=55-75U=75U=35U=75
+MU=75U=75U-15U=555575U555U=75U=75U575U=74U-34U-35U=75U=74U=74
+MU=34U=75U=75U=75U-35U=75U-;55U175=74U=74U-35U=74U-75U-545=75
+MU-35U-34U-75U=75U=75U575U=7555555555U=75U-75U-355=75U5555=75
+M5575U=75U=74UM5655155=75U-35U=35U=75U=75U=37U]35U=75U575U=74
+MU-75U-75U=75U=75U=75U=75U=75U=75U=75U-35U555U-75U=75U-75U=76
+MU5=55-75U=75U=75U=35U-75U=355=75U-?5U=74U=34U=74U=75U=34U=75
+MU-75U=35U=75U=55U=755=75U-35U=74U-75U-35U=75U=35U=75U=75U=75
+M5575U=755=75U575U-35U=75U=35U=75U=555=755555U=75U=74U=75U=75
+MU=75U-35U=34U-75U-34U=75U-75U=74U575U=75U=75U-15U-34U-75U-35
+M5535U-75U=34U555U-355575U5555=7555555=555=75U=755=75U=75U575
+MU-75U5555555U575U=75U5555=75U575U=34U=75U-75U=75U-34U-75U575
+MU=555=75U=34U=35U=755575U-34U=75U5555=75U=75U=75U=75U=75U=75
+MU=75U=34U=75U=755=75U=55U=75U555U=54555"9F5P=D=;U-#%:B<A/#$#
+M:^::@HNUMK:_IJ"]@Y&!B+6=8&F$L[R$-28F/6V:X@$V-P,;#CPE/7JVO(("
+M/C\`F8^'_OV!MK?C"S(.@;JDL74)#&6<EFT>Q8N\L4@R)3#ZL;*"%``=\_P8
+M-#1BM+NRVC,[-MZ)B9%B39N-E`T\,A6QI;WB-3,/VY[F%!2=M["9"SL^'K2Y
+ML.`##13F4P<(&H:_OH$(.S\:C;:/QQ98F9X7-S(-@+B[C0(\,!V9A.1H78&W
+MC1\\.PJ'OKF"!34->>U^!@;EM[ZT$C\Z-9RPL)L1'EZ0]``Q-?FRI;%I/3X(
+M[H^&R6SCC8[V-#DS5[*ZL7PT-@3GE6<;;X&SL.\V.CUDMK^U3P$%5NQN#C40
+MB;B_DC<[,VZ/M85[8I6`G00S/02+NKZ8"#(U89Z19!;CB[&!`#DX`X^YO9X&
+M"1OU_AT/!I*RN8D!.3D-A[&U[A!LE)E\"S,(G;^ZM1H],@&0@)!G99FUB6<P
+M.#:4O+N*$30+%^W+'@9UB+RQ2#(Z,>6QLH)N!&GIX!@T-&>WNK+V,#DWT(^,
+MZVS5A(^4#S\R%K:EO>,U,`W?D\,2%Y^VLY@+.SX9M;ZQX0$`;>-/``H%@;ZY
+M@`@X/!N#MX+6%,J$FQ$V/0V`N+N-`STQ$IR;P!30@K:/'#PX"H2^OH,:"@!T
+MXV(``.2VN;<0/SLUD[&VGA83]YS*`C`U_;*EL6\R/P[M@H57;>N.B/(T.3-:
+ML[JQ<C0T&N3L:P1N@+*SZ#8Z/6&WO(I)!Q_W[A4(-!*(N+^=-S@P:(V+F61D
+MDXV?!S(]!XBZOI@),PIGG>AI$.^ULX,`.3D"C;ZRGP<,'?_W&`D!DK*XB`8Y
+M.0V$MHOB%GN2FGDU,@N2O[JU&#(S!I&&ZVUXA;2+9#`X-NJ\N(L6-0YJXE,%
+M`'2*O[%$,CHQ_+:S@&\8>I?C!3<W8+:ZO?PQ/C17C8/@;,N!B)<./ST0M[JR
+MX@HQ`]J70AD1F;&RF@L[/QB*O[;F!@=^[W("-`2!OKF`"3@\&H"T@%QHYX:%
+M$#$\#(&XNXT`,C83DIU"$<6,L8X</#L*A;^_@!@)!UGF%0T#Y;&YMQ$_.S61
+MMK><%!3@F,H,,S3WLJ6Q8S,\#^.`GG5MEHB*^30X,TJSN[9W-349Y.00!FB"
+MO;*5-CH]8K2]B$X$$>;K%C4W'(B[OI\T.3!K@XZ29G.9CY@'/3P&B+N^FPXP
+M"&60Y!82Z+2R@@`Y.`*"O[.<!`(6Y\,%"@"2O;B+!SX^#9JWCN<409B$>#4]
+M-9"_NK4>,C,'EX7G:G^'MXI[,SLV[[VYBQ<+#&WC<08"<;6^L%8R.C'TM["&
+M;1Q%DNT$-C9LMJ6]Y3$^-%V#AOQO^8**D0X^/1*WNK+M"#<!P>MD!1.;L+V$
+M"SL_&XB\M^<$&ECK90PW!X&^N(,..3T:AHJ'36WH@X<0,#P.AKBXC0$S-Q&0
+MEF02S8ZSB!T\.S68O+R`'@\%V>00#@WZL;BV%SPX-9>WM),5;Y6%]`\R-\.R
+MI;!F,#T,YH:096V3M;3D-S@S?;"[MDD+"QWD]A\#%8*\LI8V.C)NM;*.3AMI
+MZ)43-#8>B+N^GC4^,6N`C9=@0X6(F@8]/P&)N[Z;##$.>9?.'!^5M[V-`3DX
+M#8.\LYT%`6GBW@8U`I*]NXH$/CX-F+6,_FK&A(9X-#PUEK^ZM1PS,`25F<X6
+M?8&QM7TS.S'CLKF(%0D#9.!D``Q\M;FSVS,[,<>TMH=B$/69[P8Q'ZBBI;./
+MDW4<``DT,#T^/SD\/S,P-`L`!!5E^NJ9A(.-B8B*BK6*BXB.C(*`AH6>D)7B
+M^<1;<V=M:!06$1`3$Q,3$!$1%Q05:6QC9F5_<$I!7U33V,;-R?7T]_?W]_?T
+M]<O)S,/!Q-C>TM#6U51645!24EU<7%]?7U]<75U24U!145975U15U=74U]?6
+MUM;6UM;6UM;6UM;6UM?7U]?4U-34U-34U-34U-35U=75U=75U=34U=75U-75
+MU=34U-34U-34U-34U=34U-34U-34U-34U=74U-75U-34U-34U-75U-75U=75
+MU-34U-74U=75U=34U-34U-74U=75U=75U=74U-34U-75U=75U=75U-34U-34
+MU-75U-34U-34U-34U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=35U-75U=75U=75U=75
+MU=75U=755=75U=75U=75U=555=75U=75U=35U=75U=75U=75U=75U=75U=55
+M5575U=75U=75U=75U=75U=75U=34U-75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=55U=75U=75U=75U=755=75U575U=75U=7555555=75U=75U=75
+MU=75U=75U=75U=75U=5555555555U=75U=75U=55U=75U=75U=75U=75U=75
+M5=75U=75U=75555555555=75U=75U=555=75U=75U-35U-75U=75U=75U=75
+MU=75U55555755=75U=75U=755555U=75U=75U=75U=55U=/BD.WA\\1727=Y
+M>&1E9V5D>WA\<G=U0T1<4=;2V=K!P\S.R,C(R,G)SLS"P,;$VMG?TM/1U]15
+M5%915E!275U<7%Q=75)24U!045%65E=75%75U=34U-?4U-37U]34U-34U-75
+MU575U=75555555555=7555555%55U55555555555555555555515U=75U=75
+MU=74U=75U=75U555555555555575U=75U=555=75U=75U575U=75U-75U-75
+MU=75U=5555555555U=755=55U5755575U555U=34U=55U555555555755=75
+MU=75U=74U=755575U55555555555U=75U=755=75U=75U=75U-74U-75U=75
+MU=75U-75U=75U=55U=75U=555-75U=75U=75U=75U=75U=75U=75U5555=75
+MU=75U=74U555U=55U=75U=75U=75U=75U5555=77U5=55=55U=75U=74U=74
+MU=74U-34U-37U-755=755=555-555=5555755555U=75U=34U-75U575U=75
+MU=75U=75U=75U=75U=75U=75U-;55%55U575U=74U=75U=75U=755=755%35
+M5=75U=75U=75U=75U=755=555=55U=75U=75U=75U=75U-74U-34U-74U-75
+MU%755=75U=74UM5455355=755=75U=75U=75U=75U=75U-35U=7555555555
+M5575U=74U-34U-34U-34U-35U=7555755555U=75U=75U=75U=75U=75U=36
+MU5155=75U=75U=755=75U=75U=75U515U=75U-34U-34U-34U=35U=75U575
+MU5755555U=75U-75U=75U=75U=74U=74U=75U=75U=35U-;55U55U555U=75
+MU=75U-34U-35U-35U=34U5555575U=75U=75U-75U=75U-74U=34U=35U=75
+MU=75U=75U=75U=75U575U=75U=75U=74U]5755155=75U=75U-74U-74U-75
+MU-555=55U=75U=74U=75U=75U575U575U=75U5755=75U=55U=75U=35U=75
+MU=75U=35U=75U=75U=36U%155=55U-75U=75U-35U-75U=74U=74U]755555
+M5555U575U=55U=75U=75U=75U=34U-75U=75U=55U=75U=75U=555=75U=75
+MU=75U-;55U54U=75U=75U=75U=75U-75U=755%755=75U=74U-74U=75U575
+MU=755=75U=555=555=555555U=75U=75U=75U=75U=75U=75U=74UM545535
+MU=75U=75U=74U=35U=75U575U-35U5555555U5555575U=75U=75U=75U=35
+MU-75U=75U=75U=75U=75U=75U=555=75U=75U=76U5945%55U575U=75U=75
+MU=75U55555145575U-34U-35U-75U=555555U55555555555555555555=75
+MU=75U575U555U57555555555U=?55U555=75U=74U=75U=75U=75U-35U=34
+MU=555514555555555=755575U=75U=75U=75U=55U=55U555U5755575U=75
+MU=75U=75U=74UM5755155=75U=75U=75U=75U575U=555-75U=35U=75U=55
+MU=75U=75U=75U=75U5755575U=75U=74U=35U=75U=75U=75U=75U=755=36
+MU5=55-75U=75U=75U=75U-75U=35U=74U]3555555=75U=75U=75U=75U=75
+MU-75U=34U=75U=75U=55U=55U=75U=75U=75U-34U-34U-'55%55U=74U=35
+MU=34U=34U-35U=745535U=74U-35U-75U=75U=75U=75U=75U5755555U=75
+MU=75U=35U=75U=35U-35U=75U575U575UU575535U=74U-74U=34U=34U=35
+MU=75U-?4U575U=75U=75U=75U=75U=75U=35U=75U=75U575U=75U=74U-74
+MU-75U=75U=75U-35U-36U5155=75U-75U-34U-35U-75U555U5575%55U=34
+MU=34U-35U-75U=75U575U=55U555U5755555U=75U=75U=75U=55U5755575
+M5=75U=35U=55U=55U=75U=75U=75U=75U=75U=74U575U555U555U=75U=34
+MU=75U=74U=74U=34U=75U=75U=55U5555=75U=75U=74U=75U=75U=55U575
+MU=75U=75U=75U=55U=75U=155%75U=34U=74U-34U=35U-75U=75U=755=75
+M5555U=75U=75U=34U=74U=75U=34U=75U=75U=75U5555=55U=75U=75U-74
+MU=34U=74U=75U]5555555=75U5755=75U=75U=75U=34U-34U-5555755=75
+MU=75U=755=755=555=75U=75U-35U=75U=75U-75U=75U=75U=75U=74U575
+MU=74U-75U=75U=75U=74U=75U=34U=35U=75U=74U=35U=35U=75U=75U=55
+MU=75U=75U=34U]35U=75U5555575U575U=34U=75U=55U=35557555755=75
+MU=75U=75U=75U=55U=75U=75U=55U=75U=75U=75U=55U=75U=75U-34U-34
+MU%75U=75U=755=74U=75U=74U=75U=555=75U-34U-34U=35U=75U=75U=75
+MU=55U=55U=55U555U555U=75555555555575U=75U=75U=755555U=75U=75
+MU=75U=35U=755=75U=74U-75U=75U=55U555U555U575U=755=75U=35U=75
+MU=55U5755=74U=75U=75U=75U=75U-74U-35U=755=755=7555755555U=75
+MU=555U15U=35U-34U-75U=75U=75U575U=75U575U555U=75U=75U=75U=34
+MU-35U-34U=755575557555555=55U=75U=75U=35U=34U=75U575U]34U=75
+MU555U=75U=75U=75U=75U=75U=74U=75U=75U=75U=75U=75U=74U=75U=75
+MU=5!9F1P<49:U=':8B0@/C$"%/J9@XJUMK&ZH:2"Z96"O;F+D9:(CG(\)SD6
+MB8(=,STU`S0X)32%L(@'/S\"^NP5$I:PN8D#/S'GL+*-Y):(M>$U/`V.NKZ:
+M!P-A[V((-6>QNK8</#T$EI!M'>^WLYTW)3+4M[:>:G^;AVDP/P*(N[SK#PD4
+MX&<,#O>SNK0$/S(<A816%9>WL>\Q)3#KL+"?$&F1GA`P/02TNK+&-340X'(#
+M`^^RN(X,.3(4@(#\;)>UM-4S.C>8O;.3&1/MD1TQ,Q:QI;!A-C<3[M4$!)"R
+MOH$U.S-[CH_C;>N(B6(R.PN#OK.5!QOWZ1PV-G"SI;82,S80E_X>'Y^RO)PV
+M.C#+M8ON;^",@Q`].0*(N+/E`@9$X!TT-?B]NK4'/3$7G.@7%INSL^`P.C:5
+MMK7I%?>!A!@]/P6TN[!>"0)YYQ,*#Y>\NXP,/S%MA))C:9JQMDP].C2;L[?L
+M$$":G`0R,A2QNK9L-0YAYA0/`9F_N88U.39W@)IV8)NVM14\.PF`O;?D&6"3
+ME`8S,4.RNK0<-@MC[&T#&X>_OY(V.#?PCH%49IFTCQX_.`")O[?-!Q;HXP8P
+M-."\NH@&,S5FE'$'$(&\LN0S.S25M8W!8)*(@0<_/ABTN;=V`Q[[^`8V")*^
+MNX(,/35\G<$>:8.]L7T].PN9MX[,;I2,F0,_/6NPN+1H#@3&\@0T`H2YN(0U
+M/S53A>`69(*RM!$_.`R`L(C8%^&!EPP\,U>RNXH<-0!0_1L+!(.YOI$V/C7_
+M@99O<X.PB04Y.0:.LHM$'=N;X`\]-^F_NX\'-P);Y!T,$H^YO?(S.0N5C)YD
+M=8&V@P,Y/A^TO(MZ!7^3]P\R"IFYN(`-,`Q1[Q0`:8F^L&<\.0^>BX1S=H>U
+MF@\Y/&VQOHEK`6CKTPPP#(&XN9L*,@_!EF8%?HN_MQ(^.0.&M(%Q>YN)E@LY
+M,\>RN8\=#!/F4PTW!XR[OY4W/0_EGEL<7(N]BP<Y.02,L8-_;9*#YC4^-I6_
+MN8,$"!C\40`U'(N[O<,P/`SJA/P7P8BS@@PX/Q.ULX-A%^B'WC4_-9JYN8<"
+M-`3QQ0<.:;6[L&(]/P.=@^ENRHZQA0L[/6>VO8-J'/V>=S4]#X.[OIP(-@;R
+M_!L#=+>XMQ\_/P:$CI!CR8RTD30[,_>SO(`3!$26934P!HFZO^PT,`;G[1,'
+MSK>^B@$Y/QB"M9]ATH"(Y3<X-I:\OX<:`&'I80LV'+6ZO5<Q,P;IEFX9Y[>\
+MC0X[/!>(MYMC3H2-6S8Y-86^OY@!#!7A9@XU;[:ZL&DR,@20GG(0[[>RA#4[
+M,G^TL9IH9YZ&83$_#X*XO)8/"Q#D>`T)1;&[MQD\/1N;A]H5Z+2QD38Z,/ZQ
+ML)L6%9>9%3$]!HNZO>0*-!SF30$"^K"XBP`^/1*&@^1OZ8JT_C$[-I&RLYX?
+M'>:0%C8S'[>ELT\W-Q_LP`4'ZK.^@@DX,FB,CNYMXHF(<3,X-82_LI`$!=KK
+M$#<V;;&EL14P,1R4YAP9D+.\A30[,TJ*BI5O^(*-:S(Y#XVYLNX#`7;C$#4U
+MU[.ZM!L],1.=E!40G+"REC$Z,>6WM)<5WX:'$C(_!HJ[L_<.#&'F%PL.XKV[
+MB`,_,!2%G&=JGK&Q]C,Z-Y"PMY40<YB>&#,]'+:ZL'TU"6[A:0\#D+RX@@@Y
+M,6&!A$%MG[>T93T["H2]MNX>;I&6!3,P8["EMA<V-6CL9``$F+R^A30X,5^/
+M@,%@DK6)$3PX#(V_L>4$$^WO!#$WP+VZM1LP-&F46@0<A+R]E#$[-^>*C/-B
+MEHB#&SP^!XJYMM`#&_#G!38*ZKRZC@,]-&.2\Q\4AKVPP#([-)"WB?]I[HV%
+M!CP\$K:[MV4&I:"ZL8*59Q@""#0R,CX_.3P\,S$U"`$::G#DE)B'@XR)B(J*
+MM8J+B(Z,@H"'FI^0E>/\VD1]9FQK%!81$!,3$Q,0$187%&IH;&-F97]Q2$9<
+M5-/8QLW)]?3W]_?W]_3UR\[-P\;%V-_=T-;55%904U)=7%]?7UQ?7%Q=75)3
+M4%!15E=45=75U-34U]?6U];6T='1T=;6UM?7U]?7U]?7U-34U-35U=74U=74
+MU=75U=75U=75U-35U-34U-34U-75U-34U-34U-34U-34U-34U-34U-34U-34
+MU=75U=75U-34U-34U-74U=75U-34U-34U-34U-34U=35U-34U-35U=75U=75
+MU=75U-75U=75U=75U=75U=75U=75U=75U=75U=74U-35U=75U=75U=75U=35
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U575U=75U=75U=75U575
+MU=75U=75U=75U=75U=75U=75U=75U=75U=555=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=555=55U=75U=75U=75U=75U=75U=34U-35
+MU-75U=75U-75U-75U=75U=55U=75U=75U=75U=75U=75U=75U=75U=755=55
+MU=75U=75U=75U=75U=75U=35U-75U=75U=75U=75U=755=55555555555=75
+MU575U5555=75U=74U=75U=75U=75U=75U=75U=75555555555=75U=55U555
+M5555U=75U=75U=755=75U=75U=74U=75U=55U=75U=75U=75U=755=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U-75U=75U=75U=75U=35U=75
+MU=7WEI3FY\#90TM\>65E9&=D97AY<G!U24=;4%30W-K&PLW.R<C(R<G)SL_-
+MPL#&Q=O>W]+0UM355%914%-275U=75U=4E)34U!145%145975%555=75U=34
+MU-74U];45-55U-74U-34U-35U5755=555%755515U-1555155%1455555=55
+MU=75U=555=555=755=75U5755575U575U=75U-75U-75U=75U=74U]575%35
+M5575U=75U=75U=55U=75U=55U5145=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U-75U=75U=75U575U5555=76U5=55%555=75U=755=75
+MU=34U=75U-75U=34U=555555U=55U=755=75U=75U=75U=74U=75U=75U=75
+MU=55U555U=75U5555=755575U=?55U145575U=35U=75U-35U-75U-35U=55
+M5U75U=75U=74U-35U=75U=5555555555U=55U=74U-35U=74U-34U=74U-35
+MU=75U=75U=75UM1755755=75U=75U=75U=75U=75U=75U=74U-75U5555575
+MU=755=7555555=75U575U575U-755575U=75U=755=75U=755=75U=75U=36
+MU%155=55U=75U-74U-35U=755=75U5755%15U=75U=75U-35U575U=555575
+MU=75U=75U575U=745=75U=755=75U-75U=75U=555555U==55U145=75U=74
+MU-74U-74U-34U-34U-35U-?5U=7555755575U=75U=75U555U555U575U=75
+MU=75U=755=5555555=75U=75U=75U575UM565575U=35U=75U=75U=75U=74
+MU=74U-55U=35U=74U-34U-75U-75U=75U=75555555755=75U=75U=75U=55
+MU=55U=75U=75U575U=76U5355575U=75U=75U=75U=74U=35U=75U=37U-75
+MU=55U575U=75U=75U=75U=75U=35U=35U-75U=75U=74U-34U=75U=75U=75
+MU=75U=;55U545575U=75U=75U-34U-75U555U=545-75U=35U=75U=75U=75
+M5=55U=75U=55U=555=75U-75U-75U-74U=75U=74U=74U=74U=74UM575515
+M5=75U=34U=75U=75U=75U=75U=74U]35U555555555555=55U575U=75U=55
+M5=75U=75U=55U=75U575U575U555U=75U=75U=34U574U=75U=75U=75U=75
+MU=75U=55U=34U555U=55U=75U=75U=75U555U55555555555555555555555
+M55755=75U=75U=5555555555U=955U545=55U=75U=75U=75U=75U=74U-75
+MU-?55554555455545575U=75U=75U=75U=74U=75U575U=75U555U=755=75
+MU=74U=34U=74UM5755355=555=55U=75U=75U=755555U=555=75U-74U-35
+MU=75U=55U5555555U=55U=55U=75U=75U=755=55U=75U555U555U5555=77
+M55=45-75U=75U=35U=75U=55U=55U=75U=37U%55555455555=55U=74U=75
+MU=75U=75U=74U=555=75U=755=755=75U=75U=75U=55U=?55U55U=75U-35
+MU=75U=75U=75U=75U=355=74U-34U-34U-75U-34U=34U-34U=75U=755575
+MU=75U=75U-74U-35U-35U=755=75U=75U]575575U=75U-75U=75U=75U=75
+MU=35U=75U]34U=75U=75U575U=75U=75U=75U=75U-34U=34U-35U=34U=35
+MU=75U575U=75U-75U-36U%155=74U-34U=34U-34U=74U=755=74U515U=74
+MU-35U-74U=35U-75U=75U=75U=74U=75U=74U-75U=75U=35U=35U=755=75
+M5=75U=?55U545575U-75U-35U=75U=75U575U=75U=?7U=75U575U=75U=75
+MU=55U=55U=75U=75U=35U=75U=35U=75U=75U=75U=75U=34U-34UM145575
+MU=75U=75U=75U=75U=75U=75U-15U=34U-34U-35U=5555555575U=75U=75
+M555555555=75U=35U=35U=75555555555575U=76U5=55555U=75U=75U=75
+MU575U=75U=75U=74U-7555555=555=75U=34U-34U-34U=74U=75U=35U=74
+MU-75U=75U=75U=75U=75U=75U-;45U55U=74U=34U-35U-75U=75U5555=75
+M5%75U=75U=75U=74U=75U=75U=34U-34U-75U=55U=555=75U575U=75U=74
+MU-75U=75U=74UM5755155=75U=75U=74U=35U=34U-34U-74U]?5U=75U=55
+M5=75U=755=75U=75U=74U-34U-75U=75U575U=75U=555=755=75U=75U=36
+MU5355=75U=35U-34U-34U-34U=35U=75U555U=74U-34U-35U=75U=75U=75
+MU=75U=75U5555=75U5755575U=75U=75U=7555755=75U=;55E1455755=75
+MU=75U=75U=75U=75U=35U=?4U=555575U=75U=75U=75U=75U575U=75U=75
+MU-755=75U=75U=34U=75U=75U=75U=74UM14U575U=55U=75U=75U=75U-74
+MU-35U=355575U=75U-34U-35U-74U-75U=75U=74U=74U=74U=75U=74U-34
+MU-34U-75U=755=55557755?55=75U-75U=75U=75U-34U-35U=35U=74U%55
+M5575U=75U=75U=75U575U=75U=34U=35U=35U=75U=355=555575U=75U=55
+MU=55U=35U=75U-75U=74U=74U=74U-34U-34U=755535U=74U=34U=75U=74
+MU=75U=34U=74U-75U=75U-35U=74U-35U=35U=75U=75U=75U=74UM545575
+MU=75U=75U=75U=75U=755=75U=74U]?4U=7555555555U=75U=75U-35U=35
+MU=74U-35U=75U=75U-75U575U=55U=75U=75U=31U5355-75U=34U-34U-75
+MU=555=75U=75U-545=55U=75U=75U=75U=75U=75U=75U=75U-75U-75U-75
+MU=75U-34U=75U=75U=75U=75U=?55U145=75U=34U=75U=75U=75U-75U=75
+MU=?7U=55555555555=55U=75U=75U=75U=75U=75555>969S<T)$5M;913TC
+M)3,/$\N%@(N+MK:SMK>PIZRGA1]FFI@<#G:VL_H\)S\#`S`R!8.-!B4G,6!A
+M``:>LK80/SUIC(#YX+>XMA@]-)&VB>SJM+V&-3@UA;:"0,2/M4D].@^,L(9I
+M<H:!&CDY$[:RA!!DA9P"/C/IO+V2&FF2X`@\"X*[L\H"$NY8"C,%M[JW$`H;
+M^V<*-T.]NHP"-@7^80D/G;FYDS0P&^)_`AJ-N+)D,C`0D%0$;;6XM`$^,7R$
+M^QW"M[^&-#LWZ8WJ:N^VL/HR.P^'BY!BE[2U$CDY'HJWD&V7BH$-.SW`L+:5
+M%.Z-E#0X-X2_MO<?_(1`,3X#M;BT;0=$D!0P,FZRNX\%#6;L'S$TE[ZYF0X(
+M;N48-P*"N[S=-S5LY!X+$[2ZMADR-7+I$P/0L+N,"#\*_9)I&Y:ROY<P.0R3
+MA7(7A;*Q:3\^&H"#TF&&LXD#.SU_BH_.>8&WF#0Z,9"QB-9EAXC#,SL.C+V)
+M96Z9@1$]/ARVOX(1$)>2!SPS^[R_FP<:Y^`",@J&N+WE#@;-Q@PQ!+6EL10T
+M`]]1#35^L[J(`S`"]]X`#9>_N)@T,@'L^00;AKZ]33(]&)SH$FF/OK<$.3)M
+M@9)K1XN]@#4[,>&)FF?WBK'L,SL+A[>$9/^)BQ4_.02*L(5N]8V&`3D]2;"S
+MG!-:AY8(.3:9O[/@!&&=VC0\#8B[MF<-%^AF-#`7L+J+&@L=YVHT-.*_NX<.
+M-QSD%0L#AKB_^38V$.]L#1*+N[$2/3%MDWP'2[>XC@XY-\&%V1WBL;R=,3@(
+MDX+G:I"QL7L_.0:#B.YCG+:)!S@_;+6U[F*<M9H*.S"5L[3X%9&-^38X"X*_
+MM'0=[85L,S\;MKF)$03.D1XS,-B\N88&`TK@!#`*A;B_Z`@.>_T'-P>+NK-O
+M-@M]_@0(8[&ZM0$R"-'B'@#BLKB$-#\/[9$6'IB\O<PR/P:9F&!H@;VW&#D\
+M%H*&='^"LX((.S/RM8)%3(*WE#$Z-86QC7%T@(YF/3@!BKV";V:%AQH_/&:S
+MO(0<%).6`C\VD[Z\EP$?[_,),@R/N[-U"03_0P@Q$[&EM!@W!O9S#@KRO+N#
+M#C`&^DX"`)NYONDQ,P65V@<=C+FP%SPS%IGF'WN*OHL-.3%%@)04]+2]F#8[
+M-)&)G6+CM+9>/3@"@[2>8.R*CALY/A:TL9UKX8R%#S@SX[*PZA++AN`T.36`
+MOK'3!'2<?38\!+>[M!<";>L4-C%TO;N-`0@4YA,W"YRYN9,*-!?D$PH'C+N]
+M>3`W:>\7#&BWN[0'/#1WD&T'\+"Y@#4^"N&%=1*1L[WF,CD-F(#,:)BPMQ,^
+M/A^,COMFA;:"##LRU[>*_F&:M9`W.S>8L[76:)^-3C,Y`HB_B&,3E)H3,CUJ
+ML+Z"'AKEE`<R-I6^OI\#`=+Z`#`/@KN]VPH-0<\#-Q^WI;8<,0]2RP$(U;*Z
+MC`\R#//D!0&3O+Z0,3P`E)42$H:_LV(\/!F%G&A@C+R*`#@R>HR$946.LX0T
+M.S:5M8%]WHZW]S([#H.Q@6?7@HP3/SX?M+*'%7>'F@`^,O>RO9T9;9_O"3\U
+MA[FR^0`1ZE<U,@:UNK9K"1GG934V9K.ZB08T!?EC"PB7OKB;-3$;X60,!X"X
+MO%8P,!*42084B[BV!3\Q8YCU&5&WOH(*.#?Y@.(7X[:RE3,X"9B)EVR7M[=K
+M/SD$C[218I:UC0`X/'RVMI5KE8^2-3@VG;VV^!+FAL0V/@^.N;1Z!=V<:#`]
+M$[&XB1\#?N@<,3;GO[B$`@YMY!@V#X:[O^0T-6SE&#49M;JP$3`U>N(=#'&Q
+MNX@,/`K%EA0$Z+*^GC8^#Y289Q"8O;-V/#X'A(%;;8:SM0<X/&F)C<5X@;:'
+M"CLP[;>.W7F&M>8P.PJ!LHEP8YJ":3T^!;2_C147DYD%/#):O:"LI[R*F=$3
+M`0XU,#(_/CX^/STP-@H,!QUAW.^2A8&-CXB+BK6UBHN)CXV#AH28G9;NY/54
+M=7IC:147$1`3$Q,3$Q`1%A<5:VYM861X<G1-6U#7W\7#S\OU]_?W]_?T]<K(
+MS\+!Q]K9W-+1U%5745!34EU=7%Q?7U]<7%U24U-045975%155=75U-?7U];6
+MUM;6UM;6UM;6UM?7U]?7U]34U=34U=74U-34U=75U=75U=74U=34U-34U-34
+MU-34U-34U-34U-34U-34U-34U-34U-34U-35U=75U=35U-74U-34U=75U=75
+MU-34U-34U-75U=74U-74U-74U=75U=75U=75U=75U=75U=75U=75U=34U-74
+MU=75U=75U=75U=74U=75U=75U=75U=74U-75U=75U=75U=74U-34U=75U=75
+MU=75U=75U=75U=55U=75U=75U=75U55555555=75U=75U=75U555U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=74U=75U=75U=75U=75U=75U=55
+M55555575U=75U=75U=75U=75U=74U-74U=35U=75U=75U-34U=75U=75U=75
+MU=74U=75U=5555755=55U=75U=755=555=55U=75U=75U=75U=75U=75U=75
+MU=75U555U575U=75U575555555555=75U=75U=755=75U=75U=35U=75U=75
+MU=75U=75U=75U55555555575U=75U57555555=75U=35U=75U=75U=75U=75
+MU-75U=755=75U=75U=75U=75U555U=75U=75U=75U=7'E9'AX<K:6DMS>7ID
+M9&=E9'AX?7-T2D%%4E;1W=O$P\S.SLO(R\C(R<[-PL'&Q=O9W]+0UM155U91
+M4%)=4EU=4E)24U)34%!04%%15E975U=55575U=35U-34U-?4U-34U-34U=35
+MU=75U=555555555455145%55555555755555U=75U575U5755574U5155554
+M55555=75U=555=75U=75U575U=555=5555555=75U=75U5755575U=75U-36
+MU%155=75U=75U-7555555555U=75U-75U=555%75U=75U=74U=75U=755=75
+M55555=755=55U=75U=55U=75U=75U-75U=75U555U555U=75U=75U=75U=75
+MU=75U=75U=75U=75U575U=74U]35U=755=755=755=75U=75U=75U=75U=75
+MU-75U-35U=75U=75U=75U=75U=75U=75U-75U=75U=74U=75U=75U=75U=75
+MU=755=755%=55=74U=34U=35U=55U=15U=35U=75U5555575U=75U=75U=75
+MU-75U=75U=34U=74U-7555555%555575U=74U-34U=74U=75U=75U=55U=?5
+MU=55555555755555U=55U555U=75U=55U=75U=75U=74U=755=75U=75U555
+M5575U=755=75U575U=75U=75U=34U-35U=75555555175555U=75U=35U-35
+MU=75U=75U575U575U575U575U=75U=75U=34U=34U=75U=755575U=555575
+MU5755575U=35U=34U-?4U-35U=755=74U-5555555=755555U575U=75U-74
+MU-74U=74U=75U=75U=75U=34U=75U=75U=75U=34U-75U=35U=75U=75U=34
+MU=75U=75U-75U=345=75U=34U-74U-74U=74U=74U=75U55555555=75U=55
+MU=75U=75U=75U=75U=75U=35U=555555U=75U=34U-34U=75U=55U=75U=74
+MU=74U]35U5755=75U-74U-35U-75U=75U=35U=74U=34U=75U=755=555=75
+MU=75U-74U-35U-55U575U=75U=74U=75U575U=75U=35U=74U555U=74U=34
+MU=75U=755=5555555555555555555=5555555=75U=75U555U55555755575
+MU575U=75U=75U=75U=75U=75U=75U575U-75U=34U=75U575U=75U=75U=34
+MU=75U=75U=75U=75U555555555555575U=75U=755=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=545-75U-34U=75U=75U=75U=75U=75U=75U575
+MU=75U575U=75U=55555555555=555555U554555555555555555555755=75
+MU=75U=75U=74U%5555555575U=75U=5555555555U=75U=74U=75U=75U=75
+M5=75U=75U=75U=75U575U575U=75U=75U=75U=75U=75U=75U=75U=755%75
+MU=75U-75U=75U=75U=75U5755555555555555=75U=75U=75U=55U=75U=75
+MU=555=755=75U575U575U=75U575U555U=75U=75U=75U-15U55555555555
+MU=74U=75U-75U=75U=75U=755=75U=75U=75U=35U=75U=75U=75U-55U555
+M5=75U=74U=75U=75U=75U=755575U515U=74U-34U-34U=75U=35U=34U-75
+MU=75U=75U=75U-34U-75U=75U-35U-74U-75U=74U575U=35U=75U=75U=75
+MU=75U=75U=75U=75U=?7U-75U=75U=75U=75U=75U=75U=75U=35U=75U=55
+MU575U-74U-34U-35U=75U=75U-35U=75U=35U-75U=75U=74U-34U-34U=75
+MU=545=75U=75U=75U=75U5555575U=75U-75U=75U575U=75U=75U=74U-34
+MU=74U=75U=75U]575%155=55U=35U=75U=35U=75U=75U=34U=74U-75U=55
+MU=75U575U555U=75U=75U=74U-34U=34U=75U=75U=75U=75U=755=75U=36
+MU%355=55U=34U-34U=75U=75U=35U-35U-35U575U-34U-34U-74U-75U%75
+M555555555=755=75U=35U=74U=75U=34U=35U=55U=75U-?55U1455555=75
+MU-34U-35U-75U=75U=75U575U]?5U=74U=75U575U=75U=34U-34U=35U=75
+MU=75U=75555555555=55U5755=75U=74UM14U575U=75U=75U=75U=75U-34
+MU-34U=75U554U=74U-75U=74U-74U-75U=75U=75U=55U=55U=75U-35U-35
+MU=75U575U575U-75U=76U5=55%55U=75U=75U=75U=75U=75U575U=555=37
+MU5755575U575U=755=75U=55U5555=55U=35U=75U=55U=755=755=75U=75
+MU-75U=;45U55U=74U-34U-35U-74U=75U=74U=755=555-55U=35U-35U-34
+MU-35U=75U=55U=75U=55U575U5555555U=75U=75U=75U=75U=74UM145575
+M5=75U=75U=74U=35U-75U=35U=75U=74U]55U=55557555545=55U=55U=75
+MU=75U=75U=75U=75U=75U575U57555555=55U=71U%=55-55U=75U=74U-34
+MU-35U=75U575U=755575U=35U=75U-35U=75U=75U=75U555555555155575
+MU-34U-34U=34U=74U=35U=34U-;55U545575U=35U=75U=75U=75U-34U=75
+MU=55U-?5U5555515U555U5755=55U5555=75U=74U=75U=75U=75U=75U=55
+M5555U=75U=74T=175%155=75U=75U=75U=75U=75U=755W-@?W-*1%S6W=H"
+M+2<S"A]WD(2/BK.[O(N.B+2DHJ2`&@UKGX#F'01\[7`T)"$_9;6)$#@A)0.0
+MA/`:!7"7\@0T#)&\I;!K,CT?M+B]A1$?5)V5:P5YC[RSYC$Z,.F\N8X%,300
+ME)5D$]:`M9@"/SP?M[J]RS$_"^*.@N%I7YZ%=0@P#82^N(,(.SP1BK.)=P<<
+MQN)N`@Q$M;^W$3\Z"H:^O)H`-`-=E\43%Y.TM^HU.#/2O:6W$3,S!Y*"G')A
+ME(.:'3$R!(B[OY<V.S''M;>%%1]PE?,%-0V7L[F.`CLY!XN_L?H-#A+GY1<$
+M88"PM'TS.S>>OKB-`3,T:IF:]VG%AHF3`CTS8K&ELV4R/@F1M8GB%F/KDGH.
+M-P:!OKZ:-#H]8+>]B6`"!W3C>@<&]+6]BQH^.`R/N+R2#C8-T)SM;VF6BXKR
+M-#XV[K^ZM04\,@6%B81+:>6%DQ\W,1"UN[WP,SLV[+:QA1,':N;S'@X'G;.\
+M@0D[/ARWN;%7"S49X.IE''V!MHAJ,CD+AKBX@0\]-VV'@>QM1YB#[@TS-M>S
+MNK80/SD,FK:*XAP0]Y1[#34>@KZ]ES$Z,].POXX7"0-G[U8>&^6ULX(!/CX&
+MM;N][C4S#_>$DW!MZXR,1S0\-9R^NHX#/C(9@+2!=!%;DY4<-31AM[NP>ST[
+M-)VSLYH;`ASP^Q8`'IFPLI@U.SQLL;NV9C0W&^B=Q!1TA[2"$C(_#8R[N9@U
+M/S=\C8^6;&26A/@",37CLKJU!#DY`X"SM.<%&G;L<0$.%(R\L_,S.C'OO;Z,
+M&30.8Y3E%!/AB+:$`CX\'+>ZLLPV/0_@@X70;.2&AF4T,@^$N;B`"#@R$8ZV
+M@WX9;>SM$P@)7+>YMQ$_.PN'O+*?!@@%S>)C!1&8L;&5-#@SU+*ZM!$Q,1J0
+MA.UM<9B)AQ@S/02+NK^4-CDWWXB*DFL5Y)S.`#</D;VXB0(X/@2.O;?V``!L
+MX%$:`&&/O;9\,CLWG[^Y@P8V"V*2EWL4YXRUG0\_,FRPI;!E,SP,EXZ`]VK3
+MF9MB-3`!@[FYFC0[,F"ULXUC!Q+VX1<,`ORWOXH:/C@,C;ZRD0TT!LR77!)H
+MF;>T_38Y,>R\NHH:,C`8F8.09&60@Y\%,#`2M+J]\S,X-."TM)P1'$>4VP8U
+M`9Z]OH`).S\<M;^W7@\/%^#R$`5WC+.U%3TX"X:YN8<,,S5GFIG?:?V`B>L.
+M/#%6LJ6V$3P_#9ZUC/T19)23;P@W&(RYO)8Q.C!4MKV-%`(%7.!C`0?BM[V,
+M`3DY!HNXLNP+-@#PG.=K8IR*B$TV/C2=OKN.`SPS'(:)F'EOXH27!38W8K>Z
+MLWX].#60L;:<'P1MX\$:#AJ%LKR:-3L\;K&YM&8*"Q+O[F,<68*VCQP]/@R,
+MN[Z9"STT<8&&Y&_2A8/X#C(TX+VZM`4^/P"&MHCP'A?XE6T/"A:)OK+_,SHQ
+MXK.\@AP(`''O21@9Z+2SA@PY/Q^WNK/,-S`"YH26>V"6CX)A-CP)A+FX@PD^
+M,Q:-M81E%M^2[QHT-5^QN[86/S@(A;*PDP0"$/CS$@,2A+.SES<[,ERSN+46
+M-S0<EY-2%U"!M($%/3P'B[J_ES<_--R,C>AI?9.$V@\P")&\NXD#.#\$C+.*
+MP`086.QD``]@B+^Q<#(Z-Y*\OX`$-`Q^E_,6$.N*MIX)/CUHL:6P>#$R`I6#
+MF$9M[8"':S<R`X.XN84T.#-CB[:&8QEGZ.8>"P_YL;FU&CDX#(*_L)<#"1CS
+MX6D$%82QMO@V.S'CO+N+&#`V'9V%YV]'A8F;!S(R'+2EO?\P/C7GBHB7%&GC
+MG%T--P*8O+F#"3L_'(J]M40#`6?C2`0`=8B]M!4\.PJ'OKZ'`C8)?)WJ817N
+MCK65"S\P1+*EMA8R/0.=B8;3:\N;GA0T,06/N+^1-CLP6;>P@14'$?GE$P\`
+M[K&_C@`Y.0:(N;/B#C4$_Y1U'6*%M[5#,3DWDKZ[CP$],1.%@)1A<IV"D`8P
+M,6ZVNK-S,CD*EK>TEA,=T)1:`#4'A+R_A34[/6BWO[5G#@QH[<\=!=:)LX@?
+M/#D/C;B_F0DS"TB%GUENYH*.Y0L\-^:]NK0:/SP!A+6"V!%REI$7"C<3B+B]
+MY#,Z,>>PLH$2`AO9YF@!!9>VO8`,.#\9M+NPSC4V!N><_!5GF+6.8S$^"X2X
+MN(,//S$4@(Z<9F+HA.@&,31#L;JQ%#\X"9NPMY&+HJ2RB9U!'0`)-3`R/SX^
+M/SPR,3<(#043>\+JG82`C8Z(BXJ*BHN(B8^-@X:%F9*4[/K.779D8F@5%Q$0
+M$Q,3$Q,0$184%6AO8F%D>7-U0EA1T=[$PL[*]?3W]_?W]/7*R<_"P<3;WMW3
+MUM155U%04U)=7%]?7U]<7UQ=4E-04%%65E145=75U-?7U];6UM;6UM;6UM;6
+MUM;7U]?7U]34U-34U-34U-34U=75U=75U=75U-34U-34U=74U-34U-37U-34
+MU-34U-34U-34U-34U-34U-35U-35U-34U-75U=75U=74U=34U-34U-35U=35
+MU-34U-34U-35U=75U=74U-34U-34U-75U=75U=74U-34U=75U=75U=75U=75
+MU=75U=75U=75U=74U-35U=75U=75U=75U-35U-75U=75U=75U=75U-75U=75
+M5=75U=75U=75U=755=55U=75U=75U=75U55555555575U=75U=755=75U=75
+MU=75U=35U=75U=75U=34U-34U=75U=75U=75U=75U=755=555555U=75U=75
+MU5755=55U=75U=75U=75U=75U=75U=35U-75U=75U=75U=75U=75U=75U=75
+M5=55U=75U=75U555U=75U=75U=75U=555=75U=75U-75U=75U=75U=75U=75
+MU=75U55555755=75U=75U575U5755=75U=75U=75U=55U575U=75U=75U=55
+M55555=75U=75U=75U575U=75U=75U=75U=75U=75U=75U=35U=75U5555=55
+MU=75U=75U=75U=75U=75U=75U=755=75U=75U=75U=75U=55U=75U=74U=75
+MU=75U=75U=75U=35U=35U=55U=75U=GID./A]\5<2W%Y>V1D9V5D>'A]<W1+
+M0$525M;2V,7`PL_.R,C+R,C)SLS"P,;%VMG?W=#1U]555U914U-275U=7%)=
+M4E-24U-04%%145=45%55U=34U-?4U]?4U]34U-35U-75555555555=755555
+M5555555555555555557555145%555=555=755555U5555575U=75U=74U-74
+MU]15U5555555555555755575U=75U=75U=75U=755=55U=75557555555555
+M5%155=755=75U=75U=35U=35U=35U=35U-35U-75U-75U%55U=74U-35U575
+MU5755555557555555%55U575U=74U-34U=35U-35U-75U=55U=75U=55U=75
+MU=75U=35U-75U-35U=55U555U575U=75U-?4U575557555555575U=75U=34
+MU-35U=75U=75U=75U=755=555=755=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U57555755575U-555=75U-34U=75U=75U=75U=75U=75U=75U=75U-35
+MU-75U=755=55U=75U=75U=75U=35U=75U-74U-75U=75U575U=75U575U=75
+MU=755=74U=75U=5555555=75U=75U-35U-75U-75U=75U=75U=5555555555
+M55555575U=75U-55U=75U=74U-74U575U=75U=755575U=75U=755535U=35
+MU-34U=555=75U=75U-75U55555555575U=74U=75U=74U=75U=75U=75U=74
+MU5555=75U555U=75U=75U=755=75U=75U=755575U]35U=75555555555=75
+MU=35U-34U-34U-34U-75U=755555U575U=75U=75U=75U=755=75U=74U=75
+MU=74U-34U=35U=35U=35U=75U514U575U-74U-34U-74U=75U=74U-35U=75
+MU-35U=75U=75U=75U=74U-75U=75U575UM5755155=74U=74U=74U-34U-75
+MU=75U5555=55U=34555555155575U=75U=74U-34U=74U=75U=75U=75U=75
+MU=75U=75U=755=75U=31U5=55%55U=75U-35U=75U=75U=75U=75U=75U-55
+M5=75U-34U-35U-75U=75U=55555555555=75U=75U5555575U=75U=75U=75
+MU=75U=;55U145575U=35U=75U-75U=75U=75U=75U=75U=74U%7555555=75
+M55555555U5555=75U=75U=75U=75U5755575U=75U=755=75U=74UM145575
+MU=75U=75U=75U=55U=75U=75U=755=755%155575U=75U=34U=35U=75U-75
+MU5755=75U575U=75U575U=75U575U=75U=75U=36U5=45-75U=75U=75U=75
+MU=75U=75U5755575U=74U]35U57555155555557555555555U5555555U=55
+M5575U=75555555755=755=75U=;55U5455755=75U=75U=35U=75U=75U=55
+M55555517U=75U-75U=75U=75U=75U=75U5555=75U=75U=75U=75U=75U=75
+MU=55U=75U=74UM5755155555U=75U-75U=55U=75U=75U=75U=755=34U=55
+M555555755=75U=755=75U=755=75U-35U=75U=7555755=75U=75U=55U=36
+MU%?5U=35U=55U5555=75U=75U=75U=74U-74U-355=34U-34U-34U=75U=75
+MU=75U=75U=75U=75U=35U-35U=35U-34U-75U-75U-75U-;45%55U=74U-75
+MU575U-36U]355%75U-?4U5545%35U]7555145%75U=75U=75U=5555555575
+MU575U=555555U=75U=75U-35U=75U-34UM575574U-34U=74U-74U=75U=75
+M5=74U-7555755U355=35U=15U=75U-?4U575U=34U-35U=75U-7555145=75
+MU-75U=74U-35U=75U-36U%=45-75U=75U=5?969S<T-%5]'91STC)3,/$\J8
+M@+"TBK2WL*6ELXJVO+#B#0SMO;B&-20["6X;"C0:^60P)B$WAK""!C`T%N1E
+M!6B-O[W@,3\'M+N]G11SG)]H#`6#N+B%-SDTE[2.\!?VA94"/3'QO;N-#C\W
+M?H218&":M(,'/C\0L+NT$30/<>IZ!!6#O;%L/SL-C[RT7082Y?X$-`"&OK^5
+M,#LUD+2,P17GAY4",C>5OKN#"3PUTX>087Z'M(``/CQNL[NU'S0,2.EB!VB-
+MO;<0/CL`B+RU?0$0Y_<&-`:#N;SD,S@+GK2-56KMA^\//32=N;B&"CP*]H:7
+M8G:&M(<-.3USLKB)!30"7>]I!V..O+09.3@$M;R+8`$6X<$!-`6,N+W2/3@.
+MA;2#0FOHA^<)/36:N+B;-3P)Y(:5;$&`M(4..3+'O;B,!S<#V>T5!WB(O(H'
+M.#D>M+R.:0$5X]0#-!F)N+)^/#D"A[2!<VF4A_`+/0B&N+F3-ST/[(;N;E2"
+MM)X+.#/AO+F#`#0!R.,6!TZ*O(D`.#X1M[R,%P9I[48"-1**N[!H/SX!@;2&
+M>FR6A]TU/0^"N[[K-CT-E8?C:<:,M)`U.#&4O[F'`C0'\N80!].TO(\,.SQL
+MMKV#$`9B['$,-1>TN[$3/SX$@[2$9F.0ATPT/0*/NKS[,3T`EH?D:/"/M.HW
+M.#:<OKZ;##0$^^42!/&WO(,).SUPL;V&'`9G[WH/-6RWN[8;/C\8C;2;8F:=
+MA'LW,@&(NKU5,#(&DX?]:.6.M.$V.#2%N;^=#C0;Y_X<!.>VO88U.C+;L+*$
+M&0=Y[V`."GZQN[0'.3P3C[2>;WN?A&TV,@2UNK)X,S(%G(3(:..(M?4Q.#6!
+MN+R4"34>X/8>!>FQO84T.C/GL[*8&P1W[VD("E*PNXH#.3T5B;62:7.9A14Q
+M,AFWI;!H,S,9GH7?:>F+M44P.0B"N+W@"S42XL(8&I>QO9PV.C'JLK.=!01&
+M[!0+"/&SN(D/.#)AB+61:DF;FA`Q,Q"VI;$0,C`2FYI2;I2*BV4S.0^.N[+T
+M"C41[-,:&)*PLI<Q.C:2LK"7!`57[1$*">.RN(T(.#!TBHJ5%5^:F1\P,&BP
+MI;<9/3$6A9M";Y"UB&@R.0.+N[!;-0H4[EX%'IFSL^,S.C28O;'N!QO;XQ(*
+M#I2]N(`U.#'9M8OO%=V%GQHS,'JSNK0$/39HA9EV;9VUCA$]/@:UN[%E-0AI
+M[D@$'86RL\LR.S6'O;;G!AG(X1XU#)*\N80T.#;XM8CF%,Z$D@0S,5.]NHL!
+M/3=FA)]_8)FTC!X\/QJWN[9N-`E@Z7T$$X>RL$X].PB`O+?U!A_PY!LU`IB_
+MOIXV.#?LM([_%/*$D0$R-OR\NHX-/#1PAYUE9YJTC04_/QVVN[06-`YEZ64'
+M%H"]L6`\.`R-O+16!AWY^04U`(2^OY8Q.#67M(_)%>6'E`,R-^^_NX(./#5?
+MAY!F>X2T@`8^/!6PN[4<-`QQ[F`':H*]MA<_.`..O+5V`1/D\`<U!H"YO.TS
+M.`N2M(W3%>"'Z`TR-)&^NX$(/`K"AY9C<X:TA@,^/6>SNX@;-`U![V\';(^\
+MM!P^.0>+O(MD`1'FS@$T!(VYO?0R.0Z9M()::N^'X`XR-9ZYN(4U/`C^AI1M
+M28&TA`PY,EBRN(\$-P/4[&H'9XF\M04Y/ANUO(EO`13@W``T&XZXLDP].0R%
+MM(!T:.J'^0@]"X2XN9PT/0[@ANAO7H.TF`DY,_*\N((!-P#'XA<'<(N\BP8X
+M/A*TO(\5`6KB70(U'(NXLV,\/@.&M(9^;Y>'S`H]#H&[OI<W/0SIA^UNW8VT
+MG0HY,.^_N8$#-`;WX!$'7K6\C@(X/Q6WO8(1!F_M2`TU$;6[L!<_/@:`M(=D
+M;9&'4C4R#(V[O^,V/0.4A^9IR(RTES0X-I&^OH4--`?_YQ,$P+2\C0\[/6:V
+MO8`2!F#L?`PU:[2[MA\^/P6"M(5@8)*'<30R`XZZO/4Q,@&1A_AH_XZT[S<X
+M-YF^OYX/-`7E^QT$_K>\@`L[,D"QLH<?!F7O9PXU8;:[MP4^/!^,M)AM9)R$
+M9C<R!HJZO4\P,@>2A/%HYXFU^#8X-(2YOY`.-!CF\A\%X[:]AS4[,_2PLH48
+M!WWO;0D*=+&[M0$Y/1&.M9QN?IZ%:38R!;2ZLV$S,QJ?A,-H[(BUV3`Y"H"X
+MO.@(-1_C]1D%ZK&]F#<Z,..SLYX:!$KL:P@+W["[BP(Y,FF)M9-H<9B%%S$S
+M'+>EL!0R,!^9A=%IZHJ*=S,Y"8VXLN4+-1/MQ1L;D;"RDS8Z,9>RLY,%!5CM
+M%PL(^;*XCPXX,V6+M9=J0YN;$C$S%K&EMATR,!.;FEYOE[6+8#(Y#8F[L\0U
+M"A;OU1H9G;.RZC`Z-YRRL+.BI+*.DW4?``DU,#T_/CX^/#(Q-P@-!1-YS96=
+MA(",CHB+M8JUBXN)CXV#AH69DI3L^LY==F1B:!47$1`3$Q,3$Q`1%A05:&]B
+M861Y<W5#6%'6WL3"SLKT]_?W]_?T]<K)S\+!Q]K>W-/6U%1645-375U<7%]?
+M7UQ?7%U=4E-045975%555=74U-?7UM;6T=;1T=;6UM;6UM?7U]?4U-34U=74
+MU=75U-35U=75U=75U=75U=34U-74U-34U=34U-34U-34U-34U=75U=35U-34
+MU-34U=35U=75U=74U-34U-35U=75U=75U=34U-75U=75U=75U=74U=74U=75
+MU=75U=35U-34U=74U=75U=75U=74U=35U-35U=75U=75U=75U=75U=75U=75
+MU=35U=75U=75U=75U=74U-35U-75U575U575U=75U=755555U575U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=555=55U=75U=75U=555555
+MU=75U=75U=75U=755=75U=75U=75U=755555U=55U=75U=75U=75U=75U=74
+MU-34U-35U=75U-75U-35U-75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+M5555U555U=75U=75U555U=75U=75U-75U=755=55U=75U=75U57555555555
+MU=75U=75U=75U=75U=75U-35U=75U=75U=75U=75U=75U55555555575U=75
+MU5755575U=75U=75U=75U=75U=75U=75U=75U=755=55U=75U=75U=75U575
+MU=75U=75U=75U=7:ZY'@X?3$7DAP>7MD9&=E9'AX?7-T2T%%4E;1TMO%P\+.
+MR<C(R,G(SL_-PL#&Q-O9W]W0T=#545%045-24E)24E)=4E)24U-04%%64597
+M5%155=755=74U-?7U]?7U]?7U-?4U-34U=755555U555555555555%145514
+M5515U=75U=74UM165%15U=75U=75U=75U=75U=55557555555=755575U-75
+M55755=555555U=75U=75U=75U=75U=74U-75U=5555555555555555755=76
+MU5945%75U=75U=75U=35U=75U=75U575U=555=55U514U575U=75U=75U=75
+MU=75U57555555=755575U=74U-34U=74U-75U=75U=75U-'45U1455755=75
+MU=75U=75U=35U=35U=55U575U=75U-34U=555555U575U=75U=75U=75U=75
+MU=35U-75U575U=74U=75555555555=75UM1655155=75U=75U-74U-75U-75
+MU=75U=75U=75U=545=75U-75U=75U=75U=75U=75U=75U=755=555575U=75
+MU=74U=34U-75U=74U=36U5945%555=75U=75U=75U=755=75U=75U575U555
+M5574U%75555555555=75U=75U=75U=755=75U=35U=75U=555=75U=55U=55
+M55555==55E55U=74U-34U-35U-74U=75U=75U=75U575U=555U355=75U=75
+MU=755=75U=75U=35U=75U=75U=75U=75U=75U=75U=75U=555575U-555=75
+MU=74U-75U=75U=75U=74U=34U-35U=75U=74U]35U=75U=75U=75U=75U=75
+MU-75U=75U-75U-35U=75U=75U=75U=75U=75U=34U%75U=75U-34U-35U=75
+MU=75U575U=755=755575U554U=75U-35U-35U=75U=75U=75U=75U=75U=75
+MU=75U575U=75U=74U-74U-34U-34555555555=75U=75U=75U=75U=75U=75
+MU=75U=75U=?4U=75U=75U=75U=75U=75U=75U-75U=75U555555555755555
+M557555555555U=55U=75U=35U=35U=75U=35U=75U=75U=75U=75U-555=74
+MU-34U-35U=75U=75555555555575U555557555555575U=75U=75U=35U=34
+MU5755=55U=75U=55U=75U-75U-35U575U=75U=755=74U%75555555155555
+M5575U575U=75U=74U=35U=74U-75U=75555555555=555=555%55U=75U=75
+MU575U=75U=75U=75U=75U-75U=755%74U=75U=74U=35U=75U=75U5555555
+M55555%555=75U=75U=755=75U=75U=75U-55U5555575U=75U=755=75U=75
+MU=75U5555575U575U-35U=75U=75U5555555U=75U=74U=755575U=555555
+M5575U=75U=355555U=74U575U=75U=75U=75U=75U5755=75U=75U=35U=75
+M55145575U=75U-75U=75U=75U=55U=75U=75U=75U=75U=75U575U575U=75
+MU=75U=355%5555555555U=75U=75U=75U575U=75U=75U=75U=37U=555515
+M5575U=75U=35U=75U575U575U=75U=75U=35U5555575U=75U=74U-55U=74
+M5=75U=75U=75U=34U-34U-35U=75U=75U=555-75U=75U-34U-34U-35U-55
+MU55555755=755575U=74U=75U=75U=75U=75U-37U%755=75U=35U=75U=75
+MU=75U=75U-74U-35U=75U=74U]34U=75U=755555U=75U-74U-34U-35U=34
+MU=555=75U=755=74U=755=75U=35U=75U-75U-75U-35U-75U=75U=755555
+MU=75U=75U575U-34U-34U-35U=35U=75U=75U=75U=75U=75U575U=75U=75
+MU=75U=75U=55U-5555555=55U=75U-74U-35U=75U=75U=74U=75U575U-?4
+MU=755575U=75U=34U=75U=74U5555=74U=34U-35U=75U=55U=75U575U=74
+MU5555=75U5755555U=75U=74U=74U=74U=75U=75U554U=35U-34U-34U-35
+M55555555U=55U=755555U575U575U=755575U=74U=75U=555555U=74U-34
+MU-75U=75U575U=75U=35U-75U=75U-37U-75U=75U=75U=75U=75U=75U5-Y
+M87)S3$10UM_6-R(D,@D3T)^&L;>*M+:SO+:TN:"F@`P(T+2TRQMO[QXY(#IL
+MCI$U/C$##ST_!;2RE#$^#Y292GB"O[!I/3#NO;*'QIN(GP\R![>EL&`(&^10
+M`@_NO+Z6,#X"DII_%)NVC`TZ//2PMN`?U)C6-#T$MKJT&S<!_,`&`9R_O_HR
+M/@2&@O%AFK>!"3LPD[RQ_P5DD78T,Q&PNH@#,`/X^!H%FKRS9S\^'HR.YF"?
+MBI\U.S>&OK%=`!3O>34V<+VZ@@@R`^SK$!*'O;8=.3]JM;7B;Y&,Z#0Y"X^X
+MMF,/'^5Y"#7ZO+B%-SP`D9UL%8:RM08[/$:VM.(7XH'Q-S\#M+NW$S4%\G$,
+M#Y:_OI4P/P:8A'1BA[&,##LR[;.VY!S#F$`W/1BQNK4$-P;]4`$!F;^\TCT_
+M!8&#QV:$MX<*.S&>O+;#!7Z1>S0P:+.ZCPTP`.?S!1N$O[-K/C\3CX_^89B*
+MDS0X-("^MG$`%>YF-3=7O;N!"C(`Z>X2$(:]MQLY/&"UBN=ODXSC-SD.B;BW
+M:P\=YV8+"NR_N)\V/0:0DFYH@;*+`SL]QK:TY!?N@=XV/P:WN[0?-1K^?@\,
+MG;Z^XS,\!)J%<F&!L(().S"5L[?Q'/>8<C8R';"ZB`8W!_A'``:%OKUW/#\>
+M@(#69(>WA34[-H6\MU`%<9%A-S!GLKJ-#S`&X?0%&8:_L!$^/!2.C_=GFHJ7
+M-S@U@KZW9`!IZ6TT-_:\NX0U,P;J[1T6@+RT!#@]?+6+_VV=C/@V.0V*N+07
+M#Q/G8@L+E+ZYD3$]!Y*0:V^#LHD-.S+YL;7S%.J!138_!+:[BALU&/MG#PV9
+MOK_S,CP:A9IX9("P@`L[,9"RM,0=_)AG-C(6L[J.`#<%Y74#!X>^LF$\/!*`
+M@5YXAK>9-#LWA[RW2P5/D6\W,7>]NX`),0?CP`0?@+^Q'SD];HZ,P&6%BN@V
+M.`B/N;1M`&WI:S0TYK^XF#0S!)3@'!2"O+4!.#);M(CT8I^,R#$^`[6XM1,/
+M$>9I"@B3OK[J,3(%G9$58X*RCPX[,^*QM<P4E(9S,3P8L;N(!0H?Y6`.`X6Y
+MO-0R/1Z$F&1X@["&-3LVG[*T41WEF&TQ,FBRNXT"-QKG<@,$@;FS:C\]%H.&
+M0WV!MYTW.S6!O+1_!5Z1%38QU[R[AP@Q!>W=!!V"OK8:.3UFB8W2>(2*XS$X
+M#HFYM6L`8.D4-#3IOKB=-S,%E^<?:HR\B@,X,\>TB<1@F8S5,#X&M+B*'`\7
+MYA4U#I^YON$P,AB<EQ1FC+*-"#LPZK&+TA66AF0P/!VPNXX'"AWE;`D`A[F]
+M<3T]$H2987*-L(0T.S>;LK5,$N:9:S$S9K*[@PTW&.9[`@6#N;`1/SUJ@H=T
+M=H.WD38["H._M6<%U)$7-C;QO[B%"C$;[U$'$XR^MP<Y,G.(@E!\AXKY,#@-
+MB[F*%`!DZ1$W-9>YN98W,!B6^AYNC[R(##LS_[2/UV:;C$@P/@2WN(@9#Q7A
+M%S4/FKF_\3,R'YZ4%WJ/LH,*.S&1L8A<:I"&;3`]$;"[C`8*$^1K"0&!N+)A
+M/3(1AY]C=(RPFS<[-(2RBG`2XYD7,#-VO;N!#S<?X6<"&(VYL1P^,FV"AW!/
+M@K>5,3L(C;^*8AK;D1`Q-N:_N)DU,1GN1P<6CKZT`3@S6(B#1'&!B\XP.0.U
+MN8@1`7GN$S<*DKF^Z#8P'Y;\&6*)O(X..S#@MXQ>9)J->#,_&[:XCAL,:.81
+M-0R$N+S4,S,2GNL6<HFR@34[-IVQB4]HDX=J,SUKL[B"``L1Y!4(!H.XLFL\
+M,Q6'G&U`C["?-CLUAK*(>Q/OGA`P,%6\N(0.-!WA8PT>C[BQ&SXS9(V$?T6-
+MM^TP.`Z/OXAI&LZ6'3$WZ;ZYDC4V'.E*!A2)OK4#.##%BX!)2H&+43,Y`;2^
+MB1(!<.\<-@N9N+[A,3`=D?<99HB\C`@[,>FWC4UZA8U@,C\<L;B,!0QOYA(U
+M#8:XO'<R,Q&9Z1%*B+*'-#LWF;".<6Z=AQ8R,F"RN(`#"Q?G%P@'C;BS$3PS
+M;H:2;%.)L9`Q.PJ`LHEF$.B?'3,P][^XF@DT$^!O#1R)N+8$/C!QC85[5HRW
+MY3,X#(F_CA4;\9<>,326N;F6-#83Z',&:XN^B@PX,/.+@79&@(AU,CD'M[Z/
+M'`%*[!XV"(6XO_`Q,1"0S1AXBKR""CLVE[>"=WZ$@F@R/Q"PN8($#&/F'#0"
+M@[N]9S(P%)CM$5J+LH4W.S2:L(Q^;)R'$S(R?;VXAP((%><0";6IH+NQ@^YC
+M&@(+,3,_/SD^/STS-C4.`1EI0>&1FX:"C(F(BHJ*BHN)CHR"@8>;G)'KX?#2
+M3'YA;VH4%A$0$Q,3$Q`1%A<5:VYM8&=[?79.1%+5W=K!S,C*]/?W]_?T]/7(
+MSLW`Q]K8W-+1U]545E%34EU<7%]?7UQ<75U24E-04%%65U15U=34U-?7UM;6
+MUM;6T='1T=;6UM;7U]?7U]37U-34U-34U=75U=75U=75U=75U=75U=75U=74
+MU-34U-35U-74U-34U-34U-34U-75U=34U-34U-74U-35U=75U=35U-34U-35
+MU-74U-34U-34U-34U-35U=75U=34U-34U-35U=75U=75U=74U=75U=75U=75
+MU=74U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=755=75U=75U=75
+MU=75U=755=75U=75U=75U=555=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=5555555575U=75U=75U575U=75U=74U=74U=75U=75U=75
+MU=74U=75U=75U=75U=34U=75U=75U=75U=75U=75U=75555555755=75U555
+MU55555555575U=75U=7555755575U=75U=75U=75U=75U=74U=75U=75U=75
+MU=75U=75U=75555555755=75U=75U=55U575U=75U=75U=755=755=55U=75
+MU=75U5555555U575U=75U=755=75U=75U=75U=75U=75U=75U=74U-75U=75
+MU=75U=75U=75U=7555555555U=75U=75U=55U=75U=7#E);AYLG:6DAS>7ID
+M9&=E97YY?'-T2T9:4U?0W=O$P\+.SLO(R\C+R<[,PL#&Q=O9W-/3T-=55%91
+M4%-24EU=75U=4E)34U!045%65E=45%155=75U=34U-?4U-?4U-?7T-=4U575
+MU=75U=75555555155514551455155=555=755%=5U=75U=75U=75U=75U=75
+MU575555555555555U=75U=75U=75U=55U575U=36U5945%555=75U=74U=34
+MU=75U=75U=75U55555555555U=?5555555755=555=75U=75U=75U=75U=55
+MU=55551555555555U555U=75U=;55U54U575U-74U=75U=74U=75U=75U=35
+MU-34U=75U554U575U-34U-35U=75U=75U=75U=75U=75U5555555U575U=74
+MU-75U-75U575U=55U=75U=74U=755=75U=75U555U575U-75U-75U=755=74
+MU-755=5555555555U575U575U=75U-75U-35U-75U=75U=75U=75U=755=74
+MU5755=75U=755=75U=75U=35U=75U=75U555U555U5555535U=75U=75U=75
+MU=75U=5555555555U555U574U=74U=74U=75U=75U=34U=?45=55U=75U=75
+MU=75U=75U=75U575U=75U=75U=75U575U]75U57555555555U=55U5555=75
+M5=75U=34U=35U=75U=75U=55U5555=75U-55U555U=75U=75U=75U=75U=75
+MU=74U=75U-75U=755515U=75U=75U=75U-34U-34U-34U=75U=75U-75U=35
+MU=755=75U=55U=75U=74U5555=55U=75U=75U=75U-75U=75U=75U=75U=74
+MU=35U-?4U=75U555U=55U=75U-75U=75U=75U=35U-34U-74U-35U=75U=75
+MU=75U=355=75U-74U-74U-75U=74U=75U=74U=75U=35U-7555545=55U=75
+MU-34U=75U=35U-75U-35U-75U=75U=75U-74U=75U=75U555U=75U-75U=75
+MU=75U=75U=75U=75U-34U=74U=35U=75U=755574U-5555555=555=555555
+MU575U=75U-74U=75U=75U=75U-35U=75U=755=74U5755=74U-34U=75U=55
+MU=755=75U=35U=55U55555555%55U=75U=34U-75U=75U=75U=75U=75U=75
+M5=75U=74U=75U=75U=75U=75U=35U=55U=755=7555555=75U=74U-75U=75
+MU=55U=75U575U]35U575555555155575U=75U=75U575U=75U-75U=75U=35
+MU=755=755=75U-75U=75U=75U-75U=75U55555555555557555555575U514
+M5575U=74U-74U-35U=34U=755=75U=755=75U=75U=75U=75U=75U-35U=34
+MU5555%55555555755555U555U=75U=75U-75U=75U=75U=?4U5555%155555
+M5575U=75U=34U-75U=555=555%555555555555555575U=755555U555U=75
+MU=75U=75U=75U=74U=75U575555555545-75U=34U-35U=35U=35U=755=75
+MU=75U=75U=75U=75U=75U=55U555U575U-55U=75U=75U=75U=75U=75U=75
+MU=755=75U=555=755=74U-75U=55U=555=55U=75U=75U=75U=75U=34U=75
+MU=75U=75U=75U575U=75U5755=75U=75U=35U=75U=74U=75U=75U=75U-74
+MU=355=75U-34U-34U-34U=75U-35U=75U55555555575U=74U=75U-34U-34
+MU=75U-34U=34U-35U=75U=75U=75U=34U=75U=75U=75U=74U=74U]?5U=75
+MU=75U=75U=75U=34U-34U-74U=75U575U555U=75U5755=555=75UM575%35
+MU=35U=75U-75U=75U-75U=35U-75U=35U=75U555U=74U-34U-75U=74U=75
+MU=75U=75U=7555555=75U=75U=74U=755575U=75U555U555U=55U=75U=35
+MU=75U=75U=74U-35U-75U-75U=34U=5555555=75U=74U=34U=34U-34U=75
+MU=35U=555555U=55U=555=55U=555%55U=75U-75U=75U575U=75U=755=75
+MU=755=75U=545=74U=34U-35U=75U=75U=75U=75U=75U=75U=75U=74U=75
+MU=75U=55U575U555U=75U575U=75U=75U=35U=75U=75U=74U=75U=555=75
+MU-7555755=75U=555575U=75U=75U=75U=35U555U575U=75U=75U555U=74
+MU575U=74U=35U=7555555=75U=35U=34U-34U-35U=7555=4U=74U=34U-74
+MU-35U-35U=75U=75U=75U555U5555575U=75U=75U=75U=355=755=75U=75
+MU=75U=75U=555=75U=75U=75U-35U=75U-?4U=75555555555=55U=55U555
+M5575U=75U=75U=75U=34U=75U=755575U-555=75U=35U=35U=75U=75U=35
+MU=75U=75U-75U575U554U=34U-34U-34U=34U=35U=75U575555555555=75
+MU=75U=75U=75U=74U-74U5755=75U=55U=55U=75U-74U=75U=75U=74U=75
+MU=755=37U=75U575U=75U=75U-755=75U-35U=75U=75U=74U=75U5755=55
+MU=75U=35U=55U-75U=75U=75U575U-75U=75U=75U=75U=74U-355=34U=75
+MU=75U=155555U55555555=75U575U=75U=35U=75U=74U-35U575U-35U=75
+M5555U=75U5555=75U=75U=75U=75U=34U=345=75U]75U=75U=75U=75U=35
+M6F=G<'!!1531V'P[(#@P#!;SGH"TM;>WL+*]M[>]IZ>W&S4;B;NQ'3@E-VAX
+M`#0*&@4V)24(@;:=,2<Y8[>QGQH$3)WM:FV&O;^:-3T&MZ2Y[C4T:8"-E7SF
+M@8<6-C%CL+N)"3H]0;>VE@<!8^5B``>6L;#G,SL+C[NR6#8V$YN$]V/B@H80
+M,3!FL[J+##@SW+>VD!L;1.-I`@:3L[/@,SH*C+BS1C<W$)R<0V_JCX`=,S-B
+ML[J*##@ST;2TEQX2].T6#@"=LK+B,SH*C;FS6C0U%Y.79&^0B(,<,C)LL[J*
+M#3DP5+6UZQT5X.P="P.<O;WL,SH*@KFP6S4+:I'B:&Z?M8T?/3UNL[J*`CXQ
+M4XN(XA!FE>X8-0V?O+SN,SH*@[ZQ6@L.;93W$6F:MX\9/#QKL[J*`S\V78F,
+MY1=&DN@%-P^>O[_K,SH*@+^V6@X-9.A''FN$MHD9/SP5L[J*`#PW7(R#]VKT
+MF^H'-@Z9O[^5,SL+@;RW10P`<>UG!16&L(L8/S\4L[J+`#TT7(*'TF_BAY0!
+M,0B9OKZ4,SL+AK*T1P($7^%J!A2`LXH8/C\7L[N+`3(U4X&;0F"7@)<#,PN9
+MN;Z4,SL+A[.U0P$9P/H3`Q>"LK48/CX6L+N(!C`*5H>2?F6<C9$-,C68N;Z7
+M,#@(A+"(3`<0^?(9#!:,O+08.3X1L+B(!S$)U)KJ8'*:B9`//369N;F6,#D)
+MA;:.=1INX\H$"1".O[08.3X0L;B)!#8/W9_E:TJ&BI(./#29N;F1,3X.F+>-
+M=A]]E<0!"A*)OK<8.3X0L;F.!30"VI#2%D2#M)P(/S>9N+F0,3X/GK6`<Q#?
+MD=`"-1V(N;89.3X3MKZ/&S4!PI1\$E&,MYX+/C>>N+F0-C\,G(N'?Q7DG%`/
+M-Q^+N+89.3X2M[^-&0L$].UN&=*)L9@*.3:?N;F0-SP-DHZ;>FV5FUL)-AF*
+MN+$>.3X2M+V"'@\8\OH1!<2+L)LU.#:<N;Z3-S("DXV=9WB2A$,*,1NUN[$?
+M.3\2M+*`'`(3^,D>!\VULX4U.#&=N;Z0-#,`D8"48$.:@4@U,`6UNK$</C\2
+MM;.!$@$5YU,$`<NTLH0U.S&2OK^0-3`&EX?@;=B&@W4W,@2UNK`=/CP2B[&'
+M$`1GXW8!`O2VO8<U.S&3OK^0"C$'E)CU:?V#C'<V/0>UNK`2/SP2B;:%$1E!
+M[F0-#/>QO(8T.S&1O[R0"#<%ZI)!%>&/CG8Q/`>UNK`3/ST2C[29%Q/TZFP.
+M#O:QOX8T.C"6O+V1#C09Z)1G%^Z(BW8Q/`:UNK`1/#(3C+6=%!7BEQ4+"/:P
+MOH$T.C"4O+V6#`H=[N,5$92UM78P/P&UNK`6/3,0@HB6:F:7D!8U"O>SN8`U
+M.C&5O;.7#0X6[/<2$Y&WM'0S/@"UNK`7,C,1@(SH:$^?G1,W-?6RN(,U.S'K
+MLK"4`PUHXE\8')*VMW4R.0.UNK`4,S$6AH/F;L*%GAPV-,ZRN(,U.S'NL['J
+M`0!FX'@''I^QMDXR.0.UNK$5,#84A(?W;.>!FQDQ-\"]NX(U.S'ML;;I!P1T
+MX6\`&YBSL4`].`**N[%K,3<5FIM18NN"A1LP-MN]NX(*.#;CMK?M!1G<X1<-
+M!9JRL%H].`V+N+%I-C1IF9-R8Y&.AP4R,=*]NXT+.#;FM[7A&!#^YAT.!X6]
+MLUT].`V(N+9O-PIMG>IC8)^+A@0],%6]NXT+.3?DM(OZ'&[LYA@+!H2\LE0]
+M.PV)N;=L-`EFD.458)JU@`<\,UR]NHT(/C?ZBH[S$WR7X00U`(>_LM(].PV.
+MOK=B"@QXE-P38(>W@@<_,T2]NHT)/S3XB(+"%]*=X08W`X:^O=H].`R/O[1C
+M"`-WZ'(>8(&QC08_,DZ]NXT./#7_CX'7:^6:X`,V`H:YO,(].`R,O+5A#P9>
+MXFP%8X*PCP$^/7>]NXT,/0K]@H5`8NN'X@TP#(:YO/4].`V"O8MF`AK8Y!8&
+M8HRSC@$Y/7*]NXT-,@CS@)]R9).`[`\S#X&XO/$R.`V#LXEF`!WQ\A\#;(Z]
+MB0$Y/'ZRN(T",P[PAY9G<IB-[PDR"8:XO_TR.0V`L(]G!Q3DS`4,;XB\BP$X
+M/&6RN((#,0SPFNUM38>.Z`@]"(:XO_DR/@*&MHUG&F#LT`8.:8J_B@$X/&>S
+MN8(`-@+SG_%J5H"+Z@H\"X:[O^4S/@*'MX!G'TR56`,+:K6^M0$X//VNK*>\
+MBIO%$`8.-3`R/C\Y/S\R,S<U`@<08,KOG(6`C8Z(BHJUBHJ(B8^-@(:%F9*7
+M[^7)4'=E8FD5%Q$0$Q,3$Q,0$184%6AO8F%D>7-T0EA1UM[$PL[*]/3W]_?W
+M]/7*R<_"P<?;V=S3T=155U%04U)=7%]?7U]<7%U=4E-04%%65U=45=75U-?7
+MU];6UM;6UM;6UM'6UM;6U]?7U]34U-34U-34U-35U=75U=75U=74U=35U=75
+MU=75U=34U-34U-34U-34U-34U-34U-34U-35U=35U-74U-34U=75U=75U=75
+MU-34U-34U-75U=75U=74U-74U=34U=74U=75U-34U-34U-75U=75U=34U-34
+MU-75U=75U=75U=35U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=555=55U=55U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U575U=75U=35U=35U=75U=75U=75U=75U=75
+M5=55U=75U=75U=75U=75U=75U=74U=75U=75U=75U=75U=75U=75U=55U=75
+MU=74U=75U=755=75U=75U=75U=755=755=75U=75U=75U=75U=75U=75U-75
+MU=75U5555575U=75U=75U55555555=75U=75U=75U575U=75U=75U=75U=55
+MU=75U=75U=75U55555555575U=75U=75U575U=75U=75U=75U=75U=75U=75
+MU=75U=755555U575U=75U=75U575U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U/*1E>;EQM]-2WQY
+M965D9&5E>'YS=W5*05I35-/?VL?"S,G)R\O*R,C.S\W#P<?%V][?TM#6U%57
+M5E934E)=75Q=75U24U)34%!145%75U=55574U=34U-34U-34U-34U-34U=36
+MU%=55=75U=74U55555545%1555545=5555555555555555545-55U=75U-35
+MU-75U=75555555555=75555555555=75U=75U-75U=55U-;55E54U555U=75
+MU=75U=555555U55555555=75U=55U=555=37U=75U=755=755=75U=74U=35
+MU-34U-35U=55U=55555455555555U=75UM565515U=74U-35U=35U=75U=74
+MU=35U=75U=75U=75U=755=75U=34U-34U=75U=75U=755=75U=75U=75U575
+MU=75U=55U=75U=55U=71U%945%55U=74U=74U=34U=74U-75U=75U=75U=75
+MU=755575U-75U=755=7555555555U=55U=75U=75U-74U=75U575U575U=75
+MU=75U-;45U145575U=75U=75U=755=75U=75U=34U=74U-75U=755515U=75
+MU=75U=35U=55555555555575U575U575U=74U-74U-34U=74U=74T=145535
+M5=75U=75U=75U=55U=75U=75U=75U=75U575U=35U=?4U=75U555U5555515
+MU=75U=75U=755=75U=75U=755575U=75U=75U=36U%=45=35U=75U=355=75
+MU=34U=55U=75U=55U=755575U-55U=75U-34U=34U-34U-74U-75U5555=75
+MU=555=755=75U=75U=75U=55U=;55U54U575U=75U=35U=75U-75U=74U=35
+MU=75U=75U=35U=77U]74U=55U=5555555=75U=75U=34U=34U=34U-75U=75
+MU-75U=75U-75U-35U574U=74U-34U-75U=75U=75U=75U=75U=75U=75U=34
+M5575U=34U=75U=75U=75U=75U=75U=75U=555%75U=75U=75U-75U=75U=71
+MU%=55555U555U=75U=75U=74U=75U=75U=75U=75U=75U=75U]1555555=55
+M5=755=75U=5555555555U=75U-35U-75U=35U-75U=75U=;45U55U5755=75
+MU=75U=75U=5555555=75U=75U=35U=34U%75U=75U=75U=75U=75U-75U=35
+MU=75U=75U=74U-75U-75U575U575U574UM565%355=75U=75U=755=74U=75
+MU=75U=75U=75U=55U=55U=34U=55U=75U=755575U=74U=75U=75U=75U-75
+MU=75U=755=75U=75U=31U%=55-55U=35U-35U=75U=75U=75U=75U=55U555
+MU555U5545=75U-74U-755555U=75U=75U55555555%155%55U=75U575U=75
+MU=75U-;55E145555U=55U=75U575U=75U=75U=35U=55U55555755574U%55
+M5%555%555%755=55U=75U=75U=75U=35U=35U=755=755=75U=75UM165555
+MU=75U=55U575U=75U=74U575U=75U575U=555=755515U=75U=75U=34U=35
+MU=755=75U=75U=55U575U575U=75U=75U=75U=76U5=45%555=75U=75U=35
+MU-75U=75U=74U=75U=755=75U=74U]?5U55555555=75U=75U=75U=75U=75
+MU=75U=35U=75U=75U=75U=75U-;45U55U575U=74U=35U-34U=74U-74U=74
+MU=75U=34U=34U-54U=74U-34U-35U-35U=75U=75U=75U555U5555575U=55
+M5575U=75U574UM175535U=75U=74U-34U-35U-75U=75U=75U=75U-74U-35
+MU=34U=75U=75U-75U=35U-34U-34U=75U=75U=75U5555575U=75U=75U=36
+MU5=55-75U=75U=75U=74U-34U-35U=34U=35U=35U=75U=545-75U-34U-34
+MU-75U-75U=75U=75U=74U=55U=75U=75U=74U=75U=75U=;55E145575U=75
+MU=35U-34U-35U-75U=75U575U=55U575U=74U]35U=55555555555575U=74
+MU-77U-34U=34U=74U=75U=75U=75U=75UM5655355=75U-35U-74U-35U=75
+MU-35U=74U=35U-75U=755%35U=74U=74U-75U=75U=75U=75U=75U=75U=75
+MU=34U=75U=75U=75U=36U%=55=555=555555U=75U575U=75U575U=75U=75
+MU=75U575U-355575557555755=75U=35U-35U-35U=35U-35U=75U=75U-34
+MU-74U-'45U55U575U-34U-35U-75U=75U=75U=34U=75U=74U=74U-54U=75
+MU-34U-35U-35U=75U=75U5555=555555U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=55U=55U575U=75U=75U=75U=75U=755=37U=5555555=75U=55
+MU=75U-75U-74U-74U=75U=755575U575U=75U=75U5755575U=75U=35U=75
+MU=75U=74U=74U=75U=75U=75U=555-75U=34U-35U=75U=75U=75U=75U575
+MU575U555U=75U=75U=75U=75U=;55E54U=75U=74U=35U-34U=75U=34U=75
+MU=75U=35U=75U=74U]75U=75U575U5555555U=75U=75U=74U=74U=74U=75
+MU=75U=75U=75UM5755355=75U=75U575U=74U-34U-74U-75U=75U=75U=75
+M5535U=74U-34U-34U-74U5755=755=5555555555U=755=75U=75U=755=76
+MU5=45=75U-75U-75U=75U=75U=75U=75U=75U-74U=75U-75U-?4U%555555
+M5555U=555=755=75U=755=555555U=75U4!F9'!Q1EK4T=IL)"`_,0(5Y9F#
+MBK6QL;RRMHNWOJ&FMQ@T#9Z_OY<S)B0(E)\7,3X]"P8""@@?[)$3-C\*F+^Y
+MAPHY-I^XI+<4-0SAM;>`]$;KFY47`1.$L+#J-S@VD;ZX@`H[/6VTLX,?"@UF
+ME.-A%?Z!@LH.,`^;O[Z%-#HR_[R[B`8R-FF"BYMM'7GL^Q,#&9VVMNLT.3:6
+MOKN-"#L]8+>]CQ,*#V"3D5EIPX6`_0TQ#)^]OX4T.CW`O;N+!CTP%X*UA&T;
+M:OCG:P8>EK2WE34^-I6_NX\..SQNMK^($#0+:)V9\VQ$G(?Z`#<,D[*_A#4Z
+M/56]NHH'/#,3C;>`8P02QN-E&ASKBK27"#PV[KR[C@\[/Q6VOHH6-S46GX3L
+M8WB4A><'-`V6L[R'"SL]0KVZM00_,AR,MHUF`1I#[%D=$N..M98./3?@O;N)
+M##L_%K:YM!<V-Q*9@)9F;>>?X!L+`I6QO8<).#UPLKJT!3\\&(RPCGH#!F7I
+M\!40_H**D0TR-^6RNXD-.SX3MKBW%3$V&9B-GG@5WI'C'0X`[+:RA@\Y/7JR
+MI;<:/C\%C[.+<@T";NOB9A;"@8F0`S`T\+.XB`,[/ARVN[9H,3`%FXZ$<1!_
+MZ>T7`@'FM+.&#3XR8;.EMQ@^/P>/LK5(#P\6ZI=;%5V%C)`&,33-L+B+`#@^
+M&;>[L6TP,P>;BX%''&CE[6T!!O^*L($#/S)LL*6V'SX^`8^\MUT)"QV5G?)O
+M=IR#D`4W-="QN8L&.#X;M[JP9C,]`9NUC=`8$][M?`4$R8FQ@0$\,FBQNK8=
+M/CD`C[^VV0LU&Y6;[F9EE(>0&30*6;:^B@<Y.06WNK-[,SP"F[>.RP4;<>)1
+M'!K0C+>!!S(S%;:ZL1`^.`*,O['W"C<$ZH>0?6+FFY$3"@M)M+^*!3XY!+2Z
+MLW<S/PR;MHKY!P=BX_`7'EJ`M(8%,S,7MKJQ%SXX#(R^L_LU,0'K@)A$:-J2
+MEA0."7.UO(H8/SX'M;JR13,^#IBQM.`&`Q?AX&`2=(>*AADP,!:TN[!J/SL/
+MC;FRX#4P`NF"A]H4<Y67;`T/>(B]BA\\/@:UNKW3,CD(F;"WZ`$,'.>50Q9^
+MF(F''38Q$+6XL&P_.PZ"N;WI-#,/[X^#_1%OYY5[`0UGC[.*$ST^`8NZO,@S
+M.`J>L[&7``@:^Y#Q:623C806-S83BKBP83P["(.XO)0T/0GBB8S@$Q'9Z4,%
+M`&&"L(L6,C\`B+J\_S,X-9RRLY,#-0;SG.QG8.N!A6HU-Q*(N;!X/3L+@+B_
+MD30\"N&+B.H='G+MVQ\&8H&VB&HS/`".N[SF,SLTG;VRGP(T`\N;D75MY82;
+M8@@T'8Z_L'0].PJ!N+Z=-#\UY;6UD1P$;N?]%P5LA+>);#$\`XR[O^TS.S>3
+MO;V;`C8,WH29WF[9GYEZ#S4<C;RP6#([-8:XOIXT/C?]M+><'@$0_^%C&6^8
+MM8YG-CT#C;B_ZS`Z-I&\O(0",0E<AH?Y:'&7G70""QR#O;'2,S@UA[BYFS0Y
+M-LNWMIL>`AG)Z4X3;I*(CWTT,@.#N;^4,#HQE+R^A@(P"DJ`@.QK8N&04`8)
+M'(:SL<DP.#6%N+B$-#DQWK>PA!D/!-64]!5IE(R-3C4S`H&^OY$Q.C'KO+F`
+M`C(T?H.,EFH7QI3!&@P<A+"V_38Y-)NYN(<U.#!<MK*!&0@`3I'B9FGC@(-0
+M"#`#A[^_DS8Z,.^\N8("/3=FC8B<:AUR[_,=`QR8MK;E-SXTGKFX@34[,TJV
+MO8(9-0QXDI9,;O.$@=H/-@.%O+R<-SHPX;RXC`(\,6^,M9IK&V[DY10&'9VW
+MM^$T/S2=OKB`"CLR?[&\C!XT"6.?G\YO5)Z']0(W`YB]O)XT.S/[O+N.`SPP
+M%8^WAV@'$/7@8042EK6T[34\-)&_N(,+.SUGL;^)'S<U:YF$X6USEIK\`34`
+MG+.]F#0[,_&\NX@`/S,1CK:`;@$84^Q.'!/HB;7I"#TTE+RXC0@[/6VQOHL=
+M-C06FX&48&/CG_H%"P"0L+V:-3@SQ+VZB@$^,A*.L(UM`@=RZ<D7$>&,B^H/
+M,C7HO;B,#CL\:[&YM1(Q-A*%C9UG%<R0YQX.`92VLH4(.3-6O;JU!CX]'XFS
+MB6`,`V#JX&`7\X".E0TS->VRN(\/.S\4L;BT$#`Q'H6.FG@0=NO@$0T&Z;>S
+MA0X^,TVRNK0'/CP;B;*+9`X/%9643A7=A(R4`#$UY[.YC@TX/Q&QN[<6,S,%
+MA(N&<1QOY^-H`0?@M;"$##\SXZZLI[^UF\81!@XU,#(^/CD_/S(S-S4-!Q!C
+MR>R<A8"-CHF*BK6*BHB)CXV#AH28DI?OY<A1=V5C:147$1`3$Q,3$Q`1%A05
+M:&]B861Y<W1"6%'1WL3"SLOU]/?W]_?T]<K)S\+!Q-O>W-/1U]5745!375Q<
+M7U]?7%Q=75U24U!045975U15U=34U-?7U]?6UM;6UM;1T=;6UM;7U]?7U]?4
+MU-34U-35U=75U=75U=75U=75U=75U=75U=34U-34U-34U-74U-34U-34U-34
+MU-75U-74U-34U-35U-75U=75U=34U-34U-75U=75U=75U-34U-34U=75U=75
+MU=74U-75U=75U=75U=75U=35U-75U=75U=75U=34U-34U-35U=75U=75U-75
+MU=75U=75U=75U=75U=75U=75U=75U=75U-75U=75U=75U=75U=75U=75U555
+M5555U=75U=75U=755=55U575U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU-75U=75U=75U=75U=75U=75U=555=75U=75U=75U=75U=75U=75U=75U=75
+MU=55U=75U=75U=75U=5555555555U=75U=55555555555=75U575U=555555
+MU=75U=75U=75U=75U=75U=75U=35U=75U=75U=75U=75U=7555755575U=75
+MU=75U555U=75U=75U=75U=75U=75U=75U=75U=75U55555555=55U=555=55
+M5555U=75U=75U=75U=75U=75U-74U=35U=75U=75U=75U=75U=755555U575
+MU=75U=75U=75U=75U=?ZD.CA^\333G5^>61E9V1E>GA_<G9U3$1>4=33WL7&
+MPLS.R,O(R\O+R<S"P\;$VMG?W=/1U]555U914%)34EU24EU24E)34U!14596
+M5E=45-755=75U=75U-34U-34U-34U=35U=75U=75U=55557555555%545U14
+M55555=75U=75U-75U=755=755555555555755=75557555755=75U=555555
+M5=755=755=555=755=75U=75U=75U=74U=75U=75U=74U]35557555555555
+M555555555=755=75U=75U=55U=75U=75U=75557555155-55U=75U=75U=75
+MU=75U=75U=75U=75U=75U=55U=74U575U=34U-34U-35U-35U=75U=755555
+M5555U575U=75U=75U=35U=35U-?55=75U=75U=75U=75U=75U=75U=74U-75
+MU575U575U=555555U=35U575U=75U=75U=75U=75U=75U=74U-75U=34U=75
+MU=5555555=75U-55U575U=75U=35U=75U=755=755=75U=75U=74U=74U=75
+MU=545=75U=75U=35U=75U=75U=75U55555755555U=75U-75U-75U=75U=74
+MU5755=74U-755=755=555=755=75U=75U=55U=35U=75U=755=74U5555555
+M55755=55557555555=75U575U=74U=75U=75U575U=75U=3555555575U=75
+MU=755=75U=75U=755=75U=75U=75U=75U=755575U=34U-34U-74U-74U-74
+MU=75U=7555555555U=55U=75U=74U=75U-555=75U=75U=75U=75U=555=55
+MU=75U=75U57555555575U575U-75U5555=55U=75U=75U=75U=75U=34U=74
+MU=75U=75U=75U=75U=74U-75U=74U=34U-34U-35U=75U=75U575U5555575
+M5=7555755515U=74U=74U-34U=75U=555555U=55U=75U=75U575U=75U=75
+MU-75U=34U=75U-35U=75U=75U-74U=75U=74U-75U=75U575U=75U=75U=34
+MU=75U=755=75U=555=5555555575U=55U=75U=55U55555555=74U-75U=74
+MU-75U=75U=75U575U=75U=75U=35U=755=755=755=545=75U=75U=75U-34
+MU-75U=75U=755=55U=75U=75U=75U=75U=75U-74U535U=75U=35U=755=75
+MU-75U=75U=75U=75U=75U=55U=55U=74U]75U555U575U=75U=75U-75U=75
+MU=75U=7555555555555555755=755%155575U=75U=75U=75U=75U=35U=75
+MU=74U=75U-75U=755515U=74U-74U-75U=75U=75U5555555555555155555
+M5555U=755=75U=54555555555555U=7555555555555555555=55U=75U=75
+MU=75U]35U=755555U555557555755=75U=75U=75U=75U=75U575U=75U=74
+MU5555555U555U=75U-35U=75U=555555U555U=75U=75U=75U5145=75U=74
+MU=74U=75U=7555555575U=75U=75U=75U=75U=75U=75U-'45U545575U=75
+MU=75U=75U=55U=75U=75U=75U=755575U=75U=34U=555555U=75U=75U=35
+MU=75U=75U=75U=35U=75U=75U=75U=75UM5655155=75U=75U-74U-34U-74
+MU=75U575U=75U=555=7555545-75U-34U-35U=55U=75U=75U=75U=55U=55
+MU=75U=75U=74U=75U=76U5945%55U=75U=75U=75U5755=75U=74U=75U=75
+MU=75U=75U=74U]755=55U555U575U=75U=75U-35U-75U-74U-75U-74U-74
+MU=34U-;45U55U=74U-34U-75U-75U=75U=75U=75U=55U=55U=35U=755515
+MU=75U=75U-75U=75U-55U57555555555U5555=75U=75U=75U=75UM565535
+MU=75U=75U=75U=755=755=75U=75U=35U-75U=75U=75U]?4U=75U=75U=75
+MU=74U=74U=75U=75U=75U-74U=75U=75U=75U=36U%=45-75U=75U=34U-35
+MU-74U-35U=555=555=55U=755575U514U=74U-74U-75U=75U=75U=75U=75
+MU575U=75U=75U=75U=75U=75U-;45E54U=75U=75U=75U=55U=75U=75U=75
+MU555U575U=74U=75U=37U555555555555555U555U=75U=755=75U=34U=35
+MU=75U=755575UM565%=5U=75U-75U-34U-35U-75U-35U-755=74U=75U=75
+MU-155=75U-34U-34U-35U=755=75U=75U=75U=555555U=75U-34U-34U-31
+MU%=55=55U=755575U=75U575U555U=75U=75U-34U=35U=75U=74U-75U=75
+MU=75U555U5555=55U=75U=75U=74U=755=75U=75U=75U-;45U54U=75U=75
+MU=34U=34U-35U=755575U=75U=75U=555=75U555U-34U-34U-74U=75U=75
+MU=75557555555555U=7555555=755575UM575%355=555555U=75U=75U=34
+MU-15U=75U=75U=75U=75U575U=?5U575U5555=75U575U=75U=74U=75U=75
+MU=74U=75U=55U=75U=36U%=45%55U=75U-75U=755=75U=75U-35U-75U-75
+MU=35U-75U-54U=35U-34U-74U=75U=75U=75U=75U=75U=75U=74U-75U=74
+MU=74U-'45U55U=75U-75U=75U5555=55U575U=75U=75U-75U=74U-34U=37
+MU-75U=5555555575U=75U=74U=35U=35U=35U-34U-35U=75U=74T=175535
+MU=74U=75U=75U=75U=75U-75U-74U-35U=75U=55U=355=74U-34U-34U-34
+MU=75U=75U=555=755=555555U=75U=75U=75U=76U5955%55U=75U=75U=75
+MU=75U=74U-74U=74U=75U=75U=755=74U-355=75U=755=75U=75U=75U=55
+MU=75U-75U=75U=75U=75U=75U=355-55U=75U=74U-34U-74U=34U=34U-35
+MU=745=75U=75U=74U%55U-34U-35U=75U=75U=55U=755=7555555575U=75
+MU=75U575U575UM565%15U=75U=74U-75U=75U=74U=75U=755=75U=55U=75
+MU=55U-?5U=55U555U=75U=75U=75U=35U-35U=35U-5555755=75U=75U=31
+MU%=55-75U=34U-75U=75U=75U=35U-74U-75U-34U=34U=75U=54U=35U-75
+MU-75U-35U=75U=75U=75U=75U-75U=75U=75U=74U-34U-'75]55U=75U=35
+MU5555=75U=75U=35U=55U=75U=75U=75U=75U=77U-74U=75U=7555555=75
+MU=355555U=34U-35U=75U=35U=75U=34T=175535U=75U=75U=75U=74U-34
+MU=75U575U575U=75U=75U=755%74U-34U-34U=75U=75U=75U57555555555
+M5=55U=75U=555=555=76U5=55-75U=74U-75U=75U-75U=75U=7555555575
+M5=75U=755=74U]35U575U55555754']@?7-.1%/1W-PU(B0R"!)<G(>)B["]
+ML+6WL*:MO<P1E(^!<'2!M<8_(3[!BN`V.S(-#S`V;8Z&"R<Z:[:VX0<7E>(:
+M`)>^I8(U/1^TO8S6_H:9!3<$M:6P!3\V^X^89DZ'AAD\,O"_ON\Q,!R=ZQ5R
+M@K?I,3@"M+N*!#0%X_`8$(&]M0`[,I2\L/0#'_E0`P_BLK_A/3@$B[&>$F^7
+MY0TQ&K2ZM0\Y-)>+FF=;AX4%/3:<N+_',#%JA)!B7(VUQC,Y&K"[C`(W&N_\
+M'Q6#LHP).C&%O[9_#QCR60`#D+VR<C\Y$+>PDQD5Z,H--Q>QNXPU.`J8M9IB
+M3X6<!C(UAKN];STQ>H&=9M&"B&<R/VJ]N(<(-AF4YQ-AC;"'-#LT@KFW%`@:
+M_%P&!)N\L1`Y/WBQL.L$%N/6##5RL[B$-C@/@;>;:W.9EP,S#X^ZL!D\-MR"
+MGV??@XT1/3+1O[F=-#$=D^P7<(RQDC8[#HJXM1DU&N75!!F&O;0'.#W[LK'X
+M`1+D10T(_;*^EC,X`8^VGA9EDN(-,`:UNK<`/C?CCIEFWX"!&#TPE;F^YC$Q
+M%YGJ:UB/M^8P.0:WN(X!-!O@VAH1@[V(##LPD[RQ6P(<^TX"#)2]O,\\.1FU
+ML9(=8I;R##$<MKJ("#DUD(N98-2&F@<]-YJ[O'8S,6*$EFS<C+5",CX=L[B`
+M##<9Z?<>;HVR@PH[-X>^MV(/'OY(`P"?O+-L/CYKM[&4&&CJW@\W;["[@#0Y
+M"86UF6]>A)(#,@N#NK,6/39+@9-@PXV):#T\9;VXF@HV')?[$GJ/L)HW.PJ/
+MN;03"!G[3`$%A+RV&3@\7["QX`07[5H/-5&RN9DP.0*#M)\52ICJ#3,"B+JV
+M!#\W\(*=8<F"@AP],_F^N90W-A&2X!9,CK&4,3@-M;B(!348YUH''("\M0`[
+M,NZRML(!$.9T#`GCO;_L,CD$CK>2$7^=YP\P!+2ZM0T^-.B.G&'/@(8$/3:3
+MN+_),39KF.EJT(ZW]#,Y!;&XC0`T&>+5!1>-O8\).S&9O+9R`A+E<PT-D+R]
+M3#\^$K6VEAUFD<@.-A&QNX\*.0N<BY]BQ(:8`3TTA[N]8#,V9824;\^/BF4R
+M/Q>RN(8.-QSKPQECC[*!-#LT@+ZT:@\<^G,#!IJ\L!8Y/V:VMNX;;Y52#C=E
+ML[B'-CD,A[6<;M>$D0(R#HRZL!P]-U6!EF+VC(X6/3U&O+F<-3<3EO(2<XZP
+MGS8["8FYBAP('^5Q`!J&O+<$.#WTL+;^!!7L=0XU]+VYDS,Y`8*TDA5%F^\/
+M,P"*NK<!/S3DC9-@\XV#&#PP[[Z^[3<V%)WD%E.)MNTP.`"TN(X'"A_F2P<2
+M@KR*#3LPE[VV4P$6X7P/#NJ\O_\]/AN(MY$1=IS_#C`8M[J+#CXUEXZ28_&#
+MA`8\-IFXO%HP-F*8[17"B;11,CX>L+B#`C0<[5D%:HR]C0L[-H6_MV8"$.1[
+M#`*?O[)G/S\4M+:5'&61W`DV%;"[@C0Y"9F+DFWU@9\#/0J`N[(5,C=VA.MN
+M\(Z*;#T\;;*YA0DT$NK=&62.LH0W.S6-OK46#Q+E>P('A+^Q'3D\=[:VX1MC
+ME4P)-$^RN(4Q.0*&M9-HQ827##(,B;JQ&CPTS(&4;?Z/CQ(\,LR_OI$U-Q:1
+M]1U,B+"0,3@,BKF(&`@=Y'X`&("_M`8X,N>SML@':.]\"0KDO;Z5,CD'C+21
+M%%&;X`XS!K2ZM`,_->V-D6/XC(`%/#&7N;_^-C=HG?@1WHBV^C,Y![>YC`8*
+M'>%P!A&,O(@/.S&2O;=T`13@90X/D;^\TSP^'(NWE!!,G/0(,!RVNHD(/@N0
+MCI!B^8*%`#PWA;N]>#`W9)O@%?&(M'`]/A.SN88--1+O3P5OCKV#-3LTAK^T
+M;P(6YV<,`YN_LV@^/V^TM^P<?Y!="#9BL[N`-SX/FHB0;/*!G0T]"X*ZLQ`R
+M-UB'[FG[B8L4/#Q^O;F9"S01E5$8?XBRFS8["(^^BA,/$.1F#02&O[$;.#W7
+ML;?X&V:4<`@TW;VXGS`^`("UD6C+A^H.,@*+NK8$/#3]@95LY(Z,&3PSY+Z^
+MZS0W%9'&'5*+L)4P.`*UN8X%"!/G9`,?@K^U`SLSZ;.WT0=L[F4("^^\ON,R
+M/@6/M)<7WYKE"#,$M[JU#3\*ZX*78N>,@0<\,9*XO-LV-V*<\Q'(B[;,,CD:
+MMKF#``H3X'D&%X^\C@@[-IF]M'@!:N-A"0R=O[UW/S\0BK3H$%B?V@LQ$;&Z
+MC`H^"9V/EF+D@IH#/#2&N[)M,#1RF^04^8NU9CT_%;.YA`\U$>]V!&.(O8$T
+M.S6`O[45`A?F8P\`A+ZS$3D\9+>WX1]VD$\+-GBRNX<V/@V$B)9O^("0#ST)
+MC[JP'S(TW(?B:.:(B!`\/5F\OI(*-!>51!ATB[.?,3L.B;Z('`\6YV,-!8"^
+MM@0X,O:QM_0:EJVAN;>&X6D$#0LW,CT^/SD\/#`Q-0X&&&Q,XY::AH*,B8B*
+MBK6*BXF.C(*!AYN<D>OA\--,>6%O:A06$1`3$Q,3$!$6%Q1J:6U@9WI\=DE$
+M7=7=VL#,R/7T]_?W]_3URLC.S<#&Q=C?TM'7U51645!24EU<7U]?7UQ<75)3
+M4U!15E975%55U=34U];6UM;6UM;6UM;6UM;6UM;7U]?4U-34U-34U-34U-75
+MU=75U=75U=35U=35U-75U=34U-34U-34U-34U-34U-34U-34U-34U-35U-74
+MU=34U-34U-74U=75U=74U-34U-74U=75U-35U=34U-74U=75U=75U=75U-75
+MU=75U=75U=75U=34U-75U=75U=75U=74U=75U=75U=75U=75U=74U=75U=75
+MU=75U-74U-75U=75U=75U=75U=75U=75U555U=75U=75U=75U=55U=75U=75
+MU=75U=755=75U=75U=35U=75U=75U=75U=74U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=555=755=75U=75U=75U=75U=75U=34U-35U-75U=75
+MU=74U-75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=555555U=55U=75
+MU=7555755=75U=75U=75U=75U=75U=75U=75U=75555555555=755=55U555
+MU575U=75U=75U=75U=75U=75U=75U=75U5555555U=75U=75U=55U=75U=75
+MU=75U=75U=75U=75U=34U=35U=55U=75U=75U=75U=755575U=75U=75U=75
+MU=75U=;FD^[A_L77271Y>&1D9V1D>GA\<W=U341?4=33WL7&PLS)R,C+R\C(
+MSLS"P\;'VMG?W=#6U]545U914%!24E)=75)=4E)34U!045965E=45%555575
+MU-34U-?6U]34U=75U=74U=755575U57555555%54555555555=55U5555555
+M55555=55U575U=555=75U=75U=75555555555=75U=75U=75U5755%155=75
+MU=75U-74U=75U555555555555=755555U5555555U=55U=555555U=555=75
+M5=75U=75U=75U=55U555U575U=75U=755575U575U-5555555=555555U=75
+MU=75U=75U=35U=35U=75U5755=55U=74U-75U-75U=75U=75U-74U=34U=75
+MU=555575U=75U=74U=35U=34U5155=75U=74U-75U=75U=75U=75U=75U=55
+MU5555555U=75U=75U=75U=755=555=75U=75U=75U=75U=75U=74U=34U-34
+MU-35U=55U=55U=?4U=75U5555=555575U=75U-35U-35U=75U=75U=75U-75
+MU=75U-34U-7555755=555=75U=755=7555555=75U=55U=55555555555554
+M5=74U-34U]34U=35U=75U-75U=75U575U5555575U=35U=75U=75U=755=75
+MU=75U=75U=75U=75U=35U=75U=75U=755555U575U=75U=77U]75U=555555
+MU=75U=75U=75U=75U=74U=34U=75U=75U-35U=755=555=555575U=55U=75
+MU=75U-75U-75U=755575U=75U=75U=755535U=75U=75U5755=75U=75U555
+MU=755=755=75U=75U=755=75U5555555U=75U=75U=555=55U=75U=75U=75
+MU=35U-75U-75U-74U-34U]?4U=55555555755=555=75U=75U-35U-75U-75
+MU=75U-75U=34U=75U=75U=75U=74U-35U=55U555U=75U=755=75U=555555
+M5=755515U=75U-34U-34U-74U=755=75U=75U=55555555555555U=75U-75
+MU=555=55U=55U=55U5755575U575U=75U-74U-34U-75U555U=75U=?7U=55
+MU=555=75U=74U-75U-75U-75U555U5555=75U=75U=75U-355555U=75U=74
+MU=75U=74U=75U=75U=75U=34U=75U=755555U5545%55U=75U5555=555575
+MU=75U=75U=75U5755575U575U=75U=755=5555755=75U=34U=7555555555
+M55755=75U=34U-35U=75U=75U=74U]7555555=5555555555U=75U=75U=75
+MU=75U=75U=75U=75U=75U5755=555555U=35U-35U-355555U=75U-75U=75
+MU=75U=5555555%155=74U=34U=75U=75U=55555555755=5555155=555=75
+MU=75U=74U-34U=75U-75U5555554555555155=55U=75U=75U55555555555
+MU-35U=7555755=555=555555555555755=555555U=75U=75U=55U=555=75
+MU=55U=75U=34U-75U=75U575U-75U=75U=75U=755555U5545=35U=35U-34
+MU-34U-75U=55U=75U575U=555=75U=75U=35U=75U=75U=75U=75U=75U=75
+MU=75U=755=75U575U=75U=75U=75U=75U=37U=75U=555=555=75U=75U=75
+MU-75U=75U=35U=75U=75U555U575U=75U=75U-74U-34U-34U=75U=75U=75
+MU-75U=75U=75U=75U=155-75U=75U-75U=75U-75U-75U=555555U=75U=34
+MU-34U-75U=75U=75U-75U=75U=5555555=75U=74U=34U=34U-75U=75U=75
+MU=35U=74U]75U=755=755555U=75U=75U=75U=75U-74U-35U575U=75U575
+M5=755=75U-74U=35U-34U-75U=35U=35U=75U=75U=75U=75U=755575U-37
+MU-34U-34U-35U-75U=755=55555555555=75U=74U-34U-75U=75U=75U=34
+MU=35U=75U=75U=35U=75U=75U=75U-34U=75U=75U]?4U=75U=75U=75U=74
+MU=75U=75U=75U=34U=35U=75U=34U=75U=75U=75U=74U-34U-75U=75U=75
+MU-34U-35U=55U=75U-75U=75U5575%55U-74U-34U-34U=34U=75U555U575
+M5575U=35U=75U=35U-75U=75U=35U=75U555U575U=75U=75U=75U=75U=55
+M5555U=75U=75U=77U=755575U=5555555=75U=35U=75U=75U-34U575U555
+MU5555=75U=35U-75U=75U=75U575U=75U=74U=75U=75U=75U=75U-75U=15
+M5-75U=34U=74U=34U=34U=75U5555555U5555=55U=75U=75U=75U=75U=75
+MU=75U-75U575U=75U=75U=75U=555=75U=75U=34U=75U=74U]35U5555555
+MU=755=75U=75U-75U=74U=75U575U=75U=75U=75U=75U=75U=75U=35U=34
+MU=74U=75U=75U=75U555U=75U-35U=75U535U=74U-34U-34U-35U=75U=55
+MU=55U5755575U=75U=75U=75U575U575U=75U=75U=75U=75U=75U=75U=75
+M5=555575U=75U=55U555U=35555555555555U=75U=75U=75U=75U=74U=34
+MU=75U=75U=75U=755=75U=75U=75U=75U-75U=75U=35U-34U-35U=75U=55
+MU575U=55U=75U-34U-34U-34U-35U=75U=35U=35U=75U=75U=75U=74U-34
+MU-75U=75U=35U=75U=75U=74U-75U=75U=75U=75U=75U-75U-75U=34U575
+M55755=75U=75U=7555555575U=74U-?4U-755=755=75U=355=75U=75U=75
+MU=75U=75U=34U=755=55U=75U=75U=35U-35U=755575U=35U-34U-34U=75
+MU=7555555575U=755555U575U575U=75U=555=75U=75U=75U5555=75U=75
+MU575U=75U=75U=74U=345=755575U-75U=75U5755575U=35U=75U=555=35
+MU=35U=75U=75U575U=75U=75U=55U575U=74U-34U=34U-35U=75U=75U=75
+MU=35U=75U=75U555U=74U-34U-34U-75U=555575U=75U=75U5555=555=35
+MU=35U=55U=55U=75U-74U-75U575U=34U=35U=75U=75U=74U=75U5555555
+MU=?4U=75U575U=55U575U=755=75U=75U=75U=75U575U575U=75U-755=75
+MU=75U=75U=75U=34U=74U=75U=35U=35U=75U=75U=75U=54U=34U-34U=34
+MU-74U=75U=75U=75U=75U=75U=75U=755=75U=75U5755=55U=75U=75U-75
+MU=75U=75U=75U=7555555=75U=75U-74U=77U]74U=755=55555555555=75
+MU=75U=75U=75U-75U=75U=34U-34U=75U=75U=75U=74U=35U=75U555U=75
+MU=74U=75U5755=755=755%34U-77U-34U-75U=75U=75U=755=555=555=75
+MU=75U=34U=34U]35U-75U-75U-35U=75U=75U-74U=75U=75U=75U-74U-34
+MU-75U575U-35555555755=755=75U=75U-34U-35U-75U-75U=75U=75U=75
+MU575U=75U=74U=75U=75U-74U-75U=74U=75U=75U=75U=35U=74U555U-75
+MU-35U=35U=75U=75U=555=75U=75U=75U=75U=75U-75U=7555555=55U=75
+MU=75U5555=755=75U=75U=35U=75U=755=75U=75U=?7U=75U5555555U575
+MU=75U-35U=75U=75U=755575U=75U=75U-75U=75U=75U=75U=75U=75U=75
+MU=34U-34U-34U=75U=75U=75U=545=75U=35U=75U=75U=755=55U=75U575
+MU555U575U=75U=75U=75U5555=75U=75U=75U=75U=75U=75U=75U=555=55
+MU=35U=75U=34U=37U]7555755575U555U=755=555=55U=75U=34U-75U=75
+MU=75U=35U=75U=75U=55U5555=75U=75U-35U-35U-75U=75U=75U-35U=75
+M5535U=75U=34U-34U-74U575U575555555555=555=75U=35U=34U-35U=75
+MU-35U=75U=555=75U=75U=55U555U=55U=74U=74U=74U=74U]35U-75U=75
+MU=75U=75U=75U=74U=35U-34U]34U=7555755575U=75U=75U=34U=34U-74
+MU=74U=74U=75U=75U-34U=75U=755=75U555U=74U-34U-74U-34U=75U=75
+MU=75U=555=55U=75U=75U=75U=355555U5555575U=75U=75U=55U=75U=75
+MU=75U=74U=75U=75U=55U=34U=555=755=55U=55U=75U-75U-35U=75U-75
+MU=5555555575U=555=75U=75U=75U=75U=75U=75U-75U=75U=35U-34U-75
+MU=74U=555%75U=34U-34U-34U=75U=755=75U=75U=75U=74U-34U-75U=74
+MU-55U=75U=75U=755=75U=75U=34U=75U=75U=55U=75U=75U=75U=77U]34
+MU=7555755=75U=75U575U575U=55U=75U=75U=74U=75U=355555U=75U=75
+MU=75U=75U=75U=74U-34U-35U=75U=75U=75U=755574U-34U-34U-35U=75
+MU=555=7555555555U555U575U=75U=75U-55U=75U=75U=555=75U=75U-75
+MU=75U-75U=75U-34U-75U=74U=75U-?4U=74U=74U-74U575U5755=75U=35
+MU-34U=75U=555555U575U%75U=75U=75U=75U=74U-34U-34U-75U=75U=75
+MU=74U=74U=75U554U=75U-34U-35U-35U=75U=75U=75U=34U-75U=75U=35
+MU=34U=35U=75U=35U-34U=75U=75U=75U575U=55U=75U=75U=75U=75U=35
+MU=37U=75555555555=75U=75U=75U=75U=75U=35U=75U5555555U=55U=75
+MU=75U=75U=75U-74U-34U=74U=7555755=75U=75U-75U=555%55U=75U=75
+MU=74U=75U555U555U555U=55U=75U=55U=75U=74U575U=75U575U5555575
+MU=75U-34U=74U-35U=35U=35U=75U=34U=74U-75U=555=755=55U=75U575
+MU=75U575U=74U-35U=75U=75U=34U=75U=75U=755=755=75U=35U=75U=75
+MU=75U=75U-35U-75U=345535U=74U-34U-74U-34U-74U-75U=75U=75U=75
+MU=34U=75U=75U-555=74U=75U=75U=75U=75U=35U=35U=74U=75U=555555
+MU575U=75U-?4U5755575U=74U=755=75U=75U=75U-74U-35U=75U=75U=75
+MU575U=55U=75U=75U=75U=34U-34U]34U-75U=755=55U=75U575U5545=75
+MU-74U-34U-35U=75U5755=755=7555555575U=755=75U=75U=75U=755=55
+MU=75U=755575U=75U=75U=75U=74U-74U-75U=755=37U=75U=555=755=75
+MU=75U=755=75U=75U=75U=75U=75U=75U-75U575U=75U=75U-75U-75U=75
+MU=75U=75U=74U=74U=74U=75U=355-74U-34U-34U-75U=75U=75U=34U=75
+MU575U=75U-74U-74U-74U=755=75U=755%74U-?5U-=55=555-555=75U-55
+MU-34U=75U-35U=74UM75U5555555U575U=75U=75U=75U-34U-74U-74U535
+MU-755=7455555=75U=75U555U555U=75U=77U-35U=34U=75U=75U=55U=55
+M5515U=74U-?4U-35U-75U55555755=74U=75U555U=75U=75U=74U-34U-34
+MU=75U555U555U=75U=75U=75U=75U=75U=75U575U-74U-55U=34U555U=55
+M5555U=75U=75U=75U=75U=74U=75557555555=555555U=55U=75U=35U=34
+MU-35U-35U=75U=55U=75U-35U=55U57555545=75U]34U-34U=75U=75U=75
+MU=55U=7555555555U=74U=75U=34U=555=55U=75U=55U=75U=75U=75U=75
+MU=34U-34U-75U-55U=55U=77U-75U=55557555755575U=75U=74U-74U-35
+MU=75U=75U=75U=75U=755575U=75U=75U-34U=75U-75U=75U=75U=74U-34
+MU=35U=755%35U=34U-34U-34U=75U5555555U=75U=55U5755=75U=75U=75
+M5575U=75U=75U=75U=75U=755=75U5755575U575U=75U=75U=75U=74U]35
+MU=75U=75U=555=75U=55U=75U=55U=75U=75U=75U=75U=75U575U575U=75
+MU=75U=75U=75U=75U=75U=75U575U=75U=74U=34U%15U=75U=34U-34U-75
+MU=75U=75U=555575U=75U-34U-75U-75U-75U=75U=75U=755=755=75U=75
+MU=75U-75U=75U5555=75U=75U=35U-?4U=75U575U=75U=75U=755=555555
+MU=75U=75U=75U=75U=75U=755=75U=555555U=75U-34U-34U=75U=75U=75
+MU=75U=75U=55U=545-55U=35U-35U=34U-34U=75U=75U575U=75U=75U-34
+MU-75U=35U=755=75U=75U=75U=75U=75U=75U=35U=75U=75U=74U-75U=75
+MU=37U-75U=5555555555U=75U=75U=75U=75U=35U=755=75U=75U=75U=55
+MU=75U=75U-75U=75U=75U-75U575U=75U575U=75U-35U-345=75U=34U-34
+MU-74U=75U=75U=755555U=555555555555555575U=75U=75U-75U=75U=55
+M5575U-35U=75U-75U=75U=74U=34U-34U-75U]?4U555555555545=75U=75
+MU=75U=75U=74U=74U=75U=555555U=55U=55U=75U=75U=34U=75U=75U=75
+MU=75U=74U-75U=35U=75U575U-34U-35U-35U-34U-35U-34U=75U=75U=75
+MU-75U-74U-75U-75U=555575U=75U=34U-74U=355=755575U=74U-75U=75
+MU=55U=55U=?4U=75U57555555=555575U=35U=75U-75U=75U575U=74U-34
+MU=75U=75U575U=75U=75U-75U-75U=75U=75U=35U-35U=34U=75U=555=75
+MU=34U]34U=75U=755=75U=34U575U=75U=75U=75U=74U-74U=35U=35U=75
+M5=755=555555U=75U=75U=75U=75U=55U=75U=75U=77U]34U55555755555
+M5=55U=75U=75U575U=74U=75U=75U-75U575U=75U=75U575U=34U-35U-35
+MU=35U=34U-34U=74U=75U=75U-755574U-34U=34U-75U=75U=74U=74U=75
+MU=75U=75U=75U=75U=34U=75U=35U=75U=34U=75U5755=75U555U5555575
+MU-35U=75U=34U575U-?4U55555555555U=75U=75U=75U=35U=755=75U=75
+M5=75U=555=55U=55U=55U=74U-75U=75U-75U=75U=75U=75U-75U=75U=75
+MU515U=34U-35U=35U=75U-74U-35U=75U-75U=75U=75U=755=75U=75U=74
+MU=74U-75U575U=75U=75U=75U=755575U=75U=75U=75U=55U=34U=75U=55
+M5=55U=75U=75U=75U=755=55U=75U-55U=75U=55U575U=75U=75U-35U=74
+MU=75U575U=75U=75U=75U=75U-75U=34U=755-745=35U=35U=75U=75U-15
+MU=55U=7555555555U575U=755575U=75U555U=555=55U=75U=75U=75U=75
+MU=34U-75U=75U=755=74U-34U]35U-155555U555U575U=75U=75U=555=75
+MU=75U=74U=75U=555=74U=755=74U=75U=34U-75U=35U=55U=74U=75U=35
+MU=555=755515U=74U-75U=75U=75U=75U=75U575U=5555555575U=75U-35
+M5=75U=75U=75U=35U=75U=75U=555575U=75U=75U-35U-34U=75U555U=35
+M55755=5555555575U=75U=75U=75U=75U=34U=35U=55U=75U=755=555555
+MU=75U-75U=75U=75U=74U-35U=74U=75U-34U%75U554U=74U-34U=35U=75
+MU=75U=75U=555575U555U=75U-34U-75U-75U=75U=75U-75U=75U=75U=55
+MU555U=75U=75U=75U=75U=75U=35U=37U55555555555U=75U-74U=35U=75
+MU-35U=74U-34U=75U=75U=75U=75U=75U=75U=75U=74U-35U=74U-75U=75
+MU=75U=75U=35U=355=75U=34U-34U=75U=5555555575U=55U=34U-75U=75
+MU=5555555=75U=75U5755555U=74U-34U=75U=35U=75U=75U=74U-75U555
+M5574U%555=755=75U=555=55U=75U=75U=34U=34U-75U575U=75U=75U=75
+MU=75U=75U=75U=34U=75U=75U=75U-35U=75U=75U=75U=355575U=34U-34
+MU=34U575U=75U-75U=75U=5455545=75U=74U=34U-34U=75U=75U=75U=75
+M5=555=555575U=75U=74U-34U-34U=75U=75U=355=75U=75U=55U=755=75
+MU=75U=75U=75U=755=75U=75U=55U=75U=55U=755=74U-34U-35U-75U=55
+MU=34U-75U=755575U-74U-55U=75U-34U=34U-75U=35U=75U=55U=75U515
+M5=755=77U=74U=75U-35U-15U=75U555U=75U=34U%75U575U-75U-34U=75
+MU=555=555=77U-75U=75U=75555555555=75U=34U-75U-34U=55U=55U=75
+MU=75U=35U=75U555U=75U-75U-34U=755=75U=75U=34U-34U-55U=755%15
+MU=34U=34U=34U=75U=75U=75U=55U=75U=74U-75U=75U575U5755555U=55
+MU=75U=75U-74U-37U-75U=75U=75U=75U=75U=75U=74U]35U=75U=755575
+M5=75U=74U=75U=55U=75U-35U=75U5555=75U575U=75U-75U=34U=55U=75
+MU=74U=34U=75U=75U=35U=15U=75U515U=34U-35U-75U=34U-35U=555=75
+M5=55U5555575U=75U=75U=555=555=75U-35U=755555U=75U=35U=755575
+MU=555=74U-75U-35U=34U=5555155=555=75U-75U-34U-74U=34U=75U=75
+MU=75U=755=7555555=75U-34U-35U5555=75U=74U=34U-75U=75U=75U=75
+MU5545=75U-75U=35U-34U-74U=5555555575U=35U=75U=75U555U=74U-74
+MU=75U=75U-34U=555=75U=75U=75U=75U=75U=75U=55U=75U=77U]75U554
+M55155=75U=34U-35U-755575U=34U-34U=75U=74U-34U-34U=75U=75U=75
+MU=74U-75U-75U=75U=75U=34U=35U-3555755%35U=37U-34U-35U=755=75
+MU=75U=75555555555=55U=75U=75U=75U-55U-34U-75U=555575U=755555
+MU=34U-75U=74U=75U=75U575U-35U5755575U575U=74U=75U=75U=75U=75
+MU=75U=75U=75U-35U-75U=75U=75U=75U575U=75U=75U=75U-35U=75U=75
+MU=74U=35U554U=34U-34U-35U=35U=75U=75U=75U=75U=75U=34U-75U=34
+MU=55U=55U575U=74U-75U=75U=75U=74U575U=75U=75U=75U=75U555U=?4
+MU=75U55555545575U=74U=35U=75U-35U-34U-75U-75U=75U=75U=755575
+MU575U=74U-75U=75U=75U=34U-35U=35U=75U575U-545=35U-75U=35U-35
+MU=34U-35U-75U-75U=75U575U=74U=75U=75U5755=74U=74U-34U=55U555
+MU575U=75U=35U=34U=75U=55U=75U=74U%75U5545575U=75U=75U-74U=34
+MU-75U=75U=74U-34U=75U5555575U=75U=755=55557555555575U=75U=75
+MU=55U575U555U5755-74U-34U-34U=75U=75U=35U-35U=75U=55U575U=75
+MU=75U=74U=75U=75U=75U=75U=75U=75U=75U=75U=755575U=75U=74U575
+MU=75U-15U5555575U=75U=75U=75U=74U-75U=75U=55U=75U-75U=75U555
+M5555U=75U=75U=34U-75U=74U=34U-75U575U=75U=35U=35U515U=74U-34
+MU=74U=75U=34U=35U-755575U=75U=74U-35U=35U=75U-74U=75U-34U=75
+MU=555=75U5755=75U=35U=75U=75U=75U=55U=?7U=55555555555=75U=75
+MU=555575U=75U-74U=75U=55U=75U=755=75U=34U=35U=35U-75U=75U=75
+MU-35U=75U=555575U=75U=555=75U-35U-34U-75U=75U=75U=75U5555575
+MU575U=74U575U-34U-75U=755=75U=75U=75U=755=75U=75U=55U=75U=55
+MU=55U=75U=77U]75U=75557555555555U=75U=75U=75U-37U-75U=75U=75
+MU57555555555U=75U-74U-75U=75U=75U=35U-75U=75U=75U=75U=755574
+MU=34U=74U=75U=75U=74U=34U=75U=34U=75U-75U=75U-755=75U=74U-34
+MU=75U5755=555555U=75U=75U-35U-74U-75U=75U=75U-35U5555%15U=75
+MU=74U=34U-75U=75U=74U-35U=74U=75U=15U=74U-75U-75U=75U=34U-55
+MU575U=75U=75U575U=74U=755=555514U=74U-75U=75U=75U=75U=75U=74
+MU=34U=75U=75U-74U-34U-75U=75U-75U-75U555U555555555755=75U=34
+MU=34U=35U=75U=75U=34U=555555U5755555U=35U=75U-35U=75U=75U555
+MU555U575U=75U=75U=75U-34U-34U=75U=75U=755575U=74U-74U-34U=75
+MU=755-75U-34U-34U-34U=35U=55U=55U=55U%55U=75U575U575U=75U575
+M5=755=75U=75U=35U=75U=35U-34U-34U=75U=34U=35U=75U=74U]75U=55
+MU5555555U=75U=75U=75U575U=74U=755575U=75U-75U=75U=35U-75U-75
+MU-74U=35U=75U=75U=75U-35U=75U-75U=755535U=34U=34U=75U=75U=75
+MU=75U=75U575U=755=75U=75U-3555555555U=75U=35U=35U=75U-75U=75
+MU=75U-35U-34U-74U=75U-75U-34U=75U575U55555755575U=34U-74U-75
+MU-75U=34U-34U-35U=75U=75U=75U-35U-35U=75U=755=75U=75U=75U=75
+MU5755=75U555U=74U-74U-35U-34U-35U-35U555U5555555U5755=75U=34
+MU=75U=35U=35U-34U-35U=75U575U=75U=75U=75U-75U=75U=75U=74U=36
+MU-75555455555=75U=75U=75U-75U-74U-75U575U=555=755555U=75U555
+MU=75U=75U=35U=75U=75U=75U=75U=35U=75U-75U=745%75U=34U-34U=34
+MU=34U-75U=55555555555575U=75U=75U-75U=75U-75U-74U-75U=75U=75
+MU=75U=75U=75U=75U=755=755=75U=74U]35U=5555755575U=75U=75U=75
+MU=75U=75U=75U=75U=74U55555555=55U=75U-34U=75U=75U=75U=75U=75
+MU=75U=35U=75U=75U515U-74U=75U-34U=75U=34U=75U555U5555555U=75
+MU=75U=7555555=75U=74U=74U=755555U=75U=75U=75U=75U=75U=75U575
+MU=75U-?4U=75U555U=75U575U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U-34U-35U-75U-74U-74U=75U=545-75U=34
+MU-35U=75U=75U=75U=75U=75U=75U=75U=75U=75U5555555U575U=555555
+M55555=75U=75U=75U=75U=75U=75U=75U=75U=37U-5555555=555=75U-35
+MU-34U-35U=35U-34U-34U=75U=35U=35U-75U-74U-755=75U=75U=75U=75
+MU5555=755=75U=755=75U=355=74U=35U=75U-34U-75U=75U=75U=75U=75
+MU-75U=75U=75U-35U=75U=75U-75U=755555U=75U=75U=75U=75U=75U=75
+MU=35U-35U=75U-35U5555555U575U=75U=75U575U=75U=75U=75U=75U=74
+MU575U=755=75U=74U=34U=34U=75U=75U=75U=75U=75U=75U-35U=74U515
+MU=74U-34U-74U=75U=75U=75U=75U=7555555575U=75U=355=75U=75U=75
+MU-34U-74U=35U=75U=75U=55U=75U555U=75U575U=75U-?4U=75U575U=55
+MU=75U=75U5755=75U=74U=75U=75U=75U=5555555555U=75U=75U=35U-34
+MU-75U-75U=75U=75U=75U=75U575U=545-75U=34U-34U=35U=75U=75U=75
+MU=75555555555=75U=74U=5555755=555=55U=75U575U575U=75U555U555
+MU=75U=74U=75U=75U=77U-7555755=55U=755=55U=75U=34U-34U-35U=55
+M5=55U=35U=75U=75U=75U=75U=75U-75U-75U=75U=75U=75U-35U=74U-75
+MU=555%75U=34U-34U-34U=75U=55U=75U=55U=55U=75U=55U=75U-75U=75
+MU=75U=55U=755555U5755=755=75U=34U-34U-34U-34U-34U-74U]?4U-75
+M5555U=75U=35U-75U=75U=55U=74U-34U-75U=75U575U=75U=75U=74U=34
+MU-74U=755=755=75U-34U-35U=55U=75U=75U575U-34U-34U-75U=35U=75
+MU=75U=75U=7555545555U=74U-?4U=75U=75U=74U=34U=34U-35U=75U=75
+MU=35U=34U-75U=75U575U=55U=34U=55U55555555555U=75U575U=75U=74
+MU=75U=75U=75U=555575U=75U=755=555=75U=75U=35U-75U=75U=75U=75
+MU=75U-35U=55U=34U-35U-75U=75U=75U575U=75U=75U=75U=75U=34U-34
+MU=75U=75U=75U=75U=75U=55U=55U=75U=75U=35U=555=75U=75U=75U=37
+MU]75U=555=75557555755=75U=75U=74U-34U=555=75U=755=55U=75U=75
+M5=75U=74U-35U-75U-75U=75U-75U-75U=75U=74U=755%74U=34U-74U=75
+MU=75U=755=75U=75U=75U=5555555=75U=55U=75U=75U=555555U=75U=55
+MU=555575U57555755=75U57555755=75U-35U=55557555555555U575U=75
+MU=35U=75U=75U=755=75U=75U55555555=75U=74U-34U-35U=75U=75U=75
+MU=75U=755=755575U555U=34U-35U-35U=755=755=75U=75555555555=75
+MU=75U-34U=75U=74U=75U-34U-74U=74U-75U=34U=35U=75U=75U=75U=55
+MU=55U=?4U=55U5555555U=55U575U=75U=75U=75U=75U=75U=75U=75U=75
+M5=555=755=75U=75U=74U=75U=75U=75U=75U=35U=75U=75U-145=75U-34
+MU-74U-35U=755575U=75U=74U=75U=75U=34U=74U=74U=75U=75U=75U=75
+MU=75U=75U=55U555U=55U=75U=74U=35U-34U=77U]7555555555U=755=75
+MU=75U=74U=34U=34U=75U=75U=355=75U=75U=75U=75U575U=75U=34U-75
+MU=75U=75U=75U=75U-75U=345574U=34U=34U-34U=34U-75U=75U=75U=75
+MU=75U=34U-35U-355=75U=75U-35U-35U-75U=55U=75U575U575U575U=75
+MU=74U=74U=74U-?5U=55551555555=75U=75U=75U=75U-74U-75U=75U=75
+M55155555U=74U-74U=34U-35U=75U=755=75U=75U=55U=75U=75U=75U557
+M5=75U=74U-75U=75U575U=75U=75U5555555U=75U-74U-34U=75U=74U-75
+MU=75U=74U=35U=35U=75U=74U-74U-35U=75U=75U5555=34U=555=555=55
+MU=75U=74U=34U-74U-75U=75U=75U-74U-35U=75U=75U=75U=75U=75U=75
+MU=35U=75U=755=75U=35U-34U-35U=555-75U-34U-34U-35U=75U=555575
+MU5755=755555U5555=75U575U=75U=75U=7555555=55U=75U=75U=55U=55
+MU=75U575U=55U=75U=74U]75U=75U=74U=75U=75U5755575U=75U-34U=75
+M5555U=755=75U=755575U=75U=75U=55U=75U=75U=75U=75U=75U=75U=75
+MU-355575U=34U-34U-75U=34U-74U=75U=75U=75U=75U=75U=74U-35U=75
+MU=75U=75U=75U-74U-75U=755575U=75U=34U-35U=75U=75U=75U-?4U=75
+MU5755%555555U=75U-34U-35U=75U=75U=75U=75U=75U=75U=75U575U=74
+MU=34U-34U-75U=75U=74U=75U-75U=755555U=545=75U-34U-34U=75U=55
+MU=55U=75U=75U=555555U=75U=74U=75U=75U575U=74U=75U=75U=755=75
+M5=755=75U=34U-75U=75U=755=37U=75555555555555U=74U-34U-34U-75
+MU-34U-75U=75U=55U575U=75U=75U=74U=34U-75U=75U=75U=75U=75U=55
+M5=75U=35U-355=75U-35U-35U-35U-75U=75U=75U575U=75U=74U=75U575
+MU5755=74U=34U=75U=75U=75U=75U=34U-75U=75U5555=75U=74U=74U-74
+MU]355=75U=75U=75U=75U=75U=75U575U=74U-75U=75U=555=55U=35U=75
+MU=75U=75U-74U=75U=75U=34U=75U=75U=75U=74U-34U535U=74U=74U-34
+MU=75U=75U=75U=75U=7555555=755575U=75U5755575U=75U=75U=35U=75
+MU=55U555U575U=75U=75U-75U=75U-35U-?4U=755575U=755=755=55U=75
+MU=75U=35U-35U=75U=35U=75U=75U=555575U=75U=75U=75U=75U=35U=75
+MU=75U=34U=74U-75U5545-75U-34U-34U-34U-75U=7555555=755555U=75
+MU=75U=75U=75U=75U-74U-74U=75U5555=75U=75U-74U=34U=75U=75U=75
+MU=35U=37U=5555555=555=55U=75U=75U=75U=75U-74U-75U=75U5555555
+M5=75U575U=74U=34U-34U-75U=35U=35U=755=75U=75U=75U=755-75U-35
+MU-34U-75U=75U=75U=75U=75U-75U=75U-34U-75U=75U=75U=75U=75U=75
+MU=755=75U=75U=75U-35U=75U=75U=75U=75U=74U]35U5555575U555U=75
+MU=75U=75U=75U=75U575U=75U=75U=75U=75U=55U=75U=75U-35U=55U=75
+MU=75U=755575U=75U=75U=75U535U-74U-75U-74U=75U55555755=55U=75
+MU=755=75U555U=755575U=75U=75U=75U=55U=75U=75U=75U=75U575U=75
+MU-35U=74U-35U-?4U=55U5755555U=755=75U=75U=74U-34U-34U-35U575
+MU=75U=75U=75U=75U=75U=75U575U=75U=75U=75U=74U-35U=75U=75U=15
+M5=75U=34U-74U-35U=75U=75U=75U575U=55U575U=755=75U=75U=75U=75
+MU=75U=75U5555=555=75U=75U=75U=75U=75U=75U=555=74U-5555545555
+MU=75U=75U=74U=75U=75U=75U=75U=75U555U=75U=75U=75U=75U=75U=75
+MU=75U=74U=34U=75U=75U=34U=75U=555%75U=34U-74U-75U=75U=755=75
+M5555U=555575U=75U=75U-74U-34U-34U=74U575U=75U=75U=75U=75U=75
+MU=75U=35U=75U=75U575U-155=555=75U=75U=75U=75U-75U-35U=34U-35
+MU=7555755=75U=75U=755=75U=75U=75U=74U-34U-34U-75U=75U=35U-34
+MU=75U515U-75U-74U-74U-74U=75U=755575U=755=755=75U=75U=75U=75
+MU=75U=55U=75U=55U575U=75U=75U=75U575U=75U=75U=75U=75U-?7U=75
+MU575U5755575U=75U=75U=755=75U=75U=75U=75U=55U=75U=75U=75U=75
+MU=75U=75U-75U=75U=75U=75U=75U=75U=75U=555=75U-75U-34U-34U=75
+MU=75U=75U55555555555U=75U-34U-35U=75U=35U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=74U-7555555=75U=75U=75U=75U=75U=75
+MU=34U=555=75U=55U575U=75U=75U=74U=75U=35U-74U-75U=75U=755575
+M5=75U=75U=345535U=34U=34U-74U-34U=34U=75U=35U=75U=75U=75U=75
+MU=75U=74U=75U-74U=35U=75U575U575U=75U=75U=74U=75U=75U=74U=75
+MU-35U55555555=75U=75U=75U-35U=75U=75U-75U575U=75U=75U=75U=75
+MU575U=74U=75U=75U=75U=75U=75U=75U=75U=75U=75U555U-74U-34U-35
+MU=75U=55U555U=75U=75U575U=755575U=75U=75U=75U575U=755=755=75
+MU=75U=75U=75U=75U=75U=35U=75U=755=34U=75U575U=75U=7555755=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=34U-35U=55U555
+MU=75U=75U=34U=75U=155=75U=34U-34U=75U=75U=75U=75U=74U=35U=35
+MU=35U=75U=75U=35U-35U-34U=755=555=75U=75U=75U=75U=55U=75U=34
+MU-34U-37U]55555555555=75U=74U=75U=75U=75U-34U-75U=75U=55U=75
+MU=75U=75U=75U=75U=74U=75U=75U=74U-34U=755=75U=75U=74U535U=74
+MU=74U-34U-75U=75U=7555555555U555U=75U=75U5555=75U=75U-74U=75
+MU5755575U=7444%64TQ37-34TM_>V-C8V=G?W]+2T]S>45C81%#&6]907515
+M1E344=9`T-13UE-7WUE6TE_?T%/25]#04]?65MW75=95UM965-15U]76T]54
+MUU96TE35UU'6U5=45=745%#7U%165M?5U=?5U-!6T]57TU/7UU+25%?15M'6
+M4M?7U=96U]74U=54UM75U5;45]?7U==7U57545365-=6U=17U5775=;45=55
+MU%=5U5365%755M95U-16UE755%575==1UN2AHZ4J*BXA.30%6Y*#B[>QL+.S
+ML["VM[6(C(&%G97DW'-B%!`<&!H%!`0$!`0%&A@>'1,6%&EB9W]T1%39S/?R
+M_OOEY.?GY^3DY?KY__+P]\H)(*NFL)P=-3T[)"8F(28F)R4[/S(V"P,;%4+G
+MD9N&@H^(B[6UM;6*BXB.C(*!AYJ>DY3LY/?307-E86UN:VH5%106$1`0$184
+M%6EM87IR2%O4V\_W\O[[Y>3DY^?DY.7[^?SR\?3(PL39T]=74U];149`0TU-
+M34Q-34)#0$%'1%I;6%Y?75-045975%75U=34U-34U-35U=5555555%145U=7
+M5E965E965E9645965E9645965E975E975U=75U=75%145%145%145%145%14
+M5%145%145%145%145%145%=45%175%145%155%1455155%55555555555555
+M5%555555555455555%555555555555555555555555555555555555555555
+M55555%5555555555555555555555555555755=55U=75U=75U=75U=755=75
+M55755=555=5555555=75U=75U=75U=55U=75U=75U=75U=75U=75U=75U575
+MU=75U=75U=75U=75U=75U=75U=55U55555755575U555U=75U=75U=55U575
+MU=75U575U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=74U-75U-35U-34U-75U-75U=75U=75U5755=555=555555
+M5555555555555575U555U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=55U=75U=75U=75U=75U=75U=75U=75U=75U=75U=55U=75U575U=755=75
+MU=755=75U5755=75U=755=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U-75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U-75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=31T=?45=755%165E=45%15
+M5=75U=74U-74U-34U-34U=34U-75U=55U=74U-745%74U%;5E[2U@(25Y'9@
+M%A(9&P4%!1H8&1P2%A5O87YU4M[U_>7FX^WO[NGIZ>[O[.WCX>?E^?WVRL+:
+MW==67%M'0TU.24A+2TA(3D],0D!&1%M97UU345=5U=36UM'0T]/3T]/3T-#0
+MT=;6U]?7U-7555545%145U=75E=75E=75U=75U=75U175%145%1555555555
+M55555555555555555555555555555555555555555555555555555555U555
+M5=555=55555555555555U5555555557555755555557555555555U575U=75
+M5=75U=75U=75U=75U=75U=75U=55U=75U575U555U5755=55U555U575U=55
+MU=75U575U=75U=755555U555U575U=75U=75U=55U5755=555=755=55U=75
+MU=55U=75U575U575U=755=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U555U555U555U575U=55U575U=75U575U=75U=755=75
+M5=55U=55U575U=75U=75U=75U=75U=75U=35U-75U-75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=74U=35U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=35U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U575U=75U=755=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=755=755=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=55U=75U5755=55U=55U=75U=75U575
+MU=75U=55U=55U575U=75U=55U=75U=55U=75U=75U=75U=75U=75U=75U=75
+M5=75U=75U=75U=75U575U5755=75U=75U=75U=75U=75U=75U575U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=35U=75U=75U=55U=55U=755=75U=75U=75U=75U=55U=75U=75U=75U=75
+MU=75U=75U=75U=55U575U57555755=55U555U5755=55U555U555U575U575
+M557555755=555=555=555=55U57555755555U5755=555=5555555=555575
+M5555U555555555555=555=55U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=755=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=755=755=75U575U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=55U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U575U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75U=75
+MU=75U=75U=75U=75U575U=75U575U=75U=755=75U=75U575U=75U575U=75
+MU=75U=75U=75U=75U=75U=75U=75U=7_____________________________
+M__________________________________________________________]5
+M555555555555555555555555555555555555555555555555555555555555
+M55555555555555555555555553HX,@L1DHJ]N+JXO8J2$0LR.#HX/34<E(BR
+MN+J[O+29:PDS.3H[/#0:[8ZSN;J[O+>%9@PP.3H[/S<'_HVPN;J[O[:&=`(Q
+M/CH[/C8!V8.QOKJZOK&#W`$V/CLZ/C$"2H:VO[NZN;"-_P<W/SLZ.3`,9X2W
+MO+NZN;./[1HT/#LZ.3,):)FTO+NZN+*(E!\U/3@Z.#(+$9*UO;BZN+V*DQ$+
+M,C@Z.#TU')>(LKBZN[RTF6L),SDZ.SPT&^R.L[FZN[RWA6$/,SDZ.S\W!/B-
+ML+FZN[^VAG<",#XZ.S\V`=J#L;ZZNKZQ@-,`,3X[.CXQ`DF&MK^[NKZPC?T'
+M-S\[.CDP#&2$M[^[NKFSC^(:-#P[.CDS"6F8M+R[NKBRB)0?-3TX.C@R"Q:2
+MM;VXNKB]BI,0"C(X.C@]-1R7B+*XNKN\M9YJ"3(X.CL\-!OOCK.YNKN\MX5A
+M#S,Y.CL_-P3ZC+"YNKN_MH9Q`C`^.CL_-@''@[&^NKJ^L8#6`#$^.CH^,0-,
+MAK:_N[J^L(WR!S8_.SHY,`QDA+>_N[JYLX_C!30\.SHY,PYNF+2\N[JXLHB5
+M'S4].#HX,@L6G;6]N+JXO8J0$`H].#HX/34=EXNRN+J[O;6>%0DR.#H[/#08
+M[HZSN;J[O+>%8`\S.3H[/S<$Y8RPN;J[O[:'<`(P/CH[/S8!P(.QOKJZOK&`
+MU0`Q/CHZ/C$#0(&VO[NZOK""\`<V/SLZ.3`,982WO[NZN;./X`4W/#LZ.3,.
+M;IBTO+NZN+*)E1XU/3LZ.#(+%YVUO;BZN+V*D!`*/3@Z.#TU'9:+LKBZN+VU
+MGQ4(,C@Z.SPT&.Z.L[FZN[RTA6,/,SDZ.S\W!.2,L+FZN[^VAW(-,#XZ.S\V
+M!LR#L;ZZNKZQ@%8`,3XZ.CXQ`T>!MK^[NKZP@O$&-C\[.CDP#'J$M[^[NKFS
+MC^$%-SP[.CDS#F^;M+R[NKBRB>H>-3P[.C@R"!><M;VXNKBRBI`3"CTX.C@]
+M-1*6B[*XNKB]M9\4"#(X.CL\-!CIB;.YNKN\M)IB#S,Y.CL_-P3DC+"YNKN_
+MMX=]#3`^.CL_-@;)@K&^NKN^L8!3`#$^.CH^,0-:@;:_N[J^L(+W!C8_.SHY
+M,`UXA+>_N[JYLX_A!3<\.SHY,PYLF[2\N[JYLXGK&30\.SHX,@@7G+6]N+JX
+MLHN1$PH].#HX/342D8NRN+JXO;6?%`@R.#H[/#09Z(FSN;J[O+2:;0\S.3H[
+M/#<$YXRPN;J[O[>'?PTP.3H[/S8&RH*QOKJ[OK:!7`,Q/CHZ/C$#68&VOKNZ
+MOK&"]`8V/SLZ.3`-?H>WO[NZN;",Y@4W/#LZ.3,.;9JTO+NZN;.)ZQDT/#LZ
+M.#((%)RUO;BZN+*+D1(*/3@Z.#T*$I&+LKBZN+VUG!0(,C@Z.SPT&>N)L[FZ
+MN[RTFFT.,SDZ.SPW!>:,L+FZN[^WAWX-,#DZ.S\V!O2"L;ZZN[ZV@5D#,3XZ
+M.CXQ`UR!MKZ[NKZQ@LH&-C\[.CDP#7^'M[^[NKFPC.<$-SP[.CDS#VV:M+R[
+MNKFSB>@9-#P[.C@R"!2?M;VXNKBRBY$2-3TX.C@]"A.1B[*XNKB]M9P7"#(X
+M.CL\-!GKB;.YNKN\M)ML#C,Y.CL\-P7AC[.YNKN_MX1X#3`Y.CL_-@;W@K"^
+MNKN_MH%:`S$^.CH^,0!3@+&^N[J^L8+)!C8_.SH^,`U]A[>_N[JYL(SD!#<_
+M.SHY,P]BFK2\N[JYLXGI&#0\.SHX,@@4G[6]N+JXLHN6$C4].#HX/0H3D(JR
+MN+JXO;6<%P@R.#H[/#4>ZHFRN+J[O+2;;PXS.3H[/#<%X8^SN;J[O[>$>@PP
+M.3H[/S8&\8*POKJ[NU555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+M555555555555555555555555555555555555555555555555555555555555
+755555555555555555555555555555555
+`
+end
diff --git a/usr.sbin/i4b/g711conv/g711conv.1 b/usr.sbin/i4b/g711conv/g711conv.1
index 4d91024..43abcfe 100644
--- a/usr.sbin/i4b/g711conv/g711conv.1
+++ b/usr.sbin/i4b/g711conv/g711conv.1
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: g711conv.1,v 1.3 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Mon Mar 15 16:17:23 1999]
+.\" last edit-date: [Mon Dec 13 22:54:33 1999]
.\"
.Dd March 15, 1999
.Dt G711CONV 1
@@ -66,7 +68,6 @@ A-Law and u-Law conversions are specified in ITU Recommendation G.711.
.Pp
The reference implementation done by Sun Microsystems, Inc. is available
from http://www.itu.int/itudoc/itu-t/rec/g/g700-799/refimpl.txt
-.Pp
.Sh EXAMPLES
The command:
@@ -85,12 +86,11 @@ converts the u-law coded voice of Max Headroom to A-law, reverses the
bits of the result and moves that to an active isdn4bsd telephone connection.
.Pp
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-utility and this manpage were written by
+utility and this manpage were written by
.An Hellmuth Michaelis Aq hm@kts.org
based on the G.711 conversion reference code written by Sun Microsystems,
-Inc. and code contributed to isdn4bsd by
-.An Stefan Bethke .
+Inc. and code contributed to isdn4bsd by Stefan Bethke.
diff --git a/usr.sbin/i4b/g711conv/g711conv.c b/usr.sbin/i4b/g711conv/g711conv.c
index f6a442e..5c7857d 100644
--- a/usr.sbin/i4b/g711conv/g711conv.c
+++ b/usr.sbin/i4b/g711conv/g711conv.c
@@ -65,7 +65,9 @@
* A-law / u-law conversions as specified in G.711
* -----------------------------------------------
*
- * last edit-date: [Mon Apr 26 14:00:31 1999]
+ * last edit-date: [Mon Dec 13 21:44:01 1999]
+ *
+ * $Id: g711conv.c,v 1.5 1999/12/13 21:25:24 hm Exp $
*
* $FreeBSD$
*
diff --git a/usr.sbin/i4b/isdnd/alias.c b/usr.sbin/i4b/isdnd/alias.c
index fe25e4c..a775fc9 100644
--- a/usr.sbin/i4b/isdnd/alias.c
+++ b/usr.sbin/i4b/isdnd/alias.c
@@ -30,9 +30,11 @@
* NOTE: this has to stay in sync with isdntel/alias.c to be able
* to share a common aliasfile!
*
+ * $Id: alias.c,v 1.8 1999/12/13 21:25:24 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:10:03 1999]
+ * last edit-date: [Mon Dec 13 21:45:19 1999]
*
*----------------------------------------------------------------------------*/
@@ -51,10 +53,10 @@ void
init_alias(char *filename)
{
FILE *fp;
- char buffer[MAXBUFSZ + 1];
- char number[MAXBUFSZ + 1];
- char name[MAXBUFSZ + 1];
- char *s, *d;
+ unsigned char buffer[MAXBUFSZ + 1];
+ unsigned char number[MAXBUFSZ + 1];
+ unsigned char name[MAXBUFSZ + 1];
+ unsigned char *s, *d;
struct alias *newa = NULL;
struct alias *lasta = NULL;
diff --git a/usr.sbin/i4b/isdnd/config.h b/usr.sbin/i4b/isdnd/config.h
index 6f591a9..4a7aa8c 100644
--- a/usr.sbin/i4b/isdnd/config.h
+++ b/usr.sbin/i4b/isdnd/config.h
@@ -27,9 +27,11 @@
* i4b daemon - compile time configuration header file
* ---------------------------------------------------
*
- * $FreeBSD$
+ * $Id: config.h,v 1.8 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:10:10 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:45:27 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnd/controller.c b/usr.sbin/i4b/isdnd/controller.c
index 861b79e..c3e76843 100644
--- a/usr.sbin/i4b/isdnd/controller.c
+++ b/usr.sbin/i4b/isdnd/controller.c
@@ -27,18 +27,125 @@
* i4b daemon - controller state support routines
* ----------------------------------------------
*
+ * $Id: controller.c,v 1.19 1999/12/13 21:25:24 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Mon May 10 21:35:55 1999]
+ * last edit-date: [Mon Dec 13 21:45:34 1999]
*
*---------------------------------------------------------------------------*/
#include "isdnd.h"
+static int
+init_controller_state(int controller, int ctrl_type, int card_type, int tei);
+
+/*---------------------------------------------------------------------------*
+ * get name of a controller
+ *---------------------------------------------------------------------------*/
+const char *
+name_of_controller(int ctrl_type, int card_type)
+{
+ static char *passive_card[] = {
+ "Teles S0/8",
+ "Teles S0/16",
+ "Teles S0/16.3",
+ "AVM A1 or Fritz!Card",
+ "Teles S0/16.3 PnP",
+ "Creatix S0 PnP",
+ "USRobotics Sportster ISDN TA",
+ "Dr. Neuhaus NICCY Go@",
+ "Sedlbauer win speed",
+ "Dynalink IS64PH",
+ "ISDN Master, MasterII or Blaster",
+ "AVM PCMCIA Fritz!Card",
+ "ELSA QuickStep 1000pro/ISA",
+ "ELSA QuickStep 1000pro/PCI",
+ "Siemens I-Talk",
+ "ELSA MicroLink ISDN/MC",
+ "ELSA MicroLink MCall",
+ "ITK ix1 micro",
+ "AVM Fritz!Card PCI",
+ "ELSA PCC-16",
+ "AVM Fritz!Card PnP",
+ "Siemens I-Surf 2.0 PnP",
+ "Asuscom ISDNlink 128K PnP"
+ };
+
+ static char *daic_card[] = {
+ "EICON.Diehl S",
+ "EICON.Diehl SX/SXn",
+ "EICON.Diehl SCOM",
+ "EICON.Diehl QUADRO",
+ };
+
+ if(ctrl_type == CTRL_PASSIVE)
+ {
+ int index = card_type - CARD_TYPEP_8;
+ if (index >= 0 && index < (sizeof passive_card / sizeof passive_card[0]))
+ return passive_card[index];
+ }
+ else if(ctrl_type == CTRL_DAIC)
+ {
+ int index = card_type - CARD_TYPEA_DAIC_S;
+ if (index >= 0 && index < (sizeof daic_card / sizeof daic_card[0] ))
+ return daic_card[index];
+ }
+ else if(ctrl_type == CTRL_TINADD)
+ {
+ return "Stollmann tina-dd";
+ }
+
+ return "unknown card type";
+}
+
+/*---------------------------------------------------------------------------*
+ * init controller state array
+ *---------------------------------------------------------------------------*/
+void
+init_controller(void)
+{
+ int i;
+ int max = 1;
+ msg_ctrl_info_req_t mcir;
+
+ for(i=0; i < max; i++)
+ {
+ mcir.controller = i;
+
+ if((ioctl(isdnfd, I4B_CTRL_INFO_REQ, &mcir)) < 0)
+ {
+ log(LL_ERR, "init_controller: ioctl I4B_CTRL_INFO_REQ failed: %s", strerror(errno));
+ do_exit(1);
+ }
+
+ if((ncontroller = max = mcir.ncontroller) == 0)
+ {
+ log(LL_ERR, "init_controller: no ISDN controller found!");
+ do_exit(1);
+ }
+
+ if(mcir.ctrl_type == -1 || mcir.card_type == -1)
+ {
+ log(LL_ERR, "init_controller: ctrl/card is invalid!");
+ do_exit(1);
+ }
+
+ /* init controller tab */
+
+ if((init_controller_state(i, mcir.ctrl_type, mcir.card_type, mcir.tei)) == ERROR)
+ {
+ log(LL_ERR, "init_controller: init_controller_state for controller %d failed", i);
+ do_exit(1);
+ }
+ }
+ DBGL(DL_RCCF, (log(LL_DBG, "init_controller: found %d ISDN controller(s)", max)));
+}
+
/*--------------------------------------------------------------------------*
* init controller state table entry
*--------------------------------------------------------------------------*/
-int
+static int
init_controller_state(int controller, int ctrl_type, int card_type, int tei)
{
if((controller < 0) || (controller >= ncontroller))
@@ -61,6 +168,8 @@ init_controller_state(int controller, int ctrl_type, int card_type, int tei)
isdn_ctrl_tab[controller].stateb2 = CHAN_IDLE;
isdn_ctrl_tab[controller].freechans = MAX_CHANCTRL;
isdn_ctrl_tab[controller].tei = tei;
+ isdn_ctrl_tab[controller].l1stat = LAYER_IDLE;
+ isdn_ctrl_tab[controller].l2stat = LAYER_IDLE;
DBGL(DL_RCCF, (log(LL_DBG, "init_controller_state: controller %d is %s",
controller,
name_of_controller(isdn_ctrl_tab[controller].ctrl_type,
@@ -81,7 +190,10 @@ init_controller_state(int controller, int ctrl_type, int card_type, int tei)
isdn_ctrl_tab[controller].stateb1 = CHAN_IDLE;
isdn_ctrl_tab[controller].stateb2 = CHAN_IDLE;
isdn_ctrl_tab[controller].freechans = MAX_CHANCTRL;
- isdn_ctrl_tab[controller].tei = -1;
+ isdn_ctrl_tab[controller].tei = tei;
+ isdn_ctrl_tab[controller].l1stat = LAYER_IDLE;
+ isdn_ctrl_tab[controller].l2stat = LAYER_IDLE;
+
log(LL_DMN, "init_controller_state: controller %d is %s",
controller,
name_of_controller(isdn_ctrl_tab[controller].ctrl_type,
@@ -95,7 +207,10 @@ init_controller_state(int controller, int ctrl_type, int card_type, int tei)
isdn_ctrl_tab[controller].stateb1 = CHAN_IDLE;
isdn_ctrl_tab[controller].stateb2 = CHAN_IDLE;
isdn_ctrl_tab[controller].freechans = MAX_CHANCTRL;
- isdn_ctrl_tab[controller].tei = -1;
+ isdn_ctrl_tab[controller].tei = tei;
+ isdn_ctrl_tab[controller].l1stat = LAYER_IDLE;
+ isdn_ctrl_tab[controller].l2stat = LAYER_IDLE;
+
log(LL_DMN, "init_controller_state: controller %d is %s",
controller,
name_of_controller(isdn_ctrl_tab[controller].ctrl_type,
@@ -139,6 +254,28 @@ init_active_controller(void)
}
/*--------------------------------------------------------------------------*
+ * init controller D-channel ISDN protocol
+ *--------------------------------------------------------------------------*/
+void
+init_controller_protocol(void)
+{
+ int controller;
+ msg_prot_ind_t mpi;
+
+ for(controller = 0; controller < ncontroller; controller++)
+ {
+ mpi.controller = controller;
+ mpi.protocol = isdn_ctrl_tab[controller].protocol;
+
+ if((ioctl(isdnfd, I4B_PROT_IND, &mpi)) < 0)
+ {
+ log(LL_ERR, "init_controller_protocol: ioctl I4B_PROT_IND failed: %s", strerror(errno));
+ do_exit(1);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*
* set controller state to UP/DOWN
*--------------------------------------------------------------------------*/
int
diff --git a/usr.sbin/i4b/isdnd/curses.c b/usr.sbin/i4b/isdnd/curses.c
index ca8bf75..6e01c08 100644
--- a/usr.sbin/i4b/isdnd/curses.c
+++ b/usr.sbin/i4b/isdnd/curses.c
@@ -27,9 +27,11 @@
* i4b daemon - curses fullscreen output
* -------------------------------------
*
- * $FreeBSD$
+ * $Id: curses.c,v 1.29 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:10:24 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:45:43 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnd/dial.c b/usr.sbin/i4b/isdnd/dial.c
index 0d6c3e0..dff8787 100644
--- a/usr.sbin/i4b/isdnd/dial.c
+++ b/usr.sbin/i4b/isdnd/dial.c
@@ -27,9 +27,11 @@
* i4b daemon - dial handling routines
* -----------------------------------
*
- * $FreeBSD$
+ * $Id: dial.c,v 1.8 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:10:30 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:45:51 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnd/exec.c b/usr.sbin/i4b/isdnd/exec.c
index b79b2be..c180aad 100644
--- a/usr.sbin/i4b/isdnd/exec.c
+++ b/usr.sbin/i4b/isdnd/exec.c
@@ -27,9 +27,11 @@
* exec.h - supplemental program/script execution
* ----------------------------------------------
*
- * $FreeBSD$
+ * $Id: exec.c,v 1.13 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:10:35 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:45:59 1999]
*
*---------------------------------------------------------------------------*/
@@ -60,8 +62,8 @@ sigchild_handler(int sig)
if((pid = waitpid(-1, &retstat, WNOHANG)) <= 0)
{
- log(LL_ERR, "ERROR, waitpid: %s", strerror(errno));
- do_exit(1);
+ log(LL_ERR, "ERROR, sigchild_handler, waitpid: %s", strerror(errno));
+ error_exit(1, "ERROR, sigchild_handler, waitpid: %s", strerror(errno));
}
else
{
@@ -128,7 +130,7 @@ exec_prog(char *prog, char **arglist)
{
case -1: /* error */
log(LL_ERR, "ERROR, exec_prog/fork: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "ERROR, exec_prog/fork: %s", strerror(errno));
case 0: /* child */
break;
default: /* parent */
diff --git a/usr.sbin/i4b/isdnd/fsm.c b/usr.sbin/i4b/isdnd/fsm.c
index 0dca785..63a6229 100644
--- a/usr.sbin/i4b/isdnd/fsm.c
+++ b/usr.sbin/i4b/isdnd/fsm.c
@@ -27,9 +27,11 @@
* FSM for isdnd
* -------------
*
- * $FreeBSD$
+ * $Id: fsm.c,v 1.18 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:10:41 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:46:07 1999]
*
*---------------------------------------------------------------------------*/
@@ -385,24 +387,24 @@ next_state(cfg_entry_t *cep, int event)
if(event > N_EVENTS)
{
- log(LL_ERR, "FSM: event > N_EVENTS");
- do_exit(1);
+ log(LL_ERR, "next_state: event > N_EVENTS");
+ error_exit(1, "next_state: event > N_EVENTS");
}
currstate = cep->state;
if(currstate > N_STATES)
{
- log(LL_ERR, "FSM: currstate > N_STATES");
- do_exit(1);
+ log(LL_ERR, "next_state: currstate > N_STATES");
+ error_exit(1, "next_state: currstate > N_STATES");
}
newstate = state_tab[event][currstate].newstate;
if(newstate > N_STATES)
{
- log(LL_ERR, "FSM: newstate > N_STATES");
- do_exit(1);
+ log(LL_ERR, "next_state: newstate > N_STATES");
+ error_exit(1, "next_state: newstate > N_STATES");
}
if(newstate != ST_SUSE)
diff --git a/usr.sbin/i4b/isdnd/isdnd.8 b/usr.sbin/i4b/isdnd/isdnd.8
index 3397fc3..8ab59f2 100644
--- a/usr.sbin/i4b/isdnd/isdnd.8
+++ b/usr.sbin/i4b/isdnd/isdnd.8
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: isdnd.8,v 1.27 1999/12/13 22:11:55 hm Exp $
.\"
-.\" last edit-date: [Thu May 20 14:37:42 1999]
+.\" $FreeBSD$
+.\"
+.\" last edit-date: [Mon Dec 13 22:57:10 1999]
.\"
.Dd February 23, 1999
.Dt ISDND 8
@@ -397,26 +399,25 @@ will start
with reasonable debugging messages enabled, full-screen mode of operation,
full-screen display redirected to /dev/ttyv03 and using a termcap entry
for vt100 on this display.
+
.Sh DIAGNOSTICS
Exit status is 0 on success, 1 on error.
.Pp
.Sh SEE ALSO
-.Xr i4bipr 4 ,
-.Xr i4bisppp 4 ,
-.Xr isdnd.rates 5 ,
-.Xr isdnd.rc 5 ,
-.Xr isdntel 8 ,
+.Xr syslogd 8 ,
.Xr isdntrace 8 ,
-.Xr syslogd 8
+.Xr isdntel 8 ,
+.Xr isdnd.rc 5 ,
+.Xr isdnd.rates 5 ,
+.Xr i4bisppp 4 ,
+.Xr i4bipr 4
+
.Sh BUGS
Still one or more left.
-.Sh AUTHORS
+
+.Sh AUTHOR
The
.Nm
-daemon and this manual page were written by
-.An Hellmuth Michaelis .
-He can be contacted at
-.Aq hm@kts.org
-or
-.Aq hm@hcs.de .
+daemon and this manual page were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdnd/isdnd.acct.5 b/usr.sbin/i4b/isdnd/isdnd.acct.5
index 5c0d0ba..3ee378b 100644
--- a/usr.sbin/i4b/isdnd/isdnd.acct.5
+++ b/usr.sbin/i4b/isdnd/isdnd.acct.5
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: isdnd.acct.5,v 1.11 1999/12/13 22:11:55 hm Exp $
.\"
-.\" last edit-date: [Mon Feb 15 16:54:23 1999]
+.\" $FreeBSD$
+.\"
+.\" last edit-date: [Mon Dec 13 22:58:12 1999]
.\"
.Dd September 11, 1998
.Dt ISDND.ACCT 5
@@ -84,6 +86,7 @@ is the number of seconds the connection lasted.
and
.Em OUTBYTES
is the (optional) number of bytes that were transferred.
+
.Sh FILES
.Bl -tag -width /var/log/isdnd.acct -compact
.It Pa /var/log/isdnd.acct
@@ -91,16 +94,19 @@ The default accounting information file for the
.Nm isdnd
ISDN daemon.
.El
+
.Sh EXAMPLES
This is a typical accounting line:
.Pp
.Dl 12.06.97 10:41:37 - 12.06.97 10:45:18 GROGGY 2 (65) (4711/1147)
+
.Sh SEE ALSO
-.Xr isdnd.rc 5 ,
-.Xr isdnd 8
-.Sh AUTHORS
+.Xr isdnd 8 ,
+.Xr isdnd.rc 5
+
+.Sh AUTHOR
The
.Xr isdnd 8
-daemon and this manual page were written by
-.An Hellmuth Michaelis .
-He can be contacted at hm@kts.org or hm@hcs.de.
+daemon and this manual page were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
+
diff --git a/usr.sbin/i4b/isdnd/isdnd.h b/usr.sbin/i4b/isdnd/isdnd.h
index 1307034..9565915 100644
--- a/usr.sbin/i4b/isdnd/isdnd.h
+++ b/usr.sbin/i4b/isdnd/isdnd.h
@@ -27,9 +27,11 @@
* i4b daemon - main header file
* -----------------------------
*
- * $FreeBSD$
+ * $Id: isdnd.h,v 1.72 1999/12/13 21:25:24 hm Exp $
*
- * last edit-date: [Thu May 20 14:44:18 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:46:50 1999]
*
*---------------------------------------------------------------------------*/
@@ -38,11 +40,15 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <unistd.h>
#include <strings.h>
+#include <string.h>
#include <ctype.h>
#include <syslog.h>
#include <regex.h>
+#include <time.h>
+#include <errno.h>
#ifdef USE_CURSES
#include <curses.h>
@@ -52,6 +58,7 @@
#include <errno.h>
#include <signal.h>
+#include <sys/queue.h> /* TAILQ_ macros */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -162,7 +169,9 @@ enum logids
LL_WRN, /* warning conditions - nonfatal abnormal conditions */
LL_DMN, /* normal but significant condition - status of daemon */
LL_CHD, /* informational - everything regarding call handling */
- LL_DBG /* debug messages - everything which helps debugging */
+ LL_DBG, /* debug messages - everything which helps debugging */
+ LL_MER, /* monitor error messages - not sent to remote */
+ LL_PKT /* packet logging - log the first few packets */
};
/*---------------------------------------------------------------------------*
@@ -434,6 +443,7 @@ typedef struct cfg_entry {
typedef struct isdn_ctrl_state {
int ctrl_type; /* type: active/passive */
int card_type; /* manufacturer (CARD_XXXX) */
+ int protocol; /* ISDN D-channel protocol */
int state; /* controller state */
#define CTRL_DOWN 0 /* controller inoparable */
#define CTRL_UP 1 /* controller may be used */
@@ -444,6 +454,8 @@ typedef struct isdn_ctrl_state {
int freechans; /* number of unused channels */
#define MAX_CHANCTRL 2 /* free channels per controller */
int tei; /* tei or -1 if invalid */
+ int l1stat; /* layer 1 state */
+ int l2stat; /* layer 2 state */
} isdn_ctrl_state_t;
/*---------------------------------------------------------------------------*
@@ -459,6 +471,7 @@ struct rarr {
#ifdef I4B_EXTERNAL_MONITOR
/* for each rights entry we keep one of this structures around: */
struct monitor_rights {
+ TAILQ_ENTRY(monitor_rights) list; /* a list of this structures */
char name[FILENAME_MAX]; /* net/host spec or filename */
int rights; /* bitmask of allowed acces rights */
u_int32_t net; /* net/host address (host byte order!) */
@@ -474,6 +487,9 @@ struct monitor_rights {
int isdnfd; /* file handle, /dev/i4b */
+char mailto[MAXPATHLEN] = ""; /* panic mail address */
+char mailer[MAXPATHLEN] = ""; /* panic mail address */
+
char *configfile = CONFIG_FILE_DEF; /* configuration filename */
int config_error_flag = 0; /* error counter */
@@ -556,6 +572,9 @@ char rotatesuffix[MAXPATHLEN] = "";
int isdnfd;
+char mailto[MAXPATHLEN];
+char mailer[MAXPATHLEN];
+
char *configfile;
int config_error_flag;
@@ -647,7 +666,6 @@ void display_disconnect ( cfg_entry_t *cep );
void display_l12stat(int controller, int layer, int state);
void display_tei(int controller, int tei);
void display_updown ( cfg_entry_t *cep, int updown );
-void hangup_channel ( int channel );
void do_exit ( int exitval );
void do_menu ( void );
int exec_answer ( cfg_entry_t *cep );
@@ -669,6 +687,7 @@ void handle_recovery ( void );
void if_up(cfg_entry_t *cep);
void if_down(cfg_entry_t *cep);
void init_controller ( void );
+void init_controller_protocol ( void );
void init_log ( void );
void init_screen ( void );
void log ( int what, const char *fmt, ... );
@@ -689,6 +708,7 @@ void msg_idle_timeout_ind ( msg_idle_timeout_ind_t *mp );
void msg_l12stat_ind(msg_l12stat_ind_t *ml);
void msg_teiasg_ind(msg_teiasg_ind_t *mt);
void msg_proceeding_ind ( msg_proceeding_ind_t *mp );
+void msg_packet_ind( msg_packet_ind_t *mp );
const char * name_of_controller(int ctrl_type, int card_type);
void next_state ( cfg_entry_t *cep, int event );
char * print_i4b_cause( cause_t code );
@@ -714,6 +734,8 @@ void unitlen_chkupd( cfg_entry_t *cep );
void write_pid ( void );
void yyerror ( const char *msg );
+void error_exit(int exitval, const char *fmt, ...);
+
/* montior server module */
void monitor_init();
void monitor_exit();
@@ -744,9 +766,12 @@ void monitor_evnt_disconnect(cfg_entry_t *cep);
void monitor_evnt_updown(cfg_entry_t *cep, int up);
void monitor_evnt_log(int prio, const char * what, const char * msg);
+void monitor_evnt_l12stat(int controller, int layer, int state);
+void monitor_evnt_tei(int controller, int tei);
+void monitor_evnt_acct(cfg_entry_t *cep);
+
/* controller.c */
-int init_controller_state(int controller, int ctrl_type, int card_type, int tei);
void init_active_controller(void);
int set_controller_state(int controller, int state);
int get_controller_state(int controller);
diff --git a/usr.sbin/i4b/isdnd/isdnd.rates.5 b/usr.sbin/i4b/isdnd/isdnd.rates.5
index 098e5ef..d57d703 100644
--- a/usr.sbin/i4b/isdnd/isdnd.rates.5
+++ b/usr.sbin/i4b/isdnd/isdnd.rates.5
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: isdnd.rates.5,v 1.10 1999/12/13 22:11:55 hm Exp $
.\"
-.\" last edit-date: [Sun Feb 14 10:11:05 1999]
+.\" $FreeBSD$
+.\"
+.\" last edit-date: [Mon Dec 13 22:59:31 1999]
.\"
.Dd September 11, 1998
.Dt ISDND.RATES 5
@@ -82,6 +84,7 @@ For example,
defines, that between 2:00 PM and 6:00 PM the length of one charging unit
lasts 90 seconds.
.Pp
+
.Sh FILES
.Bl -tag -width /etc/isdn/isdnd.rates -compact
.It Pa /etc/isdn/isdnd.rates
@@ -89,6 +92,7 @@ The default rates specification file for the
.Nm isdnd
ISDN daemon.
.El
+
.Sh EXAMPLES
The line:
.Bd -literal
@@ -96,19 +100,21 @@ ra0 0 00.00-05.00:240 05.00-21.00:150 21.00-24.00:240
.Ed
.Pp
defines the unit lengths for a Sunday.
+
.Sh SEE ALSO
-.Xr isdnd.rc 5 ,
-.Xr isdnd 8
-.Sh AUTHORS
+.Xr isdnd 8 ,
+.Xr isdnd.rc 5
+
+.Sh AUTHOR
The rates subsystem for the
.Xr isdnd 8
daemon to which
.Nm
-belongs was designed and written by
+belongs was designed and written by
.An Gary Jennejohn .
.Pp
The
.Xr isdnd 8
-daemon and this manual page were written by
-.An Hellmuth Michaelis .
-He can be reached at hm@kts.org or hm@hcs.de.
+daemon and this manual page were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
+
diff --git a/usr.sbin/i4b/isdnd/isdnd.rc.5 b/usr.sbin/i4b/isdnd/isdnd.rc.5
index 08ccdd6..4a65603 100644
--- a/usr.sbin/i4b/isdnd/isdnd.rc.5
+++ b/usr.sbin/i4b/isdnd/isdnd.rc.5
@@ -22,11 +22,13 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: isdnd.rc.5,v 1.41 1999/12/13 22:11:55 hm Exp $
.\"
-.\" last edit-date: [Wed Jul 28 15:57:02 1999]
+.\" $FreeBSD$
.\"
-.Dd May 20, 1999
+.\" last edit-date: [Mon Dec 13 23:00:48 1999]
+.\"
+.Dd October 11, 1999
.Dt ISDND.RC 5
.Os
.Sh NAME
@@ -58,7 +60,9 @@ or
.Pp
The configuration file consists of one
.Em system
-section and one or more
+section, one or more optional
+.Em controller
+sections and one or more
.Em entry
sections.
In the
@@ -66,6 +70,9 @@ In the
section parameters regarding the daemon operation or parameters
not associated with a single remote connection can be set.
In the
+.Em controller
+section parameters regarding a particular controller can be set.
+In the
.Em entry
section(s) parameters directly associated with a single remote
connection can be set.
@@ -122,6 +129,25 @@ If this parameter is set to
date/time information from the exchange (if provided) is written to the
logfile. The default is off. (optional)
+.It Li mailer
+This keyword is used to specify the path/name of a mail program which
+which is able to use the "-s" flag to specify a subject on its
+command line. In case of a fatal error exit of
+.Nm
+this program is used to send mail to an administrator specified by
+the keyword
+.Em mailto .
+(optional)
+
+.It Li mailto
+This keyword is used to specify the email address of someone to notify
+in case of a fatal error exit of
+.Nm .
+(See also keyword
+.Em mailer
+).
+(optional)
+
.It Li monitor-allowed
If this parameter is set to
.Em on
@@ -236,6 +262,27 @@ accounting file. (optional)
.El
+.It Li controller
+This keyword starts the controller configuration section. It must not
+have a parameter and may be used once for every controller. The keyword
+is optional. The following keywords are valid in a controller
+configuration section:
+.Bl -tag -width useacctfile -compact
+
+.It Li protocol
+This keyword is used to set the D-channel protocol for the S0-bus a
+controller is connected to. The following parameters are currently
+supported:
+.Pp
+.Bl -tag -width calledback -compact -offset
+.It Ar dss1
+The DSS1 or so-called "Euro-ISDN" D-channel protocol according to
+ITU Recommendations Q.921 and Q.931.
+.It Ar d64s
+An ISDN leased line with a single B-channel (called D64S in Germany).
+.El
+.El
+
.It Li entry
This keyword starts one configuration entry. It must not have a parameter.
This keyword must be used at least once.
@@ -712,6 +759,7 @@ network will cause a new call to be placed.
.El
.Pp
+
.Sh FILES
.Bl -tag -width /etc/isdn/isdnd.rc -compact
.It Pa /etc/isdn/isdnd.rc
@@ -719,16 +767,18 @@ The default configuration file for the
.Nm isdnd
ISDN daemon.
.El
+
.Sh SEE ALSO
-.Xr regex 3 ,
-.Xr re_format 7 ,
-.Xr isdnd 8 ,
+.Xr isdnd 8
.Xr isdnmonitor 8
-.Sh AUTHORS
+.Xr regex 3
+.Xr re_format 7
+
+.Sh AUTHOR
The
.Xr isdnd 8
-daemon and this manual page were written by
+daemon and this manual page were written by
.An Hellmuth Michaelis Aq hm@kts.org .
.Pp
-Additions to this manual page by
+Additions to this manual page by
.An Barry Scott Aq barry@scottb.demon.co.uk .
diff --git a/usr.sbin/i4b/isdnd/log.c b/usr.sbin/i4b/isdnd/log.c
index 25a0307..ddab579 100644
--- a/usr.sbin/i4b/isdnd/log.c
+++ b/usr.sbin/i4b/isdnd/log.c
@@ -27,23 +27,14 @@
* i4b daemon - logging routines
* -----------------------------
*
- * $FreeBSD$
+ * $Id: log.c,v 1.23 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:11:18 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:47:28 1999]
*
*---------------------------------------------------------------------------*/
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <time.h>
-#include <errno.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <regex.h>
-
-#include <machine/i4b_ioctl.h>
-
#include "isdnd.h"
#define LOGBUFLEN 256
@@ -63,11 +54,13 @@ struct logtab {
* table for converting internal log levels into syslog levels
*---------------------------------------------------------------------------*/
static struct logtab logtab[] = {
- {"ERR", LOG_ERR}, /* error conditions */
- {"WRN", LOG_WARNING}, /* warning conditions, nonfatal */
- {"DMN", LOG_NOTICE}, /* normal but significant condition, daemon*/
- {"CHD", LOG_INFO}, /* informational, call handling */
- {"DBG", LOG_DEBUG} /* debug messages */
+ {"ERR", LOG_ERR}, /* error conditions */
+ {"WRN", LOG_WARNING}, /* warning conditions, nonfatal */
+ {"DMN", LOG_NOTICE}, /* significant conditions of the daemon */
+ {"CHD", LOG_INFO}, /* informational, call handling */
+ {"DBG", LOG_DEBUG}, /* debug messages */
+ {"MER", LOG_ERR}, /* monitor error conditions */
+ {"PKT", LOG_INFO} /* packet logging */
};
/*---------------------------------------------------------------------------*
@@ -168,13 +161,28 @@ log(int what, const char *fmt, ...)
((!debug_noscreen) || (debug_noscreen && (what != LL_DBG))))
{
wprintw(lower_w, "%s %s %-.*s\n", dp, logtab[what].text,
+
+/*
+ * FreeBSD-current integrated ncurses. Since then it is no longer possible
+ * to write to the last column in the logfilewindow without causing an
+ * automatic newline to occur resulting in a blank line in that window.
+ */
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#endif
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 400009
+#warning "FreeBSD ncurses is buggy: write to last column = auto newline!"
+ COLS-((strlen(dp))+(strlen(logtab[what].text))+3), buffer);
+#else
COLS-((strlen(dp))+(strlen(logtab[what].text))+2), buffer);
+#endif
wrefresh(lower_w);
}
#endif
#ifdef I4B_EXTERNAL_MONITOR
- monitor_evnt_log(logtab[what].pri, logtab[what].text, buffer);
+ if(what != LL_MER) /* don't send monitor errs, endless loop !!! */
+ monitor_evnt_log(logtab[what].pri, logtab[what].text, buffer);
#endif
if(uselogfile)
diff --git a/usr.sbin/i4b/isdnd/main.c b/usr.sbin/i4b/isdnd/main.c
index 3980e69..ca4f788 100644
--- a/usr.sbin/i4b/isdnd/main.c
+++ b/usr.sbin/i4b/isdnd/main.c
@@ -27,12 +27,16 @@
* i4b daemon - main program entry
* -------------------------------
*
- * $FreeBSD$
+ * $Id: main.c,v 1.49 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Fri Jul 30 08:14:10 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:47:35 1999]
*
*---------------------------------------------------------------------------*/
+#include <locale.h>
+
#ifdef I4B_EXTERNAL_MONITOR
#include "monitor.h"
#endif
@@ -97,7 +101,9 @@ usage(void)
fprintf(stderr, " -s <facility> use facility instead of %d for syslog logging\n", LOG_LOCAL0 >> 3);
fprintf(stderr, " -t <termtype> terminal type of redirected screen (for -f)\n");
fprintf(stderr, " -u <time> length of a charging unit in seconds\n");
- fprintf(stderr, " -m inhibit network/local monitoring\n");
+#ifdef I4B_EXTERNAL_MONITOR
+ fprintf(stderr, " -m inhibit network/local monitoring (protocol %02d.%02d)\n", MPROT_VERSION, MPROT_REL);
+#endif
fprintf(stderr, "\n");
exit(1);
}
@@ -117,6 +123,8 @@ main(int argc, char **argv)
int remotesockfd = -1; /* tcp/ip monitor socket */
#endif
#endif
+
+ setlocale (LC_ALL, "");
while ((i = getopt(argc, argv, "bmc:d:fFlL:Pr:s:t:u:")) != -1)
{
@@ -126,9 +134,11 @@ main(int argc, char **argv)
do_bell = 1;
break;
+#ifdef I4B_EXTERNAL_MONITOR
case 'm':
inhibit_monitor = 1;
break;
+#endif
case 'c':
configfile = optarg;
@@ -306,6 +316,10 @@ main(int argc, char **argv)
exit(1);
}
+ /* set controller ISDN protocol */
+
+ init_controller_protocol();
+
/* init active controllers, if any */
signal(SIGCHLD, SIG_IGN); /*XXX*/
@@ -430,6 +444,57 @@ do_exit(int exitval)
}
/*---------------------------------------------------------------------------*
+ * program exit
+ *---------------------------------------------------------------------------*/
+void
+error_exit(int exitval, const char *fmt, ...)
+{
+ close_allactive();
+
+ unlink(PIDFILE);
+
+ log(LL_DMN, "fatal error, daemon terminating, exitval = %d", exitval);
+
+#ifdef USE_CURSES
+ if(do_fullscreen)
+ endwin();
+#endif
+
+#ifdef I4B_EXTERNAL_MONITOR
+ monitor_exit();
+#endif
+
+ if(mailto[0] && mailer[0])
+ {
+
+#define EXITBL 2048
+
+ char ebuffer[EXITBL];
+ char sbuffer[EXITBL];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(ebuffer, EXITBL-1, fmt, ap);
+ va_end(ap);
+
+ signal(SIGCHLD, SIG_IGN); /* remove handler */
+
+ sprintf(sbuffer, "%s%s%s%s%s%s%s%s",
+ "cat << ENDOFDATA | ",
+ mailer,
+ " -s \"i4b isdnd: fatal error, terminating\" ",
+ mailto,
+ "\nThe isdnd terminated because of a fatal error:\n\n",
+ ebuffer,
+ "\n\nYours sincerely,\n the isdnd\n",
+ "\nENDOFDATA\n");
+ system(sbuffer);
+ }
+
+ exit(exitval);
+}
+
+/*---------------------------------------------------------------------------*
* main loop
*---------------------------------------------------------------------------*/
static void
@@ -524,8 +589,8 @@ mloop(
{
if(errno != EINTR)
{
- log(LL_ERR, "ERROR, select error on isdn device, errno = %d!", errno);
- do_exit(1);
+ log(LL_ERR, "mloop: ERROR, select error on isdn device, errno = %d!", errno);
+ error_exit(1, "mloop: ERROR, select error on isdn device, errno = %d!", errno);
}
}
@@ -637,6 +702,10 @@ isdnrdhdl(void)
msg_dialoutnumber((msg_dialoutnumber_ind_t *)msg_rd_buf);
break;
+ case MSG_PACKET_IND:
+ msg_packet_ind((msg_packet_ind_t *)msg_rd_buf);
+ break;
+
default:
log(LL_WRN, "ERROR, unknown message received from /dev/isdn (0x%x)", msg_rd_buf[0]);
break;
@@ -660,6 +729,10 @@ rereadconfig(int dummy)
close_allactive();
+#if I4B_EXTERNAL_MONITOR
+ monitor_clear_rights();
+#endif
+
entrycount = -1;
nentries = 0;
@@ -670,7 +743,7 @@ rereadconfig(int dummy)
if(config_error_flag)
{
log(LL_ERR, "rereadconfig: there were %d error(s) in the configuration file, terminating!", config_error_flag);
- do_exit(1);
+ error_exit(1, "rereadconfig: there were %d error(s) in the configuration file, terminating!", config_error_flag);
}
if(aliasing)
@@ -705,14 +778,14 @@ reopenfiles(int dummy)
if((rename(acctfile, filename)) != 0)
{
log(LL_ERR, "reopenfiles: acct rename failed, cause = %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "reopenfiles: acct rename failed, cause = %s", strerror(errno));
}
}
if((acctfp = fopen(acctfile, "a")) == NULL)
{
log(LL_ERR, "ERROR, can't open acctfile %s for writing, terminating!", acctfile);
- do_exit(1);
+ error_exit(1, "ERROR, can't open acctfile %s for writing, terminating!", acctfile);
}
setvbuf(acctfp, (char *)NULL, _IONBF, 0);
}
@@ -732,7 +805,7 @@ reopenfiles(int dummy)
if((rename(logfile, filename)) != 0)
{
log(LL_ERR, "reopenfiles: log rename failed, cause = %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "reopenfiles: log rename failed, cause = %s", strerror(errno));
}
}
@@ -740,7 +813,8 @@ reopenfiles(int dummy)
{
fprintf(stderr, "ERROR, cannot open logfile %s: %s\n",
logfile, strerror(errno));
- exit(1);
+ error_exit(1, "reopenfiles: ERROR, cannot open logfile %s: %s\n",
+ logfile, strerror(errno));
}
/* set unbuffered operation */
diff --git a/usr.sbin/i4b/isdnd/monitor.c b/usr.sbin/i4b/isdnd/monitor.c
index afa54db..dd6d2cd 100644
--- a/usr.sbin/i4b/isdnd/monitor.c
+++ b/usr.sbin/i4b/isdnd/monitor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998 Martin Husemann. All rights reserved.
+ * Copyright (c) 1998,1999 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,32 +33,39 @@
* i4b daemon - network monitor server module
* ------------------------------------------
*
- * $FreeBSD$
+ * $Id: monitor.c,v 1.29 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Sun May 30 10:33:05 1999]
+ * $FreeBSD$
*
- * -mh created
+ * last edit-date: [Mon Dec 13 21:47:44 1999]
*
*---------------------------------------------------------------------------*/
#include "isdnd.h"
#ifndef I4B_EXTERNAL_MONITOR
-/* dummy version of routines needed by config file parser
+
+/*
+ * dummy version of routines needed by config file parser
* (config files should be valid with and without external montioring
- * support compiled into the daemon) */
+ * support compiled into the daemon)
+ */
+
void monitor_clear_rights()
{ }
+
int monitor_start_rights(const char *clientspec)
{ return I4BMAR_OK; }
+
void monitor_add_rights(int rights_mask)
{ }
+
void monitor_fixup_rights()
{ }
+
#else
#include "monitor.h"
-#include "vararray.h"
#include <sys/socket.h>
#include <sys/un.h>
#ifndef I4B_NOTCPIP_MONITOR
@@ -67,32 +74,35 @@ void monitor_fixup_rights()
#include <netdb.h>
#endif
-VARA_DECL(struct monitor_rights) rights = VARA_INITIALIZER;
-#define INITIAL_RIGHTS_ALLOC 10 /* most users will have one or two entries */
-static int local_rights = -1; /* index of entry for local socket, -1 if none */
+static TAILQ_HEAD(rights_q, monitor_rights) rights = TAILQ_HEAD_INITIALIZER(rights);
+
+static struct monitor_rights * local_rights = NULL; /* entry for local socket */
/* for each active monitor connection we have one of this: */
+
struct monitor_connection {
+ TAILQ_ENTRY(monitor_connection) connections;
int sock; /* socket for this connection */
int rights; /* active rights for this connection */
int events; /* bitmask of events client is interested in */
+ char source[FILENAME_MAX];
};
-static VARA_DECL(struct monitor_connection) connections = VARA_INITIALIZER;
-#define INITIAL_CONNECTIONS_ALLOC 30 /* high guess */
-/* derive channel number from config pointer */
-#define CHNO(cfgp) (((cfgp)->isdncontrollerused*2) + (cfgp)->isdnchannelused)
+static TAILQ_HEAD(connections_tq, monitor_connection) connections = TAILQ_HEAD_INITIALIZER(connections);
/* local prototypes */
-static int cmp_rights(const void *a, const void *b);
-static int monitor_command(int con_index, int fd, int rights);
-static void cmd_dump_rights(int fd, int rights, BYTE *cmd);
-static void cmd_dump_mcons(int fd, int rights, BYTE *cmd);
-static void cmd_reread_cfg(int fd, int rights, BYTE *cmd);
-static void cmd_hangup(int fd, int rights, BYTE *cmd);
-static void monitor_broadcast(int mask, const BYTE *pkt, size_t bytes);
+static int cmp_rights(const struct monitor_rights *pa, const struct monitor_rights *pb);
+static int monitor_command(struct monitor_connection *con, int fd, int rights);
+static void cmd_dump_rights(int fd, int rights, u_int8_t *cmd, const char * source);
+static void cmd_dump_mcons(int fd, int rights, u_int8_t *cmd, const char * source);
+static void cmd_reread_cfg(int fd, int rights, u_int8_t *cmd, const char * source);
+static void cmd_hangup(int fd, int rights, u_int8_t *cmd, const char * source);
+static void monitor_broadcast(int mask, u_int8_t *pkt, size_t bytes);
static int anybody(int mask);
+static void hangup_channel(int controller, int channel, const char *source);
+static ssize_t sock_read(int fd, void *buf, size_t nbytes);
+static ssize_t sock_write(int fd, void *buf, size_t nbytes);
/*
* Due to the way we structure config files, the rights for an external
@@ -102,470 +112,716 @@ static int anybody(int mask);
* entry. When closing the sys-file section of the config file, the
* "current" entry becomes invalid.
*/
-static int cur_add_entry = -1;
+static struct monitor_rights * cur_add_entry = NULL;
-/*
+/*---------------------------------------------------------------------------
* Initialize the monitor server module. This affects only active
* connections, the access rights are not modified here!
- */
-void monitor_init()
+ *---------------------------------------------------------------------------*/
+void
+monitor_init(void)
{
+ struct monitor_connection * con;
accepted = 0;
- VARA_EMPTY(connections);
+ while ((con = TAILQ_FIRST(&connections)) != NULL)
+ {
+ TAILQ_REMOVE(&connections, con, connections);
+ free(con);
+ }
}
-/*
+/*---------------------------------------------------------------------------
* Prepare for exit
- */
-void monitor_exit()
+ *---------------------------------------------------------------------------*/
+void
+monitor_exit(void)
{
- int i;
+ struct monitor_connection *c;
/* Close all open connections. */
- VARA_FOREACH(connections, i)
- close(VARA_AT(connections, i).sock);
-
- /* Remove their descriptions */
- VARA_EMPTY(connections);
+ while((c = TAILQ_FIRST(&connections)) != NULL) {
+ close(c->sock);
+ TAILQ_REMOVE(&connections, c, connections);
+ free(c);
+ }
}
-/*
+/*---------------------------------------------------------------------------
* Initialize access rights. No active connections are affected!
- */
-void monitor_clear_rights()
+ *---------------------------------------------------------------------------*/
+void
+monitor_clear_rights(void)
{
- VARA_EMPTY(rights);
- cur_add_entry = -1;
+ struct monitor_rights *r;
+ while ((r = TAILQ_FIRST(&rights)) != NULL) {
+ TAILQ_REMOVE(&rights, r, list);
+ free(r);
+ }
+ cur_add_entry = NULL;
+ local_rights = NULL;
}
-/*
+/*---------------------------------------------------------------------------
* Add an entry to the access lists. The clientspec either is
* the name of the local socket or a host- or networkname or
* numeric ip/host-bit-len spec.
- */
-int monitor_start_rights(const char *clientspec)
+ *---------------------------------------------------------------------------*/
+int
+monitor_start_rights(const char *clientspec)
{
- int i;
struct monitor_rights r;
/* initialize the new rights entry */
+
memset(&r, 0, sizeof r);
/* check clientspec */
- if (*clientspec == '/') {
+
+ if (*clientspec == '/')
+ {
struct sockaddr_un sa;
/* this is a local socket spec, check if we already have one */
- if (VARA_VALID(rights, local_rights))
+
+ if (local_rights != NULL)
return I4BMAR_DUP;
+
/* does it fit in a local socket address? */
+
if (strlen(clientspec) > sizeof sa.sun_path)
return I4BMAR_LENGTH;
+
r.local = 1;
strcpy(r.name, clientspec);
+
#ifndef I4B_NOTCPIP_MONITOR
- } else {
+
+ }
+ else
+ {
/* remote entry, parse host/net and cidr */
+
+ struct monitor_rights * rp;
char hostname[FILENAME_MAX];
char *p;
+
p = strchr(clientspec, '/');
- if (!p) {
+
+ if (!p)
+ {
struct hostent *host;
u_int32_t hn;
+
/* must be a host spec */
+
r.mask = ~0;
host = gethostbyname(clientspec);
+
if (!host)
return I4BMAR_NOIP;
+
memcpy(&hn, host->h_addr_list[0], sizeof hn);
r.net = (u_int32_t)ntohl(hn);
- } else if (p[1]) {
+ }
+ else if(p[1])
+ {
/* must be net/cidr spec */
+
int l;
struct netent *net;
u_int32_t s = ~0U;
int num = strtol(p+1, NULL, 10);
+
if (num < 0 || num > 32)
return I4BMAR_CIDR;
+
s >>= num;
s ^= ~0U;
l = p - clientspec;
+
if (l >= sizeof hostname)
return I4BMAR_LENGTH;
+
strncpy(hostname, clientspec, l);
+
hostname[l] = '\0';
+
net = getnetbyname(hostname);
+
if (net == NULL)
r.net = (u_int32_t)inet_network(hostname);
else
r.net = (u_int32_t)net->n_net;
+
r.mask = s;
r.net &= s;
- } else
+ }
+ else
+ {
return I4BMAR_CIDR;
+ }
/* check for duplicate entry */
- VARA_FOREACH(rights, i)
- if (VARA_AT(rights, i).mask == r.mask &&
- VARA_AT(rights, i).net == r.net &&
- VARA_AT(rights, i).local == r.local)
+
+ for (rp = TAILQ_FIRST(&rights); rp != NULL; rp = TAILQ_NEXT(rp, list))
+ {
+ if (rp->mask == r.mask &&
+ rp->net == r.net &&
+ rp->local == r.local)
+ {
return I4BMAR_DUP;
+ }
+ }
#endif
}
+
r.rights = 0;
/* entry ok, add it to the collection */
- cur_add_entry = i = VARA_NUM(rights);
- VARA_ADD_AT(rights, i, struct monitor_rights, INITIAL_RIGHTS_ALLOC);
- memcpy(&VARA_AT(rights, i), &r, sizeof r);
- if (r.local)
- local_rights = i;
+
+ cur_add_entry = malloc(sizeof(r));
+ memcpy(cur_add_entry, &r, sizeof(r));
+ TAILQ_INSERT_TAIL(&rights, cur_add_entry, list);
+
+ if(r.local)
+ local_rights = cur_add_entry;
DBGL(DL_RCCF, (log(LL_DBG, "system: monitor = %s", clientspec)));
return I4BMAR_OK;
}
-/*
+/*---------------------------------------------------------------------------
* Add rights to the currently constructed entry - if any.
- */
-void monitor_add_rights(int rights_mask)
+ *---------------------------------------------------------------------------*/
+void
+monitor_add_rights(int rights_mask)
{
- if (cur_add_entry < 0) return; /* noone under construction */
+ if(cur_add_entry == NULL)
+ return; /* noone under construction */
- VARA_AT(rights, cur_add_entry).rights |= rights_mask;
+ cur_add_entry->rights |= rights_mask;
DBGL(DL_RCCF, (log(LL_DBG, "system: monitor-access = 0x%x", rights_mask)));
}
-/*
+/*---------------------------------------------------------------------------
* All rights have been added now. Sort the to get most specific
* host/net masks first, so we can travel the list and use the first
* match for actual rights.
- */
-void monitor_fixup_rights()
+ *---------------------------------------------------------------------------*/
+void
+monitor_fixup_rights(void)
{
- int i;
+ struct monitor_rights * cur, * test, * next;
/* no more rights may be added to the current entry */
- cur_add_entry = -1;
+
+ cur_add_entry = NULL;
- /* sort the rights array */
- qsort(VARA_PTR(rights), VARA_NUM(rights), sizeof(struct monitor_rights), cmp_rights);
-
- /* now the local entry may have moved, update its index */
- if (VARA_VALID(rights, local_rights)) {
- local_rights = -1;
- VARA_FOREACH(rights, i) {
- if (VARA_AT(rights, i).local) {
- local_rights = i;
+ /* sort the rights */
+ for (next = NULL, cur = TAILQ_FIRST(&rights); cur != NULL; cur = next)
+ {
+ next = TAILQ_NEXT(cur, list);
+ for (test = TAILQ_FIRST(&rights); test != NULL && test != cur; test = TAILQ_NEXT(test, list))
+ {
+ if (cmp_rights(cur, test) > 0) {
+ /* move cur up the list and insert before test */
+ TAILQ_REMOVE(&rights, cur, list);
+ if (test == TAILQ_FIRST(&rights))
+ TAILQ_INSERT_HEAD(&rights, cur, list);
+ else
+ TAILQ_INSERT_BEFORE(test, cur, list);
break;
}
}
- }
+ }
}
-/* comparator for rights */
-static int cmp_rights(const void *a, const void *b)
+/*---------------------------------------------------------------------------
+ * comparator for rights
+ *---------------------------------------------------------------------------*/
+static int
+cmp_rights(const struct monitor_rights *pa, const struct monitor_rights *pb)
{
u_int32_t mask;
- struct monitor_rights const * pa = (struct monitor_rights const*)a;
- struct monitor_rights const * pb = (struct monitor_rights const*)b;
/* local sorts first */
+
if (pa->local)
return -1;
/* which is the less specific netmask? */
+
mask = pa->mask;
+
if ((pb->mask & mask) == 0)
mask = pb->mask;
+
/* are the entries disjunct? */
- if ((pa->net & mask) != (pb->net & mask)) {
+
+ if ((pa->net & mask) != (pb->net & mask))
+ {
/* simply compare net part of address */
return ((pa->net & mask) < (pb->net & mask)) ? -1 : 1;
}
+
/* One entry is part of the others net. We already now "mask" is
* the netmask of the less specific (i.e. greater) one */
+
return (pa->mask == mask) ? 1 : -1;
}
#ifndef I4B_NOTCPIP_MONITOR
-/*
+/*---------------------------------------------------------------------------
* Check if access rights for a remote socket are specified and
* create this socket. Return -1 otherwise.
- */
-int monitor_create_remote_socket(int portno)
+ *---------------------------------------------------------------------------*/
+int
+monitor_create_remote_socket(int portno)
{
struct sockaddr_in sa;
int val;
- int remotesockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (remotesockfd == -1) {
- log(LL_ERR, "could not create remote monitor socket, errno = %d", errno);
- exit(1);
+ int remotesockfd;
+
+ remotesockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+ if(remotesockfd == -1)
+ {
+ log(LL_MER, "could not create remote monitor socket: %s", strerror(errno));
+ return(-1);
}
+
val = 1;
- if (setsockopt(remotesockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val)) {
- log(LL_ERR, "could not setsockopt, errno = %d", errno);
- exit(1);
+
+ if(setsockopt(remotesockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val))
+ {
+ log(LL_MER, "could not setsockopt: %s", strerror(errno));
+ return(-1);
}
+
memset(&sa, 0, sizeof sa);
sa.sin_len = sizeof sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(portno);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(remotesockfd, (struct sockaddr *)&sa, sizeof sa) == -1) {
- log(LL_ERR, "could not bind remote monitor socket to port %d, errno = %d", portno, errno);
- exit(1);
+
+ if(bind(remotesockfd, (struct sockaddr *)&sa, sizeof sa) == -1)
+ {
+ log(LL_MER, "could not bind remote monitor socket to port %d: %s", portno, strerror(errno));
+ return(-1);
}
- if (listen(remotesockfd, 0)) {
- log(LL_ERR, "could not listen on monitor socket, errno = %d", errno);
- exit(1);
+
+ if(listen(remotesockfd, 0))
+ {
+ log(LL_MER, "could not listen on monitor socket: %s", strerror(errno));
+ return(-1);
}
- return remotesockfd;
+ return(remotesockfd);
}
#endif
-/*
+/*---------------------------------------------------------------------------
* Check if access rights for a local socket are specified and
* create this socket. Return -1 otherwise.
- */
-int monitor_create_local_socket()
+ *---------------------------------------------------------------------------*/
+int
+monitor_create_local_socket(void)
{
int s;
struct sockaddr_un sa;
/* check for a local entry */
- if (!VARA_VALID(rights, local_rights))
- return -1;
+
+ if (local_rights == NULL)
+ return(-1);
/* create and setup socket */
+
s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s == -1) {
- log(LL_ERR, "could not create local monitor socket, errno = %d", errno);
- exit(1);
+
+ if (s == -1)
+ {
+ log(LL_MER, "could not create local monitor socket, errno = %d", errno);
+ return(-1);
}
- unlink(VARA_AT(rights, local_rights).name);
+
+ unlink(local_rights->name);
+
memset(&sa, 0, sizeof sa);
sa.sun_len = sizeof sa;
sa.sun_family = AF_LOCAL;
- strcpy(sa.sun_path, VARA_AT(rights, local_rights).name);
- if (bind(s, (struct sockaddr *)&sa, SUN_LEN(&sa))) {
- log(LL_ERR, "could not bind local monitor socket [%s], errno = %d", VARA_AT(rights, local_rights).name, errno);
- exit(1);
+ strcpy(sa.sun_path, local_rights->name);
+
+ if (bind(s, (struct sockaddr *)&sa, SUN_LEN(&sa)))
+ {
+ log(LL_MER, "could not bind local monitor socket [%s], errno = %d", local_rights->name, errno);
+ return(-1);
}
- chmod(VARA_AT(rights, local_rights).name, 0500);
- if (listen(s, 0)) {
- log(LL_ERR, "could not listen on local monitor socket, errno = %d", errno);
- exit(1);
+
+ chmod(local_rights->name, 0500);
+
+ if (listen(s, 0))
+ {
+ log(LL_MER, "could not listen on local monitor socket, errno = %d", errno);
+ return(-1);
}
- return s;
+ return(s);
}
-/*
+/*---------------------------------------------------------------------------
* Prepare a fd_set for a select call. Add all our local
* filedescriptors to the set, increment max_fd if appropriate.
- */
-void monitor_prepselect(fd_set *selset, int *max_fd)
+ *---------------------------------------------------------------------------*/
+void
+monitor_prepselect(fd_set *selset, int *max_fd)
{
- int i;
+ struct monitor_connection * con;
+
+ for (con = TAILQ_FIRST(&connections); con != NULL; con = TAILQ_NEXT(con, connections))
+ {
+ int fd = con->sock;
- VARA_FOREACH(connections, i) {
- int fd = VARA_AT(connections, i).sock;
if (fd > *max_fd)
*max_fd = fd;
+
FD_SET(fd, selset);
}
}
-/*
+/*---------------------------------------------------------------------------
* Check if the result from a select call indicates something
* to do for us.
- */
-void monitor_handle_input(fd_set *selset)
+ *---------------------------------------------------------------------------*/
+void
+monitor_handle_input(fd_set *selset)
{
- int i;
+ struct monitor_connection * con, * next;
+
+ for (next = NULL, con = TAILQ_FIRST(&connections); con != NULL; con = next)
+ {
+ int fd = con->sock;
+ next = TAILQ_NEXT(con, connections);
- VARA_FOREACH(connections, i) {
- int fd = VARA_AT(connections, i).sock;
- if (FD_ISSET(fd, selset)) {
+ if (FD_ISSET(fd, selset))
+ {
/* handle command from this client */
- if (monitor_command(i, fd, VARA_AT(connections, i).rights) != 0) {
+
+ if (monitor_command(con, fd, con->rights) != 0)
+ {
/* broken or closed connection */
- log(LL_DBG, "monitor connection #%d closed", i);
- VARA_REMOVEAT(connections, i);
- i--;
+
+ char source[FILENAME_MAX];
+
+ strcpy(source, con->source);
+ TAILQ_REMOVE(&connections, con, connections);
+ free(con);
+ log(LL_DMN, "monitor closed from %s", source );
}
}
}
/* all connections gone? */
- if (VARA_NUM(connections) == 0)
+
+ if (TAILQ_FIRST(&connections) == NULL)
accepted = 0;
}
-/*
+/*---------------------------------------------------------------------------
* Try new incoming connection on the given socket.
* Setup client descriptor and send initial data.
- */
-void monitor_handle_connect(int sockfd, int is_local)
+ *---------------------------------------------------------------------------*/
+void
+monitor_handle_connect(int sockfd, int is_local)
{
struct monitor_connection *con;
+ struct monitor_rights *rp;
+
#ifndef I4B_NOTCPIP_MONITOR
struct sockaddr_in ia;
u_int32_t ha = 0;
#endif
+
struct sockaddr_un ua;
- BYTE idata[I4B_MON_IDATA_SIZE];
- int fd = -1, s, i, r_mask;
+ u_int8_t idata[I4B_MON_IDATA_SIZE];
+ int fd = -1, s, i, r_mask, t_events;
char source[FILENAME_MAX];
/* accept the connection */
- if (is_local) {
+
+ if(is_local)
+ {
s = sizeof ua;
fd = accept(sockfd, (struct sockaddr *)&ua, &s);
- strcpy(source, "local connection");
+ strcpy(source, "local");
+
#ifndef I4B_NOTCPIP_MONITOR
- } else {
+ }
+ else
+ {
+ struct hostent *hp;
+
s = sizeof ia;
fd = accept(sockfd, (struct sockaddr *)&ia, &s);
- snprintf(source, sizeof source, "tcp/ip connection from %s\n",
- inet_ntoa(ia.sin_addr));
+
+ hp = gethostbyaddr((char *)&ia.sin_addr, 4, AF_INET);
+
+ if(hp == NULL)
+ snprintf(source, sizeof source, "%s (%s)", inet_ntoa(ia.sin_addr), inet_ntoa(ia.sin_addr));
+ else
+ snprintf(source, sizeof source, "%s (%s)", hp->h_name, inet_ntoa(ia.sin_addr));
+
memcpy(&ha, &ia.sin_addr.s_addr, sizeof ha);
+
ha = ntohl(ha);
#endif
}
/* check the access rights of this connection */
+
r_mask = 0;
- VARA_FOREACH(rights, i) {
- struct monitor_rights *r = &VARA_AT(rights, i);
- if (r->local) {
- if (is_local) {
- r_mask = r->rights;
+
+ for (rp = TAILQ_FIRST(&rights); rp != NULL; rp = TAILQ_NEXT(rp, list))
+ {
+ if(rp->local)
+ {
+ if(is_local)
+ {
+ r_mask = rp->rights;
break;
}
+
#ifndef I4B_NOTCPIP_MONITOR
- } else {
- if ((ha & r->mask) == r->net) {
- r_mask = r->rights;
+ }
+ else
+ {
+ if((ha & rp->mask) == rp->net)
+ {
+ r_mask = rp->rights;
break;
}
#endif
}
}
- if (r_mask == 0) {
+ if(r_mask == 0)
+ {
/* no rights - go away */
- log(LL_DBG, "monitor access denied: %s", source);
+ log(LL_MER, "monitor access denied from %s", source);
close(fd);
return;
}
accepted = 1;
- i = VARA_NUM(connections);
- VARA_ADD_AT(connections, i, struct monitor_connection, INITIAL_CONNECTIONS_ALLOC);
- con = &VARA_AT(connections, i);
+
+ con = malloc(sizeof(struct monitor_connection));
memset(con, 0, sizeof *con);
+ TAILQ_INSERT_TAIL(&connections, con, connections);
con->sock = fd;
con->rights = r_mask;
- log(LL_DBG, "monitor access granted, rights = %x, #%d, %s",
- r_mask, i, source);
+ strcpy(con->source, source);
+
+ log(LL_DMN, "monitor opened from %s rights 0x%x", source, r_mask);
/* send initial data */
I4B_PREP_CMD(idata, I4B_MON_IDATA_CODE);
I4B_PUT_2B(idata, I4B_MON_IDATA_VERSMAJOR, MPROT_VERSION);
I4B_PUT_2B(idata, I4B_MON_IDATA_VERSMINOR, MPROT_REL);
I4B_PUT_2B(idata, I4B_MON_IDATA_NUMCTRL, ncontroller);
+ I4B_PUT_2B(idata, I4B_MON_IDATA_NUMENTR, nentries);
I4B_PUT_4B(idata, I4B_MON_IDATA_CLACCESS, r_mask);
- write(fd, idata, sizeof idata);
- for (i = 0; i < ncontroller; i++) {
- BYTE ictrl[I4B_MON_ICTRL_SIZE];
+ if((sock_write(fd, idata, sizeof idata)) == -1)
+ {
+ log(LL_MER, "monitor_handle_connect: sock_write 1 error - %s", strerror(errno));
+ }
+
+ for (i = 0; i < ncontroller; i++)
+ {
+ u_int8_t ictrl[I4B_MON_ICTRL_SIZE];
+
I4B_PREP_CMD(ictrl, I4B_MON_ICTRL_CODE);
I4B_PUT_STR(ictrl, I4B_MON_ICTRL_NAME, name_of_controller(isdn_ctrl_tab[i].ctrl_type, isdn_ctrl_tab[i].card_type));
I4B_PUT_2B(ictrl, I4B_MON_ICTRL_BUSID, 0);
I4B_PUT_4B(ictrl, I4B_MON_ICTRL_FLAGS, 0);
I4B_PUT_4B(ictrl, I4B_MON_ICTRL_NCHAN, 2);
- write(fd, ictrl, sizeof ictrl);
+
+ if((sock_write(fd, ictrl, sizeof ictrl)) == -1)
+ {
+ log(LL_MER, "monitor_handle_connect: sock_write 2 error - %s", strerror(errno));
+ }
+
+ }
+
+ /* send device names from entries */
+
+ for(i=0; i < nentries; i++) /* walk thru all entries */
+ {
+ u_int8_t ictrl[I4B_MON_IDEV_SIZE];
+ cfg_entry_t *p;
+ char nbuf[64];
+ p = &cfg_entry_tab[i]; /* get ptr to enry */
+
+ sprintf(nbuf, "%s%d ", bdrivername(p->usrdevicename), p->usrdeviceunit);
+
+ I4B_PREP_CMD(ictrl, I4B_MON_IDEV_CODE);
+/*XXX*/ I4B_PUT_2B(ictrl, I4B_MON_IDEV_STATE, 1);
+ I4B_PUT_STR(ictrl, I4B_MON_IDEV_NAME, nbuf);
+
+ if((sock_write(fd, ictrl, sizeof ictrl)) == -1)
+ {
+ log(LL_MER, "monitor_handle_connect: sock_write 3 error - %s", strerror(errno));
+ }
}
+
+/*XXX*/ t_events = con->events;
+/*XXX*/ con->events = -1;
+
+ /* current state of controller(s) */
+
+ for(i=0; i < ncontroller; i++)
+ {
+ monitor_evnt_tei(i, isdn_ctrl_tab[i].tei);
+ monitor_evnt_l12stat(i, LAYER_ONE, isdn_ctrl_tab[i].l1stat);
+ monitor_evnt_l12stat(i, LAYER_TWO, isdn_ctrl_tab[i].l2stat);
+ }
+
+ /* current state of entries */
+
+ for(i=0; i < nentries; i++)
+ {
+ cfg_entry_t *cep = &cfg_entry_tab[i];
+
+ if(cep->state == ST_CONNECTED)
+ {
+ monitor_evnt_connect(cep);
+ monitor_evnt_acct(cep);
+ monitor_evnt_charge(cep, cep->charge, 1);
+ }
+ }
+
+/*XXX*/ con->events = t_events;
+
}
-/* dump all monitor rights */
-static void cmd_dump_rights(int fd, int r_mask, BYTE *cmd)
+/*---------------------------------------------------------------------------
+ * dump all monitor rights
+ *---------------------------------------------------------------------------*/
+static void
+cmd_dump_rights(int fd, int r_mask, u_int8_t *cmd, const char *source)
{
- int i;
- BYTE drini[I4B_MON_DRINI_SIZE];
- BYTE dr[I4B_MON_DR_SIZE];
+ struct monitor_rights * r;
+ int num_rights;
+ u_int8_t drini[I4B_MON_DRINI_SIZE];
+ u_int8_t dr[I4B_MON_DR_SIZE];
+
+ for (num_rights = 0, r = TAILQ_FIRST(&rights); r != NULL; r = TAILQ_NEXT(r, list))
+ num_rights++;
I4B_PREP_EVNT(drini, I4B_MON_DRINI_CODE);
- I4B_PUT_2B(drini, I4B_MON_DRINI_COUNT, VARA_NUM(rights));
- write(fd, drini, sizeof drini);
+ I4B_PUT_2B(drini, I4B_MON_DRINI_COUNT, num_rights);
- VARA_FOREACH(rights, i) {
+ if((sock_write(fd, drini, sizeof drini)) == -1)
+ {
+ log(LL_MER, "cmd_dump_rights: sock_write 1 error - %s", strerror(errno));
+ }
+
+ for (r = TAILQ_FIRST(&rights); r != NULL; r = TAILQ_NEXT(r, list))
+ {
I4B_PREP_EVNT(dr, I4B_MON_DR_CODE);
- I4B_PUT_4B(dr, I4B_MON_DR_RIGHTS, VARA_AT(rights, i).rights);
- I4B_PUT_4B(dr, I4B_MON_DR_NET, VARA_AT(rights, i).net);
- I4B_PUT_4B(dr, I4B_MON_DR_MASK, VARA_AT(rights, i).mask);
- I4B_PUT_1B(dr, I4B_MON_DR_LOCAL, VARA_AT(rights, i).local);
- write(fd, dr, sizeof dr);
+ I4B_PUT_4B(dr, I4B_MON_DR_RIGHTS, r->rights);
+ I4B_PUT_4B(dr, I4B_MON_DR_NET, r->net);
+ I4B_PUT_4B(dr, I4B_MON_DR_MASK, r->mask);
+ I4B_PUT_1B(dr, I4B_MON_DR_LOCAL, r->local);
+ if((sock_write(fd, dr, sizeof dr)) == -1)
+ {
+ log(LL_MER, "cmd_dump_rights: sock_write 2 error - %s", strerror(errno));
+ }
}
}
-/* rescan config file */
-static void cmd_reread_cfg(int fd, int rights, BYTE *cmd)
+/*---------------------------------------------------------------------------
+ * rescan config file
+ *---------------------------------------------------------------------------*/
+static void
+cmd_reread_cfg(int fd, int rights, u_int8_t *cmd, const char * source)
{
rereadconfig(42);
}
-/* drop one connection */
-static void cmd_hangup(int fd, int rights, BYTE *cmd)
+/*---------------------------------------------------------------------------
+ * drop one connection
+ *---------------------------------------------------------------------------*/
+static void
+cmd_hangup(int fd, int rights, u_int8_t *cmd, const char * source)
{
int channel = I4B_GET_4B(cmd, I4B_MON_HANGUP_CHANNEL);
- hangup_channel(channel);
+ int ctrl = I4B_GET_4B(cmd, I4B_MON_HANGUP_CTRL);
+
+ hangup_channel(ctrl, channel, source);
}
-/* dump all active monitor connections */
-static void cmd_dump_mcons(int fd, int rights, BYTE *cmd)
+/*---------------------------------------------------------------------------
+ * dump all active monitor connections
+ *---------------------------------------------------------------------------*/
+static void
+cmd_dump_mcons(int fd, int rights, u_int8_t *cmd, const char * source)
{
- int i;
- BYTE dcini[I4B_MON_DCINI_SIZE];
+ int num_connections;
+ struct monitor_connection *con;
+ u_int8_t dcini[I4B_MON_DCINI_SIZE];
+
+ for (num_connections = 0, con = TAILQ_FIRST(&connections); con != NULL; con = TAILQ_NEXT(con, connections))
+ num_connections++;
I4B_PREP_EVNT(dcini, I4B_MON_DCINI_CODE);
- I4B_PUT_2B(dcini, I4B_MON_DCINI_COUNT, VARA_NUM(connections));
- write(fd, dcini, sizeof dcini);
+ I4B_PUT_2B(dcini, I4B_MON_DCINI_COUNT, num_connections);
+
+ if((sock_write(fd, dcini, sizeof dcini)) == -1)
+ {
+ log(LL_MER, "cmd_dump_mcons: sock_write 1 error - %s", strerror(errno));
+ }
- VARA_FOREACH(connections, i) {
+ for (con = TAILQ_FIRST(&connections); con != NULL; con = TAILQ_NEXT(con, connections))
+ {
#ifndef I4B_NOTCPIP_MONITOR
int namelen;
struct sockaddr_in name;
#endif
- BYTE dc[I4B_MON_DC_SIZE];
+ u_int8_t dc[I4B_MON_DC_SIZE];
I4B_PREP_EVNT(dc, I4B_MON_DC_CODE);
- I4B_PUT_4B(dc, I4B_MON_DC_RIGHTS, VARA_AT(connections, i).rights);
+ I4B_PUT_4B(dc, I4B_MON_DC_RIGHTS, con->rights);
+
#ifndef I4B_NOTCPIP_MONITOR
namelen = sizeof name;
- if (getpeername(VARA_AT(connections, i).sock, (struct sockaddr*)&name, &namelen) == 0)
+
+ if (getpeername(con->sock, (struct sockaddr*)&name, &namelen) == 0)
memcpy(dc+I4B_MON_DC_WHO, &name.sin_addr, sizeof name.sin_addr);
#endif
- write(fd, dc, sizeof dc);
+ if((sock_write(fd, dc, sizeof dc)) == -1)
+ {
+ log(LL_MER, "cmd_dump_mcons: sock_write 2 error - %s", strerror(errno));
+ }
}
}
-/*
+/*---------------------------------------------------------------------------
* Handle a command from the given socket. The client
* has rights as specified in the rights parameter.
* Return non-zero if connection is closed.
- */
-static int monitor_command(int con_index, int fd, int rights)
+ *---------------------------------------------------------------------------*/
+static int
+monitor_command(struct monitor_connection * con, int fd, int rights)
{
char cmd[I4B_MAX_MON_CLIENT_CMD];
u_int code;
+
/* command dispatch table */
- typedef void (*cmd_func_t)(int fd, int rights, BYTE *cmd);
+ typedef void (*cmd_func_t)(int fd, int rights, u_int8_t *cmd, const char *source);
+
static struct {
cmd_func_t call; /* function to execute */
u_int rights; /* necessary rights */
@@ -584,10 +840,14 @@ static int monitor_command(int con_index, int fd, int rights)
/* Network transfer may deliver two or more packets concatenated.
* Peek at the header and read only one event at a time... */
+
ioctl(fd, FIONREAD, &u);
- if (u < I4B_MON_CMD_HDR) {
- if (u == 0) {
- log(LL_ERR, "monitor #%d, read 0 bytes", con_index);
+
+ if (u < I4B_MON_CMD_HDR)
+ {
+ if (u == 0)
+ {
+ /* log(LL_MER, "monitor read 0 bytes"); */
/* socket closed by peer */
close(fd);
return 1;
@@ -599,7 +859,7 @@ static int monitor_command(int con_index, int fd, int rights)
if (bytes < I4B_MON_CMD_HDR)
{
- log(LL_ERR, "monitor #%d, read only %d bytes", con_index, bytes);
+ log(LL_MER, "monitor read only %d bytes", bytes);
return 0; /* errh? something must be wrong... */
}
@@ -608,14 +868,15 @@ static int monitor_command(int con_index, int fd, int rights)
if (bytes >= sizeof cmd)
{
close(fd);
- log(LL_ERR, "monitor #%d, garbage on connection", con_index);
+ log(LL_MER, "monitor: garbage on connection");
return 1;
}
/* now we know the size, it fits, so lets read it! */
- if (read(fd, cmd, bytes) <= 0)
+
+ if(sock_read(fd, cmd, bytes) <= 0)
{
- log(LL_ERR, "monitor #%d, read <= 0", con_index);
+ log(LL_MER, "monitor: sock_read <= 0");
close(fd);
return 1;
}
@@ -625,72 +886,127 @@ static int monitor_command(int con_index, int fd, int rights)
/* special case: may modify our connection descriptor, is
* beyound all rights checks */
- if (code == I4B_MON_CCMD_SETMASK) {
+
+ if (code == I4B_MON_CCMD_SETMASK)
+ {
+/*XXX*/
/*
u_int major = I4B_GET_2B(cmd, I4B_MON_ICLIENT_VERMAJOR);
u_int minor = I4B_GET_2B(cmd, I4B_MON_ICLIENT_VERMINOR);
*/
+
int events = I4B_GET_4B(cmd, I4B_MON_ICLIENT_EVENTS);
- VARA_AT(connections, con_index).events = events & rights;
+ con->events = events & rights;
return 0;
}
- if (code < 0 || code >= NUMCMD) {
- log(LL_ERR, "illegal command from client #%d: code = %d\n",
- con_index, code);
+ if (code < 0 || code >= NUMCMD)
+ {
+ log(LL_MER, "illegal command from client, code = %d\n",
+ code);
return 0;
}
+
if (cmd_tab[code].call == NULL)
return 0;
+
if ((cmd_tab[code].rights & rights) == cmd_tab[code].rights)
- cmd_tab[code].call(fd, rights, cmd);
+ cmd_tab[code].call(fd, rights, cmd, con->source);
return 0;
}
-/*
+/*---------------------------------------------------------------------------
* Check if somebody would receive an event with this mask.
* We are lazy and try to avoid assembling unneccesary packets.
* Return 0 if no one interested, nonzero otherwise.
- */
-static int anybody(int mask)
+ *---------------------------------------------------------------------------*/
+static int
+anybody(int mask)
{
- int i;
+ struct monitor_connection * con;
- VARA_FOREACH(connections, i)
- if ((VARA_AT(connections, i).events & mask) == mask)
+ for (con = TAILQ_FIRST(&connections); con != NULL; con = TAILQ_NEXT(con, connections))
+ {
+ if ((con->events & mask) == mask)
return 1;
-
+ }
return 0;
}
-/*
+/*---------------------------------------------------------------------------
+ * exec hangup command
+ *---------------------------------------------------------------------------*/
+static void
+hangup_channel(int controller, int channel, const char *source)
+{
+ cfg_entry_t * cep = NULL;
+
+ if(controller < ncontroller)
+ {
+ if(isdn_ctrl_tab[controller].state != CTRL_UP)
+ return;
+ if(isdn_ctrl_tab[controller].stateb1 != CHAN_IDLE)
+ {
+ cep = get_cep_by_cc(controller, 0);
+ if (cep != NULL && cep->isdnchannelused == channel &&
+ cep->isdncontrollerused == controller)
+ goto found;
+ }
+ if(isdn_ctrl_tab[controller].stateb2 != CHAN_IDLE)
+ {
+ cep = get_cep_by_cc(controller, 1);
+ if (cep != NULL && cep->isdnchannelused == channel &&
+ cep->isdncontrollerused == controller)
+ goto found;
+ }
+ }
+ /* not found */
+ return;
+
+found:
+ log(LL_CHD, "%05d %s manual disconnect (remote from %s)", cep->cdid, cep->name, source);
+ cep->hangup = 1;
+ return;
+}
+
+/*---------------------------------------------------------------------------
* Send an event to every connection interested in this kind of
* event
- */
-static void monitor_broadcast(int mask, const BYTE *pkt, size_t bytes)
+ *---------------------------------------------------------------------------*/
+static void
+monitor_broadcast(int mask, u_int8_t *pkt, size_t bytes)
{
- int i;
+ struct monitor_connection *con;
- VARA_FOREACH(connections, i) {
- if ((VARA_AT(connections, i).events & mask) == mask) {
- int fd = VARA_AT(connections, i).sock;
- write(fd, pkt, bytes);
+ for (con = TAILQ_FIRST(&connections); con != NULL; con = TAILQ_NEXT(con, connections))
+ {
+ if ((con->events & mask) == mask)
+ {
+ int fd = con->sock;
+
+ if((sock_write(fd, pkt, bytes)) == -1)
+ {
+ log(LL_MER, "monitor_broadcast: sock_write error - %s", strerror(errno));
+ }
}
}
}
-/*
+/*---------------------------------------------------------------------------
* Post a logfile event
- */
-void monitor_evnt_log(int prio, const char * what, const char * msg)
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_log(int prio, const char * what, const char * msg)
{
- BYTE evnt[I4B_MON_LOGEVNT_SIZE];
+ u_int8_t evnt[I4B_MON_LOGEVNT_SIZE];
time_t now;
- if (!anybody(I4B_CA_EVNT_I4B)) return;
+ if (!anybody(I4B_CA_EVNT_I4B))
+ return;
time(&now);
+
I4B_PREP_EVNT(evnt, I4B_MON_LOGEVNT_CODE);
I4B_PUT_4B(evnt, I4B_MON_LOGEVNT_TSTAMP, (long)now);
I4B_PUT_4B(evnt, I4B_MON_LOGEVNT_PRIO, prio);
@@ -700,125 +1016,274 @@ void monitor_evnt_log(int prio, const char * what, const char * msg)
monitor_broadcast(I4B_CA_EVNT_I4B, evnt, sizeof evnt);
}
-/*
+/*---------------------------------------------------------------------------
* Post a charging event on the connection described
* by the given config entry.
- */
-void monitor_evnt_charge(cfg_entry_t *cep, int units, int estimate)
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_charge(cfg_entry_t *cep, int units, int estimate)
{
- int chno = CHNO(cep);
- int mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
+ int mask;
time_t now;
- BYTE evnt[I4B_MON_CHRG_SIZE];
+ u_int8_t evnt[I4B_MON_CHRG_SIZE];
+
+ mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
- if (!anybody(mask)) return;
+ if(!anybody(mask))
+ return;
time(&now);
+
I4B_PREP_EVNT(evnt, I4B_MON_CHRG_CODE);
I4B_PUT_4B(evnt, I4B_MON_CHRG_TSTAMP, (long)now);
- I4B_PUT_4B(evnt, I4B_MON_CHRG_CHANNEL, chno);
+ I4B_PUT_4B(evnt, I4B_MON_CHRG_CTRL, cep->isdncontrollerused);
+ I4B_PUT_4B(evnt, I4B_MON_CHRG_CHANNEL, cep->isdnchannelused);
I4B_PUT_4B(evnt, I4B_MON_CHRG_UNITS, units);
I4B_PUT_4B(evnt, I4B_MON_CHRG_ESTIMATED, estimate ? 1 : 0);
monitor_broadcast(mask, evnt, sizeof evnt);
}
-/*
+/*---------------------------------------------------------------------------
* Post a connection event
- */
-void monitor_evnt_connect(cfg_entry_t *cep)
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_connect(cfg_entry_t *cep)
{
- BYTE evnt[I4B_MON_CONNECT_SIZE];
+ u_int8_t evnt[I4B_MON_CONNECT_SIZE];
char devname[I4B_MAX_MON_STRING];
- int chno = CHNO(cep);
- int mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
+ int mask;
time_t now;
+
+ mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
- if (!anybody(mask)) return;
+ if (!anybody(mask))
+ return;
time(&now);
+
snprintf(devname, sizeof devname, "%s%d", bdrivername(cep->usrdevicename), cep->usrdeviceunit);
+
I4B_PREP_EVNT(evnt, I4B_MON_CONNECT_CODE);
I4B_PUT_4B(evnt, I4B_MON_CONNECT_TSTAMP, (long)now);
I4B_PUT_4B(evnt, I4B_MON_CONNECT_DIR, cep->direction == DIR_OUT ? 1 : 0);
- I4B_PUT_4B(evnt, I4B_MON_CONNECT_CHANNEL, chno);
+ I4B_PUT_4B(evnt, I4B_MON_CONNECT_CTRL, cep->isdncontrollerused);
+ I4B_PUT_4B(evnt, I4B_MON_CONNECT_CHANNEL, cep->isdnchannelused);
I4B_PUT_STR(evnt, I4B_MON_CONNECT_CFGNAME, cep->name);
I4B_PUT_STR(evnt, I4B_MON_CONNECT_DEVNAME, devname);
- I4B_PUT_STR(evnt, I4B_MON_CONNECT_REMPHONE, cep->real_phone_incoming);
- I4B_PUT_STR(evnt, I4B_MON_CONNECT_LOCPHONE, cep->remote_phone_dialout);
+ if(cep->direction == DIR_OUT)
+ {
+ I4B_PUT_STR(evnt, I4B_MON_CONNECT_REMPHONE, cep->remote_phone_dialout);
+ I4B_PUT_STR(evnt, I4B_MON_CONNECT_LOCPHONE, cep->local_phone_dialout);
+ }
+ else
+ {
+ I4B_PUT_STR(evnt, I4B_MON_CONNECT_REMPHONE, cep->real_phone_incoming);
+ I4B_PUT_STR(evnt, I4B_MON_CONNECT_LOCPHONE, cep->local_phone_incoming);
+ }
monitor_broadcast(mask, evnt, sizeof evnt);
}
-/*
+/*---------------------------------------------------------------------------
* Post a disconnect event
- */
-void monitor_evnt_disconnect(cfg_entry_t *cep)
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_disconnect(cfg_entry_t *cep)
{
- BYTE evnt[I4B_MON_DISCONNECT_SIZE];
- int chno = CHNO(cep);
- int mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
+ u_int8_t evnt[I4B_MON_DISCONNECT_SIZE];
+ int mask;
time_t now;
+
+ mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
- if (!anybody(mask)) return;
+ if (!anybody(mask))
+ return;
time(&now);
+
I4B_PREP_EVNT(evnt, I4B_MON_DISCONNECT_CODE);
I4B_PUT_4B(evnt, I4B_MON_DISCONNECT_TSTAMP, (long)now);
- I4B_PUT_4B(evnt, I4B_MON_DISCONNECT_CHANNEL, chno);
+ I4B_PUT_4B(evnt, I4B_MON_DISCONNECT_CTRL, cep->isdncontrollerused);
+ I4B_PUT_4B(evnt, I4B_MON_DISCONNECT_CHANNEL, cep->isdnchannelused);
monitor_broadcast(mask, evnt, sizeof evnt);
}
-/*
+/*---------------------------------------------------------------------------
* Post an up/down event
- */
-void monitor_evnt_updown(cfg_entry_t *cep, int up)
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_updown(cfg_entry_t *cep, int up)
{
- BYTE evnt[I4B_MON_UPDOWN_SIZE];
- int chno = CHNO(cep);
- int mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
+ u_int8_t evnt[I4B_MON_UPDOWN_SIZE];
+ int mask;
time_t now;
+
+ mask = (cep->direction == DIR_IN) ? I4B_CA_EVNT_CALLIN : I4B_CA_EVNT_CALLOUT;
- if (!anybody(mask)) return;
+ if (!anybody(mask))
+ return;
time(&now);
+
I4B_PREP_EVNT(evnt, I4B_MON_UPDOWN_CODE);
I4B_PUT_4B(evnt, I4B_MON_UPDOWN_TSTAMP, (long)now);
- I4B_PUT_4B(evnt, I4B_MON_UPDOWN_CHANNEL, chno);
+ I4B_PUT_4B(evnt, I4B_MON_UPDOWN_CTRL, cep->isdncontrollerused);
+ I4B_PUT_4B(evnt, I4B_MON_UPDOWN_CHANNEL, cep->isdnchannelused);
I4B_PUT_4B(evnt, I4B_MON_UPDOWN_ISUP, up);
monitor_broadcast(mask, evnt, sizeof evnt);
}
-void hangup_channel(int channel)
+/*---------------------------------------------------------------------------
+ * Post a Layer1/2 status change event
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_l12stat(int controller, int layer, int state)
{
- int i;
- cfg_entry_t * cep = NULL;
+ u_int8_t evnt[I4B_MON_L12STAT_SIZE];
+ time_t now;
+
+ if(!anybody(I4B_CA_EVNT_I4B))
+ return;
+
+ time(&now);
- for (i = 0; i < ncontroller; i++)
- {
- if(isdn_ctrl_tab[i].state != CTRL_UP)
- continue;
- if(isdn_ctrl_tab[i].stateb1 != CHAN_IDLE)
+ I4B_PREP_EVNT(evnt, I4B_MON_L12STAT_CODE);
+ I4B_PUT_4B(evnt, I4B_MON_L12STAT_TSTAMP, (long)now);
+ I4B_PUT_4B(evnt, I4B_MON_L12STAT_CTRL, controller);
+ I4B_PUT_4B(evnt, I4B_MON_L12STAT_LAYER, layer);
+ I4B_PUT_4B(evnt, I4B_MON_L12STAT_STATE, state);
+
+ monitor_broadcast(I4B_CA_EVNT_I4B, evnt, sizeof evnt);
+}
+
+/*---------------------------------------------------------------------------
+ * Post a TEI change event
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_tei(int controller, int tei)
+{
+ u_int8_t evnt[I4B_MON_TEI_SIZE];
+ time_t now;
+
+ if(!anybody(I4B_CA_EVNT_I4B))
+ return;
+
+ time(&now);
+
+ I4B_PREP_EVNT(evnt, I4B_MON_TEI_CODE);
+ I4B_PUT_4B(evnt, I4B_MON_TEI_TSTAMP, (long)now);
+ I4B_PUT_4B(evnt, I4B_MON_TEI_CTRL, controller);
+ I4B_PUT_4B(evnt, I4B_MON_TEI_TEI, tei);
+
+ monitor_broadcast(I4B_CA_EVNT_I4B, evnt, sizeof evnt);
+}
+
+/*---------------------------------------------------------------------------
+ * Post an accounting event
+ *---------------------------------------------------------------------------*/
+void
+monitor_evnt_acct(cfg_entry_t *cep)
+{
+ u_int8_t evnt[I4B_MON_ACCT_SIZE];
+ time_t now;
+
+ if(!anybody(I4B_CA_EVNT_I4B))
+ return;
+
+ time(&now);
+
+ I4B_PREP_EVNT(evnt, I4B_MON_ACCT_CODE);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_TSTAMP, (long)now);
+
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_CTRL, cep->isdncontrollerused);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_CHAN, cep->isdnchannelused);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_OBYTES, cep->outbytes);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_OBPS, cep->outbps);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_IBYTES, cep->inbytes);
+ I4B_PUT_4B(evnt, I4B_MON_ACCT_IBPS, cep->inbps);
+
+ monitor_broadcast(I4B_CA_EVNT_I4B, evnt, sizeof evnt);
+}
+
+/*---------------------------------------------------------------------------
+ * read from a socket
+ *---------------------------------------------------------------------------*/
+static ssize_t
+sock_read(int fd, void *buf, size_t nbytes)
+{
+ size_t nleft;
+ ssize_t nread;
+ unsigned char *ptr;
+
+ ptr = buf;
+ nleft = nbytes;
+
+ while(nleft > 0)
+ {
+ if((nread = read(fd, ptr, nleft)) < 0)
{
- cep = get_cep_by_cc(i, 0);
- if (cep != NULL && CHNO(cep) == channel)
- goto found;
+ if(errno == EINTR)
+ {
+ nread = 0;
+ }
+ else
+ {
+ return(-1);
+ }
}
- if(isdn_ctrl_tab[i].stateb2 != CHAN_IDLE)
+ else if(nread == 0)
{
- cep = get_cep_by_cc(i, 1);
- if (cep != NULL && CHNO(cep) == channel)
- goto found;
+ break; /* EOF */
}
+
+ nleft -= nread;
+ ptr += nread;
}
- /* not found */
- return;
+ return(nbytes - nleft);
+}
-found:
- cep->hangup = 1;
- return;
+/*---------------------------------------------------------------------------
+ * write to a socket
+ *---------------------------------------------------------------------------*/
+static ssize_t
+sock_write(int fd, void *buf, size_t nbytes)
+{
+ size_t nleft;
+ ssize_t nwritten;
+ unsigned char *ptr;
+
+ ptr = buf;
+ nleft = nbytes;
+
+ while(nleft > 0)
+ {
+ if((nwritten = write(fd, ptr, nleft)) <= 0)
+ {
+ if(errno == EINTR)
+ {
+ nwritten = 0;
+ }
+ else
+ {
+ return(-1);
+ }
+ }
+
+ nleft -= nwritten;
+ ptr += nwritten;
+ }
+ return(nbytes);
+}
+
+struct monitor_rights * monitor_next_rights(const struct monitor_rights *r)
+{
+ if (r == NULL)
+ return TAILQ_FIRST(&rights);
+ else
+ return TAILQ_NEXT(r, list);
}
#endif /* I4B_EXTERNAL_MONITOR */
diff --git a/usr.sbin/i4b/isdnd/msghdl.c b/usr.sbin/i4b/isdnd/msghdl.c
index 0c72ae1..265eb6e 100644
--- a/usr.sbin/i4b/isdnd/msghdl.c
+++ b/usr.sbin/i4b/isdnd/msghdl.c
@@ -27,14 +27,32 @@
* i4b daemon - message from kernel handling routines
* --------------------------------------------------
*
- * $FreeBSD$
+ * $Id: msghdl.c,v 1.71 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Mon Jul 26 13:55:57 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:47:54 1999]
*
*---------------------------------------------------------------------------*/
#include "isdnd.h"
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_types.h>
+
+#if defined(__FreeBSD__)
+#include <net/if_var.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+
/*---------------------------------------------------------------------------*
* handle incoming CONNECT_IND (=SETUP) message
*---------------------------------------------------------------------------*/
@@ -309,13 +327,40 @@ msg_alert_ind(msg_alert_ind_t *mp)
void
msg_l12stat_ind(msg_l12stat_ind_t *ml)
{
+ if((ml->controller < 0) || (ml->controller >= ncontroller))
+ {
+ log(LL_ERR, "msg_l12stat_ind: invalid controller number [%d]!", ml->controller);
+ return;
+ }
+
#ifdef USE_CURSES
if(do_fullscreen)
display_l12stat(ml->controller, ml->layer, ml->state);
#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_l12stat(ml->controller, ml->layer, ml->state);
+#endif
DBGL(DL_CNST, (log(LL_DBG, "msg_l12stat_ind: unit %d, layer %d, state %d",
ml->controller, ml->layer, ml->state)));
+
+ if(ml->layer == LAYER_ONE)
+ {
+ if(ml->state == LAYER_IDLE)
+ isdn_ctrl_tab[ml->controller].l2stat = ml->state;
+ isdn_ctrl_tab[ml->controller].l1stat = ml->state;
+ }
+ else if(ml->layer == LAYER_TWO)
+ {
+ if(ml->state == LAYER_ACTIVE)
+ isdn_ctrl_tab[ml->controller].l1stat = ml->state;
+ isdn_ctrl_tab[ml->controller].l2stat = ml->state;
+ }
+ else
+ {
+ log(LL_ERR, "msg_l12stat_ind: invalid layer number [%d]!", ml->layer);
+ }
}
/*---------------------------------------------------------------------------*
@@ -324,17 +369,29 @@ msg_l12stat_ind(msg_l12stat_ind_t *ml)
void
msg_teiasg_ind(msg_teiasg_ind_t *mt)
{
+ if((mt->controller < 0) || (mt->controller >= ncontroller))
+ {
+ log(LL_ERR, "msg_teiasg_ind: invalid controller number [%d]!", mt->controller);
+ return;
+ }
+
#ifdef USE_CURSES
if(do_fullscreen)
display_tei(mt->controller, mt->tei);
#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_tei(mt->controller, mt->tei);
+#endif
DBGL(DL_CNST, (log(LL_DBG, "msg_teiasg_ind: unit %d, tei = %d",
mt->controller, mt->tei)));
+
+ isdn_ctrl_tab[mt->controller].tei = mt->tei;
}
/*---------------------------------------------------------------------------*
- * handle incoming L12STAT_IND message
+ * handle incoming PDEACT_IND message
*---------------------------------------------------------------------------*/
void
msg_pdeact_ind(msg_pdeact_ind_t *md)
@@ -351,9 +408,21 @@ msg_pdeact_ind(msg_pdeact_ind_t *md)
display_tei(ctrl, -1);
}
#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ {
+ monitor_evnt_l12stat(ctrl, LAYER_ONE, LAYER_IDLE);
+ monitor_evnt_l12stat(ctrl, LAYER_TWO, LAYER_IDLE);
+ monitor_evnt_tei(ctrl, -1);
+ }
+#endif
DBGL(DL_CNST, (log(LL_DBG, "msg_pdeact_ind: unit %d, persistent deactivation", ctrl)));
+ isdn_ctrl_tab[ctrl].l1stat = LAYER_IDLE;
+ isdn_ctrl_tab[ctrl].l2stat = LAYER_IDLE;
+ isdn_ctrl_tab[ctrl].tei = -1;
+
for(i=0; i < nentries; i++)
{
if((cfg_entry_tab[i].cdid != CDID_UNUSED) &&
@@ -363,6 +432,7 @@ msg_pdeact_ind(msg_pdeact_ind_t *md)
if(cep->cdid == CDID_RESERVED)
{
+ cep->state = ST_IDLE;
cep->cdid = CDID_UNUSED;
continue;
}
@@ -392,11 +462,11 @@ msg_pdeact_ind(msg_pdeact_ind_t *md)
if(do_fullscreen && (cep->connect_time > 0))
display_disconnect(cep);
#endif
-
#ifdef I4B_EXTERNAL_MONITOR
if(do_monitor && accepted)
monitor_evnt_disconnect(cep);
#endif
+
if(cep->disconnectprog)
exec_connect_prog(cep, cep->disconnectprog, 1);
@@ -444,7 +514,7 @@ msg_pdeact_ind(msg_pdeact_ind_t *md)
tp = localtime(&cep->connect_time);
- strftime(logdatetime,40,I4B_TIME_FORMAT,tp);
+ strftime(logdatetime,40,I4B_TIME_FORMAT,tp);
if(cep->inbytes != INVALID && cep->outbytes != INVALID)
{
@@ -469,6 +539,8 @@ msg_pdeact_ind(msg_pdeact_ind_t *md)
incr_free_channels(cep->isdncontrollerused);
cep->connect_time = 0;
+
+ cep->state = ST_IDLE;
}
}
}
@@ -562,7 +634,6 @@ msg_disconnect_ind(msg_disconnect_ind_t *mp)
if(do_fullscreen && (cep->connect_time > 0))
display_disconnect(cep);
#endif
-
#ifdef I4B_EXTERNAL_MONITOR
if(do_monitor && accepted)
monitor_evnt_disconnect(cep);
@@ -756,14 +827,10 @@ msg_accounting(msg_accounting_ind_t *mp)
if(do_fullscreen)
display_acct(cep);
#endif
-#ifdef NOTDEF
- else
- DBGL(DL_DRVR, (log(LL_DBG, "msg_accounting: %s%d, ioutb=%d, iinb=%d, outb=%d, inb=%d, outbps=%d, inbps=%d",
- bdrivername(mp->driver), mp->driver_unit,
- mp->ioutbytes, mp->iinbytes,
- mp->outbytes, mp->inbytes,
- mp->outbps, mp->inbps)));
-#endif
+#ifdef I4B_EXTERNAL_MONITOR
+ if(do_monitor && accepted)
+ monitor_evnt_acct(cep);
+#endif
}
}
@@ -790,17 +857,17 @@ msg_charging_ind(msg_charging_ind_t *mp)
if(mp->units_type < CHARGE_INVALID || mp->units_type > CHARGE_CALC)
{
log(LL_ERR, "msg_charging: units_type %d out of range!", mp->units_type);
- do_exit(1);
+ error_exit(1, "msg_charging: units_type %d out of range!", mp->units_type);
}
DBGL(DL_DRVR, (log(LL_DBG, "msg_charging: %d unit(s) (%s)",
mp->units, cttab[mp->units_type])));
+ cep->charge = mp->units;
+
switch(mp->units_type)
{
case CHARGE_AOCD:
- cep->charge = mp->units;
-
if((cep->unitlengthsrc == ULSRC_DYN) &&
(cep->charge != cep->last_charge))
{
@@ -808,13 +875,8 @@ msg_charging_ind(msg_charging_ind_t *mp)
handle_charge(cep);
}
break;
-
- case CHARGE_AOCE:
- cep->charge = mp->units;
- break;
case CHARGE_CALC:
- cep->charge = mp->units;
#ifdef USE_CURSES
if(do_fullscreen)
display_ccharge(cep, mp->units);
@@ -849,6 +911,106 @@ msg_idle_timeout_ind(msg_idle_timeout_ind_t *mp)
}
/*---------------------------------------------------------------------------*
+ * handle incoming MSG_PACKET_IND message
+ *---------------------------------------------------------------------------*/
+static char *
+strapp(char *buf, const char *txt)
+{
+ while(*txt)
+ *buf++ = *txt++;
+ *buf = '\0';
+ return buf;
+}
+
+static char *
+ipapp(char *buf, unsigned long a )
+{
+ unsigned long ma = ntohl( a );
+
+ buf += sprintf(buf, "%lu.%lu.%lu.%lu",
+ (ma>>24)&0xFF,
+ (ma>>16)&0xFF,
+ (ma>>8)&0xFF,
+ (ma)&0xFF);
+ return buf;
+}
+
+void
+msg_packet_ind(msg_packet_ind_t *mp)
+{
+ cfg_entry_t *cep;
+ struct ip *ip;
+ u_char *proto_hdr;
+ char tmp[80];
+ char *cptr = tmp;
+ char *name = "???";
+ int i;
+
+ for(i=0; i < nentries; i++)
+ {
+ cep = &cfg_entry_tab[i]; /* ptr to config entry */
+
+ if(cep->usrdevicename == mp->driver &&
+ cep->usrdeviceunit == mp->driver_unit)
+ {
+ name = cep->name;
+ break;
+ }
+ }
+
+ ip = (struct ip*)mp->pktdata;
+ proto_hdr = mp->pktdata + ((ip->ip_hl)<<2);
+
+ if( ip->ip_p == IPPROTO_TCP )
+ {
+ struct tcphdr* tcp = (struct tcphdr*)proto_hdr;
+
+ cptr = strapp( cptr, "TCP " );
+ cptr = ipapp( cptr, ip->ip_src.s_addr );
+ cptr += sprintf( cptr, ":%u -> ", ntohs( tcp->th_sport ) );
+ cptr = ipapp( cptr, ip->ip_dst.s_addr );
+ cptr += sprintf( cptr, ":%u", ntohs( tcp->th_dport ) );
+
+ if(tcp->th_flags & TH_FIN) cptr = strapp( cptr, " FIN" );
+ if(tcp->th_flags & TH_SYN) cptr = strapp( cptr, " SYN" );
+ if(tcp->th_flags & TH_RST) cptr = strapp( cptr, " RST" );
+ if(tcp->th_flags & TH_PUSH) cptr = strapp( cptr, " PUSH" );
+ if(tcp->th_flags & TH_ACK) cptr = strapp( cptr, " ACK" );
+ if(tcp->th_flags & TH_URG) cptr = strapp( cptr, " URG" );
+ }
+ else if( ip->ip_p == IPPROTO_UDP )
+ {
+ struct udphdr* udp = (struct udphdr*)proto_hdr;
+
+ cptr = strapp( cptr, "UDP " );
+ cptr = ipapp( cptr, ip->ip_src.s_addr );
+ cptr += sprintf( cptr, ":%u -> ", ntohs( udp->uh_sport ) );
+ cptr = ipapp( cptr, ip->ip_dst.s_addr );
+ cptr += sprintf( cptr, ":%u", ntohs( udp->uh_dport ) );
+ }
+ else if( ip->ip_p == IPPROTO_ICMP )
+ {
+ struct icmp* icmp = (struct icmp*)proto_hdr;
+
+ cptr += sprintf( cptr, "ICMP:%u.%u", icmp->icmp_type, icmp->icmp_code);
+ cptr = ipapp( cptr, ip->ip_src.s_addr );
+ cptr = strapp( cptr, " -> " );
+ cptr = ipapp( cptr, ip->ip_dst.s_addr );
+ }
+ else
+ {
+ cptr += sprintf( cptr, "PROTO=%u ", ip->ip_p);
+ cptr = ipapp( cptr, ip->ip_src.s_addr);
+ cptr = strapp( cptr, " -> " );
+ cptr = ipapp( cptr, ip->ip_dst.s_addr);
+ }
+
+ log(LL_PKT, "%s %s %u %s",
+ name, mp->direction ? "send" : "recv",
+ ntohs( ip->ip_len ), tmp );
+}
+
+/*---------------------------------------------------------------------------*
* get a cdid from kernel
*---------------------------------------------------------------------------*/
int
@@ -861,7 +1023,7 @@ get_cdid(void)
if((ioctl(isdnfd, I4B_CDID_REQ, &mcr)) < 0)
{
log(LL_ERR, "get_cdid: ioctl I4B_CDID_REQ failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "get_cdid: ioctl I4B_CDID_REQ failed: %s", strerror(errno));
}
return(mcr.cdid);
@@ -913,7 +1075,7 @@ sendm_connect_req(cfg_entry_t *cep)
if((ret = ioctl(isdnfd, I4B_CONNECT_REQ, &mcr)) < 0)
{
log(LL_ERR, "sendm_connect_req: ioctl I4B_CONNECT_REQ failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "sendm_connect_req: ioctl I4B_CONNECT_REQ failed: %s", strerror(errno));
}
decr_free_channels(cep->isdncontrollerused);
@@ -961,7 +1123,7 @@ sendm_connect_resp(cfg_entry_t *cep, int cdid, int response, int cause)
if((ret = ioctl(isdnfd, I4B_CONNECT_RESP, &mcr)) < 0)
{
log(LL_ERR, "sendm_connect_resp: ioctl I4B_CONNECT_RESP failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "sendm_connect_resp: ioctl I4B_CONNECT_RESP failed: %s", strerror(errno));
}
DBGL(DL_DRVR, (log(LL_DBG, "sendm_connect_resp: sent CONNECT_RESP")));
@@ -976,7 +1138,7 @@ int
sendm_disconnect_req(cfg_entry_t *cep, int cause)
{
msg_discon_req_t mcr;
- int ret;
+ int ret = 0;
mcr.cdid = cep->cdid;
@@ -987,7 +1149,6 @@ sendm_disconnect_req(cfg_entry_t *cep, int cause)
if((ret = ioctl(isdnfd, I4B_DISCONNECT_REQ, &mcr)) < 0)
{
log(LL_ERR, "sendm_disconnect_req: ioctl I4B_DISCONNECT_REQ failed: %s", strerror(errno));
- do_exit(1);
}
else
{
@@ -1010,7 +1171,7 @@ sendm_alert_req(cfg_entry_t *cep)
if((ret = ioctl(isdnfd, I4B_ALERT_REQ, &mar)) < 0)
{
log(LL_ERR, "sendm_alert_req: ioctl I4B_ALERT_REQ failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "sendm_alert_req: ioctl I4B_ALERT_REQ failed: %s", strerror(errno));
}
else
{
diff --git a/usr.sbin/i4b/isdnd/pathnames.h b/usr.sbin/i4b/isdnd/pathnames.h
index b1d85a5..eaabf14 100644
--- a/usr.sbin/i4b/isdnd/pathnames.h
+++ b/usr.sbin/i4b/isdnd/pathnames.h
@@ -27,9 +27,11 @@
* i4b daemon - location of files
* ------------------------------
*
- * $FreeBSD$
+ * $Id: pathnames.h,v 1.10 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Thu Apr 29 09:07:29 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:48:01 1999]
*
*---------------------------------------------------------------------------*/
@@ -44,8 +46,6 @@
#define TINA_FILE_DEF "/etc/isdn/tinainitprog"
-#define LIBDIR "/usr/local/lib/isdn"
-
#define LOG_FILE_DEF "/var/log/isdnd.log"
#ifdef __bsdi__
#define ACCT_FILE_DEF "/var/log/isdnd.acct"
diff --git a/usr.sbin/i4b/isdnd/pcause.c b/usr.sbin/i4b/isdnd/pcause.c
index a6b016a..d31c56e 100644
--- a/usr.sbin/i4b/isdnd/pcause.c
+++ b/usr.sbin/i4b/isdnd/pcause.c
@@ -27,9 +27,11 @@
* printing cause values
* ---------------------
*
+ * $Id: pcause.c,v 1.12 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:11:49 1999]
+ * last edit-date: [Mon Dec 13 21:48:07 1999]
*
*---------------------------------------------------------------------------*/
@@ -78,6 +80,7 @@ static char *cause_i4b_tab[CAUSE_I4B_MAX+1] = {
"destination out of order",
"temporary failure",
"layer 1 error / persistent deactivation",
+ "dialing impossible on leased line",
"ERROR, invalid I4B cause value!"
};
diff --git a/usr.sbin/i4b/isdnd/process.c b/usr.sbin/i4b/isdnd/process.c
index 67747ea..f546043 100644
--- a/usr.sbin/i4b/isdnd/process.c
+++ b/usr.sbin/i4b/isdnd/process.c
@@ -27,11 +27,11 @@
* i4b daemon - process handling routines
* --------------------------------------
*
- * $FreeBSD$
+ * $Id: process.c,v 1.8 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:11:54 1999]
+ * $FreeBSD$
*
- * -hm debugging processhandling
+ * last edit-date: [Mon Dec 13 21:48:19 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnd/rates.c b/usr.sbin/i4b/isdnd/rates.c
index 20fd961..2765373 100644
--- a/usr.sbin/i4b/isdnd/rates.c
+++ b/usr.sbin/i4b/isdnd/rates.c
@@ -35,9 +35,11 @@
* i4b daemon - charging rates description file handling
* -----------------------------------------------------
*
- * $FreeBSD$
+ * $Id: rates.c,v 1.10 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:12:01 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:48:31 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnd/rc_config.c b/usr.sbin/i4b/isdnd/rc_config.c
index 1ab383a..9968d21 100644
--- a/usr.sbin/i4b/isdnd/rc_config.c
+++ b/usr.sbin/i4b/isdnd/rc_config.c
@@ -27,9 +27,11 @@
* i4b daemon - config file processing
* -----------------------------------
*
- * $FreeBSD$
+ * $Id: rc_config.c,v 1.49 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Thu May 20 14:11:26 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:48:38 1999]
*
*---------------------------------------------------------------------------*/
@@ -42,9 +44,9 @@
#include "y.tab.h"
#include "monitor.h"
-#include "vararray.h"
extern int entrycount;
+extern int controllercount;
extern int lineno;
extern char *yytext;
@@ -125,6 +127,9 @@ set_config_defaults(void)
nregprog = nregexpr = 0;
rt_prio = RTPRIO_NOTUSED;
+
+ mailer[0] = '\0';
+ mailto[0] = '\0';
/* clean regular expression table */
@@ -143,6 +148,16 @@ set_config_defaults(void)
strcpy(rotatesuffix, "");
+ /*
+ * controller table cleanup, beware: has already
+ * been setup in main, init_controller() !
+ */
+
+ for(i=0; i < ncontroller; i++)
+ {
+ isdn_ctrl_tab[i].protocol = PROTOCOL_DSS1;
+ }
+
/* entry section cleanup */
for(i=0; i < CFG_ENTRY_MAX; i++, cep++)
@@ -198,6 +213,17 @@ set_config_defaults(void)
}
/*---------------------------------------------------------------------------*
+ * internaly set values for ommitted controler sectin
+ *---------------------------------------------------------------------------*/
+void
+cfg_set_controller_default()
+{
+ controllercount = 0;
+ DBGL(DL_RCCF, (log(LL_DBG, "[defaults, no controller section] controller %d: protocol = dss1", controllercount)));
+ isdn_ctrl_tab[controllercount].protocol = PROTOCOL_DSS1;
+}
+
+/*---------------------------------------------------------------------------*
* extract values from config and fill table
*---------------------------------------------------------------------------*/
void
@@ -458,6 +484,16 @@ cfg_setval(int keyword)
strcpy(cfg_entry_tab[entrycount].local_phone_incoming, yylval.str);
break;
+ case MAILER:
+ strcpy(mailer, yylval.str);
+ DBGL(DL_RCCF, (log(LL_DBG, "system: mailer = %s", yylval.str)));
+ break;
+
+ case MAILTO:
+ strcpy(mailto, yylval.str);
+ DBGL(DL_RCCF, (log(LL_DBG, "system: mailto = %s", yylval.str)));
+ break;
+
case MONITORPORT:
monitorport = yylval.num;
DBGL(DL_RCCF, (log(LL_DBG, "system: monitorport = %d", yylval.num)));
@@ -481,6 +517,19 @@ cfg_setval(int keyword)
strcpy(cfg_entry_tab[entrycount].name, yylval.str);
break;
+ case PROTOCOL:
+ DBGL(DL_RCCF, (log(LL_DBG, "controller %d: protocol = %s", controllercount, yylval.str)));
+ if(!(strcmp(yylval.str, "dss1")))
+ isdn_ctrl_tab[controllercount].protocol = PROTOCOL_DSS1;
+ else if(!(strcmp(yylval.str, "d64s")))
+ isdn_ctrl_tab[controllercount].protocol = PROTOCOL_D64S;
+ else
+ {
+ log(LL_ERR, "ERROR parsing config file: unknown parameter for keyword \"protocol\" at line %d!", lineno);
+ config_error_flag++;
+ }
+ break;
+
case REACTION:
DBGL(DL_RCCF, (log(LL_DBG, "entry %d: dialin_reaction = %s", entrycount, yylval.str)));
if(!(strcmp(yylval.str, "accept")))
@@ -690,8 +739,10 @@ cfg_setval(int keyword)
cfg_entry_tab[entrycount].usrdevicename = BDRV_IPR;
else if(!strcmp(yylval.str, "isp"))
cfg_entry_tab[entrycount].usrdevicename = BDRV_ISPPP;
+#ifdef __bsdi__
else if(!strcmp(yylval.str, "ibc"))
cfg_entry_tab[entrycount].usrdevicename = BDRV_IBC;
+#endif
else
{
log(LL_ERR, "ERROR parsing config file: unknown parameter for keyword \"usrdevicename\" at line %d!", lineno);
@@ -812,9 +863,12 @@ print_config(void)
{
#define PFILE stdout
+#ifdef I4B_EXTERNAL_MONITOR
+ extern struct monitor_rights * monitor_next_rights(const struct monitor_rights *r);
+ struct monitor_rights *m_rights;
+#endif
cfg_entry_t *cep = &cfg_entry_tab[0]; /* ptr to config entry */
int i, j;
- extern VARA_DECL(struct monitor_rights) rights;
time_t clock;
char mytime[64];
@@ -857,23 +911,24 @@ print_config(void)
fprintf(PFILE, "monitor-allowed = %s\n", do_monitor ? "on\t\t\t\t# remote isdnd monitoring allowed" : "off\t\t\t\t# remote isdnd monitoring disabled");
fprintf(PFILE, "monitor-port = %d\t\t\t\t# TCP/IP port number used for remote monitoring\n", monitorport);
- if(VARA_NUM(rights))
+ m_rights = monitor_next_rights(NULL);
+ if(m_rights != NULL)
{
char *s = "error\n";
char b[512];
-
- VARA_FOREACH(rights, i)
+
+ for ( ; m_rights != NULL; m_rights = monitor_next_rights(m_rights))
{
- if(VARA_AT(rights, i).local)
+ if(m_rights->local)
{
- fprintf(PFILE, "monitor = \"%s\"\t\t# local socket name for monitoring\n", VARA_AT(rights, i).name);
+ fprintf(PFILE, "monitor = \"%s\"\t\t# local socket name for monitoring\n", m_rights->name);
}
else
{
struct in_addr ia;
- ia.s_addr = ntohl(VARA_AT(rights, i).net);
+ ia.s_addr = ntohl(m_rights->net);
- switch(VARA_AT(rights, i).mask)
+ switch(m_rights->mask)
{
case 0xffffffff:
s = "32";
@@ -979,17 +1034,17 @@ print_config(void)
}
b[0] = '\0';
- if((VARA_AT(rights, i).rights) & I4B_CA_COMMAND_FULL)
+ if((m_rights->rights) & I4B_CA_COMMAND_FULL)
strcat(b, "fullcmd,");
- if((VARA_AT(rights, i).rights) & I4B_CA_COMMAND_RESTRICTED)
+ if((m_rights->rights) & I4B_CA_COMMAND_RESTRICTED)
strcat(b, "restrictedcmd,");
- if((VARA_AT(rights, i).rights) & I4B_CA_EVNT_CHANSTATE)
+ if((m_rights->rights) & I4B_CA_EVNT_CHANSTATE)
strcat(b, "channelstate,");
- if((VARA_AT(rights, i).rights) & I4B_CA_EVNT_CALLIN)
+ if((m_rights->rights) & I4B_CA_EVNT_CALLIN)
strcat(b, "callin,");
- if((VARA_AT(rights, i).rights) & I4B_CA_EVNT_CALLOUT)
+ if((m_rights->rights) & I4B_CA_EVNT_CALLOUT)
strcat(b, "callout,");
- if((VARA_AT(rights, i).rights) & I4B_CA_EVNT_I4B)
+ if((m_rights->rights) & I4B_CA_EVNT_I4B)
strcat(b, "logevents,");
if(b[strlen(b)-1] == ',')
diff --git a/usr.sbin/i4b/isdnd/rc_parse.y b/usr.sbin/i4b/isdnd/rc_parse.y
index 7d77359..bace84d 100644
--- a/usr.sbin/i4b/isdnd/rc_parse.y
+++ b/usr.sbin/i4b/isdnd/rc_parse.y
@@ -30,9 +30,11 @@
* i4b daemon - runtime configuration parser
* -----------------------------------------
*
- * $FreeBSD$
+ * $Id: rc_parse.y,v 1.24 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Thu May 20 14:05:26 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:48:48 1999]
*
*---------------------------------------------------------------------------*/
@@ -56,6 +58,7 @@
#endif
extern void cfg_setval(int keyword);
+extern void cfg_set_controller_default();
extern void reset_scanner(FILE *infile);
extern void yyerror(const char *msg);
extern int yylex();
@@ -66,6 +69,7 @@ extern int nentries;
int saw_system = 0;
int entrycount = -1;
+int controllercount = -1;
%}
@@ -83,6 +87,7 @@ int entrycount = -1;
%token CALLOUT
%token CHANNELSTATE
%token CONNECTPROG
+%token CONTROLLER
%token DIALOUTTYPE
%token DIALRANDINCR
%token DIALRETRIES
@@ -104,6 +109,8 @@ int entrycount = -1;
%token LOCAL_PHONE_DIALOUT
%token LOCAL_PHONE_INCOMING
%token LOGEVENTS
+%token MAILER
+%token MAILTO
%token MONITOR
%token MONITORACCESS
%token MONITORPORT
@@ -112,6 +119,7 @@ int entrycount = -1;
%token NO
%token OFF
%token ON
+%token PROTOCOL
%token RATESFILE
%token RATETYPE
%token REACTION
@@ -143,6 +151,7 @@ int entrycount = -1;
%type <num> sysfilekeyword sysnumkeyword sysstrkeyword sysboolkeyword
%type <num> numkeyword strkeyword boolkeyword monrights monright
+%type <num> cstrkeyword
%type <str> filename
%union {
@@ -158,6 +167,7 @@ config: sections
sections: possible_nullentries
syssect
+ optcontrollersects
entrysects
;
@@ -174,6 +184,22 @@ entrysects: entrysect
| entrysects entrysect
;
+optcontrollersects:
+ controllersects
+ |
+ {
+ cfg_set_controller_default();
+ }
+ ;
+
+controllersects: controllersect
+ | controllersects controllersect
+ ;
+
+/* ============== */
+/* system section */
+/* ============== */
+
syssect: SYSTEM sysentries
;
@@ -305,11 +331,17 @@ sysnumkeyword: MONITORPORT { $$ = MONITORPORT; }
| RTPRIO { $$ = RTPRIO; }
;
-sysstrkeyword: ROTATESUFFIX { $$ = ROTATESUFFIX; }
+sysstrkeyword: MAILER { $$ = MAILER; }
+ | MAILTO { $$ = MAILTO; }
+ | ROTATESUFFIX { $$ = ROTATESUFFIX; }
| REGEXPR { $$ = REGEXPR; }
| REGPROG { $$ = REGPROG; }
;
+/* ============= */
+/* entry section */
+/* ============= */
+
entrysect: ENTRY
{
entrycount++;
@@ -394,4 +426,39 @@ boolkeyword: DIALRANDINCR { $$ = DIALRANDINCR; }
| USEDOWN { $$ = USEDOWN; }
;
+
+/* ================== */
+/* controller section */
+/* ================== */
+
+controllersect: CONTROLLER
+ {
+ controllercount++;
+ }
+ controllers
+ ;
+
+controllers: controller
+ | controllers controller
+ ;
+
+controller: strcontroller
+ | nullentry
+ | error '\n'
+ ;
+
+strcontroller: cstrkeyword '=' STRING '\n'
+ {
+ cfg_setval($1);
+ }
+ | cstrkeyword '=' NUMBERSTR '\n'
+ {
+ cfg_setval($1);
+ }
+ ;
+
+cstrkeyword: PROTOCOL { $$ = PROTOCOL; }
+ ;
+
+
%%
diff --git a/usr.sbin/i4b/isdnd/rc_scan.l b/usr.sbin/i4b/isdnd/rc_scan.l
index 9e0df6e..e9d9814 100644
--- a/usr.sbin/i4b/isdnd/rc_scan.l
+++ b/usr.sbin/i4b/isdnd/rc_scan.l
@@ -30,9 +30,11 @@
* i4b daemon - runtime configuration lexical analyzer
* ---------------------------------------------------
*
- * $FreeBSD$
+ * $Id: rc_scan.l,v 1.27 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Thu May 20 14:04:13 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:48:57 1999]
*
*---------------------------------------------------------------------------*/
@@ -96,6 +98,7 @@ beepconnect { return BEEPCONNECT; }
callbackwait { return CALLBACKWAIT; }
calledbackwait { return CALLEDBACKWAIT; }
connectprog { return CONNECTPROG; }
+controller { return CONTROLLER; }
dialin-reaction { return REACTION; }
dialout-type { return DIALOUTTYPE; }
dialrandincr { return DIALRANDINCR; }
@@ -116,6 +119,8 @@ isdntxdel-incoming { return ISDNTXDELIN; }
isdntxdel-outgoing { return ISDNTXDELOUT; }
local-phone-dialout { return LOCAL_PHONE_DIALOUT; }
local-phone-incoming { return LOCAL_PHONE_INCOMING; }
+mailer { return MAILER; }
+mailto { return MAILTO; }
monitor-allowed { return MONITORSW; }
monitor-port { return MONITORPORT; }
monitor { return MONITOR; }
@@ -130,6 +135,7 @@ name { return NAME; }
no { return NO; }
off { return OFF; }
on { return ON; }
+protocol { return PROTOCOL; }
ratesfile { return RATESFILE; }
ratetype { return RATETYPE; }
recoverytime { return RECOVERYTIME; }
diff --git a/usr.sbin/i4b/isdnd/support.c b/usr.sbin/i4b/isdnd/support.c
index bf15653..07a40f4 100644
--- a/usr.sbin/i4b/isdnd/support.c
+++ b/usr.sbin/i4b/isdnd/support.c
@@ -27,9 +27,11 @@
* i4b daemon - misc support routines
* ----------------------------------
*
- * $FreeBSD$
+ * $Id: support.c,v 1.63 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Mon Jul 5 15:29:22 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:49:05 1999]
*
*---------------------------------------------------------------------------*/
@@ -58,12 +60,14 @@ find_active_entry_by_driver(int drivertype, int driverunit)
if(cep->cdid == CDID_UNUSED)
{
- DBGL(DL_MSG, (log(LL_DBG, "find_active_entry_by_driver: entry %d, cdid is CDID_UNUSED!", i)));
+ DBGL(DL_MSG, (log(LL_DBG, "find_active_entry_by_driver: entry %d [%s%d], cdid=CDID_UNUSED !",
+ i, bdrivername(drivertype), driverunit)));
return(NULL);
}
else if(cep->cdid == CDID_RESERVED)
{
- DBGL(DL_MSG, (log(LL_DBG, "find_active_entry_by_driver: entry %d, cdid is CDID_RESERVED!", i)));
+ DBGL(DL_MSG, (log(LL_DBG, "find_active_entry_by_driver: entry %d [%s%d], cdid=CDID_RESERVED!",
+ i, bdrivername(drivertype), driverunit)));
return(NULL);
}
return(cep);
@@ -504,7 +508,7 @@ find_matching_entry_incoming(msg_connect_ind_t *mp)
if((ioctl(isdnfd, I4B_UPDOWN_IND, &mui)) < 0)
{
log(LL_ERR, "find_matching_entry_incoming: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "find_matching_entry_incoming: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
}
cep->down_retry_count = 0;
@@ -575,108 +579,6 @@ get_cep_by_cdid(int cdid)
}
/*---------------------------------------------------------------------------*
- * get name of a controller
- *---------------------------------------------------------------------------*/
-const char *
-name_of_controller(int ctrl_type, int card_type)
-{
- static char *passive_card[] = {
- "Teles S0/8",
- "Teles S0/16",
- "Teles S0/16.3",
- "AVM A1 or Fritz!Card",
- "Teles S0/16.3 PnP",
- "Creatix S0 PnP",
- "USRobotics Sportster ISDN TA",
- "Dr. Neuhaus NICCY Go@",
- "Sedlbauer win speed",
- "Dynalink IS64PH",
- "ISDN Master, MasterII or Blaster",
- "AVM PCMCIA Fritz!Card",
- "ELSA QuickStep 1000pro/ISA",
- "ELSA QuickStep 1000pro/PCI",
- "Siemens I-Talk",
- "ELSA MicroLink ISDN/MC",
- "ELSA MicroLink MCall",
- "ITK ix1 micro",
- "AVM Fritz!Card PCI",
- "ELSA PCC-16",
- "AVM Fritz!Card PnP",
- "Siemens I-Surf 2.0 PnP",
- "Asuscom ISDNlink 128K PnP"
- };
-
- static char *daic_card[] = {
- "EICON.Diehl S",
- "EICON.Diehl SX/SXn",
- "EICON.Diehl SCOM",
- "EICON.Diehl QUADRO",
- };
-
- if(ctrl_type == CTRL_PASSIVE)
- {
- int index = card_type - CARD_TYPEP_8;
- if (index >= 0 && index < (sizeof passive_card / sizeof passive_card[0]))
- return passive_card[index];
- }
- else if(ctrl_type == CTRL_DAIC)
- {
- int index = card_type - CARD_TYPEA_DAIC_S;
- if (index >= 0 && index < (sizeof daic_card / sizeof daic_card[0] ))
- return daic_card[index];
- }
- else if(ctrl_type == CTRL_TINADD)
- {
- return "Stollmann tina-dd";
- }
-
- return "unknown card type";
-}
-
-/*---------------------------------------------------------------------------*
- * init controller state array
- *---------------------------------------------------------------------------*/
-void
-init_controller(void)
-{
- int i;
- int max = 1;
- msg_ctrl_info_req_t mcir;
-
- for(i=0; i < max; i++)
- {
- mcir.controller = i;
-
- if((ioctl(isdnfd, I4B_CTRL_INFO_REQ, &mcir)) < 0)
- {
- log(LL_ERR, "init_controller: ioctl I4B_CTRL_INFO_REQ failed: %s", strerror(errno));
- do_exit(1);
- }
-
- if((ncontroller = max = mcir.ncontroller) == 0)
- {
- log(LL_ERR, "init_controller: no ISDN controller found!");
- do_exit(1);
- }
-
- if(mcir.ctrl_type == -1 || mcir.card_type == -1)
- {
- log(LL_ERR, "init_controller: ctrl/card is invalid!");
- do_exit(1);
- }
-
- /* init controller tab */
-
- if((init_controller_state(i, mcir.ctrl_type, mcir.card_type, mcir.tei)) == ERROR)
- {
- log(LL_ERR, "init_controller: init_controller_state for controller %d failed", i);
- do_exit(1);
- }
- }
- DBGL(DL_RCCF, (log(LL_DBG, "init_controller: found %d ISDN controller(s)", max)));
-}
-
-/*---------------------------------------------------------------------------*
* return b channel driver type name string
*---------------------------------------------------------------------------*/
char *
@@ -785,7 +687,7 @@ unitlen_chkupd(cfg_entry_t *cep)
if((ioctl(isdnfd, I4B_TIMEOUT_UPD, &tupd)) < 0)
{
log(LL_ERR, "ioctl I4B_TIMEOUT_UPD failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "ioctl I4B_TIMEOUT_UPD failed: %s", strerror(errno));
}
}
@@ -865,7 +767,7 @@ if_up(cfg_entry_t *cep)
if((ioctl(isdnfd, I4B_UPDOWN_IND, &mui)) < 0)
{
log(LL_ERR, "if_up: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "if_up: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
}
cep->down_retry_count = 0;
@@ -898,7 +800,7 @@ if_down(cfg_entry_t *cep)
if((ioctl(isdnfd, I4B_UPDOWN_IND, &mui)) < 0)
{
log(LL_ERR, "if_down: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "if_down: ioctl I4B_UPDOWN_IND failed: %s", strerror(errno));
}
cep->went_down_time = time(NULL);
cep->down_retry_count = 0;
@@ -942,7 +844,7 @@ dialresponse(cfg_entry_t *cep, int dstat)
if((ioctl(isdnfd, I4B_DIALOUT_RESP, &mdr)) < 0)
{
log(LL_ERR, "dialresponse: ioctl I4B_DIALOUT_RESP failed: %s", strerror(errno));
- do_exit(1);
+ error_exit(1, "dialresponse: ioctl I4B_DIALOUT_RESP failed: %s", strerror(errno));
}
DBGL(DL_DRVR, (log(LL_DBG, "dialresponse: sent [%s]", stattab[dstat])));
diff --git a/usr.sbin/i4b/isdnd/timer.c b/usr.sbin/i4b/isdnd/timer.c
index df556d2..34dea3a 100644
--- a/usr.sbin/i4b/isdnd/timer.c
+++ b/usr.sbin/i4b/isdnd/timer.c
@@ -27,9 +27,11 @@
* i4b daemon - timer/timing support routines
* ------------------------------------------
*
- * $FreeBSD$
+ * $Id: timer.c,v 1.19 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:12:32 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:49:13 1999]
*
*---------------------------------------------------------------------------*/
@@ -46,7 +48,7 @@ static void recover_illegal(cfg_entry_t *cep);
static void
recover_illegal(cfg_entry_t *cep)
{
- log(LL_ERR, "recover_illegal: ERROR, entry %s attempting disconnect!", cep->name);
+ log(LL_ERR, "recover_illegal: ERROR, entry %s attempting disconnect!", cep->name);
sendm_disconnect_req(cep, (CAUSET_I4B << 8) | CAUSE_I4B_NORMAL);
log(LL_ERR, "recover_illegal: ERROR, entry %s - reset state/cdid!", cep->name);
cep->state = ST_IDLE;
diff --git a/usr.sbin/i4b/isdnd/vararray.h b/usr.sbin/i4b/isdnd/vararray.h
deleted file mode 100644
index c71f816..0000000
--- a/usr.sbin/i4b/isdnd/vararray.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 1997, 1998 Martin Husemann <martin@rumolt.teuto.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * vararray.h: basic collection macros for variable sized (growing) arrays:
- * macro version of popular C++ template classes,
- * not as elegant in use as the template version,
- * but has maximum runtime performance and can give
- * pointers to array contents (i.e. for ioctl's).
- * Works in C as well as in C++.
- * CAVEAT: in C++ only useable for aggregateable objects,
- * it does use memcpy instead of copy constructors!
- */
-
-#ifndef VARARRAY_H
-#define VARARRAY_H
-/* declare a variable sized array, element type is t */
-#define VARA_DECL(t) struct { int used, allocated; t *data; }
-
-/* aggregate initializer for a variable array */
-#define VARA_INITIALIZER { 0, 0, NULL }
-
-/* free all allocated storage */
-#define VARA_FREE(a) { if ((a).data != NULL) free((a).data); \
- (a).allocated = 0; (a).used = 0; }
-
-/* number of elments currently in array*/
-#define VARA_NUM(a) ((a).used)
-
-/* number of elements already allocated in array */
-#define VARA_ALLOCATED(a) ((a).allocated)
-
-/* pointer to array data */
-#define VARA_PTR(a) ((a).data)
-
-/* empty the array */
-#define VARA_EMPTY(a) { (a).used = 0; }
-
-#ifdef __cplusplus
-#define VARA_NEW(t,c) new t[c]
-#define VARA_DELETE(p) delete [] p
-#else
-#define VARA_NEW(t,c) (t*)malloc(sizeof(t)*(c))
-#define VARA_DELETE(p) free(p)
-#endif
-
-/* add an element (not changing any data).
- * a is the array, i the index,
- * t the element type and n the initial allocation */
-#define VARA_ADD_AT(a,i,t,n) \
-{ \
- if ((i) >= (a).allocated) { \
- int new_alloc = (a).allocated ? (a).allocated*2 : (n); \
- t *new_data; \
- if (new_alloc <= (i)) new_alloc = (i)+1; \
- new_data = VARA_NEW(t, new_alloc); \
- if ((a).data) { \
- memcpy(new_data, (a).data, (a).used*sizeof(t)); \
- VARA_DELETE((a).data); \
- } \
- (a).data = new_data; \
- (a).allocated = new_alloc; \
- } \
- if ((i) >= (a).used) { \
- if (i > (a).used) \
- memset(&((a).data[(a).used]), 0, \
- sizeof(t)*((i)-(a).used+1)); \
- (a).used = (i)+1; \
- } \
-}
-
-/* return an l-value at index i */
-#define VARA_AT(a,i) ((a).data[(i)])
-
-/* iterate through the array */
-#define VARA_FOREACH(a,i) for ((i) = 0; (i) < (a).used; (i)++)
-
-/* check for a valid index */
-#define VARA_VALID(a,i) ((i) >= 0 && (i) < (a).used)
-
-/* remove one entry */
-#define VARA_REMOVEAT(a,i) \
-{ \
- if ((i) < ((a).used -1)) \
- memmove(&((a).data[(i)]), &((a).data[(i)+1]), sizeof((a).data[0])); \
- (a).used--; \
-}
-
-/* free all storage allocated for the array */
-#define VARA_DESTROY(a) \
-{ \
- if ((a).data) VARA_DELETE((a).data); \
- (a).allocated = 0; \
- (a).used = 0; \
- (a).data = NULL; \
-}
-
-#endif
-
diff --git a/usr.sbin/i4b/isdndebug/Makefile b/usr.sbin/i4b/isdndebug/Makefile
index cf52818..b22566d 100644
--- a/usr.sbin/i4b/isdndebug/Makefile
+++ b/usr.sbin/i4b/isdndebug/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
PROG = isdndebug
SRCS = main.c
MAN8 = isdndebug.8
diff --git a/usr.sbin/i4b/isdndebug/isdndebug.8 b/usr.sbin/i4b/isdndebug/isdndebug.8
index 6fafa50..3322caa 100644
--- a/usr.sbin/i4b/isdndebug/isdndebug.8
+++ b/usr.sbin/i4b/isdndebug/isdndebug.8
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: isdndebug.8,v 1.10 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sat May 29 11:03:15 1999]
+.\" last edit-date: [Mon Dec 13 23:01:42 1999]
.\"
.Dd May, 29, 1999
.Dt ISDNDEBUG 8
@@ -95,6 +97,7 @@ Reset the Q.921 (D-channel layer 2) frame receive/transmit statistics to zero.
.Pp
.Sh FILES
/dev/i4bctl
+
.Sh EXAMPLES
The command:
.Bd -literal -offset indent
@@ -102,8 +105,9 @@ isdndebug -g
.Ed
.Pp
displays the current debugging level for all ISDN layers
-.Sh AUTHORS
+
+.Sh AUTHOR
The
.Nm
-utility and this manpage were written by
+utility and this manpage were written by
.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdndebug/main.c b/usr.sbin/i4b/isdndebug/main.c
index 8cc4867..dd49747 100644
--- a/usr.sbin/i4b/isdndebug/main.c
+++ b/usr.sbin/i4b/isdndebug/main.c
@@ -27,9 +27,11 @@
* main.c - i4b set debug options
* ------------------------------
*
- * $FreeBSD$
+ * $Id: main.c,v 1.23 1999/12/13 21:25:25 hm Exp $
*
- * last edit-date: [Fri Jul 30 08:14:34 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:49:40 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/Makefile b/usr.sbin/i4b/isdndecode/Makefile
index cad91437..c6e4671 100644
--- a/usr.sbin/i4b/isdndecode/Makefile
+++ b/usr.sbin/i4b/isdndecode/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
PROG = isdndecode
SRCS = main.c layer1.c layer2.c layer3.c \
layer3_subr.c facility.c pcause.c
diff --git a/usr.sbin/i4b/isdndecode/decode.h b/usr.sbin/i4b/isdndecode/decode.h
index bdd917a..83bab00 100644
--- a/usr.sbin/i4b/isdndecode/decode.h
+++ b/usr.sbin/i4b/isdndecode/decode.h
@@ -27,9 +27,11 @@
* decode.h - isdndecode header file
* ---------------------------------
*
+ * $Id: decode.h,v 1.6 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:15:59 1999]
+ * last edit-date: [Mon Dec 13 21:49:50 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/facility.c b/usr.sbin/i4b/isdndecode/facility.c
index c9003f8..3bb7b08 100644
--- a/usr.sbin/i4b/isdndecode/facility.c
+++ b/usr.sbin/i4b/isdndecode/facility.c
@@ -27,9 +27,11 @@
* facility.c - decode Q.932 facilities
* ------------------------------------
*
+ * $Id: facility.c,v 1.4 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:11 1999]
+ * last edit-date: [Mon Dec 13 21:49:56 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/facility.h b/usr.sbin/i4b/isdndecode/facility.h
index 5e98e72..2a2832e 100644
--- a/usr.sbin/i4b/isdndecode/facility.h
+++ b/usr.sbin/i4b/isdndecode/facility.h
@@ -27,9 +27,11 @@
* facility.h - Q.932 facility header file
* ---------------------------------------
*
+ * $Id: facility.h,v 1.4 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:17 1999]
+ * last edit-date: [Mon Dec 13 21:50:06 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/isdndecode.8 b/usr.sbin/i4b/isdndecode/isdndecode.8
index be06df5..552e62a 100644
--- a/usr.sbin/i4b/isdndecode/isdndecode.8
+++ b/usr.sbin/i4b/isdndecode/isdndecode.8
@@ -22,11 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: isdndecode.8,v 1.7 1999/12/13 22:11:55 hm Exp $
.\"
-.\" last edit-date: [Sun Feb 14 10:16:25 1999]
+.\" last edit-date: [Mon Dec 13 23:03:21 1999]
.\"
-.\" -hm writing manual page
+.\" $FreeBSD$
.\"
.Dd September 17, 1998
.Dt ISDNDECODE 8
@@ -149,12 +149,14 @@ ISDN D-channel layer 2 protocol description.
ISDN D-channel layer 3 protocol description.
.El
.Pp
+
.Sh FILES
.Bl -tag -width daddeldi -compact
.It Pa /dev/i4btrc<n>
The devicefile(s) used to get the decode messages for ISDN card unit <n>
out of the kernel.
.El
+
.Sh EXAMPLES
The command:
.Bd -literal -offset indent
@@ -164,10 +166,13 @@ isdndecode -f /var/tmp/isdn.decode
will start D channel tracing on passive controller 0 with all except B
channel tracing enabled and logs everything into the output file
/tmp/isdn.decode.
+
.Sh SEE ALSO
.Xr isdnd 8
+
.Sh BUGS
Still one left.
+
.Sh STANDARDS
ITU Recommendations I.430, Q.920, Q.921, Q.930, Q.931
.Pp
@@ -178,9 +183,9 @@ ETSI Recommendation ETS 300 179 (10/92), ETS 300 180 (10/92)
ETSI Recommendation ETS 300 181 (04/93), ETS 300 182 (04/93)
.Pp
ITU Recommendation X.208, X.209
-.Sh AUTHORS
+
+.Sh AUTHOR
The
.Nm
-utility and this manual page was written by
+utility and this manual page were written by
.An Hellmuth Michaelis Aq hm@kts.org .
-
diff --git a/usr.sbin/i4b/isdndecode/layer1.c b/usr.sbin/i4b/isdndecode/layer1.c
index 4737438..c08b628 100644
--- a/usr.sbin/i4b/isdndecode/layer1.c
+++ b/usr.sbin/i4b/isdndecode/layer1.c
@@ -27,9 +27,11 @@
* layer1.c - isdndecode, decode and print layer 1 information
* -----------------------------------------------------------
*
+ * $Id: layer1.c,v 1.4 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:40 1999]
+ * last edit-date: [Mon Dec 13 21:50:34 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/layer2.c b/usr.sbin/i4b/isdndecode/layer2.c
index 9b5b737..1e53986 100644
--- a/usr.sbin/i4b/isdndecode/layer2.c
+++ b/usr.sbin/i4b/isdndecode/layer2.c
@@ -27,9 +27,11 @@
* layer2.c - decode and print layer 2 (Q.921) information
* -------------------------------------------------------
*
+ * $Id: layer2.c,v 1.5 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:46 1999]
+ * last edit-date: [Mon Dec 13 21:50:41 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/layer3.c b/usr.sbin/i4b/isdndecode/layer3.c
index c7b6927..e1df3c5 100644
--- a/usr.sbin/i4b/isdndecode/layer3.c
+++ b/usr.sbin/i4b/isdndecode/layer3.c
@@ -27,9 +27,11 @@
* layer3.c - decode and print layer 3 (Q.931) information
* -------------------------------------------------------
*
+ * $Id: layer3.c,v 1.7 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:52 1999]
+ * last edit-date: [Mon Dec 13 21:50:48 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/layer3_subr.c b/usr.sbin/i4b/isdndecode/layer3_subr.c
index 1872170..ce3d580 100644
--- a/usr.sbin/i4b/isdndecode/layer3_subr.c
+++ b/usr.sbin/i4b/isdndecode/layer3_subr.c
@@ -27,9 +27,11 @@
* layer3_subr.c - subroutines for IE decoding
* -------------------------------------------
*
+ * $Id: layer3_subr.c,v 1.6 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:16:58 1999]
+ * last edit-date: [Mon Dec 13 21:51:00 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/main.c b/usr.sbin/i4b/isdndecode/main.c
index ead3252..4062871 100644
--- a/usr.sbin/i4b/isdndecode/main.c
+++ b/usr.sbin/i4b/isdndecode/main.c
@@ -27,9 +27,11 @@
* main.c - isdndecode main program file
* -------------------------------------
*
+ * $Id: main.c,v 1.12 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Fri Jul 30 08:14:58 1999]
+ * last edit-date: [Mon Dec 13 21:51:07 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/pcause.c b/usr.sbin/i4b/isdndecode/pcause.c
index a9f7f2f..610a960 100644
--- a/usr.sbin/i4b/isdndecode/pcause.c
+++ b/usr.sbin/i4b/isdndecode/pcause.c
@@ -27,9 +27,11 @@
* pcause.c - printing cause values
* --------------------------------
*
+ * $Id: pcause.c,v 1.5 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:17:10 1999]
+ * last edit-date: [Mon Dec 13 21:51:20 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdndecode/pcause.h b/usr.sbin/i4b/isdndecode/pcause.h
index 3f31eb9..2c1c7f4 100644
--- a/usr.sbin/i4b/isdndecode/pcause.h
+++ b/usr.sbin/i4b/isdndecode/pcause.h
@@ -27,9 +27,11 @@
* pcause.h - Q.850 causes definitions
* -----------------------------------
*
+ * $Id: pcause.h,v 1.4 1999/12/13 21:25:25 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:17:15 1999]
+ * last edit-date: [Mon Dec 13 21:51:32 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdnmonitor/Makefile b/usr.sbin/i4b/isdnmonitor/Makefile
index 9d3811b..11b81bc 100644
--- a/usr.sbin/i4b/isdnmonitor/Makefile
+++ b/usr.sbin/i4b/isdnmonitor/Makefile
@@ -1,8 +1,11 @@
+# $FreeBSD$
PROG = isdnmonitor
-SRCS = main.c
+SRCS = main.c curses.c
MAN8 = isdnmonitor.8
# compile debug support
COPTS += -DDEBUG
+LDADD += -lcurses
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/i4b/isdnmonitor/curses.c b/usr.sbin/i4b/isdnmonitor/curses.c
new file mode 100644
index 0000000..1e7eec1
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/curses.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b daemon - curses fullscreen output
+ * -------------------------------------
+ *
+ * $Id: curses.c,v 1.10 1999/12/13 21:25:25 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:51:47 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "monprivate.h"
+
+#ifndef WIN32
+
+static void display_bell(void);
+static void display_chans(void);
+
+/*---------------------------------------------------------------------------*
+ * program exit
+ *---------------------------------------------------------------------------*/
+void
+do_exit(int exitval)
+{
+ if(curses_ready)
+ endwin();
+ exit(exitval);
+}
+
+/*---------------------------------------------------------------------------*
+ * init curses fullscreen display
+ *---------------------------------------------------------------------------*/
+void
+init_screen(void)
+{
+ char buffer[512];
+ int uheight, lheight;
+ int i, j;
+
+ initscr(); /* curses init */
+
+ if((COLS < 80) || (LINES < 24))
+ {
+ endwin();
+ fprintf(stderr, "ERROR, minimal screensize must be 80x24, is %dx%d, terminating!",COLS, LINES);
+ exit(1);
+ }
+
+ noecho();
+ raw();
+
+ uheight = nctrl * 2; /* cards * b-channels */
+ lheight = LINES - uheight - 6 + 1; /* rest of display */
+
+ if((upper_w = newwin(uheight, COLS, UPPER_B, 0)) == NULL)
+ {
+ endwin();
+ fprintf(stderr, "ERROR, curses init upper window, terminating!");
+ exit(1);
+ }
+
+ if((mid_w = newwin(1, COLS, UPPER_B+uheight+1, 0)) == NULL)
+ {
+ endwin();
+ fprintf(stderr, "ERROR, curses init mid window, terminating!");
+ exit(1);
+ }
+
+ if((lower_w = newwin(lheight, COLS, UPPER_B+uheight+3, 0)) == NULL)
+ {
+ endwin();
+ fprintf(stderr, "ERROR, curses init lower window, LINES = %d, lheight = %d, uheight = %d, terminating!", LINES, lheight, uheight);
+ exit(1);
+ }
+
+ scrollok(lower_w, 1);
+
+ sprintf(buffer, "----- isdn controller channel state ------------- isdnmonitor %02d.%02d.%d -", VERSION, REL, STEP);
+
+ while(strlen(buffer) < COLS)
+ strcat(buffer, "-");
+
+ move(0, 0);
+ standout();
+ addstr(buffer);
+ standend();
+
+ move(1, 0);
+ /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */
+ addstr("c tei b remote iface dir outbytes obps inbytes ibps units");
+
+ if(hostname)
+ sprintf(buffer, "----- isdn userland interface state ------------- %s:%d -", hostname, portno);
+ else
+ sprintf(buffer, "----- isdn userland interface state ------------- %s -", sockpath);
+
+ while(strlen(buffer) < COLS)
+ strcat(buffer, "-");
+
+ move(uheight+2, 0);
+ standout();
+ addstr(buffer);
+ standend();
+
+ sprintf(buffer, "----- isdnd logfile display --------------------------------------------------");
+ while(strlen(buffer) < COLS)
+ strcat(buffer, "-");
+
+ move(uheight+4, 0);
+ standout();
+ addstr(buffer);
+ standend();
+
+ refresh();
+
+ for(i=0, j=0; i <= nctrl; i++, j+=2)
+ {
+ mvwprintw(upper_w, j, H_CNTL, "%d --- 1 ", i); /*TEI*/
+ mvwprintw(upper_w, j+1, H_CNTL, " L12 2 ");
+ }
+ wrefresh(upper_w);
+
+#ifdef NOTDEF
+ for(i=0, j=0; i < nentries; i++) /* walk thru all entries */
+ {
+ p = &cfg_entry_tab[i]; /* get ptr to enry */
+
+ mvwprintw(mid_w, 0, j, "%s%d ", bdrivername(p->usrdevicename), p->usrdeviceunit);
+
+ p->fs_position = j;
+
+ j += ((strlen(bdrivername(p->usrdevicename)) + (p->usrdeviceunit > 9 ? 2 : 1) + 1));
+ }
+#else
+ mvwprintw(mid_w, 0, 0, "%s", devbuf);
+#endif
+ wrefresh(mid_w);
+
+ wmove(lower_w, 0, 0);
+ wrefresh(lower_w);
+
+ curses_ready = 1;
+}
+
+/*---------------------------------------------------------------------------*
+ * display the charge in units
+ *---------------------------------------------------------------------------*/
+void
+display_charge(int pos, int charge)
+{
+ mvwprintw(upper_w, pos, H_UNITS, "%d", charge);
+ wclrtoeol(upper_w);
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display the calculated charge in units
+ *---------------------------------------------------------------------------*/
+void
+display_ccharge(int pos, int units)
+{
+ mvwprintw(upper_w, pos, H_UNITS, "(%d)", units);
+ wclrtoeol(upper_w);
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display accounting information
+ *---------------------------------------------------------------------------*/
+void
+display_acct(int pos, int obyte, int obps, int ibyte, int ibps)
+{
+ mvwprintw(upper_w, pos, H_OUT, "%-10d", obyte);
+ mvwprintw(upper_w, pos, H_OUTBPS, "%-4d", obps);
+ mvwprintw(upper_w, pos, H_IN, "%-10d", ibyte);
+ mvwprintw(upper_w, pos, H_INBPS, "%-4d", ibps);
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * erase line at disconnect time
+ *---------------------------------------------------------------------------*/
+void
+display_disconnect(int pos)
+{
+ wmove(upper_w, pos, H_TELN);
+ wclrtoeol(upper_w);
+ wrefresh(upper_w);
+
+ if(do_bell)
+ display_bell();
+}
+
+/*---------------------------------------------------------------------------*
+ * display interface up/down information
+ *---------------------------------------------------------------------------*/
+void
+display_updown(int pos, int updown, char *device)
+{
+ if(updown)
+ wstandend(mid_w);
+ else
+ wstandout(mid_w);
+
+ mvwprintw(mid_w, 0, pos, "%s ", device);
+
+ wstandend(mid_w);
+ wrefresh(mid_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display interface up/down information
+ *---------------------------------------------------------------------------*/
+void
+display_l12stat(int controller, int layer, int state)
+{
+ if(controller > nctrl)
+ return;
+
+ if(!(layer == 1 || layer == 2))
+ return;
+
+ if(state)
+ wstandout(upper_w);
+ else
+ wstandend(upper_w);
+
+ if(layer == 1)
+ {
+ mvwprintw(upper_w, (controller*2)+1, H_TEI+1, "1");
+
+ if(!state)
+ mvwprintw(upper_w, (controller*2)+1, H_TEI+2, "2");
+ }
+ else if(layer == 2)
+ {
+ mvwprintw(upper_w, (controller*2)+1, H_TEI+2, "2");
+ if(state)
+ mvwprintw(upper_w, (controller*2)+1, H_TEI+1, "1");
+ }
+
+ wstandend(upper_w);
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display TEI
+ *---------------------------------------------------------------------------*/
+void
+display_tei(int controller, int tei)
+{
+ if(controller > nctrl)
+ return;
+
+ if(tei == -1)
+ mvwprintw(upper_w, controller*2, H_TEI, "---");
+ else
+ mvwprintw(upper_w, controller*2, H_TEI, "%3d", tei);
+
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display bell :-)
+ *---------------------------------------------------------------------------*/
+static void
+display_bell(void)
+{
+ static char bell[1] = { 0x07 };
+ write(STDOUT_FILENO, &bell[0], 1);
+}
+
+/*---------------------------------------------------------------------------*
+ * curses menu for fullscreen command mode
+ *---------------------------------------------------------------------------*/
+void
+do_menu(void)
+{
+ static char *menu[WMITEMS] =
+ {
+ "1 - (D)isplay refresh",
+ "2 - (H)angup (choose a channel)",
+ "3 - (R)eread config file",
+ "4 - (Q)uit the program",
+ };
+
+ WINDOW *menu_w;
+ int c;
+ int mpos;
+ fd_set set;
+ struct timeval timeout;
+
+ /* create a new window in the lower screen area */
+
+ if((menu_w = newwin(WMENU_HGT, WMENU_LEN, WMENU_POSLN, WMENU_POSCO )) == NULL)
+ {
+ return;
+ }
+
+ /* create a border around the window */
+
+ box(menu_w, '|', '-');
+
+ /* add a title */
+
+ wstandout(menu_w);
+ mvwaddstr(menu_w, 0, (WMENU_LEN / 2) - (strlen(WMENU_TITLE) / 2), WMENU_TITLE);
+ wstandend(menu_w);
+
+ /* fill the window with the menu options */
+
+ for(mpos=0; mpos <= (WMITEMS-1); mpos++)
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+
+ /* highlight the first menu option */
+
+ mpos = 0;
+ wstandout(menu_w);
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ wstandend(menu_w);
+
+ /* input loop */
+
+ for(;;)
+ {
+ wrefresh(menu_w);
+
+ FD_ZERO(&set);
+ FD_SET(STDIN_FILENO, &set);
+ timeout.tv_sec = WMTIMEOUT;
+ timeout.tv_usec = 0;
+
+ /* if no char is available within timeout, exit menu*/
+
+ if((select(STDIN_FILENO + 1, &set, NULL, NULL, &timeout)) <= 0)
+ goto mexit;
+
+ c = wgetch(menu_w);
+
+ switch(c)
+ {
+ case ' ':
+ case '\t': /* hilite next option */
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ mpos++;
+ if(mpos >= WMITEMS)
+ mpos = 0;
+ wstandout(menu_w);
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ wstandend(menu_w);
+ break;
+
+ case ('0'+WREFRESH+1): /* display refresh */
+ case 'D':
+ case 'd':
+ wrefresh(curscr);
+ goto mexit;
+
+ case ('0'+WQUIT+1): /* quit program */
+ case 'Q':
+ case 'q':
+ do_exit(0);
+ goto mexit;
+
+
+ case ('0'+WHANGUP+1): /* hangup connection */
+ case 'H':
+ case 'h':
+ display_chans();
+ goto mexit;
+
+ case ('0'+WREREAD+1): /* reread config file */
+ case 'R':
+ case 'r':
+ reread();
+ goto mexit;
+
+ case '\n':
+ case '\r': /* exec highlighted option */
+ switch(mpos)
+ {
+ case WREFRESH:
+ wrefresh(curscr);
+ break;
+
+ case WQUIT:
+ do_exit(0);
+ break;
+
+ case WHANGUP:
+ display_chans();
+ break;
+
+ case WREREAD:
+ reread();
+ break;
+ }
+ goto mexit;
+ break;
+
+ default:
+ goto mexit;
+ break;
+ }
+ }
+
+mexit:
+ /* delete the menu window */
+
+ delwin(menu_w);
+
+ /* re-display the original lower window contents */
+
+ touchwin(lower_w);
+ wrefresh(lower_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display connect information
+ *---------------------------------------------------------------------------*/
+void
+display_connect(int pos, int dir, char *name, char *remtel, char *dev)
+{
+ char buffer[256];
+
+ /* remote telephone number */
+
+ sprintf(buffer, "%s/%s", name, remtel);
+
+ buffer[H_IFN - H_TELN - 1] = '\0';
+
+ mvwprintw(upper_w, pos, H_TELN, "%s", buffer);
+
+ /* interface */
+
+ mvwprintw(upper_w, pos, H_IFN, "%s ", dev);
+
+ mvwprintw(upper_w, pos, H_IO, dir ? "out" : "in");
+
+ mvwprintw(upper_w, pos, H_OUT, "-");
+ mvwprintw(upper_w, pos, H_OUTBPS, "-");
+ mvwprintw(upper_w, pos, H_IN, "-");
+ mvwprintw(upper_w, pos, H_INBPS, "-");
+
+ if(do_bell)
+ display_bell();
+
+ wrefresh(upper_w);
+}
+
+/*---------------------------------------------------------------------------*
+ * display channel information for shutdown
+ *---------------------------------------------------------------------------*/
+static void
+display_chans(void)
+{
+ char buffer[80];
+ int i;
+ int cnt = 0;
+ WINDOW *chan_w;
+ int nlines, ncols, pos_x, pos_y;
+ fd_set set;
+ struct timeval timeout;
+
+ /* need this later to close the connection */
+ struct ctlr_chan {
+ int cntl;
+ int chn;
+ } *cc = NULL;
+
+ for(i = 0; i < nctrl; i++)
+ {
+ if(remstate[i].ch1state)
+ cnt++;
+ if(remstate[i].ch2state)
+ cnt++;
+ }
+
+ if(cnt > 0)
+ {
+ if ((cc = (struct ctlr_chan *)malloc (cnt *
+ sizeof (struct ctlr_chan))) == NULL)
+ {
+ return;
+ }
+ nlines = cnt + 4;
+ ncols = 60;
+ }
+ else
+ {
+ nlines = 5;
+ ncols = 22;
+ }
+
+ pos_y = WMENU_POSLN + 4;
+ pos_x = WMENU_POSCO + 10;
+
+ /* create a new window in the lower screen area */
+
+ if((chan_w = newwin(nlines, ncols, pos_y, pos_x )) == NULL)
+ {
+ if (cnt > 0)
+ free(cc);
+ return;
+ }
+
+ /* create a border around the window */
+
+ box(chan_w, '|', '-');
+
+ /* add a title */
+
+ wstandout(chan_w);
+ mvwaddstr(chan_w, 0, (ncols / 2) - (strlen("Channels") / 2), "Channels");
+ wstandend(chan_w);
+
+ /* no active channels */
+ if (cnt == 0)
+ {
+ mvwaddstr(chan_w, 2, 2, "No active channels");
+ wrefresh(chan_w);
+ sleep(1);
+
+ /* delete the channels window */
+
+ delwin(chan_w);
+ return;
+ }
+
+ nlines = 2;
+ ncols = 1;
+
+ for (i = 0; i < nctrl; i++)
+ {
+ if(remstate[i].ch1state)
+ {
+ sprintf(buffer, "%d - Controller %d channel %s", ncols, i, "B1");
+ mvwaddstr(chan_w, nlines, 2, buffer);
+ cc[ncols - 1].cntl = i;
+ cc[ncols - 1].chn = CHAN_B1;
+ nlines++;
+ ncols++;
+ }
+ if(remstate[i].ch2state)
+ {
+ sprintf(buffer, "%d - Controller %d channel %s", ncols, i, "B2");
+ mvwaddstr(chan_w, nlines, 2, buffer);
+ cc[ncols - 1].cntl = i;
+ cc[ncols - 1].chn = CHAN_B2;
+ nlines++;
+ ncols++;
+ }
+ }
+
+ for(;;)
+ {
+ wrefresh(chan_w);
+
+ FD_ZERO(&set);
+ FD_SET(STDIN_FILENO, &set);
+ timeout.tv_sec = WMTIMEOUT;
+ timeout.tv_usec = 0;
+
+ /* if no char is available within timeout, exit menu*/
+
+ if((select(STDIN_FILENO + 1, &set, NULL, NULL, &timeout)) <= 0)
+ break;
+
+ ncols = wgetch(chan_w);
+
+ if (!(isdigit(ncols)))
+ {
+ display_bell();
+ continue;
+ }
+
+ nlines = ncols - '0';
+
+ if ((nlines == 0) || (nlines > cnt))
+ {
+ display_bell();
+ continue;
+ }
+
+ hangup(cc[nlines-1].cntl, cc[nlines-1].chn);
+ break;
+ }
+
+ free(cc);
+
+ /* delete the channels window */
+
+ delwin(chan_w);
+}
+
+#endif /* !WIN32*/
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnmonitor/isdnmonitor.8 b/usr.sbin/i4b/isdnmonitor/isdnmonitor.8
index 2bf1f05..e29a6ae 100644
--- a/usr.sbin/i4b/isdnmonitor/isdnmonitor.8
+++ b/usr.sbin/i4b/isdnmonitor/isdnmonitor.8
@@ -1,41 +1,180 @@
-.\" Copyright (c) 1998 Martin Husemann <martin@rumolt.teuto.de>
-.\" All rights reserved.
+.\"
+.\" Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
-.\" 2. The name of the author may not be used to endorse or promote products
-.\" derived from this software withough specific prior written permission
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
.\"
-.\" $FreeBSD$
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
.\"
-.\" last edit-date: [Fri Jan 30 22:49:48 1998]
+.\" $Id: isdnmonitor.8,v 1.8 1999/12/13 22:11:55 hm Exp $
.\"
-.\" -mh writing manual pages
+.\" $FreeBSD$
.\"
+.\" last edit-date: [Mon Dec 13 23:04:25 1999]
.\"
-.Dd April 18, 1998
+.Dd September 25, 1999
.Dt ISDNMONITOR 8
.Os
.Sh NAME
.Nm isdnmonitor
-.Nd raw sample and test client for isdnd network monitoring
+.Nd isdn4bsd / isdnd remote monitoring tool
+.Sh SYNOPSIS
+.Nm isdnmonitor
+.Op Fl c
+.Op Fl d Ar debuglevel
+.Op Fl f Ar filename
+.Op Fl h Ar hostspec
+.Op Fl l Ar pathname
+.Op Fl p Ar portspec
.Sh DESCRIPTION
+.Nm Isdnmonitor
+is used to remotely monitor the operation of the isdn demon,
+.Xr isdnd 8 ,
+which manages all ISDN related connection and disconnection of ISDN
+devices supported by the isdn4bsd package.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl c
+Switch to (curses-) fullscreen mode of operation. In this mode,
+.Nm
+behaves nearly exactly as
+.Xr isdnd 8
+in fullscreen mode. In fullscreen mode, entering the control character
+.Em Control-L
+causes the display to be refreshed and entering
+.Em Carriage-Return
+or
+.Em Enter
+will pop-up a command window. Because
+.Nm
+will not listen to messages while the command window is active,
+this command window will disappear automatically after 5 seconds without
+any command key press.
+.Pp
+While the command window is active,
+.Em Tab
+or
+.Em Space
+advances to the next menu item. To execute a command, press
+.Em Return
+or
+.Em Enter
+for the highlighted menu item, or enter the number corresponding to the
+item to be executed or enter the capitalized character in the menu item
+description.
+.It Fl d
+If debugging support is compiled into
+.Nm isdnmonitor
+this option is used to specify the debugging level.
+.\" The debugging level is the sum of the
+.\" following values:
+.\" .Pp
+.\" .Bl -tag -width Ds -compact -offset indent
+.\" .It Ar 0x001
+.\" general debugging.
+.\" .It Ar 0x002
+.\" rates calculation.
+.\" .It Ar 0x004
+.\" timing calculations.
+.\" .It Ar 0x008
+.\" state transitions.
+.\" .It Ar 0x010
+.\" retry handling.
+.\" .It Ar 0x020
+.\" dialing.
+.\" .It Ar 0x040
+.\" process handling.
+.\" .It Ar 0x080
+.\" isdn4bsd kernel i/o calls.
+.\" .It Ar 0x100
+.\" controller and channel busy/free messages.
+.\" .It Ar 0x200
+.\" isdnmonitor.rc configuration file processing.
+.\" .El
+.\" .Pp
+.\" The value can be specified in any number base supported by the
+.\" .Xr sscanf 3
+.\" library routine.
+.Pp
+In addition, this option accepts also the character 'n' as an argument to
+disable displaying debug messages on the full-screen display.
+.Pp
+.It Fl f
+Specifying this option causes
+.Nm isdnmonitor
+to write its normal output and - if enabled - debugging output to a file
+which name is specified as the argument.
+.It Fl l
+is used to specify a Unix local domain socket name to be used for communication
+between
+.Xr isdnd 8
+and
+.Nm isdnmonitor .
+.It Fl h
+is used to specify a hostname or a dotted-quad IP address of a machine
+where an
+.Xr isdnd 8
+is running which should be monitored.
+.It Fl p
+This option may be used to specify a remote port number in conjunction
+with the
+.Fl h
+option.
+.El
+
+.Sh ENVIRONMENT
+The following environment variables affect the execution of
+.Nm isdnmonitor :
+.Bl -tag -width Ds
+.It Ev TERM
+The terminal type when running in full-screen display mode.
+See
+.Xr environ 7
+for more information.
+.El
+
+.Sh EXAMPLES
+For a first try, the following command should be used to start
+.Nm
+to monitor a locally running isdnd:
+.Bd -literal -offset indent
+isdnmonitor -h localhost
+.Ed
+.Pp
+
+.Sh DIAGNOSTICS
+Exit status is 0 on success, 1 on error.
+.Pp
+
+.Sh SEE ALSO
+.Xr isdnd 8
+
+.Sh BUGS
+Still one (or) more left.
+
+.Sh AUTHOR
The
.Nm
-is not intended for real world use. It will be replaced
-by something with a better user interface as soon as the monitoring
-subsystem is functional.
+utility was written by
+.An Martin Husemann
+and
+.An Hellmuth Michaelis .
+This manual page was written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdnmonitor/main.c b/usr.sbin/i4b/isdnmonitor/main.c
index 873c241..1c0b199 100644
--- a/usr.sbin/i4b/isdnmonitor/main.c
+++ b/usr.sbin/i4b/isdnmonitor/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998 Martin Husemann. All rights reserved.
+ * Copyright (c) 1998,1999 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,36 +33,51 @@
* i4b daemon - network monitor client
* -----------------------------------
*
- * $FreeBSD$
+ * $Id: main.c,v 1.34 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun May 30 15:19:47 1999]
+ * $FreeBSD$
*
- * -mh created
- * -hm checking in
- * -hm porting to HPUX
- * -mh all events the fullscreen mode displays now as monitor event
+ * last edit-date: [Mon Dec 13 21:52:11 1999]
*
*---------------------------------------------------------------------------*/
-
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
+#ifndef WIN32
#include <unistd.h>
#include <netdb.h>
+#endif
#include <sys/types.h>
+#ifndef WIN32
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#else
+#include <stdarg.h>
+#include <windows.h>
+extern char *optarg;
+int getopt(int nargc, char * const nargv[], const char *ostr);
+#define close(f) closesocket(f)
+#define sleep(s) Sleep(s*1000)
+#define vsnprintf _vsnprintf
+#define ssize_t long
+#endif
+#ifdef ERROR
+#undef ERROR
+#endif
-#include <machine/i4b_ioctl.h>
+#define MAIN
+#include "monprivate.h"
+#undef MAIN
-#ifdef __hpux
+#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
@@ -75,61 +90,121 @@
/*
* Local function prototypes
*/
-static int connect_local(const char *sockpath);
-static int connect_remote(const char *host, int portno);
+static int connect_local(char *sockpath);
+static int connect_remote(char *host, int portno);
static void usage();
static void mloop();
static void handle_input();
static void print_menu();
-static void print_logevent(time_t tstamp, int prio, const char * what, const char * msg);
-static void print_charge(time_t tstamp, int channel, int units, int estimated);
-static void print_connect(time_t tstamp, int dir, int channel, const char * cfgname, const char * devname, const char * remphone, const char * locphone);
-static void print_disconnect(time_t tstamp, int channel);
-static void print_updown(time_t tstamp, int channel, int isup);
-static void handle_event(BYTE *msg, int len);
+static void print_logevent(time_t tstamp, int prio, char * what, char * msg);
+static void print_charge(time_t tstamp, int controller, int channel, int units, int estimated);
+static void print_connect(time_t tstamp, int dir, int controller, int channel, char * cfgname, char * devname, char * remphone, char * locphone);
+static void print_disconnect(time_t tstamp, int controller, int channel);
+static void print_updown(time_t tstamp, int contoller, int channel, int isup);
+static void handle_event(u_int8_t *msg, int len);
#ifdef DEBUG
-static void dump_event(BYTE *msg, int len, int readflag);
+static void dump_event(u_int8_t *msg, int len, int readflag);
#endif
+static ssize_t sock_read(int fd, void *buf, size_t nbytes);
+static ssize_t sock_write(int fd, void *buf, size_t nbytes);
+
+static void mprintf(char *fmt, ...);
+
/*
* Global variables
*/
-static int dumpall = 0;
+static int debug = 0;
+#define DBG_DUMPALL 0x01
+#define DBG_PSEND 0x02
+
static int monsock = -1;
-static int state = 0;
+static int state = ST_INIT;
static int sub_state = 0;
static int sub_state_count = 0;
static int isdn_major = 0;
static int isdn_minor = 0;
-static int nctrl = 0;
static u_int32_t rights = 0;
-/*
- * Parse command line, startup monitor client
- */
+static char *logfilename = NULL;
+static FILE *lfp = NULL;
+
+/*---------------------------------------------------------------------------
+ * Display usage and exit
+ *---------------------------------------------------------------------------*/
+static void
+usage()
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "isdnmonitor - version %02d.%02d.%d, %s %s (protocol %02d.%02d)\n", VERSION, REL, STEP, __DATE__, __TIME__, MPROT_VERSION, MPROT_REL);
+#ifdef FOREIGN
+ fprintf(stderr, " usage: isdnmonitor [-c] [-d val] [-f name] [-h host] [-p port]\n");
+#else
+ fprintf(stderr, " usage: isdnmonitor [-c] [-d val] [-f name] [-h host] [-l path] [-p port]\n");
+#endif
+ fprintf(stderr, " -c switch to curses fullscreen output\n");
+ fprintf(stderr, " -d <val> debug flags (see source ...)\n");
+ fprintf(stderr, " -dn no debug output on fullscreen display\n");
+ fprintf(stderr, " -f <name> filename to log output to\n");
+ fprintf(stderr, " -h <host> hostname/address to connect to\n");
+#ifndef FOREIGN
+ fprintf(stderr, " -l <path> pathname to local domain socket to connect to\n");
+#endif
+ fprintf(stderr, " -p <port> portnumber to use to connect to remote host\n");
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------
+ * Parse command line, startup monitor client
+ *---------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
- char * sockpath = NULL;
- char * hostname = NULL;
- int portno = DEF_MONPORT;
int i;
- while ((i = getopt(argc, argv, "dh:p:l:")) != -1)
+#ifdef WIN32
+ WSADATA wsCaps;
+ WSAStartup(MAKEWORD(2, 0), &wsCaps);
+#endif
+
+ portno = DEF_MONPORT;
+ devbuf[0] = '\0';
+
+#ifndef FOREIGN
+ while((i = getopt(argc, argv, "cd:f:h:p:l:")) != -1)
+#else
+ while((i = getopt(argc, argv, "cd:f:h:p:")) != -1)
+#endif
{
- switch (i)
+ switch(i)
{
+ case 'c':
+ fullscreen = 1;
+ break;
case 'd':
- dumpall = 1;
+ if(*optarg == 'n')
+ {
+ debug_noscreen = 1;
+ }
+ else
+ {
+ if((sscanf(optarg, "%i", &debug)) != 1)
+ usage();
+ }
+ break;
+ case 'f':
+ logfilename = optarg;
break;
case 'h':
hostname = optarg;
break;
+#ifndef FOREIGN
case 'l':
sockpath = optarg;
break;
+#endif
case 'p':
- if ((sscanf(optarg, "%i", &portno)) != 1)
+ if((sscanf(optarg, "%i", &portno)) != 1)
usage();
break;
default:
@@ -138,18 +213,23 @@ int main(int argc, char **argv)
}
}
- if (hostname && sockpath)
+#ifndef FOREIGN
+ if(hostname && sockpath)
{
fprintf(stderr, "Error: can not use local socket path on remote machine\n"
"conflicting options -h and -l!\n");
return 1;
}
- if (sockpath)
+ if(sockpath)
{
monsock = connect_local(sockpath);
}
- else if (hostname)
+ else if(hostname)
+#else
+ if(hostname)
+#endif
+
{
monsock = connect_remote(hostname, portno);
}
@@ -158,13 +238,25 @@ int main(int argc, char **argv)
usage();
}
- if (monsock == -1)
+ if(monsock == -1)
{
fprintf(stderr, "Could not connect to i4b isdn daemon.\n");
return 1;
}
+ if(logfilename != NULL)
+ {
+ if((lfp = fopen(logfilename, "w")) == NULL)
+ {
+ fprintf(stderr, "could not open logfile [%s], %s\n", logfilename, strerror(errno));
+ exit(1);
+ }
+ }
+
+#ifndef WIN32
signal(SIGPIPE, SIG_IGN);
+#endif
+
mloop();
close(monsock);
@@ -172,30 +264,12 @@ int main(int argc, char **argv)
return 0;
}
-/*
- * Display usage and exit
- */
-static void usage()
-{
- fprintf(stderr, "usage:\n"
- " isdnmonitor [-d] -h (host) -p (port)\n"
- "or\n"
- " isdnmonitor [-d] -l (path)\n"
- "where (host) is the hostname and (port) the port number of\n"
- "the isdnd to be monitored and (path) is the pathname of the\n"
- "local domain socket used to communicate with a daemon on the\n"
- "local machine.\n"
- "Options are:\n"
- " -d dump all incoming packets as hexdump\n"
- );
- exit(0);
-}
-
-/*
- * Connect via tcp/ip.
- * Return socket if successfull, -1 on error.
- */
-static int connect_remote(const char *host, int portno)
+/*---------------------------------------------------------------------------
+ * Connect via tcp/ip.
+ * Return socket if successfull, -1 on error.
+ ---------------------------------------------------------------------------*/
+static int
+connect_remote(char *host, int portno)
{
struct sockaddr_in sa;
struct hostent *h;
@@ -203,7 +277,7 @@ static int connect_remote(const char *host, int portno)
h = gethostbyname(host);
- if (!h)
+ if(!h)
{
fprintf(stderr, "could not resolve hostname '%s'\n", host);
exit(1);
@@ -211,23 +285,23 @@ static int connect_remote(const char *host, int portno)
remotesockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (remotesockfd == -1)
+ if(remotesockfd == -1)
{
fprintf(stderr, "could not create remote monitor socket: %s\n", strerror(errno));
exit(1);
}
- memset(&sa, 0, sizeof sa);
+ memset(&sa, 0, sizeof(sa));
#ifdef BSD4_4
- sa.sin_len = sizeof sa;
+ sa.sin_len = sizeof(sa);
#endif
sa.sin_family = AF_INET;
sa.sin_port = htons(portno);
- memcpy(&sa.sin_addr.s_addr, h->h_addr_list[0], sizeof sa.sin_addr.s_addr);
+ memcpy(&sa.sin_addr.s_addr, h->h_addr_list[0], sizeof(sa.sin_addr.s_addr));
- if (connect(remotesockfd, (struct sockaddr *)&sa, sizeof sa) == -1)
+ if(connect(remotesockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
{
fprintf(stderr, "could not connect remote monitor: %s\n", strerror(errno));
exit(1);
@@ -236,17 +310,19 @@ static int connect_remote(const char *host, int portno)
return remotesockfd;
}
-/*
- * Connect local.
- * Return socket on success, -1 on failure.
- */
-static int connect_local(const char *sockpath)
+#ifndef FOREIGN
+/*---------------------------------------------------------------------------
+ * Connect local.
+ * Return socket on success, -1 on failure.
+ *---------------------------------------------------------------------------*/
+static int
+connect_local(char *sockpath)
{
int s;
struct sockaddr_un sa;
/* check path length */
- if (strlen(sockpath) >= sizeof sa.sun_path)
+ if(strlen(sockpath) >= sizeof(sa.sun_path))
{
fprintf(stderr, "pathname to long for local socket: %s\n",
sockpath);
@@ -256,35 +332,57 @@ static int connect_local(const char *sockpath)
/* create and setup socket */
s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s == -1)
+ if(s == -1)
{
fprintf(stderr, "could not create local monitor socket:%s\n", strerror(errno));
exit(1);
}
- memset(&sa, 0, sizeof sa);
-
-#ifndef __hpux
- sa.sun_len = sizeof sa;
-#endif
+ memset(&sa, 0, sizeof(sa));
+ sa.sun_len = sizeof(sa);
sa.sun_family = AF_LOCAL;
strcpy(sa.sun_path, sockpath);
- if (connect(s, (struct sockaddr *)&sa, sizeof sa))
+ if(connect(s, (struct sockaddr *)&sa, sizeof(sa)))
{
fprintf(stderr, "could not connect local monitor socket [%s]: %s\n", sockpath, strerror(errno));
}
return s;
}
+#endif
-/*
- * main event loop
- */
-static void mloop()
+/*---------------------------------------------------------------------------*
+ * data from keyboard available, read and process it
+ *---------------------------------------------------------------------------*/
+#ifndef WIN32
+static void
+kbdrdhdl(void)
+{
+ int ch = getch();
+
+ switch(ch)
+ {
+ case 0x0c: /* control L */
+ wrefresh(curscr);
+ break;
+
+ case '\n':
+ case '\r':
+ do_menu();
+ break;
+ }
+}
+#endif
+
+/*---------------------------------------------------------------------------
+ * main event loop
+ *---------------------------------------------------------------------------*/
+static void
+mloop()
{
- for (;;)
+ for(;;)
{
fd_set rd, wr, ex;
@@ -296,51 +394,83 @@ static void mloop()
select(monsock+1, &rd, &wr, &ex, NULL);
- if (FD_ISSET(fileno(stdin), &rd))
+ if(FD_ISSET(fileno(stdin), &rd))
{
- handle_input();
+#ifndef WIN32
+ if(fullscreen && curses_ready)
+ kbdrdhdl();
+ else
+#endif
+ if(!fullscreen)
+ handle_input();
+ else
+ getchar();
}
- if (FD_ISSET(monsock, &rd))
+ if(FD_ISSET(monsock, &rd))
{
- BYTE buf[4096];
- u_long u;
+ u_int8_t buf[8192];
int bytes, ret;
/* Network transfer may deliver two or more packets concatenated.
* Peek at the header and read only one event at a time... */
- ioctl(monsock, FIONREAD, &u);
-
- if (u < I4B_MON_EVNT_HDR)
- continue; /* not enough data there yet */
-
bytes = recv(monsock, buf, I4B_MON_EVNT_HDR, MSG_PEEK);
+ if(bytes == 0)
+ {
+ close(monsock);
+
+#ifndef WIN32
+ if(curses_ready)
+ {
+ endwin();
+ curses_ready = 0;
+ }
+#endif
+
+ mprintf("remote isdnd has closed our connection\n");
+ exit(0);
+ }
+ else if(bytes < 0)
+ {
+ fprintf(stderr, "recv error: %s\n", strerror(errno));
+ close(monsock);
+ exit(1);
+ }
+
if (bytes < I4B_MON_EVNT_HDR)
continue; /* errh? something must be wrong... */
bytes = I4B_GET_2B(buf, I4B_MON_EVNT_LEN);
- if (bytes >= sizeof buf)
+ if(bytes >= sizeof(buf))
+ {
+ fprintf(stderr, "mloop: socket recv buffer overflow %d!\n", bytes);
break;
+ }
/* now we know the size, it fits, so lets read it! */
- ret = read(monsock, buf, bytes);
+ ret = sock_read(monsock, buf, bytes);
- if (ret == 0)
+ if(ret == 0)
{
- printf("remote isdnd has closed our connection\n");
- break;
+ close(monsock);
+#ifndef WIN32
+ if(curses_ready)
+ endwin();
+#endif
+ mprintf("remote isdnd has closed our connection\n");
+ exit(0);
}
- else if (ret < 0)
+ else if(ret < 0)
{
- printf("error reading from isdnd: %s", strerror(errno));
+ mprintf("error reading from isdnd: %s", strerror(errno));
break;
}
#ifdef DEBUG
- if (dumpall)
+ if(debug & DBG_DUMPALL)
dump_event(buf, ret, 1);
#endif
handle_event(buf, ret);
@@ -352,39 +482,75 @@ static void mloop()
/*
* Dump a complete event packet.
*/
-static void dump_event(BYTE *msg, int len, int read)
+static void dump_event(u_int8_t *msg, int len, int read)
{
int i;
if(read)
- printf("read from socket:");
+ mprintf("read from socket:");
else
- printf("write to socket:");
+ mprintf("write to socket:");
- for (i = 0; i < len; i++)
+ for(i = 0; i < len; i++)
{
- if (i % 8 == 0)
- printf("\n%02d: ", i);
- printf("0x%02x %c ", msg[i], isprint(msg[i]) ? msg[i] : '.');
+ if(i % 8 == 0)
+ mprintf("\n%02d: ", i);
+ mprintf("0x%02x %c ", msg[i], isprint(msg[i]) ? msg[i] : '.');
}
- printf("\n");
+ mprintf("\n");
}
#endif
-static void print_logevent(time_t tstamp, int prio, const char * what, const char * msg)
+static void
+print_logevent(time_t tstamp, int prio, char * what, char * msg)
{
char buf[256];
- strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
- printf("log: %s prio %d what=%s msg=%s\n",
- buf, prio, what, msg);
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+ mprintf("log: %s prio %d what=%s msg=%s\n", buf, prio, what, msg);
+
+#ifndef WIN32
+ if(fullscreen)
+ {
+ if((!debug_noscreen) || (debug_noscreen && (((strcmp(what, "DBG"))) != 0)))
+ {
+/*
+ * FreeBSD-current integrated ncurses. Since then it is no longer possible
+ * to write to the last column in the logfilewindow without causing an
+ * automatic newline to occur resulting in a blank line in that window.
+ */
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#endif
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 400009
+#warning "FreeBSD ncurses is buggy: write to last column = auto newline!"
+ wprintw(lower_w, "%s %s %-.*s\n", buf, what,
+ COLS-((strlen(buf))+(strlen(what))+3), msg);
+#else
+ wprintw(lower_w, "%s %s %-.*s\n", buf, what,
+ COLS-((strlen(buf))+(strlen(what))+2), msg);
+#endif
+ wrefresh(lower_w);
+ }
+ }
+#endif
}
-static void print_charge(time_t tstamp, int channel, int units, int estimated)
+static void
+print_charge(time_t tstamp, int controller, int channel, int units, int estimated)
{
char buf[256];
- strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
- printf("%s: channel %d, charge = %d%s\n",
- buf, channel, units, estimated ? " (estimated)" : "");
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+ mprintf("%s: controller %d, channel %d, charge = %d%s\n",
+ buf, controller, channel, units, estimated ? " (estimated)" : "");
+#ifndef WIN32
+ if(fullscreen)
+ {
+ if(estimated)
+ display_ccharge(CHPOS(controller, channel), units);
+ else
+ display_charge(CHPOS(controller, channel), units);
+ }
+#endif
}
/*
@@ -395,23 +561,35 @@ static void print_charge(time_t tstamp, int channel, int units, int estimated)
static void print_connect(
time_t tstamp, /* server time of event */
int outgoing, /* 0 = incoming, 1 = outgoing */
+ int controller, /* controller number */
int channel, /* channel no, used to identify this connection until disconnect */
- const char * cfgname, /* name of config entry/connection */
- const char * devname, /* device used (e.g. isp0) */
- const char * remphone, /* phone no of remote side */
- const char * locphone) /* local phone no */
+ char * cfgname, /* name of config entry/connection */
+ char * devname, /* device used (e.g. isp0) */
+ char * remphone, /* phone no of remote side */
+ char * locphone) /* local phone no */
{
char buf[256];
- strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
- if (outgoing)
- printf("%s: calling out to '%s' [from msn: '%s']",
+ if(channel == 0)
+ remstate[controller].ch1state = 1;
+ else
+ remstate[controller].ch2state = 1;
+
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+
+ if(outgoing)
+ mprintf("%s: calling out to '%s' [from msn: '%s']",
buf, remphone, locphone);
else
- printf("%s: incoming call from '%s' [to msn: '%s']",
+ mprintf("%s: incoming call from '%s' [to msn: '%s']",
buf, remphone, locphone);
- printf(", channel %d, config '%s' on device '%s'\n",
- channel, cfgname, devname);
+ mprintf(", controller %d, channel %d, config '%s' on device '%s'\n",
+ controller, channel, cfgname, devname);
+
+#ifndef WIN32
+ if(fullscreen)
+ display_connect(CHPOS(controller, channel), outgoing, cfgname, remphone, devname);
+#endif
}
/*
@@ -419,59 +597,159 @@ static void print_connect(
* A real monitor could free the "per connection" state
* for this channel now
*/
-static void print_disconnect(time_t tstamp, int channel)
+static void
+print_disconnect(time_t tstamp, int controller, int channel)
{
char buf[256];
- strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
- printf("%s: channel %d disconnected\n",
- buf, channel);
+
+ if(channel == 0)
+ remstate[controller].ch1state = 0;
+ else
+ remstate[controller].ch2state = 0;
+
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+
+ mprintf("%s: controller %d, channel %d disconnected\n",
+ buf, controller, channel);
+
+#ifndef WIN32
+ if(fullscreen)
+ display_disconnect(CHPOS(controller, channel));
+#endif
}
/*
* Print an up- or down event
*/
-static void print_updown(time_t tstamp, int channel, int isup)
+static void
+print_updown(time_t tstamp, int controller, int channel, int isup)
{
char buf[256];
- strftime(buf, sizeof buf, I4B_TIME_FORMAT, localtime(&tstamp));
- printf("%s: channel %d is %s\n",
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+ mprintf("%s: channel %d is %s\n",
buf, channel, isup ? "up" : "down");
}
/*
+ * Print l1 / l2 status
+ */
+static void
+print_l12stat(time_t tstamp, int controller, int layer, int state)
+{
+ char buf[256];
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+
+ mprintf("%s: layer %d change on controller %d: %s\n",
+ buf, layer, controller, state ? "up" : "down");
+#ifndef WIN32
+ if(fullscreen)
+ display_l12stat(controller, layer, state);
+#endif
+}
+
+/*
+ * Print TEI
+ */
+static void
+print_tei(time_t tstamp, int controller, int tei)
+{
+ char buf[256];
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+
+ mprintf("%s: controller %d, TEI is %d\n",
+ buf, controller, tei);
+
+#ifndef WIN32
+ if(fullscreen)
+ display_tei(controller, tei);
+#endif
+}
+
+/*
+ * Print accounting information
+ */
+static void
+print_acct(time_t tstamp, int controller, int channel, int obytes, int obps,
+ int ibytes, int ibps)
+{
+ char buf[256];
+ strftime(buf, sizeof(buf), I4B_TIME_FORMAT, localtime(&tstamp));
+
+ mprintf("%s: controller %d, channel %d: %d obytes, %d obps, %d ibytes, %d ibps\n",
+ buf, controller, channel, obytes, obps, ibytes, ibps);
+#ifndef WIN32
+ if(fullscreen)
+ display_acct(CHPOS(controller, channel), obytes, obps, ibytes, ibps);
+#endif
+}
+
+static void
+print_initialization(void)
+{
+#ifndef WIN32
+ if(fullscreen)
+ {
+ if(curses_ready == 0)
+ init_screen();
+ }
+ else
+#endif
+ {
+ print_menu();
+ }
+}
+
+/*
* Dispatch one message received from the daemon.
*/
-static void handle_event(BYTE *msg, int len)
+static void
+handle_event(u_int8_t *msg, int len)
{
- BYTE cmd[I4B_MON_ICLIENT_SIZE];
+ u_int8_t cmd[I4B_MON_ICLIENT_SIZE];
int local;
u_int32_t net;
u_int32_t mask;
u_int32_t who;
+ static int first = 1;
- switch (state)
+ switch(state)
{
- case 0: /* initial data */
+ case ST_INIT: /* initial data */
isdn_major = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMAJOR);
isdn_minor = I4B_GET_2B(msg, I4B_MON_IDATA_VERSMINOR);
nctrl = I4B_GET_2B(msg, I4B_MON_IDATA_NUMCTRL);
+ nentries = I4B_GET_2B(msg, I4B_MON_IDATA_NUMENTR);
rights = I4B_GET_4B(msg, I4B_MON_IDATA_CLACCESS);
- printf("remote protocol version is %02d.%02d, %d controller(s) found, our rights = %x\n",
- isdn_major, isdn_minor, nctrl, rights);
+ mprintf("remote protocol version is %02d.%02d\n", isdn_major, isdn_minor);
- if (nctrl > 0)
+ if(isdn_major != MPROT_VERSION || isdn_minor != MPROT_REL)
{
- state = 1;
- sub_state = 0;
+ fprintf(stderr, "ERROR, remote protocol version mismatch:\n");
+ fprintf(stderr, "\tremote major version is %02d, local major version is %02d\n", isdn_major, MPROT_VERSION);
+ fprintf(stderr, "\tremote minor version is %02d, local minor version is %02d\n", isdn_minor, MPROT_REL);
+ exit(1);
+ }
+
+ mprintf("our rights = 0x%x\n", rights);
+
+ sub_state = 0;
+ first = 1;
+
+ if(nctrl > 0)
+ {
+ state = ST_ICTRL;
+ }
+ else if(nentries > 0)
+ {
+ state = ST_IDEV;
}
else
{
- state = 2;
-
- /* show menu for the first time */
- print_menu();
+ state = ST_ANYEV;
+ sleep(2);
+ print_initialization();
}
/* set maximum event mask */
@@ -481,43 +759,79 @@ static void handle_event(BYTE *msg, int len)
I4B_PUT_4B(cmd, I4B_MON_ICLIENT_EVENTS, ~0U);
#ifdef DEBUG
- if (dumpall)
- dump_event(cmd, sizeof cmd, 0);
+ if(debug & DBG_DUMPALL)
+ dump_event(cmd, sizeof(cmd), 0);
#endif
- write(monsock, cmd, sizeof cmd);
-
+ if((sock_write(monsock, cmd, sizeof(cmd))) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
break;
- case 1: /* initial controller list */
- printf("controller %d: %s\n", sub_state++, msg+I4B_MON_ICTRL_NAME);
+ case ST_ICTRL: /* initial controller list */
+ if(first)
+ {
+ first = 0;
+ mprintf("%d controller(s) found:\n", nctrl);
+ }
+ mprintf("\tcontroller %d: %s\n", sub_state++, msg+I4B_MON_ICTRL_NAME);
- if (sub_state >= nctrl)
+ if(sub_state >= nctrl)
{
- state = 2; /* end of list reached */
sub_state = 0;
-
- /* show menu for the first time */
- print_menu();
+ first = 1;
+ if(nentries > 0)
+ {
+ state = ST_IDEV; /* end of list reached */
+ }
+ else
+ {
+ state = ST_ANYEV;
+ sleep(2);
+ print_initialization();
+ }
}
break;
- case 2: /* any event */
+ case ST_IDEV: /* initial entry devicename list */
+ if(first)
+ {
+ first = 0;
+ mprintf("%d entries found:\n", nentries);
+ }
+
+ mprintf("\tentry %d: device %s\n", sub_state++, msg+I4B_MON_IDEV_NAME);
- switch (I4B_GET_2B(msg, I4B_MON_EVNT))
+ strcat(devbuf, msg+I4B_MON_IDEV_NAME);
+ /* strcat(devbuf, " "); */
+
+ if(sub_state >= nentries)
+ {
+ first = 1;
+ state = ST_ANYEV; /* end of list reached */
+ sub_state = 0;
+ sleep(2);
+ print_initialization();
+ }
+ break;
+
+ case ST_ANYEV: /* any event */
+ switch(I4B_GET_2B(msg, I4B_MON_EVNT))
{
case I4B_MON_DRINI_CODE:
- state = 3; /* list of rights entries will follow */
+ state = ST_RIGHT; /* list of rights entries will follow */
sub_state = 0;
sub_state_count = I4B_GET_2B(msg, I4B_MON_DRINI_COUNT);
- printf("monitor rights:\n");
+ mprintf("monitor rights:\n");
break;
case I4B_MON_DCINI_CODE:
- state = 4;
+ state = ST_CONNS;
sub_state = 0;
sub_state_count = I4B_GET_2B(msg, I4B_MON_DCINI_COUNT);
- printf("monitor connections:\n");
+ mprintf("monitor connections:\n");
break;
case I4B_MON_LOGEVNT_CODE:
@@ -526,9 +840,10 @@ static void handle_event(BYTE *msg, int len)
msg+I4B_MON_LOGEVNT_WHAT,
msg+I4B_MON_LOGEVNT_MSG);
break;
-
+
case I4B_MON_CHRG_CODE:
print_charge(I4B_GET_4B(msg, I4B_MON_CHRG_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_CHRG_CTRL),
I4B_GET_4B(msg, I4B_MON_CHRG_CHANNEL),
I4B_GET_4B(msg, I4B_MON_CHRG_UNITS),
I4B_GET_4B(msg, I4B_MON_CHRG_ESTIMATED));
@@ -538,6 +853,7 @@ static void handle_event(BYTE *msg, int len)
print_connect(
I4B_GET_4B(msg, I4B_MON_CONNECT_TSTAMP),
I4B_GET_4B(msg, I4B_MON_CONNECT_DIR),
+ I4B_GET_4B(msg, I4B_MON_CONNECT_CTRL),
I4B_GET_4B(msg, I4B_MON_CONNECT_CHANNEL),
msg+I4B_MON_CONNECT_CFGNAME,
msg+I4B_MON_CONNECT_DEVNAME,
@@ -548,34 +864,58 @@ static void handle_event(BYTE *msg, int len)
case I4B_MON_DISCONNECT_CODE:
print_disconnect(
I4B_GET_4B(msg, I4B_MON_DISCONNECT_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_DISCONNECT_CTRL),
I4B_GET_4B(msg, I4B_MON_DISCONNECT_CHANNEL));
break;
case I4B_MON_UPDOWN_CODE:
print_updown(
I4B_GET_4B(msg, I4B_MON_UPDOWN_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_UPDOWN_CTRL),
I4B_GET_4B(msg, I4B_MON_UPDOWN_CHANNEL),
I4B_GET_4B(msg, I4B_MON_UPDOWN_ISUP));
break;
-
+ case I4B_MON_L12STAT_CODE:
+ print_l12stat(
+ I4B_GET_4B(msg, I4B_MON_L12STAT_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_L12STAT_CTRL),
+ I4B_GET_4B(msg, I4B_MON_L12STAT_LAYER),
+ I4B_GET_4B(msg, I4B_MON_L12STAT_STATE));
+ break;
+ case I4B_MON_TEI_CODE:
+ print_tei(
+ I4B_GET_4B(msg, I4B_MON_TEI_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_TEI_CTRL),
+ I4B_GET_4B(msg, I4B_MON_TEI_TEI));
+ break;
+ case I4B_MON_ACCT_CODE:
+ print_acct(
+ I4B_GET_4B(msg, I4B_MON_ACCT_TSTAMP),
+ I4B_GET_4B(msg, I4B_MON_ACCT_CTRL),
+ I4B_GET_4B(msg, I4B_MON_ACCT_CHAN),
+ I4B_GET_4B(msg, I4B_MON_ACCT_OBYTES),
+ I4B_GET_4B(msg, I4B_MON_ACCT_OBPS),
+ I4B_GET_4B(msg, I4B_MON_ACCT_IBYTES),
+ I4B_GET_4B(msg, I4B_MON_ACCT_IBPS));
+ break;
default:
- printf("unknown event code: %d\n", I4B_GET_2B(msg, I4B_MON_EVNT));
+ mprintf("unknown event code: %d\n", I4B_GET_2B(msg, I4B_MON_EVNT));
}
break;
- case 3: /* one record in a list of monitor rights */
+ case ST_RIGHT: /* one record in a list of monitor rights */
rights = I4B_GET_4B(msg, I4B_MON_DR_RIGHTS);
net = I4B_GET_4B(msg, I4B_MON_DR_NET);
mask = I4B_GET_4B(msg, I4B_MON_DR_MASK);
local = I4B_GET_1B(msg, I4B_MON_DR_LOCAL);
- if (local)
+ if(local)
{
- printf("\tlocal: rights = %x\n", rights);
+ mprintf("\tlocal: rights = %x\n", rights);
}
else
{
- printf("\tfrom: %d.%d.%d.%d, mask %d.%d.%d.%d, rights = %x\n",
+ mprintf("\tfrom: %d.%d.%d.%d, mask %d.%d.%d.%d, rights = %x\n",
(net >> 24) & 0x00ff, (net >> 16) & 0x00ff, (net >> 8) & 0x00ff, net & 0x00ff,
(mask >> 24) & 0x00ff, (mask >> 16) & 0x00ff, (mask >> 8) & 0x00ff, mask & 0x00ff,
rights);
@@ -583,32 +923,32 @@ static void handle_event(BYTE *msg, int len)
sub_state++;
- if (sub_state >= sub_state_count)
+ if(sub_state >= sub_state_count)
{
- state = 2;
- print_menu();
+ state = ST_ANYEV;
+ print_initialization();
}
break;
- case 4:
+ case ST_CONNS:
who = I4B_GET_4B(msg, I4B_MON_DC_WHO);
rights = I4B_GET_4B(msg, I4B_MON_DC_RIGHTS);
- printf("\tfrom: %d.%d.%d.%d, rights = %x\n",
+ mprintf("\tfrom: %d.%d.%d.%d, rights = %x\n",
(who >> 24) & 0x00ff, (who >> 16) & 0x00ff, (who >> 8) & 0x00ff, who & 0x00ff,
rights);
sub_state++;
- if (sub_state >= sub_state_count)
+ if(sub_state >= sub_state_count)
{
- state = 2;
- print_menu();
+ state = ST_ANYEV;
+ print_initialization();
}
break;
default:
- printf("unknown event from remote: local state = %d, evnt = %x, len = %d\n",
+ mprintf("unknown event from remote: local state = %d, evnt = %x, len = %d\n",
state, I4B_GET_2B(msg, I4B_MON_EVNT), len);
}
}
@@ -616,68 +956,92 @@ static void handle_event(BYTE *msg, int len)
/*
* Process input from user
*/
-static void handle_input()
+static void
+handle_input()
{
char buf[1024];
- int channel;
+ int channel, controller;
- fgets(buf, sizeof buf, stdin);
+ fgets(buf, sizeof(buf), stdin);
- switch (atoi(buf))
+ switch(atoi(buf))
{
case 1:
{
- BYTE cmd[I4B_MON_DUMPRIGHTS_SIZE];
+ u_int8_t cmd[I4B_MON_DUMPRIGHTS_SIZE];
I4B_PREP_CMD(cmd, I4B_MON_DUMPRIGHTS_CODE);
#ifdef DEBUG
- if (dumpall)
+ if(debug & DBG_DUMPALL)
dump_event(cmd, I4B_MON_DUMPRIGHTS_SIZE, 0);
#endif
- write(monsock, cmd, I4B_MON_DUMPRIGHTS_SIZE);
+ if((sock_write(monsock, cmd, I4B_MON_DUMPRIGHTS_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
}
break;
case 2:
{
- BYTE cmd[I4B_MON_DUMPMCONS_SIZE];
+ u_int8_t cmd[I4B_MON_DUMPMCONS_SIZE];
I4B_PREP_CMD(cmd, I4B_MON_DUMPMCONS_CODE);
#ifdef DEBUG
- if (dumpall)
+ if(debug & DBG_DUMPALL)
dump_event(cmd, I4B_MON_DUMPMCONS_CODE, 0);
#endif
- write(monsock, cmd, I4B_MON_DUMPMCONS_SIZE);
+ if((sock_write(monsock, cmd, I4B_MON_DUMPMCONS_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
}
break;
case 3:
{
- BYTE cmd[I4B_MON_CFGREREAD_SIZE];
+ u_int8_t cmd[I4B_MON_CFGREREAD_SIZE];
I4B_PREP_CMD(cmd, I4B_MON_CFGREREAD_CODE);
#ifdef DEBUG
- if (dumpall)
+ if(debug & DBG_DUMPALL)
dump_event(cmd, I4B_MON_CFGREREAD_CODE, 0);
#endif
- write(monsock, cmd, I4B_MON_CFGREREAD_SIZE);
+ if((sock_write(monsock, cmd, I4B_MON_CFGREREAD_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
}
break;
case 4:
{
- BYTE cmd[I4B_MON_HANGUP_SIZE];
+ u_int8_t cmd[I4B_MON_HANGUP_SIZE];
I4B_PREP_CMD(cmd, I4B_MON_HANGUP_CODE);
+
+ printf("Which controller you wish to hangup? ");
+ fgets(buf, sizeof(buf), stdin);
+ controller = atoi(buf);
+ I4B_PUT_4B(cmd, I4B_MON_HANGUP_CTRL, controller);
+
printf("Which channel do you wish to hangup? ");
- fgets(buf, sizeof buf, stdin);
+ fgets(buf, sizeof(buf), stdin);
channel = atoi(buf);
I4B_PUT_4B(cmd, I4B_MON_HANGUP_CHANNEL, channel);
+
#ifdef DEBUG
- if (dumpall)
+ if(debug & DBG_DUMPALL)
dump_event(cmd, I4B_MON_HANGUP_CHANNEL, 0);
#endif
- write(monsock, cmd, I4B_MON_HANGUP_SIZE);
+ if((sock_write(monsock, cmd, I4B_MON_HANGUP_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
}
break;
@@ -692,12 +1056,141 @@ static void handle_input()
}
}
+void
+reread(void)
+{
+ u_int8_t cmd[I4B_MON_CFGREREAD_SIZE];
+ I4B_PREP_CMD(cmd, I4B_MON_CFGREREAD_CODE);
+#ifdef DEBUG
+ if(debug & DBG_DUMPALL)
+ dump_event(cmd, I4B_MON_CFGREREAD_CODE, 0);
+#endif
+ if((sock_write(monsock, cmd, I4B_MON_CFGREREAD_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
+}
+
+void
+hangup(int ctrl, int chan)
+{
+ u_int8_t cmd[I4B_MON_HANGUP_SIZE];
+
+ I4B_PREP_CMD(cmd, I4B_MON_HANGUP_CODE);
+ I4B_PUT_4B(cmd, I4B_MON_HANGUP_CTRL, ctrl);
+ I4B_PUT_4B(cmd, I4B_MON_HANGUP_CHANNEL, chan);
+
+#ifdef DEBUG
+ if(debug & DBG_DUMPALL)
+ dump_event(cmd, I4B_MON_HANGUP_CHANNEL, 0);
+#endif
+
+ if((sock_write(monsock, cmd, I4B_MON_HANGUP_SIZE)) == -1)
+ {
+ fprintf(stderr, "sock_write failed: %s\n", strerror(errno));
+ exit(1);
+ }
+}
+
/*
* Display menu
*/
-static void print_menu()
+static void
+print_menu()
{
- printf("Menu: <1> display rights, <2> display monitor connections,\n");
- printf(" <3> reread config file, <4> hangup \n");
- printf(" <9> quit isdnmonitor\n");
+ if(!fullscreen)
+ {
+ printf("Menu: <1> display rights, <2> display monitor connections,\n");
+ printf(" <3> reread config file, <4> hangup \n");
+ printf(" <9> quit isdnmonitor\n");
+ fflush(stdout);
+ }
}
+
+static ssize_t
+sock_read(int fd, void *buf, size_t nbytes)
+{
+ size_t nleft;
+ ssize_t nread;
+ unsigned char *ptr;
+
+ ptr = buf;
+ nleft = nbytes;
+
+ while(nleft > 0)
+ {
+ if((nread = read(fd, ptr, nleft)) < 0)
+ {
+ if(errno == EINTR)
+ {
+ nread = 0;
+ }
+ else
+ {
+ return(-1);
+ }
+ }
+ else if(nread == 0)
+ {
+ break; /* EOF */
+ }
+
+ nleft -= nread;
+ ptr += nread;
+ }
+ return(nbytes - nleft);
+}
+
+static ssize_t
+sock_write(int fd, void *buf, size_t nbytes)
+{
+ size_t nleft;
+ ssize_t nwritten;
+ unsigned char *ptr;
+
+ ptr = buf;
+ nleft = nbytes;
+
+ while(nleft > 0)
+ {
+ if((nwritten = write(fd, ptr, nleft)) <= 0)
+ {
+ if(errno == EINTR)
+ {
+ nwritten = 0;
+ }
+ else
+ {
+ return(-1);
+ }
+ }
+
+ nleft -= nwritten;
+ ptr += nwritten;
+ }
+ return(nbytes);
+}
+
+static void
+mprintf(char *fmt, ...)
+{
+#define PRBUFLEN 1024
+ char buffer[PRBUFLEN];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buffer, PRBUFLEN-1, fmt, ap);
+ va_end(ap);
+
+ if(!fullscreen || (fullscreen && (!curses_ready)))
+ printf("%s", buffer);
+
+ if(logfilename != NULL)
+ {
+ fprintf(lfp, "%s", buffer);
+ fflush(lfp);
+ }
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnmonitor/monitor.h b/usr.sbin/i4b/isdnmonitor/monitor.h
index 8a87240..f5d532f 100644
--- a/usr.sbin/i4b/isdnmonitor/monitor.h
+++ b/usr.sbin/i4b/isdnmonitor/monitor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998 Martin Husemann. All rights reserved.
+ * Copyright (c) 1998,1999 Martin Husemann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,21 +30,19 @@
*
*---------------------------------------------------------------------------
*
- * i4b daemon - network monitor protocl definition
- * -----------------------------------------------
+ * i4b daemon - network monitor protocol definition
+ * ------------------------------------------------
*
- * $FreeBSD$
+ * $Id: monitor.h,v 1.16 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun May 30 15:50:10 1999]
+ * $FreeBSD$
*
- * -mh created
- * -hm checking in
- * -hm ported to HPUX 10.10
+ * last edit-date: [Mon Dec 13 21:52:18 1999]
*
*---------------------------------------------------------------------------*/
-#ifndef MONITOR_H
-#define MONITOR_H
+#ifndef _MONITOR_H_
+#define _MONITOR_H_
#define DEF_MONPORT 451 /* default monitor TCP port */
@@ -52,9 +50,9 @@
#define u_int8_t ubit8
#define u_int32_t ubit32
#endif
-#ifdef _WIN32
+#ifdef WIN32
#define u_int8_t BYTE
-#define u_in32_t DWORD
+#define u_int32_t DWORD
#endif
/*
@@ -71,8 +69,7 @@
* All multi-byte values are in network byte order!
*/
-/* All data packets transfered are declared as arrays of BYTE */
-#define BYTE u_int8_t
+/* All data packets transfered are declared as arrays of u_int8_t */
/* max stringlength used in this protocol */
#define I4B_MAX_MON_STRING 256
@@ -81,15 +78,8 @@
#define I4B_MAX_MON_CLIENT_CMD 16
/* Version of the monitor protocol described here */
-#define MPROT_VERSION 0 /* major version no */
-#define MPROT_REL 1 /* release no */
-/*
- * We intend to keep different versions of monitor client and isdnd
- * interoperable as long as possible. We do not, however, even try
- * to do this during early alpha or beta release phases. If you run
- * developement versions at this stage, make sure all your clients
- * and servers run the same version!
- */
+#define MPROT_VERSION 0 /* major version no */
+#define MPROT_REL 5 /* release no */
/*
* Client access rights
@@ -120,12 +110,13 @@
#define I4B_MON_EVNT_HDR 4 /* size of header */
/* Initial data send by daemon after connection is established */
-#define I4B_MON_IDATA_SIZE I4B_MON_EVNT_HDR+10
+#define I4B_MON_IDATA_SIZE I4B_MON_EVNT_HDR+12
#define I4B_MON_IDATA_CODE 0 /* event code */
#define I4B_MON_IDATA_VERSMAJOR I4B_MON_EVNT_HDR+0 /* 2 byte: isdnd major version */
#define I4B_MON_IDATA_VERSMINOR I4B_MON_EVNT_HDR+2 /* 2 byte: isdnd minor version */
#define I4B_MON_IDATA_NUMCTRL I4B_MON_EVNT_HDR+4 /* 2 byte: number of controllers */
-#define I4B_MON_IDATA_CLACCESS I4B_MON_EVNT_HDR+6 /* 4 byte: client rights */
+#define I4B_MON_IDATA_NUMENTR I4B_MON_EVNT_HDR+6 /* 2 byte: number of controllers */
+#define I4B_MON_IDATA_CLACCESS I4B_MON_EVNT_HDR+8 /* 4 byte: client rights */
/* followed by this for every controller */
#define I4B_MON_ICTRL_SIZE I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+8
@@ -135,8 +126,16 @@
#define I4B_MON_ICTRL_FLAGS I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+2 /* 4 byte: controller flags (not yet defined) */
#define I4B_MON_ICTRL_NCHAN I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+6 /* 2 byte: number of b channels on this controller */
-/* The client sets it's protocol version and event mask (usualy once after
- * connection establishement) */
+/* followed by this for every entry */
+#define I4B_MON_IDEV_SIZE I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+2
+#define I4B_MON_IDEV_CODE 2 /* event code */
+#define I4B_MON_IDEV_NAME I4B_MON_EVNT_HDR+0 /* string: name of device */
+#define I4B_MON_IDEV_STATE I4B_MON_EVNT_HDR+I4B_MAX_MON_STRING+0 /* 2 byte: state of device */
+
+/*
+ * The client sets it's protocol version and event mask (usually once after
+ * connection establishement)
+ */
#define I4B_MON_CCMD_SETMASK 0x7e /* command code */
#define I4B_MON_ICLIENT_SIZE I4B_MON_CMD_HDR+8
#define I4B_MON_ICLIENT_VERMAJOR I4B_MON_CMD_HDR+0 /* 2 byte: protocol major version (always 0 for now) */
@@ -147,8 +146,10 @@
#define I4B_MON_DUMPRIGHTS_CODE 1
#define I4B_MON_DUMPRIGHTS_SIZE I4B_MON_CMD_HDR /* no parameters */
-/* in response to a I4B_MON_DUMPRIGHTS_CODE command, the daemon sends
- * this event: */
+/*
+ * in response to a I4B_MON_DUMPRIGHTS_CODE command, the daemon sends
+ * this event:
+ */
#define I4B_MON_DRINI_CODE 2 /* event code */
#define I4B_MON_DRINI_SIZE I4B_MON_EVNT_HDR+2 /* size of packet */
#define I4B_MON_DRINI_COUNT I4B_MON_EVNT_HDR+0 /* 2 byte: number of records */
@@ -165,8 +166,10 @@
#define I4B_MON_DUMPMCONS_CODE 2
#define I4B_MON_DUMPMCONS_SIZE I4B_MON_CMD_HDR /* no parameters */
-/* in response to a I4B_MON_DUMPMCONS_CODE command, the daemon sends
- * this event: */
+/*
+ * in response to a I4B_MON_DUMPMCONS_CODE command, the daemon sends
+ * this event:
+ */
#define I4B_MON_DCINI_CODE 4 /* event code */
#define I4B_MON_DCINI_SIZE I4B_MON_EVNT_HDR+2 /* size of packet */
#define I4B_MON_DCINI_COUNT I4B_MON_EVNT_HDR+0 /* 2 byte: number of records */
@@ -183,8 +186,9 @@
/* The client requests to hangup a connection */
#define I4B_MON_HANGUP_CODE 4
-#define I4B_MON_HANGUP_SIZE I4B_MON_CMD_HDR+4
-#define I4B_MON_HANGUP_CHANNEL I4B_MON_CMD_HDR+0 /* channel to drop */
+#define I4B_MON_HANGUP_SIZE I4B_MON_CMD_HDR+8
+#define I4B_MON_HANGUP_CTRL I4B_MON_CMD_HDR+0 /* controller */
+#define I4B_MON_HANGUP_CHANNEL I4B_MON_CMD_HDR+4 /* channel */
/* The daemon sends a logfile event */
#define I4B_MON_LOGEVNT_CODE 6
@@ -196,35 +200,65 @@
/* The daemon sends a charge event */
#define I4B_MON_CHRG_CODE 7
-#define I4B_MON_CHRG_SIZE I4B_MON_EVNT_HDR+16
+#define I4B_MON_CHRG_SIZE I4B_MON_EVNT_HDR+20
#define I4B_MON_CHRG_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: timestamp */
-#define I4B_MON_CHRG_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel charged */
-#define I4B_MON_CHRG_UNITS I4B_MON_EVNT_HDR+8 /* 4 byte: new charge value */
-#define I4B_MON_CHRG_ESTIMATED I4B_MON_EVNT_HDR+12 /* 4 byte: 0 = charge by network, 1 = calculated estimate */
+#define I4B_MON_CHRG_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: channel charged */
+#define I4B_MON_CHRG_CHANNEL I4B_MON_EVNT_HDR+8 /* 4 byte: channel charged */
+#define I4B_MON_CHRG_UNITS I4B_MON_EVNT_HDR+12 /* 4 byte: new charge value */
+#define I4B_MON_CHRG_ESTIMATED I4B_MON_EVNT_HDR+16 /* 4 byte: 0 = charge by network, 1 = calculated estimate */
/* The daemon sends a connect event */
#define I4B_MON_CONNECT_CODE 8
-#define I4B_MON_CONNECT_SIZE I4B_MON_EVNT_HDR+12+4*I4B_MAX_MON_STRING
+#define I4B_MON_CONNECT_SIZE I4B_MON_EVNT_HDR+16+4*I4B_MAX_MON_STRING
#define I4B_MON_CONNECT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
#define I4B_MON_CONNECT_DIR I4B_MON_EVNT_HDR+4 /* 4 byte: direction (0 = incoming, 1 = outgoing) */
-#define I4B_MON_CONNECT_CHANNEL I4B_MON_EVNT_HDR+8 /* 4 byte: channel connected */
-#define I4B_MON_CONNECT_CFGNAME I4B_MON_EVNT_HDR+12 /* name of config entry */
-#define I4B_MON_CONNECT_DEVNAME I4B_MON_EVNT_HDR+12+I4B_MAX_MON_STRING /* name of device used for connection */
-#define I4B_MON_CONNECT_REMPHONE I4B_MON_EVNT_HDR+12+2*I4B_MAX_MON_STRING /* remote phone no. */
-#define I4B_MON_CONNECT_LOCPHONE I4B_MON_EVNT_HDR+12+3*I4B_MAX_MON_STRING /* local phone no. */
+#define I4B_MON_CONNECT_CTRL I4B_MON_EVNT_HDR+8 /* 4 byte: channel connected */
+#define I4B_MON_CONNECT_CHANNEL I4B_MON_EVNT_HDR+12 /* 4 byte: channel connected */
+#define I4B_MON_CONNECT_CFGNAME I4B_MON_EVNT_HDR+16 /* name of config entry */
+#define I4B_MON_CONNECT_DEVNAME I4B_MON_EVNT_HDR+16+I4B_MAX_MON_STRING /* name of device used for connection */
+#define I4B_MON_CONNECT_REMPHONE I4B_MON_EVNT_HDR+16+2*I4B_MAX_MON_STRING /* remote phone no. */
+#define I4B_MON_CONNECT_LOCPHONE I4B_MON_EVNT_HDR+16+3*I4B_MAX_MON_STRING /* local phone no. */
/* The daemon sends a disconnect event */
#define I4B_MON_DISCONNECT_CODE 9
-#define I4B_MON_DISCONNECT_SIZE I4B_MON_EVNT_HDR+8
+#define I4B_MON_DISCONNECT_SIZE I4B_MON_EVNT_HDR+12
#define I4B_MON_DISCONNECT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
-#define I4B_MON_DISCONNECT_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
+#define I4B_MON_DISCONNECT_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
+#define I4B_MON_DISCONNECT_CHANNEL I4B_MON_EVNT_HDR+8 /* 4 byte: channel disconnected */
/* The daemon sends an up/down event */
#define I4B_MON_UPDOWN_CODE 10
-#define I4B_MON_UPDOWN_SIZE I4B_MON_EVNT_HDR+12
+#define I4B_MON_UPDOWN_SIZE I4B_MON_EVNT_HDR+16
#define I4B_MON_UPDOWN_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
-#define I4B_MON_UPDOWN_CHANNEL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
-#define I4B_MON_UPDOWN_ISUP I4B_MON_EVNT_HDR+8 /* 4 byte: interface is up */
+#define I4B_MON_UPDOWN_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: channel disconnected */
+#define I4B_MON_UPDOWN_CHANNEL I4B_MON_EVNT_HDR+8 /* 4 byte: channel disconnected */
+#define I4B_MON_UPDOWN_ISUP I4B_MON_EVNT_HDR+12 /* 4 byte: interface is up */
+
+/* The daemon sends a L1/L2 status change event */
+#define I4B_MON_L12STAT_CODE 11
+#define I4B_MON_L12STAT_SIZE I4B_MON_EVNT_HDR+16
+#define I4B_MON_L12STAT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_L12STAT_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: controller */
+#define I4B_MON_L12STAT_LAYER I4B_MON_EVNT_HDR+8 /* 4 byte: layer */
+#define I4B_MON_L12STAT_STATE I4B_MON_EVNT_HDR+12 /* 4 byte: state */
+
+/* The daemon sends a TEI change event */
+#define I4B_MON_TEI_CODE 12
+#define I4B_MON_TEI_SIZE I4B_MON_EVNT_HDR+12
+#define I4B_MON_TEI_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_TEI_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: controller */
+#define I4B_MON_TEI_TEI I4B_MON_EVNT_HDR+8 /* 4 byte: tei */
+
+/* The daemon sends an accounting message event */
+#define I4B_MON_ACCT_CODE 13
+#define I4B_MON_ACCT_SIZE I4B_MON_EVNT_HDR+28
+#define I4B_MON_ACCT_TSTAMP I4B_MON_EVNT_HDR+0 /* 4 byte: time stamp */
+#define I4B_MON_ACCT_CTRL I4B_MON_EVNT_HDR+4 /* 4 byte: controller */
+#define I4B_MON_ACCT_CHAN I4B_MON_EVNT_HDR+8 /* 4 byte: channel */
+#define I4B_MON_ACCT_OBYTES I4B_MON_EVNT_HDR+12 /* 4 byte: outbytes */
+#define I4B_MON_ACCT_OBPS I4B_MON_EVNT_HDR+16 /* 4 byte: outbps */
+#define I4B_MON_ACCT_IBYTES I4B_MON_EVNT_HDR+20 /* 4 byte: inbytes */
+#define I4B_MON_ACCT_IBPS I4B_MON_EVNT_HDR+24 /* 4 byte: inbps */
/* macros for setup/decoding of protocol packets */
@@ -244,20 +278,22 @@
}
/* put 1, 2 or 4 bytes in network byte order into a record at offset off */
-#define I4B_PUT_1B(r, off, val) { ((BYTE*)(r))[off] = (val) & 0x00ff; }
+#define I4B_PUT_1B(r, off, val) { ((u_int8_t*)(r))[off] = (val) & 0x00ff; }
#define I4B_PUT_2B(r, off, val) { I4B_PUT_1B(r, off, val >> 8); I4B_PUT_1B(r, off+1, val); }
#define I4B_PUT_4B(r, off, val) { I4B_PUT_1B(r, off, val >> 24); I4B_PUT_1B(r, off+1, val >> 16); I4B_PUT_1B(r, off+2, val >> 8); I4B_PUT_1B(r, off+3, val); }
/* get 1, 2 or 4 bytes in network byte order from a record at offset off */
-#define I4B_GET_1B(r, off) (((BYTE*)(r))[off])
-#define I4B_GET_2B(r, off) ((((BYTE*)(r))[off]) << 8) | (((BYTE*)(r))[off+1])
-#define I4B_GET_4B(r, off) ((((BYTE*)(r))[off]) << 24) | ((((BYTE*)(r))[off+1]) << 16) | ((((BYTE*)(r))[off+2]) << 8) | (((BYTE*)(r))[off+3])
+#define I4B_GET_1B(r, off) (((u_int8_t*)(r))[off])
+#define I4B_GET_2B(r, off) ((((u_int8_t*)(r))[off]) << 8) | (((u_int8_t*)(r))[off+1])
+#define I4B_GET_4B(r, off) ((((u_int8_t*)(r))[off]) << 24) | ((((u_int8_t*)(r))[off+1]) << 16) | ((((u_int8_t*)(r))[off+2]) << 8) | (((u_int8_t*)(r))[off+3])
-/* put a string into recor r at offset off, make sure it's not to long
- * and proper terminate it */
+/*
+ * put a string into record r at offset off, make sure it's not to long
+ * and proper terminate it
+ */
#define I4B_PUT_STR(r, off, str) { \
strncpy((r)+(off), (str), I4B_MAX_MON_STRING); \
- (r)[(off)+I4B_MAX_MON_STRING-1] = (BYTE)0; }
+ (r)[(off)+I4B_MAX_MON_STRING-1] = (u_int8_t)0; }
-#endif /* MONITOR_H */
+#endif /* _MONITOR_H_ */
diff --git a/usr.sbin/i4b/isdnmonitor/monprivate.h b/usr.sbin/i4b/isdnmonitor/monprivate.h
new file mode 100644
index 0000000..ec6ec4d
--- /dev/null
+++ b/usr.sbin/i4b/isdnmonitor/monprivate.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b remote monitor - private header
+ * -----------------------------------
+ *
+ * $Id: monprivate.h,v 1.10 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:52:25 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#include <syslog.h>
+#include <regex.h>
+#include <curses.h>
+#include <fcntl.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#endif
+
+/*---------------------------------------------------------------------------*
+ * definitions in i4b_ioctl.h, do something for other systems
+ *---------------------------------------------------------------------------*/
+#if defined (__FreeBSD__) || defined(__NetBSD__) || \
+ defined (__OpenBSD__) || defined(__bsdi__)
+
+#include <machine/i4b_ioctl.h>
+
+#else
+
+#define FOREIGN 1 /* we are running on a "foreign" OS */
+
+#define I4B_TIME_FORMAT "%d.%m.%Y %H:%M:%S"
+#define VERSION 0
+#define REL 0
+#define STEP 0
+
+#endif
+
+/*---------------------------------------------------------------------------*
+ * some general definitions
+ *---------------------------------------------------------------------------*/
+#define GOOD 0 /* general "good" or "ok" return*/
+#define ERROR (-1) /* general error return */
+#define WARNING (-2) /* warning return */
+#define INVALID (-1) /* an invalid integer */
+
+/*---------------------------------------------------------------------------*
+ * state definitions
+ *---------------------------------------------------------------------------*/
+#define ST_INIT 0 /* initial data */
+#define ST_ICTRL 1 /* initial controller list */
+#define ST_IDEV 2 /* initial entry devicename list */
+#define ST_ANYEV 3 /* any event */
+#define ST_RIGHT 4 /* one record in a list of monitor rights */
+#define ST_CONNS 5 /* monitor connections */
+
+/*---------------------------------------------------------------------------*
+ * curses fullscreen display definitions
+ *---------------------------------------------------------------------------*/
+/* window dimensions */
+#define UPPER_B 2 /* upper window start */
+
+/* horizontal positions for upper window */
+#define H_CNTL 0 /* controller */
+#define H_TEI 2 /* TEI */
+#define H_CHAN (H_TEI+4) /* channel */
+#define H_TELN (H_CHAN+2) /* telephone number */
+#define H_IFN (H_TELN+23) /* interfacename */
+#define H_IO (H_IFN+7) /* incoming or outgoing */
+#define H_OUT (H_IO+4) /* # of bytes out */
+#define H_OUTBPS (H_OUT+11) /* bytes per second out */
+#define H_IN (H_OUTBPS+5) /* # of bytes in */
+#define H_INBPS (H_IN+11) /* bytes per second in */
+#define H_UNITS (H_INBPS+6) /* # of charging units */
+
+/* fullscreen mode menu window */
+#define WMENU_LEN 35 /* width of menu window */
+#define WMENU_TITLE "Command" /* title string */
+#define WMENU_POSLN 10 /* menu position, line */
+#define WMENU_POSCO 5 /* menu position, col */
+#define WMITEMS 4 /* no of menu items */
+#define WMENU_HGT (WMITEMS + 4) /* menu window height */
+
+#define WREFRESH 0
+#define WHANGUP 1
+#define WREREAD 2
+#define WQUIT 3
+
+#define WMTIMEOUT 5 /* timeout in seconds */
+
+/*---------------------------------------------------------------------------*
+ * misc
+ *---------------------------------------------------------------------------*/
+#define CHPOS(uctlr, uchan) (((uctlr)*2) + (uchan))
+
+/*---------------------------------------------------------------------------*
+ * remote state
+ *---------------------------------------------------------------------------*/
+
+#define MAX_CTRL 4
+
+typedef struct remstate {
+ int ch1state;
+ int ch2state;
+} remstate_t;
+
+/*---------------------------------------------------------------------------*
+ * global variables
+ *---------------------------------------------------------------------------*/
+#ifdef MAIN
+
+remstate_t remstate[MAX_CTRL];
+
+int nctrl = 0; /* # of controllers available */
+int curses_ready = 0; /* curses initialized */
+int do_bell = 0;
+int nentries = 0;
+int fullscreen = 0;
+int debug_noscreen = 0;
+
+#ifndef WIN32
+WINDOW *upper_w; /* curses upper window pointer */
+WINDOW *mid_w; /* curses mid window pointer */
+WINDOW *lower_w; /* curses lower window pointer */
+#endif
+
+char devbuf[256];
+
+char *sockpath = NULL;
+char *hostname = NULL;
+int portno;
+
+#else /* !MAIN */
+
+remstate_t remstate[MAX_CTRL];
+
+int nctrl;
+int curses_ready;
+int do_bell;
+int nentries;
+int fullscreen;
+int debug_noscreen;
+
+WINDOW *upper_w;
+WINDOW *mid_w;
+WINDOW *lower_w;
+
+char devbuf[256];
+
+char *sockpath;
+char *hostname;
+int portno;
+
+#endif
+
+extern void do_exit ( int exitval );
+extern void do_menu ( void );
+extern void init_screen ( void );
+extern void display_charge ( int pos, int charge );
+extern void display_ccharge ( int pos, int units );
+extern void display_connect(int pos, int dir, char *name, char *remtel, char *dev);
+extern void display_acct ( int pos, int obyte, int obps, int ibyte, int ibps );
+extern void display_disconnect ( int pos );
+extern void display_updown ( int pos, int updown, char *device );
+extern void display_l12stat ( int controller, int layer, int state );
+extern void display_tei ( int controller, int tei );
+
+extern void reread(void);
+extern void hangup(int ctrl, int chan);
+
+
diff --git a/usr.sbin/i4b/isdntel/alias.c b/usr.sbin/i4b/isdntel/alias.c
index 7663496..0f4dae7 100644
--- a/usr.sbin/i4b/isdntel/alias.c
+++ b/usr.sbin/i4b/isdntel/alias.c
@@ -27,9 +27,11 @@
* isdntel - isdn4bsd telephone answering machine support
* ======================================================
*
- * $FreeBSD$
+ * $Id: alias.c,v 1.9 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Mon Apr 26 13:53:13 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:53:37 1999]
*
*----------------------------------------------------------------------------*/
@@ -47,10 +49,10 @@ void
init_alias(char *filename)
{
FILE *fp;
- char buffer[MAXBUFSZ + 1];
- char number[MAXBUFSZ + 1];
- char name[MAXBUFSZ + 1];
- char *s, *d;
+ unsigned char buffer[MAXBUFSZ + 1];
+ unsigned char number[MAXBUFSZ + 1];
+ unsigned char name[MAXBUFSZ + 1];
+ unsigned char *s, *d;
struct alias *newa = NULL;
struct alias *lasta = NULL;
diff --git a/usr.sbin/i4b/isdntel/alias.h b/usr.sbin/i4b/isdntel/alias.h
index 1d9e71c..813d5bd 100644
--- a/usr.sbin/i4b/isdntel/alias.h
+++ b/usr.sbin/i4b/isdntel/alias.h
@@ -27,9 +27,11 @@
* isdn4bsd common alias file handling header
* ==========================================
*
+ * $Id: alias.h,v 1.5 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:19:20 1999]
+ * last edit-date: [Mon Dec 13 21:53:44 1999]
*
*----------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntel/defs.h b/usr.sbin/i4b/isdntel/defs.h
index 65109a1..9b5fd69 100644
--- a/usr.sbin/i4b/isdntel/defs.h
+++ b/usr.sbin/i4b/isdntel/defs.h
@@ -27,9 +27,11 @@
* isdntel - isdn4bsd telephone answering support
* ==============================================
*
- * $FreeBSD$
+ * $Id: defs.h,v 1.10 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Mon Apr 26 13:55:35 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:53:50 1999]
*
*----------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntel/display.c b/usr.sbin/i4b/isdntel/display.c
index bf0d898..d1f36fe 100644
--- a/usr.sbin/i4b/isdntel/display.c
+++ b/usr.sbin/i4b/isdntel/display.c
@@ -27,9 +27,11 @@
* isdntel - isdn4bsd telephone answering machine support
* ======================================================
*
- * $FreeBSD$
+ * $Id: display.c,v 1.7 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Mon Apr 26 13:57:08 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:53:57 1999]
*
*----------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntel/files.c b/usr.sbin/i4b/isdntel/files.c
index 6c007d3..54b2074 100644
--- a/usr.sbin/i4b/isdntel/files.c
+++ b/usr.sbin/i4b/isdntel/files.c
@@ -27,9 +27,11 @@
* isdntel - isdn4bsd telephone answering machine support
* ======================================================
*
- * $FreeBSD$
+ * $Id: files.c,v 1.8 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:19:38 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:54:06 1999]
*
*----------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntel/isdntel.8 b/usr.sbin/i4b/isdntel/isdntel.8
index 3c00f64..5dca414 100644
--- a/usr.sbin/i4b/isdntel/isdntel.8
+++ b/usr.sbin/i4b/isdntel/isdntel.8
@@ -22,10 +22,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" last edit-date: [Sun Feb 14 10:19:44 1999]
+.\" last edit-date: [Mon Dec 13 23:05:59 1999]
.\"
.\" $FreeBSD$
.\"
+.\" $Id: isdntel.8,v 1.9 1999/12/13 22:11:55 hm Exp $
+.\"
.Dd July 11, 1998
.Dt ISDNTEL 8
.Os
@@ -82,15 +84,15 @@ when there is no keyboard activity.
.Pp
The screen output should be obvious. If in doubt, consult the source.
.Sh SEE ALSO
-.Xr i4btel 4 ,
-.Xr isdnd.rc 5 ,
.Xr isdnd 8
+.Xr isdnd.rc 5
+.Xr i4btel 4
.Sh BUGS
Still two or more left.
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-utility and this manual page were written by
+utility and this manual page were written by
.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdntel/main.c b/usr.sbin/i4b/isdntel/main.c
index 4eff3a3..da5ec82 100644
--- a/usr.sbin/i4b/isdntel/main.c
+++ b/usr.sbin/i4b/isdntel/main.c
@@ -27,13 +27,16 @@
* isdntel - isdn4bsd telephone answering machine support
* ======================================================
*
- * $FreeBSD$
+ * $Id: main.c,v 1.12 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Fri Jul 30 08:16:03 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:54:26 1999]
*
*----------------------------------------------------------------------------*/
#define MAIN
+#include <locale.h>
#include "defs.h"
#include "alias.h"
@@ -60,6 +63,8 @@ main(int argc, char **argv)
int rrtimeout = REREADTIMEOUT;
extern char *optarg;
+
+ setlocale( LC_ALL, "");
while ((i = getopt(argc, argv, "a:d:p:t:")) != -1)
{
diff --git a/usr.sbin/i4b/isdntelctl/Makefile b/usr.sbin/i4b/isdntelctl/Makefile
index b38f206..c8971e2 100644
--- a/usr.sbin/i4b/isdntelctl/Makefile
+++ b/usr.sbin/i4b/isdntelctl/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
PROG = isdntelctl
SRCS = main.c
MAN8 = isdntelctl.8
diff --git a/usr.sbin/i4b/isdntelctl/isdntelctl.8 b/usr.sbin/i4b/isdntelctl/isdntelctl.8
index 77998ea..617a2a1 100644
--- a/usr.sbin/i4b/isdntelctl/isdntelctl.8
+++ b/usr.sbin/i4b/isdntelctl/isdntelctl.8
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: isdntelctl.8,v 1.9 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Wed Apr 21 11:27:34 1999]
+.\" last edit-date: [Mon Dec 13 23:06:45 1999]
.\"
.Dd April 21, 1999
.Dt ISDNTELCTL 8
@@ -84,12 +86,12 @@ isdntelctl -g
.Pp
displays the currently used sound format for device /dev/i4btel0.
.Sh SEE ALSO
-.Xr g711conv 1 ,
-.Xr i4btel 4 ,
-.Xr isdnd.rc 5 ,
+.Xr i4btel 4
+.Xr g711conv 1
.Xr isdnd 8
-.Sh AUTHORS
+.Xr isdnd.rc 5
+.Sh AUTHOR
The
.Nm
-utility and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+utility and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdntelctl/main.c b/usr.sbin/i4b/isdntelctl/main.c
index 00a57a2..4820fbd 100644
--- a/usr.sbin/i4b/isdntelctl/main.c
+++ b/usr.sbin/i4b/isdntelctl/main.c
@@ -27,9 +27,11 @@
* isdntelctl - i4b set telephone interface options
* ------------------------------------------------
*
+ * $Id: main.c,v 1.12 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Fri Jul 30 08:16:21 1999]
+ * last edit-date: [Mon Dec 13 21:54:50 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntest/Makefile b/usr.sbin/i4b/isdntest/Makefile
index c1240cc..7444055 100644
--- a/usr.sbin/i4b/isdntest/Makefile
+++ b/usr.sbin/i4b/isdntest/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
PROG = isdntest
SRCS = main.c
MAN8 = isdntest.8
diff --git a/usr.sbin/i4b/isdntest/isdntest.8 b/usr.sbin/i4b/isdntest/isdntest.8
index 943c451..0f59393 100644
--- a/usr.sbin/i4b/isdntest/isdntest.8
+++ b/usr.sbin/i4b/isdntest/isdntest.8
@@ -22,11 +22,13 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: isdntest.8,v 1.10 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:21:18 1999]
+.\" last edit-date: [Mon Dec 13 23:07:23 1999]
.\"
-.Dd July 9, 1998
+.Dd December 10, 1999
.Dt ISDNTEST 8
.Os
.Sh NAME
@@ -35,9 +37,11 @@
.Sh SYNOPSIS
.Nm
.Op Fl c Ar unit
-.Op Fl h
+.Op Fl d Ar level
.Op Fl i Ar number
+.Op Fl h
.Op Fl o Ar number
+.Op Fl t Ar num
.Op Fl w
.Sh DESCRIPTION
.Nm isdntest
@@ -56,12 +60,16 @@ The following options are available:
.Bl -tag -width Ds
.It Fl c
Use controller unit number for test.
+.It Fl d
+Set the debugging level
.It Fl h
Use HDLC as the B channel layer 1 protocol instead of no protocol.
.It Fl i
Use number to verify the incoming number.
.It Fl o
Use number as the outgoing number to dial.
+.It Fl t
+Set number of times the test pattern on the B-channel is exchanged
.It Fl w
Wait for keyboard input for terminating the call.
.El
@@ -97,8 +105,8 @@ has to be finished by the user by entering Control-C.
.Sh FILES
/dev/i4b
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-utility and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+utility and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdntest/main.c b/usr.sbin/i4b/isdntest/main.c
index ba29735..d050613 100644
--- a/usr.sbin/i4b/isdntest/main.c
+++ b/usr.sbin/i4b/isdntest/main.c
@@ -27,9 +27,11 @@
* main.c - i4b selftest utility
* -----------------------------
*
- * $FreeBSD$
+ * $Id: main.c,v 1.15 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Fri Jul 30 08:16:37 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:55:19 1999]
*
*---------------------------------------------------------------------------*/
@@ -87,6 +89,26 @@ int controller = 0;
int dotest = 0;
/*---------------------------------------------------------------------------*
+ * usage display and exit
+ *---------------------------------------------------------------------------*/
+static void
+usage(void)
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "isdntest - i4b selftest, version %d.%d.%d, compiled %s %s\n",VERSION, REL, STEP, __DATE__, __TIME__);
+ fprintf(stderr, "usage: isdntest [-c ctrl] [-d level] [-h] [-i telno] [-o telno] [-t num] [-w]\n");
+ fprintf(stderr, " -c <ctrl> specify controller to use\n");
+ fprintf(stderr, " -d <level> set debug level\n");
+ fprintf(stderr, " -h use HDLC as Bchannel protocol\n");
+ fprintf(stderr, " -i <telno> incoming telephone number\n");
+ fprintf(stderr, " -o <telno> outgoing telephone number\n");
+ fprintf(stderr, " -t <num> send test pattern num times\n");
+ fprintf(stderr, " -w wait for keyboard entry to disconnect\n");
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------*
* program entry
*---------------------------------------------------------------------------*/
int
@@ -301,25 +323,6 @@ isdnrdhdl(int isdnfd)
}
/*---------------------------------------------------------------------------*
- * usage display and exit
- *---------------------------------------------------------------------------*/
-static void
-usage(void)
-{
- fprintf(stderr, "\n");
- fprintf(stderr, "isdntest - i4b selftest, version %d.%d.%d, compiled %s %s\n",VERSION, REL, STEP, __DATE__, __TIME__);
- fprintf(stderr, "usage: isdntest -c <ctrl> -h -i <telno> -o <telno>\n");
- fprintf(stderr, " -c <ctrl> specify controller to use\n");
- fprintf(stderr, " -h use HDLC as Bchannel protocol\n");
- fprintf(stderr, " -i <telno> incoming telephone number\n");
- fprintf(stderr, " -o <telno> outgoing telephone number\n");
- fprintf(stderr, " -w wait for keyboard entry to disconnect\n");
- fprintf(stderr, " -t num send test pattern num times\n");
- fprintf(stderr, "\n");
- exit(1);
-}
-
-/*---------------------------------------------------------------------------*
* initiate an outgoing connection
*---------------------------------------------------------------------------*/
int
diff --git a/usr.sbin/i4b/isdntrace/1tr6.c b/usr.sbin/i4b/isdntrace/1tr6.c
index fe50837..db2bc71 100644
--- a/usr.sbin/i4b/isdntrace/1tr6.c
+++ b/usr.sbin/i4b/isdntrace/1tr6.c
@@ -27,9 +27,11 @@
* 1tr6.c - print 1TR6 protocol traces
* -----------------------------------
*
- * $FreeBSD$
+ * $Id: 1tr6.c,v 1.6 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:22:11 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:55:31 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/Makefile b/usr.sbin/i4b/isdntrace/Makefile
index 150c18d..0596e5b 100644
--- a/usr.sbin/i4b/isdntrace/Makefile
+++ b/usr.sbin/i4b/isdntrace/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
PROG = isdntrace
SRCS = q921.c q931.c q931_util.c q932_fac.c 1tr6.c trace.c \
pcause_1tr6.c pcause_q850.c
diff --git a/usr.sbin/i4b/isdntrace/cable.txt b/usr.sbin/i4b/isdntrace/cable.txt
index 1190668..21a1cdb 100644
--- a/usr.sbin/i4b/isdntrace/cable.txt
+++ b/usr.sbin/i4b/isdntrace/cable.txt
@@ -3,9 +3,11 @@
* Custom cable to trace an ISDN S0 bus with two passive (!) ISDN boards
* ---------------------------------------------------------------------
*
- * $FreeBSD$
+ * $Id: cable.txt,v 1.4 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Thu Jan 22 19:57:50 1998]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:55:42 1999]
*
* -hm documentation of analyze mode
*
diff --git a/usr.sbin/i4b/isdntrace/isdntrace.8 b/usr.sbin/i4b/isdntrace/isdntrace.8
index d648f1c..fc13bd4 100644
--- a/usr.sbin/i4b/isdntrace/isdntrace.8
+++ b/usr.sbin/i4b/isdntrace/isdntrace.8
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: isdntrace.8,v 1.12 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:22:24 1999]
+.\" last edit-date: [Mon Dec 13 23:08:17 1999]
.\"
.Dd October 19, 1998
.Dt ISDNTRACE 8
@@ -196,14 +198,14 @@ ETSI Recommendation ETS 300 181 (04/93), ETS 300 182 (04/93)
.Pp
ITU Recommendation X.208, X.209
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-utility was written by
-.An Gary Jennejohn
-and
+utility was written by
+.An Gary Jennejohn
+and
.An Hellmuth Michaelis .
.Pp
-This manual page was written by
-.An Hellmuth Michaelis Aq hm@kts.org
+This manual page was written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdntrace/pcause_1tr6.c b/usr.sbin/i4b/isdntrace/pcause_1tr6.c
index 69f4501..b319d74 100644
--- a/usr.sbin/i4b/isdntrace/pcause_1tr6.c
+++ b/usr.sbin/i4b/isdntrace/pcause_1tr6.c
@@ -27,9 +27,11 @@
* printing cause values
* ---------------------
*
+ * $Id: pcause_1tr6.c,v 1.6 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:22:30 1999]
+ * last edit-date: [Mon Dec 13 21:56:03 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/pcause_1tr6.h b/usr.sbin/i4b/isdntrace/pcause_1tr6.h
index 50cca66..67f50de 100644
--- a/usr.sbin/i4b/isdntrace/pcause_1tr6.h
+++ b/usr.sbin/i4b/isdntrace/pcause_1tr6.h
@@ -27,9 +27,11 @@
* pcause1tr6.h - 1TR6 causes definitions
* --------------------------------------
*
+ * $Id: pcause_1tr6.h,v 1.5 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:22:36 1999]
+ * last edit-date: [Mon Dec 13 21:56:10 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/pcause_q850.c b/usr.sbin/i4b/isdntrace/pcause_q850.c
index 2ac097e..57eaf32 100644
--- a/usr.sbin/i4b/isdntrace/pcause_q850.c
+++ b/usr.sbin/i4b/isdntrace/pcause_q850.c
@@ -27,9 +27,11 @@
* printing cause values
* ---------------------
*
+ * $Id: pcause_q850.c,v 1.6 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:22:42 1999]
+ * last edit-date: [Mon Dec 13 21:56:18 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/pcause_q850.h b/usr.sbin/i4b/isdntrace/pcause_q850.h
index 01f2178..ea21770 100644
--- a/usr.sbin/i4b/isdntrace/pcause_q850.h
+++ b/usr.sbin/i4b/isdntrace/pcause_q850.h
@@ -27,9 +27,11 @@
* pcauseq850.h - Q.850 causes definitions
* ---------------------------------------
*
+ * $Id: pcause_q850.h,v 1.5 1999/12/13 21:25:26 hm Exp $
+ *
* $FreeBSD$
*
- * last edit-date: [Sun Feb 14 10:22:48 1999]
+ * last edit-date: [Mon Dec 13 21:56:25 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/q921.c b/usr.sbin/i4b/isdntrace/q921.c
index 5ad964d..e8c14dc 100644
--- a/usr.sbin/i4b/isdntrace/q921.c
+++ b/usr.sbin/i4b/isdntrace/q921.c
@@ -30,18 +30,11 @@
* q.921.c - print Q.921 traces
* ----------------------------
*
- * $FreeBSD$
+ * $Id: q921.c,v 1.4 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Thu Apr 16 15:38:34 1998]
+ * $FreeBSD$
*
- * -hm splitting
- * -hm printing to buffer
- * -hm slightly reformatted TEI management proc output
- * -hm minor fixes
- * -hm fixing response/command
- * -hm fixing count off by one
- * -hm dump only Q.921 part of frame
- * -hm cleanup
+ * last edit-date: [Mon Dec 13 21:56:46 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/q931.c b/usr.sbin/i4b/isdntrace/q931.c
index f997f9e..d61ec9a 100644
--- a/usr.sbin/i4b/isdntrace/q931.c
+++ b/usr.sbin/i4b/isdntrace/q931.c
@@ -27,9 +27,11 @@
* q931.c - print Q.931 traces
* ---------------------------
*
- * $FreeBSD$
+ * $Id: q931.c,v 1.6 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:23:03 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:56:56 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/q931_util.c b/usr.sbin/i4b/isdntrace/q931_util.c
index 2afdd5a..bca17dd 100644
--- a/usr.sbin/i4b/isdntrace/q931_util.c
+++ b/usr.sbin/i4b/isdntrace/q931_util.c
@@ -27,9 +27,11 @@
* q931_util.c - utility functions to print Q.931 traces
* -----------------------------------------------------
*
- * $FreeBSD$
+ * $Id: q931_util.c,v 1.6 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:23:10 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:57:03 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/q932_fac.c b/usr.sbin/i4b/isdntrace/q932_fac.c
index 55354a8..dc3194b 100644
--- a/usr.sbin/i4b/isdntrace/q932_fac.c
+++ b/usr.sbin/i4b/isdntrace/q932_fac.c
@@ -27,9 +27,11 @@
* q932_fac.c - decode Q.932 facilities
* ------------------------------------
*
- * $FreeBSD$
+ * $Id: q932_fac.c,v 1.6 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:23:16 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:57:11 1999]
*
*---------------------------------------------------------------------------
*
diff --git a/usr.sbin/i4b/isdntrace/q932_fac.h b/usr.sbin/i4b/isdntrace/q932_fac.h
index 176a705..a3641cf 100644
--- a/usr.sbin/i4b/isdntrace/q932_fac.h
+++ b/usr.sbin/i4b/isdntrace/q932_fac.h
@@ -27,9 +27,11 @@
* q932_fac.h - facility header file
* ---------------------------------
*
- * $FreeBSD$
+ * $Id: q932_fac.h,v 1.6 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:23:22 1999]
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:57:18 1999]
*
*---------------------------------------------------------------------------
*
diff --git a/usr.sbin/i4b/isdntrace/trace.c b/usr.sbin/i4b/isdntrace/trace.c
index 465d363..b38127f 100644
--- a/usr.sbin/i4b/isdntrace/trace.c
+++ b/usr.sbin/i4b/isdntrace/trace.c
@@ -35,22 +35,11 @@
* trace.c - print traces of D (B) channel activity for isdn4bsd
* -------------------------------------------------------------
*
- * $FreeBSD$
+ * $Id: trace.c,v 1.15 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Fri Jul 30 08:16:59 1999]
+ * $FreeBSD$
*
- * -hm rewriting for isic and new trace format
- * -hm new option -f, use automatic name for -o
- * -hm changed default option setting
- * -hm multi unit support
- * -hm analyzer functionality
- * -hm binary record/playback
- * -hm -p option
- * -hm cleanup
- * -hm adding date to timestamp field
- * -hm reopen files on SIGUSR1 for rotation
- * -hm Joerg reported a bug with commandline options
- * -hm I.430 INFO signals from layer 1
+ * last edit-date: [Mon Dec 13 21:57:48 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/isdntrace/trace.h b/usr.sbin/i4b/isdntrace/trace.h
index 276b340..c7cc165 100644
--- a/usr.sbin/i4b/isdntrace/trace.h
+++ b/usr.sbin/i4b/isdntrace/trace.h
@@ -35,12 +35,11 @@
* trace.h - header file for isdn trace
* ------------------------------------
*
- * $FreeBSD$
+ * $Id: trace.h,v 1.9 1999/12/13 21:25:26 hm Exp $
*
- * last edit-date: [Sun Feb 14 10:23:35 1999]
+ * $FreeBSD$
*
- * -hm splitting
- * -hm new filenames
+ * last edit-date: [Mon Dec 13 21:58:07 1999]
*
*---------------------------------------------------------------------------*/
diff --git a/usr.sbin/i4b/man/Makefile b/usr.sbin/i4b/man/Makefile
index 65248d6..7805718 100644
--- a/usr.sbin/i4b/man/Makefile
+++ b/usr.sbin/i4b/man/Makefile
@@ -1,3 +1,4 @@
+# $FreeBSD$
MAN4 = i4b.4 i4bctl.4 i4bipr.4 i4bq921.4 i4bq931.4 i4brbch.4 i4btel.4 \
i4btrc.4 isic.4 daic.4 i4bisppp.4
diff --git a/usr.sbin/i4b/man/daic.4 b/usr.sbin/i4b/man/daic.4
index 0053a8e..8db32c8 100644
--- a/usr.sbin/i4b/man/daic.4
+++ b/usr.sbin/i4b/man/daic.4
@@ -20,16 +20,18 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $FreeBSD$
+.\" $Id: daic.4,v 1.2 1999/12/13 22:11:55 hm Exp $
+.\"
+.\" last edit-date: [Tue Dec 14 22:13:53 1999]
.\"
-.\" last edit-date: [Fri Jan 30 22:49:48 1998]
+.\" $FreeBSD$
.\"
.\" -mh writing manual pages
.\"
.\"
.Dd January 30, 1998
.Dt DAIC 4
-.Os
+.Os
.Sh NAME
.Nm daic
.Nd isdn4bsd driver for EICON.Diehl active isdn cards
diff --git a/usr.sbin/i4b/man/i4b.4 b/usr.sbin/i4b/man/i4b.4
index bc5c4b1..eab852e 100644
--- a/usr.sbin/i4b/man/i4b.4
+++ b/usr.sbin/i4b/man/i4b.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4b.4,v 1.9 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:28 1999]
+.\" last edit-date: [Mon Dec 13 23:09:12 1999]
.\"
.Dd February 3, 1998
.Dt I4B 4
@@ -102,8 +104,8 @@ Charging information from the kernel.
.Pp
.Sh SEE ALSO
.Xr isdnd 8
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4bctl.4 b/usr.sbin/i4b/man/i4bctl.4
index 9cb4ee9..c059ff20 100644
--- a/usr.sbin/i4b/man/i4bctl.4
+++ b/usr.sbin/i4b/man/i4bctl.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4bctl.4,v 1.7 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:34 1999]
+.\" last edit-date: [Mon Dec 13 23:09:46 1999]
.\"
.Dd February 3, 1998
.Dt I4BCTL 4
@@ -44,8 +46,8 @@ utility to get and set the current debugging level and other information
of the isdn4bsd package kernel ISDN handling layers.
.Sh SEE ALSO
.Xr isdndebug 8
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4bipr.4 b/usr.sbin/i4b/man/i4bipr.4
index ce3fe13..847676d 100644
--- a/usr.sbin/i4b/man/i4bipr.4
+++ b/usr.sbin/i4b/man/i4bipr.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4bipr.4,v 1.11 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:40 1999]
+.\" last edit-date: [Mon Dec 13 23:10:25 1999]
.\"
.Dd July 6, 1998
.Dt I4BIPR 4
@@ -88,12 +90,12 @@ and
for
.Em link0 .
.Sh SEE ALSO
-.Xr tcpdump 1 ,
-.Xr bpf 4 ,
-.Xr isdnd.rc 5 ,
.Xr isdnd 8
-.Sh AUTHORS
+.Xr isdnd.rc 5
+.Xr bpf 4
+.Xr tcpdump 1
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4bisppp.4 b/usr.sbin/i4b/man/i4bisppp.4
index f68ca70..d7cd9f6 100644
--- a/usr.sbin/i4b/man/i4bisppp.4
+++ b/usr.sbin/i4b/man/i4bisppp.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4bisppp.4,v 1.12 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:45 1999]
+.\" last edit-date: [Mon Dec 13 23:11:15 1999]
.\"
.Dd December 22, 1998
.Dt I4BISPPP 4
@@ -95,18 +97,18 @@ See
for a more detailed discussion of the flags,
.Pp
.Sh SEE ALSO
-.Xr tcpdump 1 ,
-.Xr bpf 4 ,
-.Xr sppp 4 ,
-.Xr isdnd.rc 5 ,
-.Xr isdnd 8 ,
+.Xr isdnd 8
+.Xr isdnd.rc 5
.Xr spppcontrol 8
-.Sh AUTHORS
+.Xr sppp 4
+.Xr bpf 4
+.Xr tcpdump 1
+.Sh AUTHOR
The
.Nm
-device driver was written by
-.An Joerg Wunsch
-and then added to ISDN4BSD by
+device driver was written by
+.An Joerg Wunsch
+and then added to ISDN4BSD by
.An Gary Jennejohn .
-This manpage was written by
-.An Hellmuth Michaelis Aq hm@kts.org
+This manpage was written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4bq921.4 b/usr.sbin/i4b/man/i4bq921.4
index 85ec7d0..8d56732 100644
--- a/usr.sbin/i4b/man/i4bq921.4
+++ b/usr.sbin/i4b/man/i4bq921.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4bq921.4,v 1.8 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:51 1999]
+.\" last edit-date: [Mon Dec 13 23:11:55 1999]
.\"
.Dd February 3, 1998
.Dt I4BQ921 4
@@ -43,8 +45,8 @@ is the ISDN D channel layer 2 handler.
ITU Recommendation Q.920 and Q.921
.Sh SEE ALSO
.Xr i4bq931 4
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4bq931.4 b/usr.sbin/i4b/man/i4bq931.4
index 34dbd69..a70a942 100644
--- a/usr.sbin/i4b/man/i4bq931.4
+++ b/usr.sbin/i4b/man/i4bq931.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4bq931.4,v 1.8 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:36:57 1999]
+.\" last edit-date: [Mon Dec 13 23:12:33 1999]
.\"
.Dd February 3, 1998
.Dt I4BQ931 4
@@ -43,8 +45,8 @@ is the ISDN D channel layer 2 handler.
ITU Recommendation Q.930 and Q.931
.Sh SEE ALSO
.Xr i4bq921 4
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4brbch.4 b/usr.sbin/i4b/man/i4brbch.4
index a79f897..ac0ca71 100644
--- a/usr.sbin/i4b/man/i4brbch.4
+++ b/usr.sbin/i4b/man/i4brbch.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4brbch.4,v 1.8 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Sun Feb 14 10:37:03 1999]
+.\" last edit-date: [Mon Dec 13 23:13:04 1999]
.\"
.Dd February 3, 1998
.Dt I4BRBCH 4
@@ -42,10 +44,10 @@ The
driver provides an interface to the raw untranslated B-channel. It is
part of the isdn4bsd package.
.Sh SEE ALSO
-.Xr isdnd.rc 5 ,
.Xr isdnd 8
-.Sh AUTHORS
+.Xr isdnd.rc 5
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4btel.4 b/usr.sbin/i4b/man/i4btel.4
index cc1caac..34ae07b 100644
--- a/usr.sbin/i4b/man/i4btel.4
+++ b/usr.sbin/i4b/man/i4btel.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4btel.4,v 1.9 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Wed Apr 21 12:03:34 1999]
+.\" last edit-date: [Mon Dec 13 23:13:39 1999]
.\"
.Dd April 21, 1999
.Dt I4BTEL 4
@@ -122,13 +124,13 @@ USER --> A-law/u-law --> bitreversing --> ISDN-line
.Sh STANDARDS
A-Law and u-Law are specified in ITU Recommendation G.711.
.Sh SEE ALSO
-.Xr g711conv 1 ,
-.Xr isdnphone 1 ,
-.Xr isdnd.rc 5 ,
-.Xr isdnd 8 ,
.Xr isdntelctl 8
-.Sh AUTHORS
+.Xr g711conv 1
+.Xr isdnphone 1
+.Xr isdnd 8
+.Xr isdnd.rc 5
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/i4btrc.4 b/usr.sbin/i4b/man/i4btrc.4
index 78e5317..020ac6c 100644
--- a/usr.sbin/i4b/man/i4btrc.4
+++ b/usr.sbin/i4b/man/i4btrc.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: i4btrc.4,v 1.9 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Fri Jul 30 09:15:57 1999]
+.\" last edit-date: [Mon Dec 13 23:14:19 1999]
.\"
.Dd July 30, 1999
.Dt I4BTRC 4
@@ -44,10 +46,10 @@ and queues it to be read and further processed by the
.Xr isdntrace 8
utility.
.Sh SEE ALSO
-.Xr isdnd 8 ,
+.Xr isdnd 8
.Xr isdntrace 8
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-device driver and this manpage were written by
-.An Hellmuth Michaelis Aq hm@kts.org
+device driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/man/isic.4 b/usr.sbin/i4b/man/isic.4
index 0c84e77..aff6b78 100644
--- a/usr.sbin/i4b/man/isic.4
+++ b/usr.sbin/i4b/man/isic.4
@@ -22,9 +22,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
+.\" $Id: isic.4,v 1.26 1999/12/13 22:11:55 hm Exp $
+.\"
.\" $FreeBSD$
.\"
-.\" last edit-date: [Fri Jul 30 09:20:24 1999]
+.\" last edit-date: [Mon Dec 13 23:16:08 1999]
.\"
.Dd July 30, 1999
.Dt ISIC 4
@@ -34,6 +36,13 @@
.Nd isdn4bsd Siemens ISDN Chipset device driver
.Sh FreeBSD SYNOPSIS
.Pp
+.Em Note:
+the keywords
+.Em net
+and
+.Em vector isicintr
+are no longer required for FreeBSD-current (FreeBSD 4.x)!
+.Pp
For a Teles S0/8 or Niccy 1008 card:
.Cd options \&"TEL_S0_8\&"
.Cd "device isic0 at isa? iomem 0xd0000 net irq 5 flags 1 vector isicintr"
@@ -397,26 +406,22 @@ for their boards, it is likely that there are many, many bugs left.
CCITT Recommendation I.430
.Sh SEE ALSO
-.Xr i4bq921 4 ,
+.Xr i4bq921 4
.Xr i4bq931 4
-.Sh AUTHORS
+.Sh AUTHOR
The
.Nm
-driver and this manpage were written by
-.An Hellmuth Michaelis .
-It is based
-on earlier work of
+driver and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
+It is based on earlier work of
.An Arne Helme ,
.An Andrew Gordon
-and
+and
.An Gary Jennejohn .
-The author can be contacted at hm@kts.org.
.Pp
-The complete porting to and maintenance of
-.Nx
-was done by
-.An Martin Husemann Aq martin@rumolt.teuto.de
+The complete porting to and maintenance of NetBSD was done by
+.An Martin Husemann Aq martin@rumolt.teuto.de .
.Pp
The NetBSD/Amiga ISDN Blaster/Master/MasterII driver was written by
-.An Ignatios Souvatzis Aq is@netbsd.org
+.An Ignatios Souvatzis Aq is@netbsd.org .
OpenPOWER on IntegriCloud